summaryrefslogtreecommitdiffstats
path: root/src/multimedia/platform
diff options
context:
space:
mode:
Diffstat (limited to 'src/multimedia/platform')
-rw-r--r--src/multimedia/platform/alsa/qalsaaudiodevice.cpp123
-rw-r--r--src/multimedia/platform/alsa/qalsaaudiodevice_p.h85
-rw-r--r--src/multimedia/platform/alsa/qalsaaudiosink.cpp749
-rw-r--r--src/multimedia/platform/alsa/qalsaaudiosink_p.h157
-rw-r--r--src/multimedia/platform/alsa/qalsaaudiosource.cpp805
-rw-r--r--src/multimedia/platform/alsa/qalsaaudiosource_p.h178
-rw-r--r--src/multimedia/platform/alsa/qalsaintegration.cpp61
-rw-r--r--src/multimedia/platform/alsa/qalsaintegration_p.h73
-rw-r--r--src/multimedia/platform/alsa/qalsamediadevices.cpp128
-rw-r--r--src/multimedia/platform/alsa/qalsamediadevices_p.h76
-rw-r--r--src/multimedia/platform/android/audio/qandroidaudiodecoder.cpp436
-rw-r--r--src/multimedia/platform/android/audio/qandroidaudiodecoder_p.h151
-rw-r--r--src/multimedia/platform/android/audio/qandroidaudiodevice.cpp75
-rw-r--r--src/multimedia/platform/android/audio/qandroidaudiodevice_p.h73
-rw-r--r--src/multimedia/platform/android/audio/qandroidaudiosink.cpp636
-rw-r--r--src/multimedia/platform/android/audio/qandroidaudiosink_p.h158
-rw-r--r--src/multimedia/platform/android/audio/qandroidaudiosource.cpp505
-rw-r--r--src/multimedia/platform/android/audio/qandroidaudiosource_p.h137
-rw-r--r--src/multimedia/platform/android/audio/qopenslesengine.cpp368
-rw-r--r--src/multimedia/platform/android/audio/qopenslesengine_p.h100
-rw-r--r--src/multimedia/platform/android/common/qandroidaudiooutput_p.h66
-rw-r--r--src/multimedia/platform/android/common/qandroidglobal_p.h64
-rw-r--r--src/multimedia/platform/android/common/qandroidmultimediautils.cpp176
-rw-r--r--src/multimedia/platform/android/common/qandroidmultimediautils_p.h78
-rw-r--r--src/multimedia/platform/android/common/qandroidvideooutput.cpp465
-rw-r--r--src/multimedia/platform/android/common/qandroidvideooutput_p.h213
-rw-r--r--src/multimedia/platform/android/common/qandroidvideosink.cpp70
-rw-r--r--src/multimedia/platform/android/common/qandroidvideosink_p.h77
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidcamera.cpp590
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidcamera_p.h133
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp794
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidcamerasession_p.h196
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidcapturesession.cpp472
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidcapturesession_p.h188
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidimagecapture.cpp113
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidimagecapture_p.h84
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidmediacapturesession.cpp152
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidmediacapturesession_p.h102
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidmediaencoder.cpp108
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidmediaencoder_p.h86
-rw-r--r--src/multimedia/platform/android/mediaplayer/qandroidmediaplayer.cpp983
-rw-r--r--src/multimedia/platform/android/mediaplayer/qandroidmediaplayer_p.h164
-rw-r--r--src/multimedia/platform/android/mediaplayer/qandroidmetadata.cpp202
-rw-r--r--src/multimedia/platform/android/mediaplayer/qandroidmetadata_p.h83
-rw-r--r--src/multimedia/platform/android/qandroidformatsinfo.cpp106
-rw-r--r--src/multimedia/platform/android/qandroidformatsinfo_p.h67
-rw-r--r--src/multimedia/platform/android/qandroidintegration.cpp161
-rw-r--r--src/multimedia/platform/android/qandroidintegration_p.h86
-rw-r--r--src/multimedia/platform/android/qandroidmediadevices.cpp116
-rw-r--r--src/multimedia/platform/android/qandroidmediadevices_p.h77
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidcamera.cpp1747
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidcamera_p.h242
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidmediametadataretriever.cpp171
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidmediametadataretriever_p.h102
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidmediaplayer.cpp581
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidmediaplayer_p.h169
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidmediarecorder.cpp344
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidmediarecorder_p.h196
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidmultimediautils.cpp79
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidmultimediautils_p.h76
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidsurfacetexture.cpp183
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidsurfacetexture_p.h95
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidsurfaceview.cpp186
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidsurfaceview_p.h113
-rw-r--r--src/multimedia/platform/darwin/audio/avfaudiodecoder.mm529
-rw-r--r--src/multimedia/platform/darwin/audio/avfaudiodecoder_p.h130
-rw-r--r--src/multimedia/platform/darwin/audio/qcoreaudiosessionmanager.mm473
-rw-r--r--src/multimedia/platform/darwin/audio/qcoreaudiosessionmanager_p.h131
-rw-r--r--src/multimedia/platform/darwin/audio/qcoreaudioutils.mm219
-rw-r--r--src/multimedia/platform/darwin/audio/qcoreaudioutils_p.h104
-rw-r--r--src/multimedia/platform/darwin/audio/qdarwinaudiodevice.mm153
-rw-r--r--src/multimedia/platform/darwin/audio/qdarwinaudiodevice_p.h87
-rw-r--r--src/multimedia/platform/darwin/audio/qdarwinaudiosink.mm691
-rw-r--r--src/multimedia/platform/darwin/audio/qdarwinaudiosink_p.h212
-rw-r--r--src/multimedia/platform/darwin/audio/qdarwinaudiosource.mm977
-rw-r--r--src/multimedia/platform/darwin/audio/qdarwinaudiosource_p.h280
-rw-r--r--src/multimedia/platform/darwin/avfvideobuffer.mm315
-rw-r--r--src/multimedia/platform/darwin/avfvideobuffer_p.h112
-rw-r--r--src/multimedia/platform/darwin/avfvideosink.mm212
-rw-r--r--src/multimedia/platform/darwin/avfvideosink_p.h129
-rw-r--r--src/multimedia/platform/darwin/camera/avfaudiopreviewdelegate.mm134
-rw-r--r--src/multimedia/platform/darwin/camera/avfaudiopreviewdelegate_p.h76
-rw-r--r--src/multimedia/platform/darwin/camera/avfcamera.mm1004
-rw-r--r--src/multimedia/platform/darwin/camera/avfcamera_p.h139
-rw-r--r--src/multimedia/platform/darwin/camera/avfcameradebug_p.h68
-rw-r--r--src/multimedia/platform/darwin/camera/avfcamerarenderer.mm298
-rw-r--r--src/multimedia/platform/darwin/camera/avfcamerarenderer_p.h129
-rw-r--r--src/multimedia/platform/darwin/camera/avfcameraservice.mm201
-rw-r--r--src/multimedia/platform/darwin/camera/avfcameraservice_p.h120
-rw-r--r--src/multimedia/platform/darwin/camera/avfcamerasession.mm521
-rw-r--r--src/multimedia/platform/darwin/camera/avfcamerasession_p.h162
-rw-r--r--src/multimedia/platform/darwin/camera/avfcamerautility.mm714
-rw-r--r--src/multimedia/platform/darwin/camera/avfcamerautility_p.h201
-rw-r--r--src/multimedia/platform/darwin/camera/avfimagecapture.mm416
-rw-r--r--src/multimedia/platform/darwin/camera/avfimagecapture_p.h117
-rw-r--r--src/multimedia/platform/darwin/camera/avfmediaassetwriter.mm579
-rw-r--r--src/multimedia/platform/darwin/camera/avfmediaassetwriter_p.h90
-rw-r--r--src/multimedia/platform/darwin/camera/avfmediaencoder.mm649
-rw-r--r--src/multimedia/platform/darwin/camera/avfmediaencoder_p.h131
-rw-r--r--src/multimedia/platform/darwin/common/avfmetadata.mm398
-rw-r--r--src/multimedia/platform/darwin/common/avfmetadata_p.h73
-rw-r--r--src/multimedia/platform/darwin/mediaplayer/avfdisplaylink.mm241
-rw-r--r--src/multimedia/platform/darwin/mediaplayer/avfdisplaylink_p.h101
-rw-r--r--src/multimedia/platform/darwin/mediaplayer/avfmediaplayer.mm1161
-rw-r--r--src/multimedia/platform/darwin/mediaplayer/avfmediaplayer_p.h180
-rw-r--r--src/multimedia/platform/darwin/mediaplayer/avfvideorenderercontrol.mm272
-rw-r--r--src/multimedia/platform/darwin/mediaplayer/avfvideorenderercontrol_p.h103
-rw-r--r--src/multimedia/platform/darwin/qdarwinformatsinfo.mm246
-rw-r--r--src/multimedia/platform/darwin/qdarwinformatsinfo_p.h74
-rw-r--r--src/multimedia/platform/darwin/qdarwinintegration.mm113
-rw-r--r--src/multimedia/platform/darwin/qdarwinintegration_p.h84
-rw-r--r--src/multimedia/platform/darwin/qdarwinmediadevices.mm348
-rw-r--r--src/multimedia/platform/darwin/qdarwinmediadevices_p.h94
-rw-r--r--src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder.cpp558
-rw-r--r--src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder_p.h144
-rw-r--r--src/multimedia/platform/gstreamer/audio/qgstreameraudiodevice.cpp92
-rw-r--r--src/multimedia/platform/gstreamer/audio/qgstreameraudiodevice_p.h78
-rw-r--r--src/multimedia/platform/gstreamer/audio/qgstreameraudiosink.cpp395
-rw-r--r--src/multimedia/platform/gstreamer/audio/qgstreameraudiosink_p.h157
-rw-r--r--src/multimedia/platform/gstreamer/audio/qgstreameraudiosource.cpp407
-rw-r--r--src/multimedia/platform/gstreamer/audio/qgstreameraudiosource_p.h159
-rw-r--r--src/multimedia/platform/gstreamer/common/qgst_p.h620
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstappsrc.cpp308
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstappsrc_p.h132
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstpipeline.cpp375
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstpipeline_p.h139
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreameraudioinput.cpp135
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreameraudioinput_p.h107
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreameraudiooutput.cpp120
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreameraudiooutput_p.h104
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamerbufferprobe.cpp119
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamerbufferprobe_p.h92
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamermediaplayer.cpp864
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamermediaplayer_p.h187
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamermessage.cpp90
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamermessage_p.h86
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamermetadata.cpp305
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamermetadata_p.h73
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamervideooutput.cpp180
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamervideooutput_p.h106
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamervideooverlay.cpp253
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamervideooverlay_p.h110
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp261
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamervideosink_p.h116
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstsubtitlesink.cpp192
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstsubtitlesink_p.h106
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstutils.cpp423
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstutils_p.h85
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstvideobuffer.cpp373
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstvideobuffer_p.h103
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstvideorenderersink.cpp601
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstvideorenderersink_p.h171
-rw-r--r--src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp738
-rw-r--r--src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera_p.h138
-rw-r--r--src/multimedia/platform/gstreamer/mediacapture/qgstreamerimagecapture.cpp301
-rw-r--r--src/multimedia/platform/gstreamer/mediacapture/qgstreamerimagecapture_p.h121
-rw-r--r--src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture.cpp370
-rw-r--r--src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture_p.h129
-rw-r--r--src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp439
-rw-r--r--src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder_p.h125
-rw-r--r--src/multimedia/platform/gstreamer/qgstreamerformatinfo.cpp459
-rw-r--r--src/multimedia/platform/gstreamer/qgstreamerformatinfo_p.h81
-rw-r--r--src/multimedia/platform/gstreamer/qgstreamerintegration.cpp123
-rw-r--r--src/multimedia/platform/gstreamer/qgstreamerintegration_p.h90
-rw-r--r--src/multimedia/platform/gstreamer/qgstreamermediadevices.cpp265
-rw-r--r--src/multimedia/platform/gstreamer/qgstreamermediadevices_p.h86
-rw-r--r--src/multimedia/platform/pulseaudio/qaudioengine_pulse.cpp479
-rw-r--r--src/multimedia/platform/pulseaudio/qaudioengine_pulse_p.h127
-rw-r--r--src/multimedia/platform/pulseaudio/qpulseaudiodevice.cpp87
-rw-r--r--src/multimedia/platform/pulseaudio/qpulseaudiodevice_p.h75
-rw-r--r--src/multimedia/platform/pulseaudio/qpulseaudiointegration.cpp68
-rw-r--r--src/multimedia/platform/pulseaudio/qpulseaudiointegration_p.h76
-rw-r--r--src/multimedia/platform/pulseaudio/qpulseaudiomediadevices.cpp82
-rw-r--r--src/multimedia/platform/pulseaudio/qpulseaudiomediadevices_p.h79
-rw-r--r--src/multimedia/platform/pulseaudio/qpulseaudiosink.cpp709
-rw-r--r--src/multimedia/platform/pulseaudio/qpulseaudiosink_p.h155
-rw-r--r--src/multimedia/platform/pulseaudio/qpulseaudiosource.cpp645
-rw-r--r--src/multimedia/platform/pulseaudio/qpulseaudiosource_p.h154
-rw-r--r--src/multimedia/platform/pulseaudio/qpulsehelpers.cpp126
-rw-r--r--src/multimedia/platform/pulseaudio/qpulsehelpers_p.h70
-rw-r--r--src/multimedia/platform/qgstreamer_platformspecificinterface.cpp21
-rw-r--r--src/multimedia/platform/qgstreamer_platformspecificinterface_p.h34
-rw-r--r--src/multimedia/platform/qnx/audio/qnxaudioutils.cpp128
-rw-r--r--src/multimedia/platform/qnx/audio/qnxaudioutils_p.h66
-rw-r--r--src/multimedia/platform/qnx/audio/qqnxaudiodevice.cpp122
-rw-r--r--src/multimedia/platform/qnx/audio/qqnxaudiodevice_p.h77
-rw-r--r--src/multimedia/platform/qnx/audio/qqnxaudiosink.cpp533
-rw-r--r--src/multimedia/platform/qnx/audio/qqnxaudiosink_p.h150
-rw-r--r--src/multimedia/platform/qnx/audio/qqnxaudiosource.cpp421
-rw-r--r--src/multimedia/platform/qnx/audio/qqnxaudiosource_p.h142
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameraaudioencodersettingscontrol.cpp87
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameraaudioencodersettingscontrol_p.h77
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameracontrol.cpp97
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameracontrol_p.h96
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameraexposurecontrol.cpp288
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameraexposurecontrol_p.h89
-rw-r--r--src/multimedia/platform/qnx/camera/bbcamerafocuscontrol.cpp300
-rw-r--r--src/multimedia/platform/qnx/camera/bbcamerafocuscontrol_p.h99
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameraimagecapturecontrol.cpp89
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameraimagecapturecontrol_p.h80
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameraimageprocessingcontrol.cpp118
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameraimageprocessingcontrol_p.h75
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameramediarecordercontrol.cpp149
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameramediarecordercontrol_p.h84
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameraorientationhandler.cpp113
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameraorientationhandler_p.h80
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameraservice.cpp96
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameraservice_p.h100
-rw-r--r--src/multimedia/platform/qnx/camera/bbcamerasession.cpp1049
-rw-r--r--src/multimedia/platform/qnx/camera/bbcamerasession_p.h202
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameravideoencodersettingscontrol.cpp88
-rw-r--r--src/multimedia/platform/qnx/camera/bbcameravideoencodersettingscontrol_p.h78
-rw-r--r--src/multimedia/platform/qnx/common/windowgrabber.cpp419
-rw-r--r--src/multimedia/platform/qnx/common/windowgrabber_p.h155
-rw-r--r--src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp630
-rw-r--r--src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol_p.h183
-rw-r--r--src/multimedia/platform/qnx/mediaplayer/mmrenderermetadata.cpp298
-rw-r--r--src/multimedia/platform/qnx/mediaplayer/mmrenderermetadata_p.h110
-rw-r--r--src/multimedia/platform/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp192
-rw-r--r--src/multimedia/platform/qnx/mediaplayer/mmrendererplayervideorenderercontrol_p.h95
-rw-r--r--src/multimedia/platform/qnx/mediaplayer/mmrendererutil.cpp165
-rw-r--r--src/multimedia/platform/qnx/mediaplayer/mmrendererutil_p.h68
-rw-r--r--src/multimedia/platform/qnx/mediaplayer/mmrenderervideowindowcontrol.cpp378
-rw-r--r--src/multimedia/platform/qnx/mediaplayer/mmrenderervideowindowcontrol_p.h118
-rw-r--r--src/multimedia/platform/qnx/mediaplayer/mmreventmediaplayercontrol.cpp229
-rw-r--r--src/multimedia/platform/qnx/mediaplayer/mmreventmediaplayercontrol_p.h95
-rw-r--r--src/multimedia/platform/qnx/mediaplayer/mmreventthread.cpp121
-rw-r--r--src/multimedia/platform/qnx/mediaplayer/mmreventthread_p.h90
-rw-r--r--src/multimedia/platform/qnx/qqnxdevicemanager.cpp122
-rw-r--r--src/multimedia/platform/qnx/qqnxdevicemanager_p.h73
-rw-r--r--src/multimedia/platform/qnx/qqnxintegration.cpp69
-rw-r--r--src/multimedia/platform/qnx/qqnxintegration_p.h76
-rw-r--r--src/multimedia/platform/qplatformaudiodecoder.cpp201
-rw-r--r--src/multimedia/platform/qplatformaudiodecoder_p.h59
-rw-r--r--src/multimedia/platform/qplatformaudioinput_p.h49
-rw-r--r--src/multimedia/platform/qplatformaudiooutput_p.h45
-rw-r--r--src/multimedia/platform/qplatformaudioresampler_p.h33
-rw-r--r--src/multimedia/platform/qplatformcamera.cpp121
-rw-r--r--src/multimedia/platform/qplatformcamera_p.h83
-rw-r--r--src/multimedia/platform/qplatformcapturablewindows_p.h44
-rw-r--r--src/multimedia/platform/qplatformimagecapture.cpp164
-rw-r--r--src/multimedia/platform/qplatformimagecapture_p.h41
-rw-r--r--src/multimedia/platform/qplatformmediacapture.cpp80
-rw-r--r--src/multimedia/platform/qplatformmediacapture_p.h73
-rw-r--r--src/multimedia/platform/qplatformmediadevices.cpp151
-rw-r--r--src/multimedia/platform/qplatformmediadevices_p.h101
-rw-r--r--src/multimedia/platform/qplatformmediaencoder.cpp195
-rw-r--r--src/multimedia/platform/qplatformmediaformatinfo.cpp40
-rw-r--r--src/multimedia/platform/qplatformmediaformatinfo_p.h40
-rw-r--r--src/multimedia/platform/qplatformmediaintegration.cpp282
-rw-r--r--src/multimedia/platform/qplatformmediaintegration_p.h139
-rw-r--r--src/multimedia/platform/qplatformmediaplayer.cpp354
-rw-r--r--src/multimedia/platform/qplatformmediaplayer_p.h94
-rw-r--r--src/multimedia/platform/qplatformmediaplugin.cpp14
-rw-r--r--src/multimedia/platform/qplatformmediaplugin_p.h42
-rw-r--r--src/multimedia/platform/qplatformmediarecorder.cpp75
-rw-r--r--src/multimedia/platform/qplatformmediarecorder_p.h (renamed from src/multimedia/platform/qplatformmediaencoder_p.h)76
-rw-r--r--src/multimedia/platform/qplatformsurfacecapture.cpp83
-rw-r--r--src/multimedia/platform/qplatformsurfacecapture_p.h87
-rw-r--r--src/multimedia/platform/qplatformvideodevices.cpp12
-rw-r--r--src/multimedia/platform/qplatformvideodevices_p.h46
-rw-r--r--src/multimedia/platform/qplatformvideosink.cpp142
-rw-r--r--src/multimedia/platform/qplatformvideosink_p.h99
-rw-r--r--src/multimedia/platform/qplatformvideosource.cpp15
-rw-r--r--src/multimedia/platform/qplatformvideosource_p.h58
-rw-r--r--src/multimedia/platform/wasm/audio/qwasmaudiodevice.cpp83
-rw-r--r--src/multimedia/platform/wasm/audio/qwasmaudiodevice_p.h67
-rw-r--r--src/multimedia/platform/wasm/audio/qwasmaudiosink.cpp487
-rw-r--r--src/multimedia/platform/wasm/audio/qwasmaudiosink_p.h124
-rw-r--r--src/multimedia/platform/wasm/audio/qwasmaudiosource.cpp347
-rw-r--r--src/multimedia/platform/wasm/audio/qwasmaudiosource_p.h111
-rw-r--r--src/multimedia/platform/wasm/qwasmmediadevices.cpp92
-rw-r--r--src/multimedia/platform/wasm/qwasmmediadevices_p.h81
-rw-r--r--src/multimedia/platform/wasm/qwasmmediaintegration.cpp75
-rw-r--r--src/multimedia/platform/wasm/qwasmmediaintegration_p.h76
-rw-r--r--src/multimedia/platform/windows/audio/qwindowsaudiodevice.cpp230
-rw-r--r--src/multimedia/platform/windows/audio/qwindowsaudiodevice_p.h91
-rw-r--r--src/multimedia/platform/windows/audio/qwindowsaudiosink.cpp608
-rw-r--r--src/multimedia/platform/windows/audio/qwindowsaudiosink_p.h160
-rw-r--r--src/multimedia/platform/windows/audio/qwindowsaudiosource.cpp698
-rw-r--r--src/multimedia/platform/windows/audio/qwindowsaudiosource_p.h170
-rw-r--r--src/multimedia/platform/windows/audio/qwindowsaudioutils.cpp114
-rw-r--r--src/multimedia/platform/windows/audio/qwindowsaudioutils_p.h153
-rw-r--r--src/multimedia/platform/windows/common/mfmetadata.cpp521
-rw-r--r--src/multimedia/platform/windows/common/mfmetadata_p.h66
-rw-r--r--src/multimedia/platform/windows/common/qwindowsiupointer_p.h90
-rw-r--r--src/multimedia/platform/windows/common/qwindowsmultimediautils.cpp232
-rw-r--r--src/multimedia/platform/windows/common/qwindowsmultimediautils_p.h80
-rw-r--r--src/multimedia/platform/windows/decoder/mfaudiodecodercontrol.cpp454
-rw-r--r--src/multimedia/platform/windows/decoder/mfaudiodecodercontrol_p.h117
-rw-r--r--src/multimedia/platform/windows/decoder/mfdecodersourcereader.cpp197
-rw-r--r--src/multimedia/platform/windows/decoder/mfdecodersourcereader_p.h101
-rw-r--r--src/multimedia/platform/windows/evr/evrcustompresenter.cpp2005
-rw-r--r--src/multimedia/platform/windows/evr/evrcustompresenter_p.h387
-rw-r--r--src/multimedia/platform/windows/evr/evrd3dpresentengine.cpp393
-rw-r--r--src/multimedia/platform/windows/evr/evrd3dpresentengine_p.h165
-rw-r--r--src/multimedia/platform/windows/evr/evrdefs.cpp48
-rw-r--r--src/multimedia/platform/windows/evr/evrdefs_p.h364
-rw-r--r--src/multimedia/platform/windows/evr/evrhelpers.cpp174
-rw-r--r--src/multimedia/platform/windows/evr/evrhelpers_p.h112
-rw-r--r--src/multimedia/platform/windows/evr/evrvideowindowcontrol.cpp269
-rw-r--r--src/multimedia/platform/windows/evr/evrvideowindowcontrol_p.h107
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowscamera.cpp135
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowscamera_p.h91
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowsimagecapture.cpp225
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowsimagecapture_p.h100
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowsmediacapture.cpp143
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowsmediacapture_p.h98
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowsmediadevicereader.cpp1054
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowsmediadevicereader_p.h189
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowsmediadevicesession.cpp399
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowsmediadevicesession_p.h136
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder.cpp253
-rw-r--r--src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder_p.h106
-rw-r--r--src/multimedia/platform/windows/mfstream.cpp361
-rw-r--r--src/multimedia/platform/windows/mfstream_p.h159
-rw-r--r--src/multimedia/platform/windows/player/mfactivate.cpp87
-rw-r--r--src/multimedia/platform/windows/player/mfactivate_p.h223
-rw-r--r--src/multimedia/platform/windows/player/mfevrvideowindowcontrol.cpp91
-rw-r--r--src/multimedia/platform/windows/player/mfevrvideowindowcontrol_p.h74
-rw-r--r--src/multimedia/platform/windows/player/mfplayercontrol.cpp328
-rw-r--r--src/multimedia/platform/windows/player/mfplayercontrol_p.h139
-rw-r--r--src/multimedia/platform/windows/player/mfplayersession.cpp2009
-rw-r--r--src/multimedia/platform/windows/player/mfplayersession_p.h275
-rw-r--r--src/multimedia/platform/windows/player/mftvideo.cpp725
-rw-r--r--src/multimedia/platform/windows/player/mftvideo_p.h131
-rw-r--r--src/multimedia/platform/windows/player/mfvideorenderercontrol.cpp2318
-rw-r--r--src/multimedia/platform/windows/player/mfvideorenderercontrol_p.h95
-rw-r--r--src/multimedia/platform/windows/player/samplegrabber.cpp172
-rw-r--r--src/multimedia/platform/windows/player/samplegrabber_p.h103
-rw-r--r--src/multimedia/platform/windows/qwindowsformatinfo.cpp104
-rw-r--r--src/multimedia/platform/windows/qwindowsformatinfo_p.h69
-rw-r--r--src/multimedia/platform/windows/qwindowsintegration.cpp126
-rw-r--r--src/multimedia/platform/windows/qwindowsintegration_p.h89
-rw-r--r--src/multimedia/platform/windows/qwindowsmediadevices.cpp532
-rw-r--r--src/multimedia/platform/windows/qwindowsmediadevices_p.h96
-rw-r--r--src/multimedia/platform/windows/sourceresolver.cpp325
-rw-r--r--src/multimedia/platform/windows/sourceresolver_p.h115
338 files changed, 1310 insertions, 77010 deletions
diff --git a/src/multimedia/platform/alsa/qalsaaudiodevice.cpp b/src/multimedia/platform/alsa/qalsaaudiodevice.cpp
deleted file mode 100644
index ed0aa0030..000000000
--- a/src/multimedia/platform/alsa/qalsaaudiodevice.cpp
+++ /dev/null
@@ -1,123 +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$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// INTERNAL USE ONLY: Do NOT use for any other purpose.
-//
-
-#include "qalsaaudiodevice_p.h"
-
-#include <alsa/version.h>
-
-QT_BEGIN_NAMESPACE
-
-QAlsaAudioDeviceInfo::QAlsaAudioDeviceInfo(const QByteArray &dev, const QString &desc, QAudioDevice::Mode mode)
- : QAudioDevicePrivate(dev, mode)
-{
- description = desc;
-
- checkSurround();
-
- minimumChannelCount = 1;
- maximumChannelCount = 2;
- if (surround71)
- maximumChannelCount = 8;
- else if (surround40)
- maximumChannelCount = 4;
- else if (surround51)
- maximumChannelCount = 6;
-
- minimumSampleRate = 8000;
- maximumSampleRate = 48000;
-
- supportedSampleFormats << QAudioFormat::UInt8 << QAudioFormat::Int16 << QAudioFormat::Int32 << QAudioFormat::Float;
-}
-
-QAlsaAudioDeviceInfo::~QAlsaAudioDeviceInfo()
-{
-}
-
-void QAlsaAudioDeviceInfo::checkSurround()
-{
- surround40 = false;
- surround51 = false;
- surround71 = false;
-
- void **hints, **n;
- char *name, *descr, *io;
-
- if(snd_device_name_hint(-1, "pcm", &hints) < 0)
- return;
-
- n = hints;
-
- while (*n != NULL) {
- name = snd_device_name_get_hint(*n, "NAME");
- descr = snd_device_name_get_hint(*n, "DESC");
- io = snd_device_name_get_hint(*n, "IOID");
- if((name != NULL) && (descr != NULL)) {
- QString deviceName = QLatin1String(name);
- if (mode == QAudioDevice::Output) {
- if(deviceName.contains(QLatin1String("surround40")))
- surround40 = true;
- if(deviceName.contains(QLatin1String("surround51")))
- surround51 = true;
- if(deviceName.contains(QLatin1String("surround71")))
- surround71 = true;
- }
- }
- if(name != NULL)
- free(name);
- if(descr != NULL)
- free(descr);
- if(io != NULL)
- free(io);
- ++n;
- }
- snd_device_name_free_hint(hints);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/alsa/qalsaaudiodevice_p.h b/src/multimedia/platform/alsa/qalsaaudiodevice_p.h
deleted file mode 100644
index 4f7bc5757..000000000
--- a/src/multimedia/platform/alsa/qalsaaudiodevice_p.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$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-
-#ifndef QALSAAUDIODEVICEINFO_H
-#define QALSAAUDIODEVICEINFO_H
-
-#include <alsa/asoundlib.h>
-
-#include <QtCore/qbytearray.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qdebug.h>
-
-#include <QtMultimedia/qaudio.h>
-#include <private/qaudiodevice_p.h>
-#include <private/qaudiosystem_p.h>
-
-QT_BEGIN_NAMESPACE
-
-
-class QAlsaAudioDeviceInfo : public QAudioDevicePrivate
-{
-public:
- QAlsaAudioDeviceInfo(const QByteArray &dev, const QString &description, QAudioDevice::Mode mode);
- ~QAlsaAudioDeviceInfo();
-
-private:
- void checkSurround();
- bool surround40;
- bool surround51;
- bool surround71;
-};
-
-QT_END_NAMESPACE
-
-
-#endif // QALSAAUDIODEVICEINFO_H
diff --git a/src/multimedia/platform/alsa/qalsaaudiosink.cpp b/src/multimedia/platform/alsa/qalsaaudiosink.cpp
deleted file mode 100644
index 7157e9508..000000000
--- a/src/multimedia/platform/alsa/qalsaaudiosink.cpp
+++ /dev/null
@@ -1,749 +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$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// INTERNAL USE ONLY: Do NOT use for any other purpose.
-//
-
-#include <QtCore/qcoreapplication.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtMultimedia/private/qaudiohelpers_p.h>
-#include "qalsaaudiosink_p.h"
-#include "qalsaaudiodevice_p.h"
-#include <QLoggingCategory>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(lcAlsaOutput, "qt.multimedia.alsa.output")
-//#define DEBUG_AUDIO 1
-
-QAlsaAudioSink::QAlsaAudioSink(const QByteArray &device)
-{
- bytesAvailable = 0;
- handle = 0;
- access = SND_PCM_ACCESS_RW_INTERLEAVED;
- pcmformat = SND_PCM_FORMAT_S16;
- buffer_frames = 0;
- period_frames = 0;
- buffer_size = 0;
- period_size = 0;
- buffer_time = 100000;
- period_time = 20000;
- totalTimeValue = 0;
- audioBuffer = 0;
- errorState = QAudio::NoError;
- deviceState = QAudio::StoppedState;
- audioSource = 0;
- pullMode = true;
- resuming = false;
- opened = false;
-
- m_volume = 1.0f;
-
- m_device = device;
-
- timer = new QTimer(this);
- connect(timer,SIGNAL(timeout()),SLOT(userFeed()));
-}
-
-QAlsaAudioSink::~QAlsaAudioSink()
-{
- close();
- disconnect(timer, SIGNAL(timeout()));
- QCoreApplication::processEvents();
- delete timer;
-}
-
-void QAlsaAudioSink::setVolume(qreal vol)
-{
- m_volume = vol;
-}
-
-qreal QAlsaAudioSink::volume() const
-{
- return m_volume;
-}
-
-QAudio::Error QAlsaAudioSink::error() const
-{
- return errorState;
-}
-
-QAudio::State QAlsaAudioSink::state() const
-{
- return deviceState;
-}
-
-int QAlsaAudioSink::xrun_recovery(int err)
-{
- int count = 0;
- bool reset = false;
-
- // ESTRPIPE is not available in all OSes where ALSA is available
- int estrpipe = EIO;
-#ifdef ESTRPIPE
- estrpipe = ESTRPIPE;
-#endif
-
- if(err == -EPIPE) {
- errorState = QAudio::UnderrunError;
- emit errorChanged(errorState);
- err = snd_pcm_prepare(handle);
- if(err < 0)
- reset = true;
-
- } else if ((err == -estrpipe)||(err == -EIO)) {
- errorState = QAudio::IOError;
- emit errorChanged(errorState);
- while((err = snd_pcm_resume(handle)) == -EAGAIN){
- usleep(100);
- count++;
- if(count > 5) {
- reset = true;
- break;
- }
- }
- if(err < 0) {
- err = snd_pcm_prepare(handle);
- if(err < 0)
- reset = true;
- }
- }
- if(reset) {
- close();
- open();
- snd_pcm_prepare(handle);
- return 0;
- }
- return err;
-}
-
-int QAlsaAudioSink::setFormat()
-{
- snd_pcm_format_t pcmformat = SND_PCM_FORMAT_UNKNOWN;
-
- switch (settings.sampleFormat()) {
- case QAudioFormat::UInt8:
- pcmformat = SND_PCM_FORMAT_U8;
- break;
- case QAudioFormat::Int16:
- if constexpr (QSysInfo::ByteOrder == QSysInfo::BigEndian)
- pcmformat = SND_PCM_FORMAT_S16_LE;
- else
- pcmformat = SND_PCM_FORMAT_S16_BE;
- break;
- case QAudioFormat::Int32:
- if constexpr (QSysInfo::ByteOrder == QSysInfo::BigEndian)
- pcmformat = SND_PCM_FORMAT_S32_LE;
- else
- pcmformat = SND_PCM_FORMAT_S32_BE;
- break;
- case QAudioFormat::Float:
- if constexpr (QSysInfo::ByteOrder == QSysInfo::BigEndian)
- pcmformat = SND_PCM_FORMAT_FLOAT_LE;
- else
- pcmformat = SND_PCM_FORMAT_FLOAT_BE;
- default:
- break;
- }
-
- return pcmformat != SND_PCM_FORMAT_UNKNOWN
- ? snd_pcm_hw_params_set_format( handle, hwparams, pcmformat)
- : -1;
-}
-
-void QAlsaAudioSink::start(QIODevice* device)
-{
- if(deviceState != QAudio::StoppedState)
- deviceState = QAudio::StoppedState;
-
- errorState = QAudio::NoError;
-
- // Handle change of mode
- if(audioSource && !pullMode) {
- delete audioSource;
- audioSource = 0;
- }
-
- close();
-
- pullMode = true;
- audioSource = device;
-
- deviceState = QAudio::ActiveState;
-
- open();
-
- emit stateChanged(deviceState);
-}
-
-QIODevice* QAlsaAudioSink::start()
-{
- if(deviceState != QAudio::StoppedState)
- deviceState = QAudio::StoppedState;
-
- errorState = QAudio::NoError;
-
- // Handle change of mode
- if(audioSource && !pullMode) {
- delete audioSource;
- audioSource = 0;
- }
-
- close();
-
- audioSource = new AlsaOutputPrivate(this);
- audioSource->open(QIODevice::WriteOnly|QIODevice::Unbuffered);
- pullMode = false;
-
- deviceState = QAudio::IdleState;
-
- open();
-
- emit stateChanged(deviceState);
-
- return audioSource;
-}
-
-void QAlsaAudioSink::stop()
-{
- if(deviceState == QAudio::StoppedState)
- return;
- errorState = QAudio::NoError;
- deviceState = QAudio::StoppedState;
- close();
- emit stateChanged(deviceState);
-}
-
-bool QAlsaAudioSink::open()
-{
- if(opened)
- return true;
-
-#ifdef DEBUG_AUDIO
- QTime now(QTime::currentTime());
- qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
-#endif
- timeStamp.restart();
- elapsedTimeOffset = 0;
-
- int dir;
- int err = 0;
- int count=0;
- unsigned int sampleRate=settings.sampleRate();
-
- if (!settings.isValid()) {
- qWarning("QAudioSink: open error, invalid format.");
- } else if (settings.sampleRate() <= 0) {
- qWarning("QAudioSink: open error, invalid sample rate (%d).",
- settings.sampleRate());
- } else {
- err = -1;
- }
-
- if (err == 0) {
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit errorChanged(errorState);
- return false;
- }
-
- // Step 1: try and open the device
- while((count < 5) && (err < 0)) {
- err=snd_pcm_open(&handle, m_device.constData(),SND_PCM_STREAM_PLAYBACK,0);
- if(err < 0)
- count++;
- }
- if (( err < 0)||(handle == 0)) {
- errorState = QAudio::OpenError;
- emit errorChanged(errorState);
- deviceState = QAudio::StoppedState;
- return false;
- }
- snd_pcm_nonblock( handle, 0 );
-
- // Step 2: Set the desired HW parameters.
- snd_pcm_hw_params_alloca( &hwparams );
-
- bool fatal = false;
- QString errMessage;
- unsigned int chunks = 8;
-
- err = snd_pcm_hw_params_any( handle, hwparams );
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSink: snd_pcm_hw_params_any: err = %1").arg(err);
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params_set_rate_resample( handle, hwparams, 1 );
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSink: snd_pcm_hw_params_set_rate_resample: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params_set_access( handle, hwparams, access );
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSink: snd_pcm_hw_params_set_access: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = setFormat();
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSink: snd_pcm_hw_params_set_format: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channelCount() );
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSink: snd_pcm_hw_params_set_channels: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params_set_rate_near( handle, hwparams, &sampleRate, 0 );
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSink: snd_pcm_hw_params_set_rate_near: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- unsigned int maxBufferTime = 0;
- unsigned int minBufferTime = 0;
- unsigned int maxPeriodTime = 0;
- unsigned int minPeriodTime = 0;
-
- err = snd_pcm_hw_params_get_buffer_time_max(hwparams, &maxBufferTime, &dir);
- if ( err >= 0)
- err = snd_pcm_hw_params_get_buffer_time_min(hwparams, &minBufferTime, &dir);
- if ( err >= 0)
- err = snd_pcm_hw_params_get_period_time_max(hwparams, &maxPeriodTime, &dir);
- if ( err >= 0)
- err = snd_pcm_hw_params_get_period_time_min(hwparams, &minPeriodTime, &dir);
-
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSink: buffer/period min and max: err = %1").arg(err);
- } else {
- static unsigned user_buffer_time = qEnvironmentVariableIntValue("QT_ALSA_OUTPUT_BUFFER_TIME");
- static unsigned user_period_time = qEnvironmentVariableIntValue("QT_ALSA_OUTPUT_PERIOD_TIME");
- const bool outOfRange = maxBufferTime < buffer_time || buffer_time < minBufferTime || maxPeriodTime < period_time || minPeriodTime > period_time;
- if (outOfRange || user_period_time || user_buffer_time) {
- period_time = user_period_time ? user_period_time : minPeriodTime;
- if (!user_buffer_time) {
- chunks = maxBufferTime / period_time;
- buffer_time = period_time * chunks;
- } else {
- buffer_time = user_buffer_time;
- chunks = buffer_time / period_time;
- }
- }
- qCDebug(lcAlsaOutput) << "buffer time: [" << minBufferTime << "-" << maxBufferTime << "] =" << buffer_time;
- qCDebug(lcAlsaOutput) << "period time: [" << minPeriodTime << "-" << maxPeriodTime << "] =" << period_time;
- qCDebug(lcAlsaOutput) << "chunks =" << chunks;
- }
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, &dir);
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSink: snd_pcm_hw_params_set_buffer_time_near: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, &dir);
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSink: snd_pcm_hw_params_set_period_time_near: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params_set_periods_near(handle, hwparams, &chunks, &dir);
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSink: snd_pcm_hw_params_set_periods_near: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params(handle, hwparams);
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSink: snd_pcm_hw_params: err = %1").arg(err);
- }
- }
- if( err < 0) {
- qWarning()<<errMessage;
- errorState = QAudio::OpenError;
- emit errorChanged(errorState);
- deviceState = QAudio::StoppedState;
- return false;
- }
- snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames);
- buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames);
- snd_pcm_hw_params_get_period_size(hwparams,&period_frames, &dir);
- period_size = snd_pcm_frames_to_bytes(handle,period_frames);
- snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir);
- snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir);
-
- // Step 3: Set the desired SW parameters.
- snd_pcm_sw_params_t *swparams;
- snd_pcm_sw_params_alloca(&swparams);
- snd_pcm_sw_params_current(handle, swparams);
- snd_pcm_sw_params_set_start_threshold(handle,swparams,period_frames);
- snd_pcm_sw_params_set_stop_threshold(handle,swparams,buffer_frames);
- snd_pcm_sw_params_set_avail_min(handle, swparams,period_frames);
- snd_pcm_sw_params(handle, swparams);
-
- // Step 4: Prepare audio
- if(audioBuffer == 0)
- audioBuffer = new char[snd_pcm_frames_to_bytes(handle,buffer_frames)];
- snd_pcm_prepare( handle );
- snd_pcm_start(handle);
-
- // Step 5: Setup timer
- bytesAvailable = bytesFree();
-
- // Step 6: Start audio processing
- timer->start(period_time/1000);
-
- timeStamp.restart();
- elapsedTimeOffset = 0;
- errorState = QAudio::NoError;
- totalTimeValue = 0;
- opened = true;
-
- return true;
-}
-
-void QAlsaAudioSink::close()
-{
- timer->stop();
-
- if ( handle ) {
- snd_pcm_drain( handle );
- snd_pcm_close( handle );
- handle = 0;
- delete [] audioBuffer;
- audioBuffer=0;
- }
- if(!pullMode && audioSource) {
- delete audioSource;
- audioSource = 0;
- }
- opened = false;
-}
-
-qsizetype QAlsaAudioSink::bytesFree() const
-{
- if(resuming)
- return period_size;
-
- if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
- return 0;
-
- int frames = snd_pcm_avail_update(handle);
- if (frames == -EPIPE) {
- // Try and handle buffer underrun
- int err = snd_pcm_recover(handle, frames, 0);
- if (err < 0)
- return 0;
- else
- frames = snd_pcm_avail_update(handle);
- } else if (frames < 0) {
- return 0;
- }
-
- if ((int)frames > (int)buffer_frames)
- frames = buffer_frames;
-
- return snd_pcm_frames_to_bytes(handle, frames);
-}
-
-qint64 QAlsaAudioSink::write( const char *data, qint64 len )
-{
- // Write out some audio data
- if ( !handle )
- return 0;
-#ifdef DEBUG_AUDIO
- qDebug()<<"frames to write out = "<<
- snd_pcm_bytes_to_frames( handle, (int)len )<<" ("<<len<<") bytes";
-#endif
- int frames, err;
- int space = bytesFree();
-
- if (!space)
- return 0;
-
- if (len < space)
- space = len;
-
- frames = snd_pcm_bytes_to_frames(handle, space);
-
- if (m_volume < 1.0f) {
- QVarLengthArray<char, 4096> out(space);
- QAudioHelperInternal::qMultiplySamples(m_volume, settings, data, out.data(), space);
- err = snd_pcm_writei(handle, out.constData(), frames);
- } else {
- err = snd_pcm_writei(handle, data, frames);
- }
-
- if(err > 0) {
- totalTimeValue += err;
- resuming = false;
- errorState = QAudio::NoError;
- if (deviceState != QAudio::ActiveState) {
- deviceState = QAudio::ActiveState;
- emit stateChanged(deviceState);
- }
- return snd_pcm_frames_to_bytes( handle, err );
- } else
- err = xrun_recovery(err);
-
- if(err < 0) {
- close();
- errorState = QAudio::FatalError;
- emit errorChanged(errorState);
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- }
- return 0;
-}
-
-void QAlsaAudioSink::setBufferSize(qsizetype value)
-{
- if(deviceState == QAudio::StoppedState)
- buffer_size = value;
-}
-
-qsizetype QAlsaAudioSink::bufferSize() const
-{
- return buffer_size;
-}
-
-qint64 QAlsaAudioSink::processedUSecs() const
-{
- return qint64(1000000) * totalTimeValue / settings.sampleRate();
-}
-
-void QAlsaAudioSink::resume()
-{
- if(deviceState == QAudio::SuspendedState) {
- int err = 0;
-
- if(handle) {
- err = snd_pcm_prepare( handle );
- if(err < 0)
- xrun_recovery(err);
-
- err = snd_pcm_start(handle);
- if(err < 0)
- xrun_recovery(err);
-
- bytesAvailable = (int)snd_pcm_frames_to_bytes(handle, buffer_frames);
- }
- resuming = true;
-
- deviceState = pullMode ? QAudio::ActiveState : QAudio::IdleState;
-
- errorState = QAudio::NoError;
- timer->start(period_time/1000);
- emit stateChanged(deviceState);
- }
-}
-
-void QAlsaAudioSink::setFormat(const QAudioFormat& fmt)
-{
- if (deviceState == QAudio::StoppedState)
- settings = fmt;
-}
-
-QAudioFormat QAlsaAudioSink::format() const
-{
- return settings;
-}
-
-void QAlsaAudioSink::suspend()
-{
- if(deviceState == QAudio::ActiveState || deviceState == QAudio::IdleState || resuming) {
- snd_pcm_drain(handle);
- timer->stop();
- deviceState = QAudio::SuspendedState;
- errorState = QAudio::NoError;
- emit stateChanged(deviceState);
- }
-}
-
-void QAlsaAudioSink::userFeed()
-{
- if(deviceState == QAudio::StoppedState || deviceState == QAudio::SuspendedState)
- return;
-#ifdef DEBUG_AUDIO
- QTime now(QTime::currentTime());
- qDebug()<<now.second()<<"s "<<now.msec()<<"ms :userFeed() OUT";
-#endif
- if(deviceState == QAudio::IdleState)
- bytesAvailable = bytesFree();
-
- deviceReady();
-}
-
-bool QAlsaAudioSink::deviceReady()
-{
- if(pullMode) {
- int l = 0;
- int chunks = bytesAvailable/period_size;
- if(chunks==0) {
- bytesAvailable = bytesFree();
- return false;
- }
-#ifdef DEBUG_AUDIO
- qDebug()<<"deviceReady() avail="<<bytesAvailable<<" bytes, period size="<<period_size<<" bytes";
- qDebug()<<"deviceReady() no. of chunks that can fit ="<<chunks<<", chunks in bytes ="<<period_size*chunks;
-#endif
- int input = period_frames*chunks;
- if(input > (int)buffer_frames)
- input = buffer_frames;
- l = audioSource->read(audioBuffer,snd_pcm_frames_to_bytes(handle, input));
-
- // reading can take a while and stream may have been stopped
- if (!handle)
- return false;
-
- if(l > 0) {
- // Got some data to output
- if (deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
- return true;
- qint64 bytesWritten = write(audioBuffer,l);
- if (bytesWritten != l)
- audioSource->seek(audioSource->pos()-(l-bytesWritten));
- bytesAvailable = bytesFree();
-
- } else if(l == 0) {
- // Did not get any data to output
- bytesAvailable = bytesFree();
- if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) {
- // Underrun
- if (deviceState != QAudio::IdleState) {
- errorState = QAudio::UnderrunError;
- emit errorChanged(errorState);
- deviceState = QAudio::IdleState;
- emit stateChanged(deviceState);
- }
- }
-
- } else if(l < 0) {
- close();
- deviceState = QAudio::StoppedState;
- errorState = QAudio::IOError;
- emit errorChanged(errorState);
- emit stateChanged(deviceState);
- }
- } else {
- bytesAvailable = bytesFree();
- if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) {
- // Underrun
- if (deviceState != QAudio::IdleState) {
- errorState = QAudio::UnderrunError;
- emit errorChanged(errorState);
- deviceState = QAudio::IdleState;
- emit stateChanged(deviceState);
- }
- }
- }
-
- if(deviceState != QAudio::ActiveState)
- return true;
-
- return true;
-}
-
-void QAlsaAudioSink::reset()
-{
- if(handle)
- snd_pcm_reset(handle);
-
- stop();
-}
-
-AlsaOutputPrivate::AlsaOutputPrivate(QAlsaAudioSink* audio)
-{
- audioDevice = qobject_cast<QAlsaAudioSink*>(audio);
-}
-
-AlsaOutputPrivate::~AlsaOutputPrivate() {}
-
-qint64 AlsaOutputPrivate::readData( char* data, qint64 len)
-{
- Q_UNUSED(data);
- Q_UNUSED(len);
-
- return 0;
-}
-
-qint64 AlsaOutputPrivate::writeData(const char* data, qint64 len)
-{
- int retry = 0;
- qint64 written = 0;
- if((audioDevice->deviceState == QAudio::ActiveState)
- ||(audioDevice->deviceState == QAudio::IdleState)) {
- while(written < len) {
- int chunk = audioDevice->write(data+written,(len-written));
- if(chunk <= 0)
- retry++;
- written+=chunk;
- if(retry > 10)
- return written;
- }
- }
- return written;
-
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qalsaaudiosink_p.cpp"
diff --git a/src/multimedia/platform/alsa/qalsaaudiosink_p.h b/src/multimedia/platform/alsa/qalsaaudiosink_p.h
deleted file mode 100644
index 9c6da2557..000000000
--- a/src/multimedia/platform/alsa/qalsaaudiosink_p.h
+++ /dev/null
@@ -1,157 +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$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#ifndef QAUDIOOUTPUTALSA_H
-#define QAUDIOOUTPUTALSA_H
-
-#include <alsa/asoundlib.h>
-
-#include <QtCore/qfile.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qelapsedtimer.h>
-#include <QtCore/qiodevice.h>
-
-#include <QtMultimedia/qaudio.h>
-#include <QtMultimedia/qaudiodevice.h>
-#include <private/qaudiosystem_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAlsaAudioSink : public QPlatformAudioSink
-{
- friend class AlsaOutputPrivate;
- Q_OBJECT
-public:
- QAlsaAudioSink(const QByteArray &device);
- ~QAlsaAudioSink();
-
- qint64 write( const char *data, qint64 len );
-
- void start(QIODevice* device) override;
- QIODevice* start() override;
- void stop() override;
- void reset() override;
- void suspend() override;
- void resume() override;
- qsizetype bytesFree() const override;
- void setBufferSize(qsizetype value) override;
- qsizetype bufferSize() const override;
- qint64 processedUSecs() const override;
- QAudio::Error error() const override;
- QAudio::State state() const override;
- void setFormat(const QAudioFormat& fmt) override;
- QAudioFormat format() const override;
- void setVolume(qreal) override;
- qreal volume() const override;
-
-
- QIODevice* audioSource;
- QAudioFormat settings;
- QAudio::Error errorState;
- QAudio::State deviceState;
-
-private slots:
- void userFeed();
- bool deviceReady();
-
-signals:
- void processMore();
-
-private:
- bool opened;
- bool pullMode;
- bool resuming;
- int buffer_size;
- int period_size;
- qint64 totalTimeValue;
- unsigned int buffer_time;
- unsigned int period_time;
- snd_pcm_uframes_t buffer_frames;
- snd_pcm_uframes_t period_frames;
- int xrun_recovery(int err);
-
- int setFormat();
- bool open();
- void close();
-
- QTimer* timer;
- QByteArray m_device;
- int bytesAvailable;
- qint64 elapsedTimeOffset;
- char* audioBuffer;
- snd_pcm_t* handle;
- snd_pcm_access_t access;
- snd_pcm_format_t pcmformat;
- snd_pcm_hw_params_t *hwparams;
- qreal m_volume;
-};
-
-class AlsaOutputPrivate : public QIODevice
-{
- friend class QAlsaAudioSink;
- Q_OBJECT
-public:
- AlsaOutputPrivate(QAlsaAudioSink* audio);
- ~AlsaOutputPrivate();
-
- qint64 readData( char* data, qint64 len) override;
- qint64 writeData(const char* data, qint64 len) override;
-
-private:
- QAlsaAudioSink *audioDevice;
-};
-
-QT_END_NAMESPACE
-
-
-#endif
diff --git a/src/multimedia/platform/alsa/qalsaaudiosource.cpp b/src/multimedia/platform/alsa/qalsaaudiosource.cpp
deleted file mode 100644
index 19c85542e..000000000
--- a/src/multimedia/platform/alsa/qalsaaudiosource.cpp
+++ /dev/null
@@ -1,805 +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$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// INTERNAL USE ONLY: Do NOT use for any other purpose.
-//
-
-#include <QtCore/qcoreapplication.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtMultimedia/private/qaudiohelpers_p.h>
-#include "qalsaaudiosource_p.h"
-#include "qalsaaudiodevice_p.h"
-
-QT_BEGIN_NAMESPACE
-
-//#define DEBUG_AUDIO 1
-
-QAlsaAudioSource::QAlsaAudioSource(const QByteArray &device)
-{
- bytesAvailable = 0;
- handle = 0;
- access = SND_PCM_ACCESS_RW_INTERLEAVED;
- pcmformat = SND_PCM_FORMAT_S16;
- buffer_size = 0;
- period_size = 0;
- buffer_time = 100000;
- period_time = 20000;
- totalTimeValue = 0;
- errorState = QAudio::NoError;
- deviceState = QAudio::StoppedState;
- audioSource = 0;
- pullMode = true;
- resuming = false;
-
- m_volume = 1.0f;
-
- m_device = device;
-
- timer = new QTimer(this);
- connect(timer,SIGNAL(timeout()),SLOT(userFeed()));
-}
-
-QAlsaAudioSource::~QAlsaAudioSource()
-{
- close();
- disconnect(timer, SIGNAL(timeout()));
- QCoreApplication::processEvents();
- delete timer;
-}
-
-void QAlsaAudioSource::setVolume(qreal vol)
-{
- m_volume = vol;
-}
-
-qreal QAlsaAudioSource::volume() const
-{
- return m_volume;
-}
-
-QAudio::Error QAlsaAudioSource::error() const
-{
- return errorState;
-}
-
-QAudio::State QAlsaAudioSource::state() const
-{
- return deviceState;
-}
-
-void QAlsaAudioSource::setFormat(const QAudioFormat& fmt)
-{
- if (deviceState == QAudio::StoppedState)
- settings = fmt;
-}
-
-QAudioFormat QAlsaAudioSource::format() const
-{
- return settings;
-}
-
-int QAlsaAudioSource::xrun_recovery(int err)
-{
- int count = 0;
- bool reset = false;
-
- // ESTRPIPE is not available in all OSes where ALSA is available
- int estrpipe = EIO;
-#ifdef ESTRPIPE
- estrpipe = ESTRPIPE;
-#endif
-
- if(err == -EPIPE) {
- errorState = QAudio::UnderrunError;
- err = snd_pcm_prepare(handle);
- if(err < 0)
- reset = true;
- else {
- bytesAvailable = checkBytesReady();
- if (bytesAvailable <= 0)
- reset = true;
- }
- } else if ((err == -estrpipe)||(err == -EIO)) {
- errorState = QAudio::IOError;
- while((err = snd_pcm_resume(handle)) == -EAGAIN){
- usleep(100);
- count++;
- if(count > 5) {
- reset = true;
- break;
- }
- }
- if(err < 0) {
- err = snd_pcm_prepare(handle);
- if(err < 0)
- reset = true;
- }
- }
- if(reset) {
- close();
- open();
- snd_pcm_prepare(handle);
- return 0;
- }
- return err;
-}
-
-int QAlsaAudioSource::setFormat()
-{
- snd_pcm_format_t pcmformat = SND_PCM_FORMAT_UNKNOWN;
-
- switch (settings.sampleFormat()) {
- case QAudioFormat::UInt8:
- pcmformat = SND_PCM_FORMAT_U8;
- break;
- case QAudioFormat::Int16:
- if constexpr (QSysInfo::ByteOrder == QSysInfo::BigEndian)
- pcmformat = SND_PCM_FORMAT_S16_LE;
- else
- pcmformat = SND_PCM_FORMAT_S16_BE;
- break;
- case QAudioFormat::Int32:
- if constexpr (QSysInfo::ByteOrder == QSysInfo::BigEndian)
- pcmformat = SND_PCM_FORMAT_S32_LE;
- else
- pcmformat = SND_PCM_FORMAT_S32_BE;
- break;
- case QAudioFormat::Float:
- if constexpr (QSysInfo::ByteOrder == QSysInfo::BigEndian)
- pcmformat = SND_PCM_FORMAT_FLOAT_LE;
- else
- pcmformat = SND_PCM_FORMAT_FLOAT_BE;
- default:
- break;
- }
-
- return pcmformat != SND_PCM_FORMAT_UNKNOWN
- ? snd_pcm_hw_params_set_format( handle, hwparams, pcmformat)
- : -1;
-}
-
-void QAlsaAudioSource::start(QIODevice* device)
-{
- if(deviceState != QAudio::StoppedState)
- close();
-
- if(!pullMode && audioSource)
- delete audioSource;
-
- pullMode = true;
- audioSource = device;
-
- deviceState = QAudio::ActiveState;
-
- if( !open() )
- return;
-
- emit stateChanged(deviceState);
-}
-
-QIODevice* QAlsaAudioSource::start()
-{
- if(deviceState != QAudio::StoppedState)
- close();
-
- if(!pullMode && audioSource)
- delete audioSource;
-
- pullMode = false;
- audioSource = new AlsaInputPrivate(this);
- audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
-
- deviceState = QAudio::IdleState;
-
- if( !open() )
- return 0;
-
- emit stateChanged(deviceState);
-
- return audioSource;
-}
-
-void QAlsaAudioSource::stop()
-{
- if(deviceState == QAudio::StoppedState)
- return;
-
- deviceState = QAudio::StoppedState;
-
- close();
- emit stateChanged(deviceState);
-}
-
-bool QAlsaAudioSource::open()
-{
-#ifdef DEBUG_AUDIO
- QTime now(QTime::currentTime());
- qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
-#endif
- elapsedTimeOffset = 0;
-
- int dir;
- int err = 0;
- int count=0;
- unsigned int sampleRate=settings.sampleRate();
-
- if (!settings.isValid()) {
- qWarning("QAudioSource: open error, invalid format.");
- } else if (settings.sampleRate() <= 0) {
- qWarning("QAudioSource: open error, invalid sample rate (%d).",
- settings.sampleRate());
- } else {
- err = -1;
- }
-
- if (err == 0) {
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit errorChanged(errorState);
- return false;
- }
-
-
- // Step 1: try and open the device
- while((count < 5) && (err < 0)) {
- err = snd_pcm_open(&handle, m_device.constData(), SND_PCM_STREAM_CAPTURE,0);
- if(err < 0)
- count++;
- }
- if (( err < 0)||(handle == 0)) {
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- return false;
- }
- snd_pcm_nonblock( handle, 0 );
-
- // Step 2: Set the desired HW parameters.
- snd_pcm_hw_params_alloca( &hwparams );
-
- bool fatal = false;
- QString errMessage;
- unsigned int chunks = 8;
-
- err = snd_pcm_hw_params_any( handle, hwparams );
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSource: snd_pcm_hw_params_any: err = %1").arg(err);
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params_set_rate_resample( handle, hwparams, 1 );
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSource: snd_pcm_hw_params_set_rate_resample: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params_set_access( handle, hwparams, access );
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSource: snd_pcm_hw_params_set_access: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = setFormat();
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSource: snd_pcm_hw_params_set_format: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params_set_channels( handle, hwparams, (unsigned int)settings.channelCount() );
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSource: snd_pcm_hw_params_set_channels: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params_set_rate_near( handle, hwparams, &sampleRate, 0 );
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSource: snd_pcm_hw_params_set_rate_near: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params_set_buffer_time_near(handle, hwparams, &buffer_time, &dir);
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSource: snd_pcm_hw_params_set_buffer_time_near: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params_set_period_time_near(handle, hwparams, &period_time, &dir);
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSource: snd_pcm_hw_params_set_period_time_near: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params_set_periods_near(handle, hwparams, &chunks, &dir);
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSource: snd_pcm_hw_params_set_periods_near: err = %1").arg(err);
- }
- }
- if ( !fatal ) {
- err = snd_pcm_hw_params(handle, hwparams);
- if ( err < 0 ) {
- fatal = true;
- errMessage = QString::fromLatin1("QAudioSource: snd_pcm_hw_params: err = %1").arg(err);
- }
- }
- if( err < 0) {
- qWarning()<<errMessage;
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- return false;
- }
- snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames);
- buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames);
- snd_pcm_hw_params_get_period_size(hwparams,&period_frames, &dir);
- period_size = snd_pcm_frames_to_bytes(handle,period_frames);
- snd_pcm_hw_params_get_buffer_time(hwparams,&buffer_time, &dir);
- snd_pcm_hw_params_get_period_time(hwparams,&period_time, &dir);
-
- // Step 3: Set the desired SW parameters.
- snd_pcm_sw_params_t *swparams;
- snd_pcm_sw_params_alloca(&swparams);
- snd_pcm_sw_params_current(handle, swparams);
- snd_pcm_sw_params_set_start_threshold(handle,swparams,period_frames);
- snd_pcm_sw_params_set_stop_threshold(handle,swparams,buffer_frames);
- snd_pcm_sw_params_set_avail_min(handle, swparams,period_frames);
- snd_pcm_sw_params(handle, swparams);
-
- // Step 4: Prepare audio
- ringBuffer.resize(buffer_size);
- snd_pcm_prepare( handle );
- snd_pcm_start(handle);
-
- // Step 5: Setup timer
- bytesAvailable = checkBytesReady();
-
- if(pullMode)
- connect(audioSource,SIGNAL(readyRead()),this,SLOT(userFeed()));
-
- // Step 6: Start audio processing
- chunks = buffer_size/period_size;
- timer->start(period_time*chunks/2000);
-
- errorState = QAudio::NoError;
-
- totalTimeValue = 0;
-
- return true;
-}
-
-void QAlsaAudioSource::close()
-{
- timer->stop();
-
- if ( handle ) {
- snd_pcm_drop( handle );
- snd_pcm_close( handle );
- handle = 0;
- }
-}
-
-int QAlsaAudioSource::checkBytesReady()
-{
- if(resuming)
- bytesAvailable = period_size;
- else if(deviceState != QAudio::ActiveState
- && deviceState != QAudio::IdleState)
- bytesAvailable = 0;
- else {
- int frames = snd_pcm_avail_update(handle);
- if (frames < 0) {
- bytesAvailable = frames;
- } else {
- if((int)frames > (int)buffer_frames)
- frames = buffer_frames;
- bytesAvailable = snd_pcm_frames_to_bytes(handle, frames);
- }
- }
- return bytesAvailable;
-}
-
-int QAlsaAudioSource::bytesReady() const
-{
- return qMax(bytesAvailable, 0);
-}
-
-qint64 QAlsaAudioSource::read(char* data, qint64 len)
-{
- // Read in some audio data and write it to QIODevice, pull mode
- if ( !handle )
- return 0;
-
- int bytesRead = 0;
- int bytesInRingbufferBeforeRead = ringBuffer.bytesOfDataInBuffer();
-
- if (ringBuffer.bytesOfDataInBuffer() < len) {
-
- // bytesAvaiable is saved as a side effect of checkBytesReady().
- int bytesToRead = checkBytesReady();
-
- if (bytesToRead < 0) {
- // bytesAvailable as negative is error code, try to recover from it.
- xrun_recovery(bytesToRead);
- bytesToRead = checkBytesReady();
- if (bytesToRead < 0) {
- // recovery failed must stop and set error.
- close();
- errorState = QAudio::IOError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- return 0;
- }
- }
-
- bytesToRead = qMin<qint64>(len, bytesToRead);
- bytesToRead = qMin<qint64>(ringBuffer.freeBytes(), bytesToRead);
- bytesToRead -= bytesToRead % period_size;
-
- int count=0;
- int err = 0;
- QVarLengthArray<char, 4096> buffer(bytesToRead);
- while(count < 5 && bytesToRead > 0) {
- int chunks = bytesToRead / period_size;
- int frames = chunks * period_frames;
- if (frames > (int)buffer_frames)
- frames = buffer_frames;
-
- int readFrames = snd_pcm_readi(handle, buffer.data(), frames);
- bytesRead = snd_pcm_frames_to_bytes(handle, readFrames);
- if (m_volume < 1.0f)
- QAudioHelperInternal::qMultiplySamples(m_volume, settings,
- buffer.constData(),
- buffer.data(), bytesRead);
-
- if (readFrames >= 0) {
- ringBuffer.write(buffer.data(), bytesRead);
-#ifdef DEBUG_AUDIO
- qDebug() << QString::fromLatin1("read in bytes = %1 (frames=%2)").arg(bytesRead).arg(readFrames).toLatin1().constData();
-#endif
- break;
- } else if((readFrames == -EAGAIN) || (readFrames == -EINTR)) {
- errorState = QAudio::IOError;
- err = 0;
- break;
- } else {
- if(readFrames == -EPIPE) {
- errorState = QAudio::UnderrunError;
- err = snd_pcm_prepare(handle);
-#ifdef ESTRPIPE
- } else if(readFrames == -ESTRPIPE) {
- err = snd_pcm_prepare(handle);
-#endif
- }
- if(err != 0) break;
- }
- count++;
- }
-
- }
-
- bytesRead += bytesInRingbufferBeforeRead;
-
- if (bytesRead > 0) {
- // got some send it onward
-#ifdef DEBUG_AUDIO
- qDebug() << "frames to write to QIODevice = " <<
- snd_pcm_bytes_to_frames( handle, (int)bytesRead ) << " (" << bytesRead << ") bytes";
-#endif
- if (deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
- return 0;
-
- if (pullMode) {
- qint64 l = 0;
- qint64 bytesWritten = 0;
- while (ringBuffer.bytesOfDataInBuffer() > 0) {
- l = audioSource->write(ringBuffer.availableData(), ringBuffer.availableDataBlockSize());
- if (l > 0) {
- ringBuffer.readBytes(l);
- bytesWritten += l;
- } else {
- break;
- }
- }
-
- if (l < 0) {
- close();
- errorState = QAudio::IOError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- } else if (l == 0 && bytesWritten == 0) {
- if (deviceState != QAudio::IdleState) {
- errorState = QAudio::NoError;
- deviceState = QAudio::IdleState;
- emit stateChanged(deviceState);
- }
- } else {
- bytesAvailable -= bytesWritten;
- totalTimeValue += bytesWritten;
- resuming = false;
- if (deviceState != QAudio::ActiveState) {
- errorState = QAudio::NoError;
- deviceState = QAudio::ActiveState;
- emit stateChanged(deviceState);
- }
- }
-
- return bytesWritten;
- } else {
- while (ringBuffer.bytesOfDataInBuffer() > 0) {
- int size = ringBuffer.availableDataBlockSize();
- memcpy(data, ringBuffer.availableData(), size);
- data += size;
- ringBuffer.readBytes(size);
- }
-
- bytesAvailable -= bytesRead;
- totalTimeValue += bytesRead;
- resuming = false;
- if (deviceState != QAudio::ActiveState) {
- errorState = QAudio::NoError;
- deviceState = QAudio::ActiveState;
- emit stateChanged(deviceState);
- }
-
- return bytesRead;
- }
- }
-
- return 0;
-}
-
-void QAlsaAudioSource::resume()
-{
- if(deviceState == QAudio::SuspendedState) {
- int err = 0;
-
- if(handle) {
- err = snd_pcm_prepare( handle );
- if(err < 0)
- xrun_recovery(err);
-
- err = snd_pcm_start(handle);
- if(err < 0)
- xrun_recovery(err);
-
- bytesAvailable = buffer_size;
- }
- resuming = true;
- deviceState = QAudio::ActiveState;
- int chunks = buffer_size/period_size;
- timer->start(period_time*chunks/2000);
- emit stateChanged(deviceState);
- }
-}
-
-void QAlsaAudioSource::setBufferSize(int value)
-{
- buffer_size = value;
-}
-
-int QAlsaAudioSource::bufferSize() const
-{
- return buffer_size;
-}
-
-qint64 QAlsaAudioSource::processedUSecs() const
-{
- qint64 result = qint64(1000000) * totalTimeValue /
- settings.bytesPerFrame() /
- settings.sampleRate();
-
- return result;
-}
-
-void QAlsaAudioSource::suspend()
-{
- if(deviceState == QAudio::ActiveState||resuming) {
- snd_pcm_drain(handle);
- timer->stop();
- deviceState = QAudio::SuspendedState;
- emit stateChanged(deviceState);
- }
-}
-
-void QAlsaAudioSource::userFeed()
-{
- if(deviceState == QAudio::StoppedState || deviceState == QAudio::SuspendedState)
- return;
-#ifdef DEBUG_AUDIO
- QTime now(QTime::currentTime());
- qDebug()<<now.second()<<"s "<<now.msec()<<"ms :userFeed() IN";
-#endif
- deviceReady();
-}
-
-bool QAlsaAudioSource::deviceReady()
-{
- if(pullMode) {
- // reads some audio data and writes it to QIODevice
- read(0, buffer_size);
- } else {
- // emits readyRead() so user will call read() on QIODevice to get some audio data
- AlsaInputPrivate* a = qobject_cast<AlsaInputPrivate*>(audioSource);
- a->trigger();
- }
- bytesAvailable = checkBytesReady();
-
- if(deviceState != QAudio::ActiveState)
- return true;
-
- if (bytesAvailable < 0) {
- // bytesAvailable as negative is error code, try to recover from it.
- xrun_recovery(bytesAvailable);
- bytesAvailable = checkBytesReady();
- if (bytesAvailable < 0) {
- // recovery failed must stop and set error.
- close();
- errorState = QAudio::IOError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- return 0;
- }
- }
-
- return true;
-}
-
-void QAlsaAudioSource::reset()
-{
- if(handle)
- snd_pcm_reset(handle);
- stop();
- bytesAvailable = 0;
-}
-
-void QAlsaAudioSource::drain()
-{
- if(handle)
- snd_pcm_drain(handle);
-}
-
-AlsaInputPrivate::AlsaInputPrivate(QAlsaAudioSource* audio)
-{
- audioDevice = qobject_cast<QAlsaAudioSource*>(audio);
-}
-
-AlsaInputPrivate::~AlsaInputPrivate()
-{
-}
-
-qint64 AlsaInputPrivate::readData( char* data, qint64 len)
-{
- return audioDevice->read(data,len);
-}
-
-qint64 AlsaInputPrivate::writeData(const char* data, qint64 len)
-{
- Q_UNUSED(data);
- Q_UNUSED(len);
- return 0;
-}
-
-void AlsaInputPrivate::trigger()
-{
- emit readyRead();
-}
-
-RingBuffer::RingBuffer() :
- m_head(0),
- m_tail(0)
-{
-}
-
-void RingBuffer::resize(int size)
-{
- m_data.resize(size);
-}
-
-int RingBuffer::bytesOfDataInBuffer() const
-{
- if (m_head < m_tail)
- return m_tail - m_head;
- else if (m_tail < m_head)
- return m_data.size() + m_tail - m_head;
- else
- return 0;
-}
-
-int RingBuffer::freeBytes() const
-{
- if (m_head > m_tail)
- return m_head - m_tail - 1;
- else if (m_tail > m_head)
- return m_data.size() - m_tail + m_head - 1;
- else
- return m_data.size() - 1;
-}
-
-const char *RingBuffer::availableData() const
-{
- return (m_data.constData() + m_head);
-}
-
-int RingBuffer::availableDataBlockSize() const
-{
- if (m_head > m_tail)
- return m_data.size() - m_head;
- else if (m_tail > m_head)
- return m_tail - m_head;
- else
- return 0;
-}
-
-void RingBuffer::readBytes(int bytes)
-{
- m_head = (m_head + bytes) % m_data.size();
-}
-
-void RingBuffer::write(char *data, int len)
-{
- if (m_tail + len < m_data.size()) {
- memcpy(m_data.data() + m_tail, data, len);
- m_tail += len;
- } else {
- int bytesUntilEnd = m_data.size() - m_tail;
- memcpy(m_data.data() + m_tail, data, bytesUntilEnd);
- if (len - bytesUntilEnd > 0)
- memcpy(m_data.data(), data + bytesUntilEnd, len - bytesUntilEnd);
- m_tail = len - bytesUntilEnd;
- }
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qalsaaudiosource_p.cpp"
diff --git a/src/multimedia/platform/alsa/qalsaaudiosource_p.h b/src/multimedia/platform/alsa/qalsaaudiosource_p.h
deleted file mode 100644
index 95df8008b..000000000
--- a/src/multimedia/platform/alsa/qalsaaudiosource_p.h
+++ /dev/null
@@ -1,178 +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$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-
-#ifndef QAUDIOINPUTALSA_H
-#define QAUDIOINPUTALSA_H
-
-#include <alsa/asoundlib.h>
-
-#include <QtCore/qfile.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qelapsedtimer.h>
-#include <QtCore/qiodevice.h>
-
-#include <QtMultimedia/qaudio.h>
-#include <QtMultimedia/qaudiodevice.h>
-#include <private/qaudiosystem_p.h>
-
-QT_BEGIN_NAMESPACE
-
-
-class AlsaInputPrivate;
-
-class RingBuffer
-{
-public:
- RingBuffer();
-
- void resize(int size);
-
- int bytesOfDataInBuffer() const;
- int freeBytes() const;
-
- const char *availableData() const;
- int availableDataBlockSize() const;
- void readBytes(int bytes);
-
- void write(char *data, int len);
-
-private:
- int m_head;
- int m_tail;
-
- QByteArray m_data;
-};
-
-class QAlsaAudioSource : public QPlatformAudioSource
-{
- Q_OBJECT
-public:
- QAlsaAudioSource(const QByteArray &device);
- ~QAlsaAudioSource();
-
- qint64 read(char* data, qint64 len);
-
- void start(QIODevice* device) override;
- QIODevice* start() override;
- void stop() override;
- void reset() override;
- void suspend() override;
- void resume() override;
- qsizetype bytesReady() const override;
- void setBufferSize(qsizetype value) override;
- qsizetype bufferSize() const override;
- qint64 processedUSecs() const override;
- QAudio::Error error() const override;
- QAudio::State state() const override;
- void setFormat(const QAudioFormat& fmt) override;
- QAudioFormat format() const override;
- void setVolume(qreal) override;
- qreal volume() const override;
- bool resuming;
- snd_pcm_t* handle;
- qint64 totalTimeValue;
- QIODevice* audioSource;
- QAudioFormat settings;
- QAudio::Error errorState;
- QAudio::State deviceState;
-
-private slots:
- void userFeed();
- bool deviceReady();
-
-private:
- int checkBytesReady();
- int xrun_recovery(int err);
- int setFormat();
- bool open();
- void close();
- void drain();
-
- QTimer* timer;
- qint64 elapsedTimeOffset;
- RingBuffer ringBuffer;
- int bytesAvailable;
- QByteArray m_device;
- bool pullMode;
- int buffer_size;
- int period_size;
- unsigned int buffer_time;
- unsigned int period_time;
- snd_pcm_uframes_t buffer_frames;
- snd_pcm_uframes_t period_frames;
- snd_pcm_access_t access;
- snd_pcm_format_t pcmformat;
- snd_pcm_hw_params_t *hwparams;
- qreal m_volume;
-};
-
-class AlsaInputPrivate : public QIODevice
-{
- Q_OBJECT
-public:
- AlsaInputPrivate(QAlsaAudioSource* audio);
- ~AlsaInputPrivate();
-
- qint64 readData( char* data, qint64 len) override;
- qint64 writeData(const char* data, qint64 len) override;
-
- void trigger();
-private:
- QAlsaAudioSource *audioDevice;
-};
-
-QT_END_NAMESPACE
-
-
-#endif
diff --git a/src/multimedia/platform/alsa/qalsaintegration.cpp b/src/multimedia/platform/alsa/qalsaintegration.cpp
deleted file mode 100644
index bfbc40c6a..000000000
--- a/src/multimedia/platform/alsa/qalsaintegration.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qalsaintegration_p.h"
-#include "qalsamediadevices_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QAlsaIntegration::QAlsaIntegration()
-{
-}
-
-QAlsaIntegration::~QAlsaIntegration()
-{
- delete m_devices;
-}
-
-QPlatformMediaDevices *QAlsaIntegration::devices()
-{
- if (!m_devices)
- m_devices = new QAlsaMediaDevices();
- return m_devices;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/alsa/qalsaintegration_p.h b/src/multimedia/platform/alsa/qalsaintegration_p.h
deleted file mode 100644
index a3b7315b3..000000000
--- a/src/multimedia/platform/alsa/qalsaintegration_p.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QALSAINTEGRATION_H
-#define QALSAINTEGRATION_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 <private/qplatformmediaintegration_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAlsaMediaDevices;
-
-class QAlsaIntegration : public QPlatformMediaIntegration
-{
-public:
- QAlsaIntegration();
- ~QAlsaIntegration();
-
- QPlatformMediaDevices *devices() override;
-
- QAlsaMediaDevices *m_devices = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/alsa/qalsamediadevices.cpp b/src/multimedia/platform/alsa/qalsamediadevices.cpp
deleted file mode 100644
index e2561e66a..000000000
--- a/src/multimedia/platform/alsa/qalsamediadevices.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qalsamediadevices_p.h"
-#include "qmediadevices.h"
-#include "qcameradevice_p.h"
-
-#include "private/qalsaaudiosource_p.h"
-#include "private/qalsaaudiosink_p.h"
-#include "private/qalsaaudiodevice_p.h"
-
-#include <alsa/asoundlib.h>
-
-QT_BEGIN_NAMESPACE
-
-QAlsaMediaDevices::QAlsaMediaDevices()
- : QPlatformMediaDevices()
-{
-}
-
-static QList<QAudioDevice> availableDevices(QAudioDevice::Mode mode)
-{
- QList<QAudioDevice> devices;
-
- QByteArray filter;
-
- // Create a list of all current audio devices that support mode
- void **hints, **n;
- char *name, *descr, *io;
-
- if(snd_device_name_hint(-1, "pcm", &hints) < 0) {
- qWarning() << "no alsa devices available";
- return devices;
- }
- n = hints;
-
- if(mode == QAudioDevice::Input) {
- filter = "Input";
- } else {
- filter = "Output";
- }
-
- while (*n != NULL) {
- name = snd_device_name_get_hint(*n, "NAME");
- if (name != 0 && qstrcmp(name, "null") != 0) {
- descr = snd_device_name_get_hint(*n, "DESC");
- io = snd_device_name_get_hint(*n, "IOID");
-
- if ((descr != NULL) && ((io == NULL) || (io == filter))) {
- auto *infop = new QAlsaAudioDeviceInfo(name, QString::fromUtf8(descr), mode);
- devices.append(infop->create());
- if (strcmp(name, "default") == 0)
- infop->isDefault = true;
- }
-
- free(descr);
- free(io);
- }
- free(name);
- ++n;
- }
- snd_device_name_free_hint(hints);
-
- return devices;
-}
-
-QList<QAudioDevice> QAlsaMediaDevices::audioInputs() const
-{
- return availableDevices(QAudioDevice::Input);
-}
-
-QList<QAudioDevice> QAlsaMediaDevices::audioOutputs() const
-{
- return availableDevices(QAudioDevice::Output);
-}
-
-QList<QCameraDevice> QAlsaMediaDevices::videoInputs() const
-{
- return {};
-}
-
-QPlatformAudioSource *QAlsaMediaDevices::createAudioSource(const QAudioDevice &deviceInfo)
-{
- return new QAlsaAudioSource(deviceInfo.id());
-}
-
-QPlatformAudioSink *QAlsaMediaDevices::createAudioSink(const QAudioDevice &deviceInfo)
-{
- return new QAlsaAudioSink(deviceInfo.id());
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/alsa/qalsamediadevices_p.h b/src/multimedia/platform/alsa/qalsamediadevices_p.h
deleted file mode 100644
index 54df9c851..000000000
--- a/src/multimedia/platform/alsa/qalsamediadevices_p.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QALSAMEDIADEVICES_H
-#define QALSAMEDIADEVICES_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 <private/qplatformmediadevices_p.h>
-#include <qset.h>
-#include <qaudio.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAlsaEngine;
-
-class QAlsaMediaDevices : public QPlatformMediaDevices
-{
-public:
- QAlsaMediaDevices();
-
- QList<QAudioDevice> audioInputs() const override;
- QList<QAudioDevice> audioOutputs() const override;
- QList<QCameraDevice> videoInputs() const override;
- QPlatformAudioSource *createAudioSource(const QAudioDevice &deviceInfo) override;
- QPlatformAudioSink *createAudioSink(const QAudioDevice &deviceInfo) override;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/android/audio/qandroidaudiodecoder.cpp b/src/multimedia/platform/android/audio/qandroidaudiodecoder.cpp
deleted file mode 100644
index 718492118..000000000
--- a/src/multimedia/platform/android/audio/qandroidaudiodecoder.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qandroidaudiodecoder_p.h"
-
-#include <QtCore/qcoreapplication.h>
-#include <QtCore/qjniobject.h>
-#include <QtCore/qjnienvironment.h>
-#include <QtCore/private/qandroidextras_p.h>
-#include <QTimer>
-#include <QFile>
-#include <QDir>
-
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-QT_BEGIN_NAMESPACE
-
-static const char tempFile[] = "encoded.tmp";
-static const char tempPath[] = "/storage/emulated/0/data/local/tmp/audiodecoder/";
-constexpr int dequeueTimeout = 5000;
-Q_LOGGING_CATEGORY(adLogger, "QAndroidAudioDecoder")
-
-Decoder::Decoder()
- : m_format(AMediaFormat_new())
-{}
-
-Decoder::~Decoder()
-{
- if (m_codec) {
- AMediaCodec_delete(m_codec);
- m_codec = nullptr;
- }
-
- if (m_extractor) {
- AMediaExtractor_delete(m_extractor);
- m_extractor = nullptr;
- }
-
- if (m_format) {
- AMediaFormat_delete(m_format);
- m_format = nullptr;
- }
-}
-
-void Decoder::stop()
-{
- const media_status_t err = AMediaCodec_stop(m_codec);
- if (err != AMEDIA_OK)
- qCWarning(adLogger) << "stop() error: " << err;
-}
-
-void Decoder::setSource(const QUrl &source)
-{
- if (!m_extractor)
- m_extractor = AMediaExtractor_new();
-
- int fd = -1;
- if (source.path().contains(QLatin1String("content"))) {
- 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(source.path()).object(),
- QJniObject::fromString(QLatin1String("r")).object());
- } else {
- fd = open(source.path().toStdString().c_str(), O_RDONLY);
- }
-
- if (fd < 0) {
- emit error(QAudioDecoder::ResourceError, tr("Invalid fileDescriptor for source."));
- return;
- }
- const int size = QFile(source.toString()).size();
- media_status_t status = AMediaExtractor_setDataSourceFd(m_extractor, fd, 0,
- size > 0 ? size : LONG_MAX);
- close(fd);
-
- if (status != AMEDIA_OK) {
- if (m_extractor) {
- AMediaExtractor_delete(m_extractor);
- m_extractor = nullptr;
- }
- emit error(QAudioDecoder::ResourceError, tr("Setting source for Audio Decoder failed."));
- }
-}
-
-void Decoder::createDecoder()
-{
- // get encoded format for decoder
- m_format = AMediaExtractor_getTrackFormat(m_extractor, 0);
-
- const char *mime;
- if (!AMediaFormat_getString(m_format, AMEDIAFORMAT_KEY_MIME, &mime)) {
- if (m_extractor) {
- AMediaExtractor_delete(m_extractor);
- m_extractor = nullptr;
- }
- emit error(QAudioDecoder::FormatError, tr("Format not supported by Audio Decoder."));
-
- return;
- }
-
- // get audio duration from source
- int64_t durationUs;
- AMediaFormat_getInt64(m_format, AMEDIAFORMAT_KEY_DURATION, &durationUs);
- emit durationChanged(durationUs / 1000);
-
- // set default output audio format from input file
- if (!m_outputFormat.isValid()) {
- int32_t sampleRate;
- AMediaFormat_getInt32(m_format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &sampleRate);
- m_outputFormat.setSampleRate(sampleRate);
- int32_t channelCount;
- AMediaFormat_getInt32(m_format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &channelCount);
- m_outputFormat.setChannelCount(channelCount);
- m_outputFormat.setSampleFormat(QAudioFormat::Int16);
- }
-
- m_codec = AMediaCodec_createDecoderByType(mime);
-}
-
-void Decoder::doDecode()
-{
- if (!m_extractor) {
- emit error(QAudioDecoder::ResourceError, tr("Cannot decode, source not set."));
- return;
- }
-
- createDecoder();
-
- media_status_t status = AMediaCodec_configure(m_codec, m_format, nullptr /* surface */,
- nullptr /* crypto */, 0);
-
- if (status != AMEDIA_OK) {
- emit error(QAudioDecoder::ResourceError, tr("Audio Decoder failed configuration."));
- return;
- }
-
- status = AMediaCodec_start(m_codec);
- if (status != AMEDIA_OK) {
- emit error(QAudioDecoder::ResourceError, tr("Audio Decoder failed to start."));
- return;
- }
-
- AMediaExtractor_selectTrack(m_extractor, 0);
-
- m_inputEOS = false;
- while (!m_inputEOS) {
- // handle input buffer
- const ssize_t bufferIdx = AMediaCodec_dequeueInputBuffer(m_codec, dequeueTimeout);
-
- if (bufferIdx >= 0) {
- size_t bufferSize = {};
- uint8_t *buffer = AMediaCodec_getInputBuffer(m_codec, bufferIdx, &bufferSize);
- const int sample = AMediaExtractor_readSampleData(m_extractor, buffer, bufferSize);
- if (sample < 0) {
- m_inputEOS = true;
- break;
- }
-
- const int64_t presentationTimeUs = AMediaExtractor_getSampleTime(m_extractor);
- AMediaCodec_queueInputBuffer(m_codec, bufferIdx, 0, sample, presentationTimeUs,
- m_inputEOS ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0);
- AMediaExtractor_advance(m_extractor);
-
- // handle output buffer
- AMediaCodecBufferInfo info;
- ssize_t idx = AMediaCodec_dequeueOutputBuffer(m_codec, &info, dequeueTimeout);
- if (idx >= 0) {
- if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM)
- break;
-
- if (info.size > 0) {
- size_t bufferSize;
- const uint8_t *bufferData = AMediaCodec_getOutputBuffer(m_codec, idx,
- &bufferSize);
- const QByteArray data((const char*)(bufferData + info.offset), info.size);
- auto audioBuffer = QAudioBuffer(data, m_outputFormat, presentationTimeUs);
- if (presentationTimeUs > 0)
- emit positionChanged(std::move(audioBuffer), presentationTimeUs / 1000);
- AMediaCodec_releaseOutputBuffer(m_codec, idx, false);
- }
- } else {
- // The outputIndex doubles as a status return if its value is < 0
- switch (idx) {
- case AMEDIACODEC_INFO_TRY_AGAIN_LATER:
- qCWarning(adLogger) << "dequeueOutputBuffer() status: try again later";
- break;
- case AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED:
- qCWarning(adLogger) << "dequeueOutputBuffer() status: output buffers changed";
- break;
- case AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED:
- m_format = AMediaCodec_getOutputFormat(m_codec);
- qCWarning(adLogger) << "dequeueOutputBuffer() status: outputFormat changed";
- break;
- }
- }
- } else {
- qCWarning(adLogger) << "dequeueInputBuffer() status: invalid buffer idx " << bufferIdx;
- }
- }
-
- emit finished();
-}
-
-QAndroidAudioDecoder::QAndroidAudioDecoder(QAudioDecoder *parent)
- : QPlatformAudioDecoder(parent),
- m_decoder(new Decoder())
-{
- connect(m_decoder, &Decoder::positionChanged, this, &QAndroidAudioDecoder::positionChanged);
- connect(m_decoder, &Decoder::durationChanged, this, &QAndroidAudioDecoder::durationChanged);
- connect(m_decoder, &Decoder::error, this, &QAndroidAudioDecoder::error);
- connect(m_decoder, &Decoder::finished, this, &QAndroidAudioDecoder::finished);
-}
-
-QAndroidAudioDecoder::~QAndroidAudioDecoder()
-{
- m_decoder->thread()->exit();
- m_decoder->deleteLater();
-}
-
-void QAndroidAudioDecoder::setSource(const QUrl &fileName)
-{
- if (!requestPermissions())
- return;
-
- if (isDecoding())
- return;
-
- m_device = nullptr;
- error(QAudioDecoder::NoError, QStringLiteral(""));
-
- if (m_source != fileName) {
- m_source = fileName;
- m_decoder->setSource(m_source);
- sourceChanged();
- }
-}
-
-void QAndroidAudioDecoder::setSourceDevice(QIODevice *device)
-{
- if (isDecoding())
- return;
-
- m_source.clear();
- if (m_device != device) {
- m_device = device;
-
- if (!requestPermissions())
- return;
-
- sourceChanged();
- }
-}
-
-void QAndroidAudioDecoder::start()
-{
- if (isDecoding())
- return;
-
- setIsDecoding(true);
- m_position = -1;
-
- QThread *threadDecoder = new QThread(this);
- m_decoder->moveToThread(threadDecoder);
- threadDecoder->start();
- decode();
-}
-
-void QAndroidAudioDecoder::stop()
-{
- if (!isDecoding())
- return;
-
- m_decoder->stop();
-
- QMutexLocker locker(&m_buffersMutex);
- m_position = -1;
- m_audioBuffer.clear();
- locker.unlock();
- setIsDecoding(false);
-}
-
-QAudioBuffer QAndroidAudioDecoder::read()
-{
- QMutexLocker locker(&m_buffersMutex);
- if (m_buffersAvailable && !m_audioBuffer.isEmpty()) {
- --m_buffersAvailable;
- return m_audioBuffer.takeFirst();
- }
-
- // no buffers available
- return {};
-}
-
-bool QAndroidAudioDecoder::bufferAvailable() const
-{
- QMutexLocker locker(&m_buffersMutex);
- return m_buffersAvailable;
-}
-
-qint64 QAndroidAudioDecoder::position() const
-{
- QMutexLocker locker(&m_buffersMutex);
- return m_position;
-}
-
-qint64 QAndroidAudioDecoder::duration() const
-{
- QMutexLocker locker(&m_buffersMutex);
- return m_duration;
-}
-
-void QAndroidAudioDecoder::positionChanged(QAudioBuffer audioBuffer, qint64 position)
-{
- QMutexLocker locker(&m_buffersMutex);
- m_audioBuffer.append(audioBuffer);
- m_position = position;
- m_buffersAvailable++;
- locker.unlock();
- emit bufferReady();
- emit QPlatformAudioDecoder::positionChanged(position);
-}
-
-void QAndroidAudioDecoder::durationChanged(qint64 duration)
-{
- QMutexLocker locker(&m_buffersMutex);
- m_duration = duration;
- locker.unlock();
- emit QPlatformAudioDecoder::durationChanged(duration);
-}
-
-void QAndroidAudioDecoder::error(const QAudioDecoder::Error err, const QString &errorString)
-{
- emit QPlatformAudioDecoder::error(err, errorString);
-}
-
-void QAndroidAudioDecoder::finished()
-{
- stop();
- // remove temp file when decoding is finished
- QFile(QString::fromUtf8(tempPath).append(QString::fromUtf8(tempFile))).remove();
- emit QPlatformAudioDecoder::finished();
-}
-
-bool QAndroidAudioDecoder::requestPermissions()
-{
- const auto writeRes = QtAndroidPrivate::requestPermission(QtAndroidPrivate::Storage);
- if (writeRes.result() == QtAndroidPrivate::Authorized)
- return true;
-
- return false;
-}
-
-void QAndroidAudioDecoder::decode()
-{
- if (m_device) {
- connect(m_device, &QIODevice::readyRead, this, &QAndroidAudioDecoder::readDevice);
- if (m_device->bytesAvailable())
- readDevice();
- } else {
- QTimer::singleShot(0, m_decoder, &Decoder::doDecode);
- }
-}
-
-bool QAndroidAudioDecoder::createTempFile()
-{
- QFile file = QFile(QString::fromUtf8(tempPath).append(QString::fromUtf8(tempFile)));
- if (!QDir().mkpath(QString::fromUtf8(tempPath)) || !file.open(QIODevice::WriteOnly)) {
- emit error(QAudioDecoder::ResourceError,
- QString::fromUtf8("Error while creating or opening tmp file"));
- return false;
- }
-
- QDataStream out;
- out.setDevice(&file);
- out << m_deviceBuffer;
- file.close();
-
- m_deviceBuffer.clear();
- m_decoder->setSource(file.fileName());
-
- return true;
-}
-
-void QAndroidAudioDecoder::readDevice() {
- m_deviceBuffer.append(m_device->readAll());
- if (m_device->atEnd()) {
- disconnect(m_device, &QIODevice::readyRead, this, &QAndroidAudioDecoder::readDevice);
- if (!createTempFile()) {
- m_deviceBuffer.clear();
- stop();
- return;
- }
- QTimer::singleShot(0, m_decoder, &Decoder::doDecode);
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/audio/qandroidaudiodecoder_p.h b/src/multimedia/platform/android/audio/qandroidaudiodecoder_p.h
deleted file mode 100644
index d6e1bf32e..000000000
--- a/src/multimedia/platform/android/audio/qandroidaudiodecoder_p.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QANDROIDAUDIODECODER_P_H
-#define QANDROIDAUDIODECODER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-#include "private/qplatformaudiodecoder_p.h"
-
-#include <QtCore/qurl.h>
-#include <QtCore/qmutex.h>
-#include <QThread>
-
-#include "media/NdkMediaCodec.h"
-#include "media/NdkMediaExtractor.h"
-#include "media/NdkMediaFormat.h"
-#include "media/NdkMediaError.h"
-
-
-QT_USE_NAMESPACE
-
-class Decoder : public QObject
-{
- Q_OBJECT
-public:
- Decoder();
- ~Decoder();
-
-public slots:
- void setSource(const QUrl &source);
- void doDecode();
- void stop();
-
-signals:
- void positionChanged(const QAudioBuffer &buffer, qint64 position);
- void durationChanged(const qint64 duration);
- void error(const QAudioDecoder::Error error, const QString &errorString);
- void finished();
-
-private:
- void createDecoder();
-
- AMediaCodec *m_codec = nullptr;
- AMediaExtractor *m_extractor = nullptr;
- AMediaFormat *m_format = nullptr;
-
- QAudioFormat m_outputFormat;
- bool m_inputEOS;
-};
-
-
-class QAndroidAudioDecoder : public QPlatformAudioDecoder
-{
- Q_OBJECT
-public:
- QAndroidAudioDecoder(QAudioDecoder *parent);
- virtual ~QAndroidAudioDecoder();
-
- QUrl source() const override { return m_source; }
- void setSource(const QUrl &fileName) override;
-
- QIODevice *sourceDevice() const override { return m_device; }
- void setSourceDevice(QIODevice *device) override;
-
- void start() override;
- void stop() override;
-
- QAudioFormat audioFormat() const override { return {}; }
- void setAudioFormat(const QAudioFormat &/*format*/) override {}
-
- QAudioBuffer read() override;
- bool bufferAvailable() const override;
-
- qint64 position() const override;
- qint64 duration() const override;
-
-private slots:
- void positionChanged(QAudioBuffer audioBuffer, qint64 position);
- void durationChanged(qint64 duration);
- void error(const QAudioDecoder::Error error, const QString &errorString);
- void readDevice();
- void finished();
-
-private:
- bool requestPermissions();
- bool createTempFile();
- void decode();
-
- QIODevice *m_device = nullptr;
- Decoder *m_decoder;
-
- QList<QAudioBuffer> m_audioBuffer;
- QUrl m_source;
-
- mutable QMutex m_buffersMutex;
- qint64 m_position = -1;
- qint64 m_duration = -1;
- long long m_presentationTimeUs = 0;
- int m_buffersAvailable = 0;
-
- QByteArray m_deviceBuffer;
-};
-
-QT_END_NAMESPACE
-
-#endif // QANDROIDAUDIODECODER_P_H
diff --git a/src/multimedia/platform/android/audio/qandroidaudiodevice.cpp b/src/multimedia/platform/android/audio/qandroidaudiodevice.cpp
deleted file mode 100644
index fcd979a5a..000000000
--- a/src/multimedia/platform/android/audio/qandroidaudiodevice.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 "qandroidaudiodevice_p.h"
-
-#include "qopenslesengine_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QOpenSLESDeviceInfo::QOpenSLESDeviceInfo(const QByteArray &device, const QString &desc, QAudioDevice::Mode mode)
- : QAudioDevicePrivate(device, mode),
- m_engine(QOpenSLESEngine::instance())
-{
- description = desc;
-
- auto channels = m_engine->supportedChannelCounts(mode);
- if (channels.size()) {
- minimumChannelCount = channels.first();
- maximumChannelCount = channels.last();
- }
-
- auto sampleRates = m_engine->supportedSampleRates(mode);
- if (sampleRates.size()) {
- minimumSampleRate = sampleRates.first();
- maximumSampleRate = sampleRates.last();
- }
- if (mode == QAudioDevice::Input)
- supportedSampleFormats.append(QAudioFormat::UInt8);
- supportedSampleFormats.append(QAudioFormat::Int16);
-
- preferredFormat.setChannelCount(2);
- preferredFormat.setSampleRate(48000);
- QAudioFormat::SampleFormat f = QAudioFormat::Int16;
- if (!supportedSampleFormats.contains(f))
- f = supportedSampleFormats.value(0, QAudioFormat::Unknown);
- preferredFormat.setSampleFormat(f);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/audio/qandroidaudiodevice_p.h b/src/multimedia/platform/android/audio/qandroidaudiodevice_p.h
deleted file mode 100644
index 81b85c9fd..000000000
--- a/src/multimedia/platform/android/audio/qandroidaudiodevice_p.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 QOPENSLESDEVICEINFO_H
-#define QOPENSLESDEVICEINFO_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 <qaudiosystem_p.h>
-#include <private/qaudiodevice_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QOpenSLESEngine;
-
-class QOpenSLESDeviceInfo : public QAudioDevicePrivate
-{
-public:
- QOpenSLESDeviceInfo(const QByteArray &device, const QString &desc, QAudioDevice::Mode mode);
- ~QOpenSLESDeviceInfo() {}
-
-private:
- QOpenSLESEngine *m_engine;
-};
-
-QT_END_NAMESPACE
-
-#endif // QOPENSLESDEVICEINFO_H
diff --git a/src/multimedia/platform/android/audio/qandroidaudiosink.cpp b/src/multimedia/platform/android/audio/qandroidaudiosink.cpp
deleted file mode 100644
index 1a0b622a3..000000000
--- a/src/multimedia/platform/android/audio/qandroidaudiosink.cpp
+++ /dev/null
@@ -1,636 +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 "qandroidaudiosink_p.h"
-#include "qopenslesengine_p.h"
-#include <QDebug>
-#include <qmath.h>
-#include <qmediadevices.h>
-
-#ifdef ANDROID
-#include <SLES/OpenSLES_Android.h>
-#include <SLES/OpenSLES_AndroidConfiguration.h>
-#endif // ANDROID
-
-#define BUFFER_COUNT 2
-
-QT_BEGIN_NAMESPACE
-
-static inline void openSlDebugInfo()
-{
- const QAudioFormat &format = QMediaDevices::defaultAudioOutput().preferredFormat();
- qDebug() << "======= OpenSL ES Device info ======="
- << "\nSupports low-latency playback: " << (QOpenSLESEngine::supportsLowLatency() ? "YES" : "NO")
- << "\nPreferred sample rate: " << QOpenSLESEngine::getOutputValue(QOpenSLESEngine::SampleRate, -1)
- << "\nFrames per buffer: " << QOpenSLESEngine::getOutputValue(QOpenSLESEngine::FramesPerBuffer, -1)
- << "\nPreferred Format: " << format
- << "\nLow-latency buffer size: " << QOpenSLESEngine::getLowLatencyBufferSize(format)
- << "\nDefault buffer size: " << QOpenSLESEngine::getDefaultBufferSize(format);
-}
-
-QAndroidAudioSink::QAndroidAudioSink(const QByteArray &device)
- : m_deviceName(device),
- m_state(QAudio::StoppedState),
- m_error(QAudio::NoError),
- m_outputMixObject(nullptr),
- m_playerObject(nullptr),
- m_playItf(nullptr),
- m_volumeItf(nullptr),
- m_bufferQueueItf(nullptr),
- m_audioSource(nullptr),
- m_buffers(nullptr),
- m_volume(1.0),
- m_pullMode(false),
- m_nextBuffer(0),
- m_bufferSize(0),
- m_elapsedTime(0),
- m_processedBytes(0),
- m_availableBuffers(BUFFER_COUNT),
- m_eventMask(SL_PLAYEVENT_HEADATEND),
- m_startRequiresInit(true)
-{
-#ifndef ANDROID
- m_streamType = -1;
-#else
- m_streamType = SL_ANDROID_STREAM_MEDIA;
-#endif // ANDROID
-}
-
-QAndroidAudioSink::~QAndroidAudioSink()
-{
- destroyPlayer();
-}
-
-QAudio::Error QAndroidAudioSink::error() const
-{
- return m_error;
-}
-
-QAudio::State QAndroidAudioSink::state() const
-{
- return m_state;
-}
-
-void QAndroidAudioSink::start(QIODevice *device)
-{
- Q_ASSERT(device);
-
- if (m_state != QAudio::StoppedState)
- stop();
-
- if (!preparePlayer())
- return;
-
- m_pullMode = true;
- m_audioSource = device;
- m_nextBuffer = 0;
- m_processedBytes = 0;
- m_availableBuffers = BUFFER_COUNT;
- setState(QAudio::ActiveState);
- setError(QAudio::NoError);
-
- // Attempt to fill buffers first.
- for (int i = 0; i != BUFFER_COUNT; ++i) {
- const int index = i * m_bufferSize;
- const qint64 readSize = m_audioSource->read(m_buffers + index, m_bufferSize);
- if (readSize && SL_RESULT_SUCCESS != (*m_bufferQueueItf)->Enqueue(m_bufferQueueItf,
- m_buffers + index,
- readSize)) {
- setError(QAudio::FatalError);
- destroyPlayer();
- return;
- }
- m_processedBytes += readSize;
- }
-
- if (m_processedBytes < 1)
- onEOSEvent();
-
- // Change the state to playing.
- // We need to do this after filling the buffers or processedBytes might get corrupted.
- startPlayer();
-}
-
-QIODevice *QAndroidAudioSink::start()
-{
- if (m_state != QAudio::StoppedState)
- stop();
-
- if (!preparePlayer())
- return nullptr;
-
- m_pullMode = false;
- m_processedBytes = 0;
- m_availableBuffers = BUFFER_COUNT;
- m_audioSource = new SLIODevicePrivate(this);
- m_audioSource->open(QIODevice::WriteOnly | QIODevice::Unbuffered);
-
- // Change the state to playing
- startPlayer();
-
- setState(QAudio::IdleState);
- return m_audioSource;
-}
-
-void QAndroidAudioSink::stop()
-{
- if (m_state == QAudio::StoppedState)
- return;
-
- stopPlayer();
- setError(QAudio::NoError);
-}
-
-qsizetype QAndroidAudioSink::bytesFree() const
-{
- if (m_state != QAudio::ActiveState && m_state != QAudio::IdleState)
- return 0;
-
- return m_availableBuffers.loadAcquire() ? m_bufferSize : 0;
-}
-
-void QAndroidAudioSink::setBufferSize(qsizetype value)
-{
- if (m_state != QAudio::StoppedState)
- return;
-
- m_startRequiresInit = true;
- m_bufferSize = value;
-}
-
-qsizetype QAndroidAudioSink::bufferSize() const
-{
- return m_bufferSize;
-}
-
-qint64 QAndroidAudioSink::processedUSecs() const
-{
- if (m_state == QAudio::IdleState || m_state == QAudio::SuspendedState)
- return m_format.durationForBytes(m_processedBytes);
-
- SLmillisecond processMSec = 0;
- if (m_playItf)
- (*m_playItf)->GetPosition(m_playItf, &processMSec);
-
- return processMSec * 1000;
-}
-
-void QAndroidAudioSink::resume()
-{
- if (m_state != QAudio::SuspendedState)
- return;
-
- if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING)) {
- setError(QAudio::FatalError);
- destroyPlayer();
- return;
- }
-
- setState(m_pullMode ? QAudio::ActiveState : QAudio::IdleState);
- setError(QAudio::NoError);
-}
-
-void QAndroidAudioSink::setFormat(const QAudioFormat &format)
-{
- m_startRequiresInit = true;
- m_format = format;
-}
-
-QAudioFormat QAndroidAudioSink::format() const
-{
- return m_format;
-}
-
-void QAndroidAudioSink::suspend()
-{
- if (m_state != QAudio::ActiveState && m_state != QAudio::IdleState)
- return;
-
- if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PAUSED)) {
- setError(QAudio::FatalError);
- destroyPlayer();
- return;
- }
-
- setState(QAudio::SuspendedState);
- setError(QAudio::NoError);
-}
-
-void QAndroidAudioSink::reset()
-{
- destroyPlayer();
-}
-
-void QAndroidAudioSink::setVolume(qreal vol)
-{
- m_volume = qBound(qreal(0.0), vol, qreal(1.0));
- const SLmillibel newVolume = adjustVolume(m_volume);
- if (m_volumeItf && SL_RESULT_SUCCESS != (*m_volumeItf)->SetVolumeLevel(m_volumeItf, newVolume))
- qWarning() << "Unable to change volume";
-}
-
-qreal QAndroidAudioSink::volume() const
-{
- return m_volume;
-}
-
-void QAndroidAudioSink::onEOSEvent()
-{
- if (m_state != QAudio::ActiveState)
- return;
-
- SLBufferQueueState state;
- if (SL_RESULT_SUCCESS != (*m_bufferQueueItf)->GetState(m_bufferQueueItf, &state))
- return;
-
- if (state.count > 0)
- return;
-
- setState(QAudio::IdleState);
- setError(QAudio::UnderrunError);
-}
-
-void QAndroidAudioSink::onBytesProcessed(qint64 bytes)
-{
- m_processedBytes += bytes;
-}
-
-void QAndroidAudioSink::bufferAvailable(quint32 count, quint32 playIndex)
-{
- Q_UNUSED(count);
- Q_UNUSED(playIndex);
-
- if (m_state == QAudio::StoppedState)
- return;
-
- if (!m_pullMode) { // We're in push mode.
- // Signal that there is a new open slot in the buffer and return
- const int val = m_availableBuffers.fetchAndAddRelease(1) + 1;
- if (val == BUFFER_COUNT)
- QMetaObject::invokeMethod(this, "onEOSEvent", Qt::QueuedConnection);
-
- return;
- }
-
- // We're in pull mode.
- const int index = m_nextBuffer * m_bufferSize;
- const qint64 readSize = m_audioSource->read(m_buffers + index, m_bufferSize);
-
- if (readSize < 1) {
- QMetaObject::invokeMethod(this, "onEOSEvent", Qt::QueuedConnection);
- return;
- }
-
-
- if (SL_RESULT_SUCCESS != (*m_bufferQueueItf)->Enqueue(m_bufferQueueItf,
- m_buffers + index,
- readSize)) {
- setError(QAudio::FatalError);
- destroyPlayer();
- return;
- }
-
- m_nextBuffer = (m_nextBuffer + 1) % BUFFER_COUNT;
- QMetaObject::invokeMethod(this, "onBytesProcessed", Qt::QueuedConnection, Q_ARG(qint64, readSize));
-}
-
-void QAndroidAudioSink::playCallback(SLPlayItf player, void *ctx, SLuint32 event)
-{
- Q_UNUSED(player);
- QAndroidAudioSink *audioOutput = reinterpret_cast<QAndroidAudioSink *>(ctx);
- if (event & SL_PLAYEVENT_HEADATEND)
- QMetaObject::invokeMethod(audioOutput, "onEOSEvent", Qt::QueuedConnection);
-}
-
-void QAndroidAudioSink::bufferQueueCallback(SLBufferQueueItf bufferQueue, void *ctx)
-{
- SLBufferQueueState state;
- (*bufferQueue)->GetState(bufferQueue, &state);
- QAndroidAudioSink *audioOutput = reinterpret_cast<QAndroidAudioSink *>(ctx);
- audioOutput->bufferAvailable(state.count, state.playIndex);
-}
-
-bool QAndroidAudioSink::preparePlayer()
-{
- if (m_startRequiresInit)
- destroyPlayer();
- else
- return true;
-
- SLEngineItf engine = QOpenSLESEngine::instance()->slEngine();
- if (!engine) {
- qWarning() << "No engine";
- setError(QAudio::FatalError);
- return false;
- }
-
- SLDataLocator_BufferQueue bufferQueueLocator = { SL_DATALOCATOR_BUFFERQUEUE, BUFFER_COUNT };
- SLDataFormat_PCM pcmFormat = QOpenSLESEngine::audioFormatToSLFormatPCM(m_format);
-
- SLDataSource audioSrc = { &bufferQueueLocator, &pcmFormat };
-
- // OutputMix
- if (SL_RESULT_SUCCESS != (*engine)->CreateOutputMix(engine,
- &m_outputMixObject,
- 0,
- nullptr,
- nullptr)) {
- qWarning() << "Unable to create output mix";
- setError(QAudio::FatalError);
- return false;
- }
-
- if (SL_RESULT_SUCCESS != (*m_outputMixObject)->Realize(m_outputMixObject, SL_BOOLEAN_FALSE)) {
- qWarning() << "Unable to initialize output mix";
- setError(QAudio::FatalError);
- return false;
- }
-
- SLDataLocator_OutputMix outputMixLocator = { SL_DATALOCATOR_OUTPUTMIX, m_outputMixObject };
- SLDataSink audioSink = { &outputMixLocator, nullptr };
-
-#ifndef ANDROID
- const int iids = 2;
- const SLInterfaceID ids[iids] = { SL_IID_BUFFERQUEUE, SL_IID_VOLUME };
- const SLboolean req[iids] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
-#else
- const int iids = 3;
- const SLInterfaceID ids[iids] = { SL_IID_BUFFERQUEUE,
- SL_IID_VOLUME,
- SL_IID_ANDROIDCONFIGURATION };
- const SLboolean req[iids] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
-#endif // ANDROID
-
- // AudioPlayer
- if (SL_RESULT_SUCCESS != (*engine)->CreateAudioPlayer(engine,
- &m_playerObject,
- &audioSrc,
- &audioSink,
- iids,
- ids,
- req)) {
- qWarning() << "Unable to create AudioPlayer";
- setError(QAudio::OpenError);
- return false;
- }
-
-#ifdef ANDROID
- // Set profile/category
- SLAndroidConfigurationItf playerConfig;
- if (SL_RESULT_SUCCESS == (*m_playerObject)->GetInterface(m_playerObject,
- SL_IID_ANDROIDCONFIGURATION,
- &playerConfig)) {
- (*playerConfig)->SetConfiguration(playerConfig,
- SL_ANDROID_KEY_STREAM_TYPE,
- &m_streamType,
- sizeof(SLint32));
- }
-#endif // ANDROID
-
- if (SL_RESULT_SUCCESS != (*m_playerObject)->Realize(m_playerObject, SL_BOOLEAN_FALSE)) {
- qWarning() << "Unable to initialize AudioPlayer";
- setError(QAudio::OpenError);
- return false;
- }
-
- // Buffer interface
- if (SL_RESULT_SUCCESS != (*m_playerObject)->GetInterface(m_playerObject,
- SL_IID_BUFFERQUEUE,
- &m_bufferQueueItf)) {
- setError(QAudio::FatalError);
- return false;
- }
-
- if (SL_RESULT_SUCCESS != (*m_bufferQueueItf)->RegisterCallback(m_bufferQueueItf,
- bufferQueueCallback,
- this)) {
- setError(QAudio::FatalError);
- return false;
- }
-
- // Play interface
- if (SL_RESULT_SUCCESS != (*m_playerObject)->GetInterface(m_playerObject,
- SL_IID_PLAY,
- &m_playItf)) {
- setError(QAudio::FatalError);
- return false;
- }
-
- if (SL_RESULT_SUCCESS != (*m_playItf)->RegisterCallback(m_playItf, playCallback, this)) {
- setError(QAudio::FatalError);
- return false;
- }
-
- if (SL_RESULT_SUCCESS != (*m_playItf)->SetCallbackEventsMask(m_playItf, m_eventMask)) {
- setError(QAudio::FatalError);
- return false;
- }
-
- // Volume interface
- if (SL_RESULT_SUCCESS != (*m_playerObject)->GetInterface(m_playerObject,
- SL_IID_VOLUME,
- &m_volumeItf)) {
- setError(QAudio::FatalError);
- return false;
- }
-
- setVolume(m_volume);
-
- const int lowLatencyBufferSize = QOpenSLESEngine::getLowLatencyBufferSize(m_format);
- const int defaultBufferSize = QOpenSLESEngine::getDefaultBufferSize(m_format);
-
- if (defaultBufferSize <= 0) {
- qWarning() << "Unable to get minimum buffer size, returned" << defaultBufferSize;
- setError(QAudio::FatalError);
- return false;
- }
-
- // Buffer size
- if (m_bufferSize <= 0) {
- m_bufferSize = defaultBufferSize;
- } else if (QOpenSLESEngine::supportsLowLatency()) {
- if (m_bufferSize < lowLatencyBufferSize)
- m_bufferSize = lowLatencyBufferSize;
- } else if (m_bufferSize < defaultBufferSize) {
- m_bufferSize = defaultBufferSize;
- }
-
- if (!m_buffers)
- m_buffers = new char[BUFFER_COUNT * m_bufferSize];
-
- setError(QAudio::NoError);
- m_startRequiresInit = false;
-
- return true;
-}
-
-void QAndroidAudioSink::destroyPlayer()
-{
- if (m_state != QAudio::StoppedState)
- stopPlayer();
-
- if (m_playerObject) {
- (*m_playerObject)->Destroy(m_playerObject);
- m_playerObject = nullptr;
- }
-
- if (m_outputMixObject) {
- (*m_outputMixObject)->Destroy(m_outputMixObject);
- m_outputMixObject = nullptr;
- }
-
- if (!m_pullMode && m_audioSource) {
- m_audioSource->close();
- delete m_audioSource;
- m_audioSource = nullptr;
- }
-
- delete [] m_buffers;
- m_buffers = nullptr;
- m_processedBytes = 0;
- m_nextBuffer = 0;
- m_availableBuffers.storeRelease(BUFFER_COUNT);
- m_playItf = nullptr;
- m_volumeItf = nullptr;
- m_bufferQueueItf = nullptr;
- m_startRequiresInit = true;
-}
-
-void QAndroidAudioSink::stopPlayer()
-{
- setState(QAudio::StoppedState);
-
- if (m_audioSource && !m_pullMode) {
- m_audioSource->close();
- delete m_audioSource;
- m_audioSource = nullptr;
- }
-
- // We need to change the state manually...
- if (m_playItf)
- (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_STOPPED);
-
- if (m_bufferQueueItf && SL_RESULT_SUCCESS != (*m_bufferQueueItf)->Clear(m_bufferQueueItf))
- qWarning() << "Unable to clear buffer";
-}
-
-void QAndroidAudioSink::startPlayer()
-{
- if (QOpenSLESEngine::printDebugInfo())
- openSlDebugInfo();
-
- if (SL_RESULT_SUCCESS != (*m_playItf)->SetPlayState(m_playItf, SL_PLAYSTATE_PLAYING)) {
- setError(QAudio::FatalError);
- destroyPlayer();
- }
-}
-
-qint64 QAndroidAudioSink::writeData(const char *data, qint64 len)
-{
- if (!len)
- return 0;
-
- if (len > m_bufferSize)
- len = m_bufferSize;
-
- // Acquire one slot in the buffer
- const int before = m_availableBuffers.fetchAndAddAcquire(-1);
-
- // If there where no vacant slots, then we just overdrew the buffer account...
- if (before < 1) {
- m_availableBuffers.fetchAndAddRelease(1);
- return 0;
- }
-
- const int index = m_nextBuffer * m_bufferSize;
- ::memcpy(m_buffers + index, data, len);
- const SLuint32 res = (*m_bufferQueueItf)->Enqueue(m_bufferQueueItf,
- m_buffers + index,
- len);
-
- // If we where unable to enqueue a new buffer, give back the acquired slot.
- if (res == SL_RESULT_BUFFER_INSUFFICIENT) {
- m_availableBuffers.fetchAndAddRelease(1);
- return 0;
- }
-
- if (res != SL_RESULT_SUCCESS) {
- setError(QAudio::FatalError);
- destroyPlayer();
- return -1;
- }
-
- m_processedBytes += len;
- setState(QAudio::ActiveState);
- setError(QAudio::NoError);
- m_nextBuffer = (m_nextBuffer + 1) % BUFFER_COUNT;
-
- return len;
-}
-
-inline void QAndroidAudioSink::setState(QAudio::State state)
-{
- if (m_state == state)
- return;
-
- m_state = state;
- Q_EMIT stateChanged(m_state);
-}
-
-inline void QAndroidAudioSink::setError(QAudio::Error error)
-{
- if (m_error == error)
- return;
-
- m_error = error;
- Q_EMIT errorChanged(m_error);
-}
-
-inline SLmillibel QAndroidAudioSink::adjustVolume(qreal vol)
-{
- if (qFuzzyIsNull(vol))
- return SL_MILLIBEL_MIN;
-
- if (qFuzzyCompare(vol, qreal(1.0)))
- return 0;
-
- return QAudio::convertVolume(vol, QAudio::LinearVolumeScale, QAudio::DecibelVolumeScale) * 100;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/audio/qandroidaudiosink_p.h b/src/multimedia/platform/android/audio/qandroidaudiosink_p.h
deleted file mode 100644
index 40b964dc2..000000000
--- a/src/multimedia/platform/android/audio/qandroidaudiosink_p.h
+++ /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$
-**
-****************************************************************************/
-
-#ifndef QOPENSLESAUDIOOUTPUT_H
-#define QOPENSLESAUDIOOUTPUT_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 <qaudiosystem_p.h>
-#include <SLES/OpenSLES.h>
-#include <qbytearray.h>
-#include <qmap.h>
-#include <QElapsedTimer>
-#include <QIODevice>
-
-QT_BEGIN_NAMESPACE
-
-class QAndroidAudioSink : public QPlatformAudioSink
-{
- Q_OBJECT
-
-public:
- QAndroidAudioSink(const QByteArray &device);
- ~QAndroidAudioSink();
-
- void start(QIODevice *device) override;
- QIODevice *start() override;
- void stop() override;
- void reset() override;
- void suspend() override;
- void resume() override;
- qsizetype bytesFree() const override;
- void setBufferSize(qsizetype value) override;
- qsizetype bufferSize() const override;
- qint64 processedUSecs() const override;
- QAudio::Error error() const override;
- QAudio::State state() const override;
- void setFormat(const QAudioFormat &format) override;
- QAudioFormat format() const override;
-
- void setVolume(qreal volume) override;
- qreal volume() const override;
-
-private:
- friend class SLIODevicePrivate;
-
- Q_INVOKABLE void onEOSEvent();
- Q_INVOKABLE void onBytesProcessed(qint64 bytes);
- void bufferAvailable(quint32 count, quint32 playIndex);
-
- static void playCallback(SLPlayItf playItf, void *ctx, SLuint32 event);
- static void bufferQueueCallback(SLBufferQueueItf bufferQueue, void *ctx);
-
- bool preparePlayer();
- void destroyPlayer();
- void stopPlayer();
- void startPlayer();
- qint64 writeData(const char *data, qint64 len);
-
- void setState(QAudio::State state);
- void setError(QAudio::Error error);
-
- SLmillibel adjustVolume(qreal vol);
-
- QByteArray m_deviceName;
- QAudio::State m_state;
- QAudio::Error m_error;
- SLObjectItf m_outputMixObject;
- SLObjectItf m_playerObject;
- SLPlayItf m_playItf;
- SLVolumeItf m_volumeItf;
- SLBufferQueueItf m_bufferQueueItf;
- QIODevice *m_audioSource;
- char *m_buffers;
- qreal m_volume;
- bool m_pullMode;
- int m_nextBuffer;
- int m_bufferSize;
- qint64 m_elapsedTime;
- qint64 m_processedBytes;
- QAtomicInt m_availableBuffers;
- SLuint32 m_eventMask;
- bool m_startRequiresInit;
-
- qint32 m_streamType;
- QAudioFormat m_format;
-};
-
-class SLIODevicePrivate : public QIODevice
-{
- Q_OBJECT
-
-public:
- inline SLIODevicePrivate(QAndroidAudioSink *audio) : m_audioDevice(audio) {}
- inline ~SLIODevicePrivate() override {}
-
-protected:
- inline qint64 readData(char *, qint64) override { return 0; }
- inline qint64 writeData(const char *data, qint64 len) override;
-
-private:
- QAndroidAudioSink *m_audioDevice;
-};
-
-qint64 SLIODevicePrivate::writeData(const char *data, qint64 len)
-{
- Q_ASSERT(m_audioDevice);
- return m_audioDevice->writeData(data, len);
-}
-
-QT_END_NAMESPACE
-
-#endif // QOPENSLESAUDIOOUTPUT_H
diff --git a/src/multimedia/platform/android/audio/qandroidaudiosource.cpp b/src/multimedia/platform/android/audio/qandroidaudiosource.cpp
deleted file mode 100644
index c7eaf57ad..000000000
--- a/src/multimedia/platform/android/audio/qandroidaudiosource.cpp
+++ /dev/null
@@ -1,505 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qandroidaudiosource_p.h"
-
-#include "qopenslesengine_p.h"
-#include <private/qaudiohelpers_p.h>
-#include <QtCore/private/qandroidextras_p.h>
-#include <qbuffer.h>
-#include <qdebug.h>
-
-#ifdef ANDROID
-#include <SLES/OpenSLES_AndroidConfiguration.h>
-#include <QtCore/qcoreapplication.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#define NUM_BUFFERS 2
-#define DEFAULT_PERIOD_TIME_MS 50
-#define MINIMUM_PERIOD_TIME_MS 5
-
-#ifdef ANDROID
-static bool hasRecordingPermission()
-{
- if (QNativeInterface::QAndroidApplication::sdkVersion() < 23)
- return true;
-
- const QtAndroidPrivate::PermissionType key(QtAndroidPrivate::Microphone);
- // Permission already granted?
- if (QtAndroidPrivate::checkPermission(key).result() == QtAndroidPrivate::Authorized)
- return true;
-
- if (QtAndroidPrivate::requestPermission(key).result() != QtAndroidPrivate::Authorized) {
- qDebug("Microphone permission denied by user!");
- return false;
- }
-
- return true;
-}
-
-static void bufferQueueCallback(SLAndroidSimpleBufferQueueItf, void *context)
-#else
-static void bufferQueueCallback(SLBufferQueueItf, void *context)
-#endif
-{
- // Process buffer in main thread
- QMetaObject::invokeMethod(reinterpret_cast<QAndroidAudioSource*>(context), "processBuffer");
-}
-
-QAndroidAudioSource::QAndroidAudioSource(const QByteArray &device)
- : m_device(device)
- , m_engine(QOpenSLESEngine::instance())
- , m_recorderObject(0)
- , m_recorder(0)
- , m_bufferQueue(0)
- , m_pullMode(true)
- , m_processedBytes(0)
- , m_audioSource(0)
- , m_bufferIODevice(0)
- , m_errorState(QAudio::NoError)
- , m_deviceState(QAudio::StoppedState)
- , m_lastNotifyTime(0)
- , m_volume(1.0)
- , m_bufferSize(0)
- , m_buffers(new QByteArray[NUM_BUFFERS])
- , m_currentBuffer(0)
-{
-#ifdef ANDROID
- if (qstrcmp(device, QT_ANDROID_PRESET_CAMCORDER) == 0)
- m_recorderPreset = SL_ANDROID_RECORDING_PRESET_CAMCORDER;
- else if (qstrcmp(device, QT_ANDROID_PRESET_VOICE_RECOGNITION) == 0)
- m_recorderPreset = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION;
- else if (qstrcmp(device, QT_ANDROID_PRESET_VOICE_COMMUNICATION) == 0)
- m_recorderPreset = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION;
- else
- m_recorderPreset = SL_ANDROID_RECORDING_PRESET_GENERIC;
-#endif
-}
-
-QAndroidAudioSource::~QAndroidAudioSource()
-{
- if (m_recorderObject)
- (*m_recorderObject)->Destroy(m_recorderObject);
- delete[] m_buffers;
-}
-
-QAudio::Error QAndroidAudioSource::error() const
-{
- return m_errorState;
-}
-
-QAudio::State QAndroidAudioSource::state() const
-{
- return m_deviceState;
-}
-
-void QAndroidAudioSource::setFormat(const QAudioFormat &format)
-{
- if (m_deviceState == QAudio::StoppedState)
- m_format = format;
-}
-
-QAudioFormat QAndroidAudioSource::format() const
-{
- return m_format;
-}
-
-void QAndroidAudioSource::start(QIODevice *device)
-{
- if (m_deviceState != QAudio::StoppedState)
- stopRecording();
-
- if (!m_pullMode && m_bufferIODevice) {
- m_bufferIODevice->close();
- delete m_bufferIODevice;
- m_bufferIODevice = 0;
- }
-
- m_pullMode = true;
- m_audioSource = device;
-
- if (startRecording()) {
- m_deviceState = QAudio::ActiveState;
- } else {
- m_deviceState = QAudio::StoppedState;
- Q_EMIT errorChanged(m_errorState);
- }
-
- Q_EMIT stateChanged(m_deviceState);
-}
-
-QIODevice *QAndroidAudioSource::start()
-{
- if (m_deviceState != QAudio::StoppedState)
- stopRecording();
-
- m_audioSource = 0;
-
- if (!m_pullMode && m_bufferIODevice) {
- m_bufferIODevice->close();
- delete m_bufferIODevice;
- }
-
- m_pullMode = false;
- m_pushBuffer.clear();
- m_bufferIODevice = new QBuffer(&m_pushBuffer);
- m_bufferIODevice->open(QIODevice::ReadOnly);
-
- if (startRecording()) {
- m_deviceState = QAudio::IdleState;
- } else {
- m_deviceState = QAudio::StoppedState;
- Q_EMIT errorChanged(m_errorState);
- m_bufferIODevice->close();
- delete m_bufferIODevice;
- m_bufferIODevice = 0;
- }
-
- Q_EMIT stateChanged(m_deviceState);
- return m_bufferIODevice;
-}
-
-bool QAndroidAudioSource::startRecording()
-{
- if (!hasRecordingPermission())
- return false;
-
- m_processedBytes = 0;
- m_lastNotifyTime = 0;
-
- SLresult result;
-
- // configure audio source
- SLDataLocator_IODevice loc_dev = { SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
- SL_DEFAULTDEVICEID_AUDIOINPUT, NULL };
- SLDataSource audioSrc = { &loc_dev, NULL };
-
- // configure audio sink
-#ifdef ANDROID
- SLDataLocator_AndroidSimpleBufferQueue loc_bq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
- NUM_BUFFERS };
-#else
- SLDataLocator_BufferQueue loc_bq = { SL_DATALOCATOR_BUFFERQUEUE, NUM_BUFFERS };
-#endif
-
- SLDataFormat_PCM format_pcm = QOpenSLESEngine::audioFormatToSLFormatPCM(m_format);
- SLDataSink audioSnk = { &loc_bq, &format_pcm };
-
- // create audio recorder
- // (requires the RECORD_AUDIO permission)
-#ifdef ANDROID
- const SLInterfaceID id[2] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION };
- const SLboolean req[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };
-#else
- const SLInterfaceID id[1] = { SL_IID_BUFFERQUEUE };
- const SLboolean req[1] = { SL_BOOLEAN_TRUE };
-#endif
-
- result = (*m_engine->slEngine())->CreateAudioRecorder(m_engine->slEngine(), &m_recorderObject,
- &audioSrc, &audioSnk,
- sizeof(req) / sizeof(SLboolean), id, req);
- if (result != SL_RESULT_SUCCESS) {
- m_errorState = QAudio::OpenError;
- return false;
- }
-
-#ifdef ANDROID
- // configure recorder source
- SLAndroidConfigurationItf configItf;
- result = (*m_recorderObject)->GetInterface(m_recorderObject, SL_IID_ANDROIDCONFIGURATION,
- &configItf);
- if (result != SL_RESULT_SUCCESS) {
- m_errorState = QAudio::OpenError;
- return false;
- }
-
- result = (*configItf)->SetConfiguration(configItf, SL_ANDROID_KEY_RECORDING_PRESET,
- &m_recorderPreset, sizeof(SLuint32));
-
- SLuint32 presetValue = SL_ANDROID_RECORDING_PRESET_NONE;
- SLuint32 presetSize = 2*sizeof(SLuint32); // intentionally too big
- result = (*configItf)->GetConfiguration(configItf, SL_ANDROID_KEY_RECORDING_PRESET,
- &presetSize, (void*)&presetValue);
-
- if (result != SL_RESULT_SUCCESS || presetValue == SL_ANDROID_RECORDING_PRESET_NONE) {
- m_errorState = QAudio::OpenError;
- return false;
- }
-#endif
-
- // realize the audio recorder
- result = (*m_recorderObject)->Realize(m_recorderObject, SL_BOOLEAN_FALSE);
- if (result != SL_RESULT_SUCCESS) {
- m_errorState = QAudio::OpenError;
- return false;
- }
-
- // get the record interface
- result = (*m_recorderObject)->GetInterface(m_recorderObject, SL_IID_RECORD, &m_recorder);
- if (result != SL_RESULT_SUCCESS) {
- m_errorState = QAudio::FatalError;
- return false;
- }
-
- // get the buffer queue interface
-#ifdef ANDROID
- SLInterfaceID bufferqueueItfID = SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
-#else
- SLInterfaceID bufferqueueItfID = SL_IID_BUFFERQUEUE;
-#endif
- result = (*m_recorderObject)->GetInterface(m_recorderObject, bufferqueueItfID, &m_bufferQueue);
- if (result != SL_RESULT_SUCCESS) {
- m_errorState = QAudio::FatalError;
- return false;
- }
-
- // register callback on the buffer queue
- result = (*m_bufferQueue)->RegisterCallback(m_bufferQueue, bufferQueueCallback, this);
- if (result != SL_RESULT_SUCCESS) {
- m_errorState = QAudio::FatalError;
- return false;
- }
-
- if (m_bufferSize <= 0) {
- m_bufferSize = m_format.bytesForDuration(DEFAULT_PERIOD_TIME_MS * 1000);
- } else {
- int minimumBufSize = m_format.bytesForDuration(MINIMUM_PERIOD_TIME_MS * 1000);
- if (m_bufferSize < minimumBufSize)
- m_bufferSize = minimumBufSize;
- }
-
- // enqueue empty buffers to be filled by the recorder
- for (int i = 0; i < NUM_BUFFERS; ++i) {
- m_buffers[i].resize(m_bufferSize);
-
- result = (*m_bufferQueue)->Enqueue(m_bufferQueue, m_buffers[i].data(), m_bufferSize);
- if (result != SL_RESULT_SUCCESS) {
- m_errorState = QAudio::FatalError;
- return false;
- }
- }
-
- // start recording
- result = (*m_recorder)->SetRecordState(m_recorder, SL_RECORDSTATE_RECORDING);
- if (result != SL_RESULT_SUCCESS) {
- m_errorState = QAudio::FatalError;
- return false;
- }
-
- m_errorState = QAudio::NoError;
-
- return true;
-}
-
-void QAndroidAudioSource::stop()
-{
- if (m_deviceState == QAudio::StoppedState)
- return;
-
- m_deviceState = QAudio::StoppedState;
-
- stopRecording();
-
- m_errorState = QAudio::NoError;
- Q_EMIT stateChanged(m_deviceState);
-}
-
-void QAndroidAudioSource::stopRecording()
-{
- flushBuffers();
-
- (*m_recorder)->SetRecordState(m_recorder, SL_RECORDSTATE_STOPPED);
- (*m_bufferQueue)->Clear(m_bufferQueue);
-
- (*m_recorderObject)->Destroy(m_recorderObject);
- m_recorderObject = 0;
-
- for (int i = 0; i < NUM_BUFFERS; ++i)
- m_buffers[i].clear();
- m_currentBuffer = 0;
-
- if (!m_pullMode && m_bufferIODevice) {
- m_bufferIODevice->close();
- delete m_bufferIODevice;
- m_bufferIODevice = 0;
- m_pushBuffer.clear();
- }
-}
-
-void QAndroidAudioSource::suspend()
-{
- if (m_deviceState == QAudio::ActiveState) {
- m_deviceState = QAudio::SuspendedState;
- emit stateChanged(m_deviceState);
-
- (*m_recorder)->SetRecordState(m_recorder, SL_RECORDSTATE_PAUSED);
- }
-}
-
-void QAndroidAudioSource::resume()
-{
- if (m_deviceState == QAudio::SuspendedState || m_deviceState == QAudio::IdleState) {
- (*m_recorder)->SetRecordState(m_recorder, SL_RECORDSTATE_RECORDING);
-
- m_deviceState = QAudio::ActiveState;
- emit stateChanged(m_deviceState);
- }
-}
-
-void QAndroidAudioSource::processBuffer()
-{
- if (m_deviceState == QAudio::StoppedState || m_deviceState == QAudio::SuspendedState)
- return;
-
- if (m_deviceState != QAudio::ActiveState) {
- m_errorState = QAudio::NoError;
- m_deviceState = QAudio::ActiveState;
- emit stateChanged(m_deviceState);
- }
-
- QByteArray *processedBuffer = &m_buffers[m_currentBuffer];
- writeDataToDevice(processedBuffer->constData(), processedBuffer->size());
-
- // Re-enqueue the buffer
- SLresult result = (*m_bufferQueue)->Enqueue(m_bufferQueue,
- processedBuffer->data(),
- processedBuffer->size());
-
- m_currentBuffer = (m_currentBuffer + 1) % NUM_BUFFERS;
-
- // If the buffer queue is empty (shouldn't happen), stop recording.
-#ifdef ANDROID
- SLAndroidSimpleBufferQueueState state;
-#else
- SLBufferQueueState state;
-#endif
- result = (*m_bufferQueue)->GetState(m_bufferQueue, &state);
- if (result != SL_RESULT_SUCCESS || state.count == 0) {
- stop();
- m_errorState = QAudio::FatalError;
- Q_EMIT errorChanged(m_errorState);
- }
-}
-
-void QAndroidAudioSource::writeDataToDevice(const char *data, int size)
-{
- m_processedBytes += size;
-
- QByteArray outData;
-
- // Apply volume
- if (m_volume < 1.0f) {
- outData.resize(size);
- QAudioHelperInternal::qMultiplySamples(m_volume, m_format, data, outData.data(), size);
- } else {
- outData.append(data, size);
- }
-
- if (m_pullMode) {
- // write buffer to the QIODevice
- if (m_audioSource->write(outData) < 0) {
- stop();
- m_errorState = QAudio::IOError;
- Q_EMIT errorChanged(m_errorState);
- }
- } else {
- // emits readyRead() so user will call read() on QIODevice to get some audio data
- if (m_bufferIODevice != 0) {
- m_pushBuffer.append(outData);
- Q_EMIT m_bufferIODevice->readyRead();
- }
- }
-}
-
-void QAndroidAudioSource::flushBuffers()
-{
- SLmillisecond recorderPos;
- (*m_recorder)->GetPosition(m_recorder, &recorderPos);
- qint64 devicePos = processedUSecs();
-
- qint64 delta = recorderPos * 1000 - devicePos;
-
- if (delta > 0) {
- const int writeSize = qMin(m_buffers[m_currentBuffer].size(),
- m_format.bytesForDuration(delta));
- writeDataToDevice(m_buffers[m_currentBuffer].constData(), writeSize);
- }
-}
-
-qsizetype QAndroidAudioSource::bytesReady() const
-{
- if (m_deviceState == QAudio::ActiveState || m_deviceState == QAudio::SuspendedState)
- return m_bufferIODevice ? m_bufferIODevice->bytesAvailable() : m_bufferSize;
-
- return 0;
-}
-
-void QAndroidAudioSource::setBufferSize(qsizetype value)
-{
- m_bufferSize = value;
-}
-
-qsizetype QAndroidAudioSource::bufferSize() const
-{
- return m_bufferSize;
-}
-
-qint64 QAndroidAudioSource::processedUSecs() const
-{
- return m_format.durationForBytes(m_processedBytes);
-}
-
-void QAndroidAudioSource::setVolume(qreal vol)
-{
- m_volume = vol;
-}
-
-qreal QAndroidAudioSource::volume() const
-{
- return m_volume;
-}
-
-void QAndroidAudioSource::reset()
-{
- stop();
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/audio/qandroidaudiosource_p.h b/src/multimedia/platform/android/audio/qandroidaudiosource_p.h
deleted file mode 100644
index 8a4621b2c..000000000
--- a/src/multimedia/platform/android/audio/qandroidaudiosource_p.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QOPENSLESAUDIOINPUT_H
-#define QOPENSLESAUDIOINPUT_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 <qaudiosystem_p.h>
-#include <QElapsedTimer>
-#include <SLES/OpenSLES.h>
-
-#ifdef ANDROID
-#include <SLES/OpenSLES_Android.h>
-
-#define QT_ANDROID_PRESET_MIC "mic"
-#define QT_ANDROID_PRESET_CAMCORDER "camcorder"
-#define QT_ANDROID_PRESET_VOICE_RECOGNITION "voicerecognition"
-#define QT_ANDROID_PRESET_VOICE_COMMUNICATION "voicecommunication"
-
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QOpenSLESEngine;
-class QIODevice;
-class QBuffer;
-
-class QAndroidAudioSource : public QPlatformAudioSource
-{
- Q_OBJECT
-
-public:
- QAndroidAudioSource(const QByteArray &device);
- ~QAndroidAudioSource();
-
- void start(QIODevice *device);
- QIODevice *start();
- void stop();
- void reset();
- void suspend();
- void resume();
- qsizetype bytesReady() const;
- void setBufferSize(qsizetype value);
- qsizetype bufferSize() const;
- qint64 processedUSecs() const;
- QAudio::Error error() const;
- QAudio::State state() const;
- void setFormat(const QAudioFormat &format);
- QAudioFormat format() const;
-
- void setVolume(qreal volume);
- qreal volume() const;
-
-public Q_SLOTS:
- void processBuffer();
-
-private:
- bool startRecording();
- void stopRecording();
- void writeDataToDevice(const char *data, int size);
- void flushBuffers();
-
- QByteArray m_device;
- QOpenSLESEngine *m_engine;
- SLObjectItf m_recorderObject;
- SLRecordItf m_recorder;
-#ifdef ANDROID
- SLuint32 m_recorderPreset;
- SLAndroidSimpleBufferQueueItf m_bufferQueue;
-#else
- SLBufferQueueItf m_bufferQueue;
-#endif
-
- bool m_pullMode;
- qint64 m_processedBytes;
- QIODevice *m_audioSource;
- QBuffer *m_bufferIODevice;
- QByteArray m_pushBuffer;
- QAudioFormat m_format;
- QAudio::Error m_errorState;
- QAudio::State m_deviceState;
- qint64 m_lastNotifyTime;
- qreal m_volume;
- int m_bufferSize;
- QByteArray *m_buffers;
- int m_currentBuffer;
-};
-
-QT_END_NAMESPACE
-
-#endif // QOPENSLESAUDIOINPUT_H
diff --git a/src/multimedia/platform/android/audio/qopenslesengine.cpp b/src/multimedia/platform/android/audio/qopenslesengine.cpp
deleted file mode 100644
index 7d207a369..000000000
--- a/src/multimedia/platform/android/audio/qopenslesengine.cpp
+++ /dev/null
@@ -1,368 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qopenslesengine_p.h"
-
-#include "qandroidaudiosource_p.h"
-#include "qandroidaudiodevice_p.h"
-
-#include <QtCore/qjniobject.h>
-#include <QtCore/private/qandroidextras_p.h>
-#include <qdebug.h>
-
-#define MINIMUM_PERIOD_TIME_MS 5
-#define DEFAULT_PERIOD_TIME_MS 50
-
-#define CheckError(message) if (result != SL_RESULT_SUCCESS) { qWarning(message); return; }
-
-Q_GLOBAL_STATIC(QOpenSLESEngine, openslesEngine);
-
-QOpenSLESEngine::QOpenSLESEngine()
- : m_engineObject(0)
- , m_engine(0)
- , m_checkedInputFormats(false)
-{
- SLresult result;
-
- result = slCreateEngine(&m_engineObject, 0, 0, 0, 0, 0);
- CheckError("Failed to create engine");
-
- result = (*m_engineObject)->Realize(m_engineObject, SL_BOOLEAN_FALSE);
- CheckError("Failed to realize engine");
-
- result = (*m_engineObject)->GetInterface(m_engineObject, SL_IID_ENGINE, &m_engine);
- CheckError("Failed to get engine interface");
-}
-
-QOpenSLESEngine::~QOpenSLESEngine()
-{
- if (m_engineObject)
- (*m_engineObject)->Destroy(m_engineObject);
-}
-
-QOpenSLESEngine *QOpenSLESEngine::instance()
-{
- return openslesEngine();
-}
-
-SLDataFormat_PCM QOpenSLESEngine::audioFormatToSLFormatPCM(const QAudioFormat &format)
-{
- SLDataFormat_PCM format_pcm;
- format_pcm.formatType = SL_DATAFORMAT_PCM;
- format_pcm.numChannels = format.channelCount();
- format_pcm.samplesPerSec = format.sampleRate() * 1000;
- format_pcm.bitsPerSample = format.bytesPerSample() * 8;
- format_pcm.containerSize = format.bytesPerSample() * 8;
- format_pcm.channelMask = (format.channelCount() == 1 ?
- SL_SPEAKER_FRONT_CENTER :
- SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT);
- format_pcm.endianness = (QSysInfo::ByteOrder == QSysInfo::LittleEndian ?
- SL_BYTEORDER_LITTLEENDIAN :
- SL_BYTEORDER_BIGENDIAN);
- return format_pcm;
-
-}
-
-QList<QAudioDevice> QOpenSLESEngine::availableDevices(QAudioDevice::Mode mode)
-{
- QList<QAudioDevice> devices;
- QJniObject devs;
- if (mode == QAudioDevice::Input) {
- devs = QJniObject::callStaticObjectMethod(
- "org/qtproject/qt/android/multimedia/QtAudioDeviceManager",
- "getAudioInputDevices",
- "()[Ljava/lang/String;");
- } else if (mode == QAudioDevice::Output) {
- devs = QJniObject::callStaticObjectMethod(
- "org/qtproject/qt/android/multimedia/QtAudioDeviceManager",
- "getAudioOutputDevices",
- "()[Ljava/lang/String;");
- }
- if (devs.isValid()) {
- QJniEnvironment env;
- jobjectArray devsArray = static_cast<jobjectArray>(devs.object());
- const jint size = env->GetArrayLength(devsArray);
- for (int i = 0; i < size; ++i) {
- QString val = QJniObject(env->GetObjectArrayElement(devsArray, i)).toString();
- int pos = val.indexOf(QStringLiteral(":"));
- devices << (new QOpenSLESDeviceInfo(
- val.left(pos).toUtf8(), val.mid(pos+1), mode))->create();
- }
- }
- return devices;
-}
-
-static bool hasRecordPermission()
-{
- const auto recordPerm = QtAndroidPrivate::checkPermission(QtAndroidPrivate::Microphone);
- return recordPerm.result() == QtAndroidPrivate::Authorized;
-}
-
-QList<int> QOpenSLESEngine::supportedChannelCounts(QAudioDevice::Mode mode) const
-{
- if (mode == QAudioDevice::Input && hasRecordPermission()) {
- if (!m_checkedInputFormats)
- const_cast<QOpenSLESEngine *>(this)->checkSupportedInputFormats();
- return m_supportedInputChannelCounts;
- } else {
- return QList<int>() << 1 << 2;
- }
-}
-
-QList<int> QOpenSLESEngine::supportedSampleRates(QAudioDevice::Mode mode) const
-{
- if (mode == QAudioDevice::Input && hasRecordPermission()) {
- if (!m_checkedInputFormats)
- const_cast<QOpenSLESEngine *>(this)->checkSupportedInputFormats();
- return m_supportedInputSampleRates;
- } else {
- return QList<int>() << 8000 << 11025 << 12000 << 16000 << 22050 << 24000
- << 32000 << 44100 << 48000 << 64000 << 88200 << 96000 << 192000;
- }
-}
-
-int QOpenSLESEngine::getOutputValue(QOpenSLESEngine::OutputValue type, int defaultValue)
-{
- static int sampleRate = 0;
- static int framesPerBuffer = 0;
-
- if (type == FramesPerBuffer && framesPerBuffer != 0)
- return framesPerBuffer;
-
- if (type == SampleRate && sampleRate != 0)
- return sampleRate;
-
- QJniObject ctx(QNativeInterface::QAndroidApplication::context());
- if (!ctx.isValid())
- return defaultValue;
-
-
- QJniObject audioServiceString = ctx.getStaticObjectField("android/content/Context",
- "AUDIO_SERVICE",
- "Ljava/lang/String;");
- QJniObject am = ctx.callObjectMethod("getSystemService",
- "(Ljava/lang/String;)Ljava/lang/Object;",
- audioServiceString.object());
- if (!am.isValid())
- return defaultValue;
-
- auto sampleRateField = QJniObject::getStaticObjectField("android/media/AudioManager",
- "PROPERTY_OUTPUT_SAMPLE_RATE",
- "Ljava/lang/String;");
- auto framesPerBufferField = QJniObject::getStaticObjectField(
- "android/media/AudioManager",
- "PROPERTY_OUTPUT_FRAMES_PER_BUFFER",
- "Ljava/lang/String;");
-
- auto sampleRateString = am.callObjectMethod("getProperty",
- "(Ljava/lang/String;)Ljava/lang/String;",
- sampleRateField.object());
- auto framesPerBufferString = am.callObjectMethod("getProperty",
- "(Ljava/lang/String;)Ljava/lang/String;",
- framesPerBufferField.object());
-
- if (!sampleRateString.isValid() || !framesPerBufferString.isValid())
- return defaultValue;
-
- framesPerBuffer = framesPerBufferString.toString().toInt();
- sampleRate = sampleRateString.toString().toInt();
-
- if (type == FramesPerBuffer)
- return framesPerBuffer;
-
- if (type == SampleRate)
- return sampleRate;
-
- return defaultValue;
-}
-
-int QOpenSLESEngine::getDefaultBufferSize(const QAudioFormat &format)
-{
- if (!format.isValid())
- return 0;
-
- const int channelConfig = [&format]() -> int
- {
- if (format.channelCount() == 1)
- return 4; /* MONO */
- else if (format.channelCount() == 2)
- return 12; /* STEREO */
- else if (format.channelCount() > 2)
- return 1052; /* SURROUND */
- else
- return 1; /* DEFAULT */
- }();
-
- const int audioFormat = [&format]() -> int
- {
- const int sdkVersion = QNativeInterface::QAndroidApplication::sdkVersion();
- if (format.sampleFormat() == QAudioFormat::Float && sdkVersion >= 21)
- return 4; /* PCM_FLOAT */
- else if (format.sampleFormat() == QAudioFormat::UInt8)
- return 3; /* PCM_8BIT */
- else if (format.sampleFormat() == QAudioFormat::Int16)
- return 2; /* PCM_16BIT*/
- else
- return 1; /* DEFAULT */
- }();
-
- const int sampleRate = format.sampleRate();
- const int minBufferSize = QJniObject::callStaticMethod<jint>("android/media/AudioTrack",
- "getMinBufferSize",
- "(III)I",
- sampleRate,
- channelConfig,
- audioFormat);
- return minBufferSize > 0 ? minBufferSize : format.bytesForDuration(DEFAULT_PERIOD_TIME_MS);
-}
-
-int QOpenSLESEngine::getLowLatencyBufferSize(const QAudioFormat &format)
-{
- return format.bytesForFrames(QOpenSLESEngine::getOutputValue(QOpenSLESEngine::FramesPerBuffer,
- format.framesForDuration(MINIMUM_PERIOD_TIME_MS)));
-}
-
-bool QOpenSLESEngine::supportsLowLatency()
-{
- static int isSupported = -1;
-
- if (isSupported != -1)
- return (isSupported == 1);
-
- QJniObject ctx(QNativeInterface::QAndroidApplication::context());
- if (!ctx.isValid())
- return false;
-
- QJniObject pm = ctx.callObjectMethod("getPackageManager", "()Landroid/content/pm/PackageManager;");
- if (!pm.isValid())
- return false;
-
- QJniObject audioFeatureField = QJniObject::getStaticObjectField(
- "android/content/pm/PackageManager",
- "FEATURE_AUDIO_LOW_LATENCY",
- "Ljava/lang/String;");
- if (!audioFeatureField.isValid())
- return false;
-
- isSupported = pm.callMethod<jboolean>("hasSystemFeature",
- "(Ljava/lang/String;)Z",
- audioFeatureField.object());
- return (isSupported == 1);
-}
-
-bool QOpenSLESEngine::printDebugInfo()
-{
- return qEnvironmentVariableIsSet("QT_OPENSL_INFO");
-}
-
-void QOpenSLESEngine::checkSupportedInputFormats()
-{
- m_supportedInputChannelCounts = QList<int>() << 1;
- m_supportedInputSampleRates.clear();
-
- SLAndroidDataFormat_PCM_EX defaultFormat;
- defaultFormat.formatType = SL_DATAFORMAT_PCM;
- defaultFormat.numChannels = 1;
- defaultFormat.sampleRate = SL_SAMPLINGRATE_44_1;
- defaultFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_32;
- defaultFormat.containerSize = SL_PCMSAMPLEFORMAT_FIXED_32;
- defaultFormat.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
- defaultFormat.channelMask = SL_ANDROID_MAKE_INDEXED_CHANNEL_MASK(SL_SPEAKER_FRONT_CENTER);
- defaultFormat.endianness = SL_BYTEORDER_LITTLEENDIAN;
-
- const SLuint32 rates[13] = { SL_SAMPLINGRATE_8,
- SL_SAMPLINGRATE_11_025,
- SL_SAMPLINGRATE_12,
- SL_SAMPLINGRATE_16,
- SL_SAMPLINGRATE_22_05,
- SL_SAMPLINGRATE_24,
- SL_SAMPLINGRATE_32,
- SL_SAMPLINGRATE_44_1,
- SL_SAMPLINGRATE_48,
- SL_SAMPLINGRATE_64,
- SL_SAMPLINGRATE_88_2,
- SL_SAMPLINGRATE_96,
- SL_SAMPLINGRATE_192 };
-
-
- // Test sampling rates
- for (size_t i = 0 ; i < std::size(rates); ++i) {
- SLAndroidDataFormat_PCM_EX format = defaultFormat;
- format.sampleRate = rates[i];
-
- if (inputFormatIsSupported(format))
- m_supportedInputSampleRates.append(rates[i] / 1000);
-
- }
-
- // Test if stereo is supported
- {
- SLAndroidDataFormat_PCM_EX format = defaultFormat;
- format.numChannels = 2;
- format.channelMask = SL_ANDROID_MAKE_INDEXED_CHANNEL_MASK(SL_SPEAKER_FRONT_LEFT
- | SL_SPEAKER_FRONT_RIGHT);
- if (inputFormatIsSupported(format))
- m_supportedInputChannelCounts.append(2);
- }
-
- m_checkedInputFormats = true;
-}
-
-bool QOpenSLESEngine::inputFormatIsSupported(SLAndroidDataFormat_PCM_EX format)
-{
- SLresult result;
- SLObjectItf recorder = 0;
- SLDataLocator_IODevice loc_dev = { SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
- SL_DEFAULTDEVICEID_AUDIOINPUT, NULL };
- SLDataSource audioSrc = { &loc_dev, NULL };
-
- SLDataLocator_AndroidSimpleBufferQueue loc_bq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 1 };
- SLDataSink audioSnk = { &loc_bq, &format };
-
- result = (*m_engine)->CreateAudioRecorder(m_engine, &recorder, &audioSrc, &audioSnk, 0, 0, 0);
- if (result == SL_RESULT_SUCCESS)
- result = (*recorder)->Realize(recorder, false);
-
- if (result == SL_RESULT_SUCCESS) {
- (*recorder)->Destroy(recorder);
- return true;
- }
-
- return false;
-}
diff --git a/src/multimedia/platform/android/audio/qopenslesengine_p.h b/src/multimedia/platform/android/audio/qopenslesengine_p.h
deleted file mode 100644
index 36e994fb2..000000000
--- a/src/multimedia/platform/android/audio/qopenslesengine_p.h
+++ /dev/null
@@ -1,100 +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 QOPENSLESENGINE_H
-#define QOPENSLESENGINE_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 <qglobal.h>
-#include <qaudio.h>
-#include <qlist.h>
-#include <qaudioformat.h>
-#include <qaudiodevice.h>
-#include <SLES/OpenSLES_Android.h>
-
-QT_BEGIN_NAMESPACE
-
-class QOpenSLESEngine
-{
-public:
- enum OutputValue { FramesPerBuffer, SampleRate };
-
- QOpenSLESEngine();
- ~QOpenSLESEngine();
-
- static QOpenSLESEngine *instance();
-
- SLEngineItf slEngine() const { return m_engine; }
-
- static SLDataFormat_PCM audioFormatToSLFormatPCM(const QAudioFormat &format);
-
- static QList<QAudioDevice> availableDevices(QAudioDevice::Mode mode);
- QList<int> supportedChannelCounts(QAudioDevice::Mode mode) const;
- QList<int> supportedSampleRates(QAudioDevice::Mode mode) const;
-
- static int getOutputValue(OutputValue type, int defaultValue = 0);
- static int getDefaultBufferSize(const QAudioFormat &format);
- static int getLowLatencyBufferSize(const QAudioFormat &format);
- static bool supportsLowLatency();
- static bool printDebugInfo();
-
-private:
- void checkSupportedInputFormats();
- bool inputFormatIsSupported(SLAndroidDataFormat_PCM_EX format);
- SLObjectItf m_engineObject;
- SLEngineItf m_engine;
-
- QList<int> m_supportedInputChannelCounts;
- QList<int> m_supportedInputSampleRates;
- bool m_checkedInputFormats;
-};
-
-QT_END_NAMESPACE
-
-#endif // QOPENSLESENGINE_H
diff --git a/src/multimedia/platform/android/common/qandroidaudiooutput_p.h b/src/multimedia/platform/android/common/qandroidaudiooutput_p.h
deleted file mode 100644
index e17f158fc..000000000
--- a/src/multimedia/platform/android/common/qandroidaudiooutput_p.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QANDROIDAUDIOOUTPUT_H
-#define QANDROIDAUDIOOUTPUT_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 <private/qplatformaudiooutput_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_MULTIMEDIA_EXPORT QAndroidAudioOutput : public QPlatformAudioOutput
-{
-public:
- QAndroidAudioOutput(QAudioOutput *qq) : QPlatformAudioOutput(qq) {}
-};
-
-QT_END_NAMESPACE
-
-
-#endif // QANDROIDAUDIOOUTPUT_H
diff --git a/src/multimedia/platform/android/common/qandroidglobal_p.h b/src/multimedia/platform/android/common/qandroidglobal_p.h
deleted file mode 100644
index 45bd22ffb..000000000
--- a/src/multimedia/platform/android/common/qandroidglobal_p.h
+++ /dev/null
@@ -1,64 +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
-
-//
-// 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 <private/qtmultimediaglobal_p.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/multimedia/platform/android/common/qandroidmultimediautils.cpp b/src/multimedia/platform/android/common/qandroidmultimediautils.cpp
deleted file mode 100644
index 75f012f07..000000000
--- a/src/multimedia/platform/android/common/qandroidmultimediautils.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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_p.h"
-#include "qandroidglobal_p.h"
-
-#include <qlist.h>
-#include <QtCore/qcoreapplication.h>
-#include <QtCore/private/qandroidextras_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();
-}
-
-QVideoFrameFormat::PixelFormat qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat f)
-{
- switch (f) {
- case AndroidCamera::NV21:
- return QVideoFrameFormat::Format_NV21;
- case AndroidCamera::YV12:
- return QVideoFrameFormat::Format_YV12;
- case AndroidCamera::YUY2:
- return QVideoFrameFormat::Format_YUYV;
- case AndroidCamera::JPEG:
- return QVideoFrameFormat::Format_Jpeg;
- default:
- return QVideoFrameFormat::Format_Invalid;
- }
-}
-
-AndroidCamera::ImageFormat qt_androidImageFormatFromPixelFormat(QVideoFrameFormat::PixelFormat f)
-{
- switch (f) {
- case QVideoFrameFormat::Format_NV21:
- return AndroidCamera::NV21;
- case QVideoFrameFormat::Format_YV12:
- return AndroidCamera::YV12;
- case QVideoFrameFormat::Format_YUYV:
- return AndroidCamera::YUY2;
- case QVideoFrameFormat::Format_Jpeg:
- return AndroidCamera::JPEG;
- default:
- return AndroidCamera::UnknownImageFormat;
- }
-}
-
-static bool androidRequestPermission(QtAndroidPrivate::PermissionType key)
-{
- if (QNativeInterface::QAndroidApplication::sdkVersion() < 23)
- return true;
-
- // Permission already granted?
- if (QtAndroidPrivate::checkPermission(key).result() == QtAndroidPrivate::Authorized)
- return true;
-
- if (QtAndroidPrivate::requestPermission(key).result() != QtAndroidPrivate::Authorized)
- return false;
-
- return true;
-}
-
-static bool androidCheckPermission(QtAndroidPrivate::PermissionType key)
-{
- if (QNativeInterface::QAndroidApplication::sdkVersion() < 23)
- return true;
-
- // Permission already granted?
- return (QtAndroidPrivate::checkPermission(key).result() == QtAndroidPrivate::Authorized);
-}
-
-bool qt_androidCheckCameraPermission()
-{
- return androidCheckPermission(QtAndroidPrivate::Camera);
-}
-
-bool qt_androidCheckMicrophonePermission()
-{
- return androidCheckPermission(QtAndroidPrivate::Microphone);
-}
-
-bool qt_androidRequestCameraPermission()
-{
- if (!androidRequestPermission(QtAndroidPrivate::Camera)) {
- qCDebug(qtAndroidMediaPlugin, "Camera permission denied by user!");
- return false;
- }
-
- return true;
-}
-
-bool qt_androidRequestRecordingPermission()
-{
- if (!androidRequestPermission(QtAndroidPrivate::Microphone)) {
- qCDebug(qtAndroidMediaPlugin, "Microphone permission denied by user!");
- return false;
- }
-
- return true;
-}
-
-bool qt_androidRequestWriteStoragePermission()
-{
- if (!androidRequestPermission(QtAndroidPrivate::Storage)) {
- qCDebug(qtAndroidMediaPlugin, "Storage permission denied by user!");
- return false;
- }
-
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/common/qandroidmultimediautils_p.h b/src/multimedia/platform/android/common/qandroidmultimediautils_p.h
deleted file mode 100644
index 5bc187da3..000000000
--- a/src/multimedia/platform/android/common/qandroidmultimediautils_p.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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
-
-//
-// 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 <qglobal.h>
-#include <qsize.h>
-#include "androidcamera_p.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);
-
-QVideoFrameFormat::PixelFormat qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat f);
-AndroidCamera::ImageFormat qt_androidImageFormatFromPixelFormat(QVideoFrameFormat::PixelFormat f);
-
-bool qt_androidRequestCameraPermission();
-bool qt_androidRequestRecordingPermission();
-bool qt_androidRequestWriteStoragePermission();
-
-bool qt_androidCheckCameraPermission();
-bool qt_androidCheckMicrophonePermission();
-
-QT_END_NAMESPACE
-
-#endif // QANDROIDMULTIMEDIAUTILS_H
diff --git a/src/multimedia/platform/android/common/qandroidvideooutput.cpp b/src/multimedia/platform/android/common/qandroidvideooutput.cpp
deleted file mode 100644
index d0f3203de..000000000
--- a/src/multimedia/platform/android/common/qandroidvideooutput.cpp
+++ /dev/null
@@ -1,465 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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_p.h"
-
-#include "androidsurfacetexture_p.h"
-#include <qvideosink.h>
-#include "private/qabstractvideobuffer_p.h"
-#include "private/qplatformvideosink_p.h"
-#include <QVideoFrameFormat>
-#include <QFile>
-#include <QtGui/private/qrhigles2_p.h>
-#include <QOpenGLContext>
-#include <QPainter>
-#include <QPainterPath>
-#include <QMutexLocker>
-#include <QTextLayout>
-#include <QTextFormat>
-
-QT_BEGIN_NAMESPACE
-
-void GraphicsResourceDeleter::deleteResourcesHelper(const QList<QRhiResource *> &res)
-{
- qDeleteAll(res);
-}
-
-void GraphicsResourceDeleter::deleteRhiHelper(QRhi *rhi, QOffscreenSurface *surf)
-{
- delete rhi;
- delete surf;
-}
-
-void GraphicsResourceDeleter::deleteThisHelper()
-{
- delete this;
-}
-
-bool AndroidTextureVideoBuffer::updateReadbackFrame()
-{
- // 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_readbackTex;
- if (m_textureUpdated && !forceUpdate)
- return true;
-
- // update the video texture (called from the render thread)
- return (m_textureUpdated = m_output->renderAndReadbackFrame());
-}
-
-QAbstractVideoBuffer::MapData AndroidTextureVideoBuffer::map(QVideoFrame::MapMode mode)
-{
- MapData mapData;
- if (m_mapMode == QVideoFrame::NotMapped && mode == QVideoFrame::ReadOnly && updateReadbackFrame()) {
- m_mapMode = mode;
- m_image = m_output->m_readbackImage;
- mapData.nPlanes = 1;
- mapData.bytesPerLine[0] = m_image.bytesPerLine();
- mapData.size[0] = static_cast<int>(m_image.sizeInBytes());
- mapData.data[0] = m_image.bits();
- }
- return mapData;
-}
-
-static QMatrix4x4 extTransformMatrix(AndroidSurfaceTexture *surfaceTexture)
-{
- QMatrix4x4 m = surfaceTexture->getTransformMatrix();
- // flip it back, see
- // http://androidxref.com/9.0.0_r3/xref/frameworks/native/libs/gui/GLConsumer.cpp#866
- // (NB our matrix ctor takes row major)
- static const QMatrix4x4 flipV(1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, -1.0f, 0.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
- m *= flipV;
- return m;
-}
-
-quint64 AndroidTextureVideoBuffer::textureHandle(int plane) const
-{
- if (plane != 0 || !rhi || !m_output->m_nativeSize.isValid())
- return 0;
-
- m_output->ensureExternalTexture(rhi);
- m_output->m_surfaceTexture->updateTexImage();
- m_externalMatrix = extTransformMatrix(m_output->m_surfaceTexture);
- return m_output->m_externalTex->nativeTexture().object;
-}
-
-QAndroidTextureVideoOutput::QAndroidTextureVideoOutput(QObject *parent) : QAndroidVideoOutput(parent) { }
-
-QAndroidTextureVideoOutput::~QAndroidTextureVideoOutput()
-{
- clearSurfaceTexture();
-
- if (m_graphicsDeleter) { // Make sure all of these are deleted on the render thread.
- m_graphicsDeleter->deleteResources({
- m_externalTex,
- m_readbackSrc,
- m_readbackTex,
- m_readbackVBuf,
- m_readbackUBuf,
- m_externalTexSampler,
- m_readbackSrb,
- m_readbackRenderTarget,
- m_readbackRpDesc,
- m_readbackPs
- });
-
- m_graphicsDeleter->deleteRhi(m_readbackRhi, m_readbackRhiFallbackSurface);
- m_graphicsDeleter->deleteThis();
- }
-}
-
-void QAndroidTextureVideoOutput::setSubtitle(const QString &subtitle)
-{
- if (!m_sink)
- return;
- auto *sink = m_sink->platformVideoSink();
- sink->setSubtitleText(subtitle);
-}
-
-QVideoSink *QAndroidTextureVideoOutput::surface() const
-{
- return m_sink;
-}
-
-void QAndroidTextureVideoOutput::setSurface(QVideoSink *surface)
-{
- if (surface == m_sink)
- return;
-
- m_sink = surface;
-}
-
-bool QAndroidTextureVideoOutput::isReady()
-{
- return true;
-}
-
-void QAndroidTextureVideoOutput::initSurfaceTexture()
-{
- if (m_surfaceTexture)
- return;
-
- if (!m_sink)
- return;
-
- QMutexLocker locker(&m_mutex);
-
- m_surfaceTexture = new AndroidSurfaceTexture(m_externalTex ? m_externalTex->nativeTexture().object : 0);
-
- if (m_surfaceTexture->surfaceTexture() != 0) {
- connect(m_surfaceTexture, &AndroidSurfaceTexture::frameAvailable,
- this, &QAndroidTextureVideoOutput::onFrameAvailable);
- } else {
- delete m_surfaceTexture;
- m_surfaceTexture = nullptr;
- if (m_graphicsDeleter)
- m_graphicsDeleter->deleteResources({ m_externalTex });
- m_externalTex = nullptr;
- }
-}
-
-void QAndroidTextureVideoOutput::clearSurfaceTexture()
-{
- QMutexLocker locker(&m_mutex);
- if (m_surfaceTexture) {
- delete m_surfaceTexture;
- m_surfaceTexture = nullptr;
- }
-
- // Also reset the attached texture
- if (m_graphicsDeleter)
- m_graphicsDeleter->deleteResources({ m_externalTex });
- m_externalTex = nullptr;
-}
-
-AndroidSurfaceTexture *QAndroidTextureVideoOutput::surfaceTexture()
-{
- initSurfaceTexture();
- 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()
-{
- m_nativeSize = QSize();
-}
-
-void QAndroidTextureVideoOutput::reset()
-{
- // flush pending frame
- if (m_sink)
- m_sink->platformVideoSink()->setVideoFrame(QVideoFrame());
-
- clearSurfaceTexture();
-}
-
-void QAndroidTextureVideoOutput::onFrameAvailable()
-{
- if (!m_nativeSize.isValid() || !m_sink)
- return;
-
- QRhi *rhi = m_sink ? m_sink->rhi() : nullptr;
- auto *buffer = new AndroidTextureVideoBuffer(rhi, this, m_nativeSize);
- const QVideoFrameFormat::PixelFormat format = rhi ? QVideoFrameFormat::Format_SamplerExternalOES
- : QVideoFrameFormat::Format_RGBA8888;
- QVideoFrame frame(buffer, QVideoFrameFormat(m_nativeSize, format));
- m_sink->platformVideoSink()->setVideoFrame(frame);
-}
-
-static const float g_quad[] = {
- -1.f, -1.f, 0.f, 0.f,
- -1.f, 1.f, 0.f, 1.f,
- 1.f, 1.f, 1.f, 1.f,
- 1.f, -1.f, 1.f, 0.f
-};
-
-static QShader getShader(const QString &name)
-{
- QFile f(name);
- if (f.open(QIODevice::ReadOnly))
- return QShader::fromSerialized(f.readAll());
-
- return QShader();
-}
-
-bool QAndroidTextureVideoOutput::renderAndReadbackFrame()
-{
- QMutexLocker locker(&m_mutex);
-
- if (!m_nativeSize.isValid() || !m_surfaceTexture)
- return false;
-
- if (!m_readbackRhi) {
- QRhi *sinkRhi = m_sink ? m_sink->rhi() : nullptr;
- if (sinkRhi && sinkRhi->backend() == QRhi::OpenGLES2) {
- // There is an rhi from the sink, e.g. VideoOutput. We lack the necessary
- // insight to use that directly, so create our own a QRhi that just wraps the
- // same QOpenGLContext.
- sinkRhi->finish();
- QRhiGles2NativeHandles h = *static_cast<const QRhiGles2NativeHandles *>(sinkRhi->nativeHandles());
- m_readbackRhiFallbackSurface = QRhiGles2InitParams::newFallbackSurface(h.context->format());
- QRhiGles2InitParams initParams;
- initParams.format = h.context->format();
- initParams.fallbackSurface = m_readbackRhiFallbackSurface;
- m_readbackRhi = QRhi::create(QRhi::OpenGLES2, &initParams, {}, &h);
- } else {
- // No rhi from the sink, e.g. QVideoWidget.
- // We will fire up our own QRhi with its own QOpenGLContext.
- m_readbackRhiFallbackSurface = QRhiGles2InitParams::newFallbackSurface({});
- QRhiGles2InitParams initParams;
- initParams.fallbackSurface = m_readbackRhiFallbackSurface;
- m_readbackRhi = QRhi::create(QRhi::OpenGLES2, &initParams);
- }
- }
-
- if (!m_readbackRhi) {
- qWarning("Failed to create QRhi for video frame readback");
- return false;
- }
-
- QRhiCommandBuffer *cb = nullptr;
- if (m_readbackRhi->beginOffscreenFrame(&cb) != QRhi::FrameOpSuccess)
- return false;
-
- if (!m_readbackTex || m_readbackTex->pixelSize() != m_nativeSize) {
- delete m_readbackRenderTarget;
- delete m_readbackRpDesc;
- delete m_readbackTex;
- m_readbackTex = m_readbackRhi->newTexture(QRhiTexture::RGBA8, m_nativeSize, 1, QRhiTexture::RenderTarget);
- if (!m_readbackTex->create()) {
- qWarning("Failed to create readback texture");
- return false;
- }
- m_readbackRenderTarget = m_readbackRhi->newTextureRenderTarget({ { m_readbackTex } });
- m_readbackRpDesc = m_readbackRenderTarget->newCompatibleRenderPassDescriptor();
- m_readbackRenderTarget->setRenderPassDescriptor(m_readbackRpDesc);
- m_readbackRenderTarget->create();
- }
-
- m_readbackRhi->makeThreadLocalNativeContextCurrent();
- ensureExternalTexture(m_readbackRhi);
- m_surfaceTexture->updateTexImage();
-
- // The only purpose of m_readbackSrc is to be nice and have a QRhiTexture that belongs
- // to m_readbackRhi, not the sink's rhi if there is one. The underlying native object
- // (and the rhi's OpenGL context) are the same regardless.
- if (!m_readbackSrc)
- m_readbackSrc = m_readbackRhi->newTexture(QRhiTexture::RGBA8, m_nativeSize, 1, QRhiTexture::ExternalOES);
-
- // Keep the object the same (therefore all references to m_readbackSrc in
- // the srb or other objects stay valid all the time), just call createFrom
- // if the native external texture changes.
- const quint64 texId = m_externalTex->nativeTexture().object;
- if (m_readbackSrc->nativeTexture().object != texId)
- m_readbackSrc->createFrom({ texId, 0 });
-
- QRhiResourceUpdateBatch *rub = nullptr;
- if (!m_readbackVBuf) {
- m_readbackVBuf = m_readbackRhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(g_quad));
- m_readbackVBuf->create();
- if (!rub)
- rub = m_readbackRhi->nextResourceUpdateBatch();
- rub->uploadStaticBuffer(m_readbackVBuf, g_quad);
- }
-
- if (!m_readbackUBuf) {
- m_readbackUBuf = m_readbackRhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64 + 64 + 4 + 4);
- m_readbackUBuf->create();
- }
-
- if (!m_externalTexSampler) {
- m_externalTexSampler = m_readbackRhi->newSampler(QRhiSampler::Nearest, QRhiSampler::Nearest, QRhiSampler::None,
- QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
- m_externalTexSampler->create();
- }
-
- if (!m_readbackSrb) {
- m_readbackSrb = m_readbackRhi->newShaderResourceBindings();
- m_readbackSrb->setBindings({
- QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, m_readbackUBuf),
- QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, m_readbackSrc, m_externalTexSampler)
- });
- m_readbackSrb->create();
- }
-
- if (!m_readbackPs) {
- m_readbackPs = m_readbackRhi->newGraphicsPipeline();
- m_readbackPs->setTopology(QRhiGraphicsPipeline::TriangleFan);
- QShader vs = getShader(QStringLiteral(":/qt-project.org/multimedia/shaders/externalsampler.vert.qsb"));
- Q_ASSERT(vs.isValid());
- QShader fs = getShader(QStringLiteral(":/qt-project.org/multimedia/shaders/externalsampler.frag.qsb"));
- Q_ASSERT(fs.isValid());
- m_readbackPs->setShaderStages({
- { QRhiShaderStage::Vertex, vs },
- { QRhiShaderStage::Fragment, fs }
- });
- QRhiVertexInputLayout inputLayout;
- inputLayout.setBindings({
- { 4 * sizeof(float) }
- });
- inputLayout.setAttributes({
- { 0, 0, QRhiVertexInputAttribute::Float2, 0 },
- { 0, 1, QRhiVertexInputAttribute::Float2, 2 * sizeof(float) }
- });
- m_readbackPs->setVertexInputLayout(inputLayout);
- m_readbackPs->setShaderResourceBindings(m_readbackSrb);
- m_readbackPs->setRenderPassDescriptor(m_readbackRpDesc);
- m_readbackPs->create();
- }
-
- QMatrix4x4 identity;
- char *p = m_readbackUBuf->beginFullDynamicBufferUpdateForCurrentFrame();
- memcpy(p, identity.constData(), 64);
- QMatrix4x4 extMatrix = extTransformMatrix(m_surfaceTexture);
- memcpy(p + 64, extMatrix.constData(), 64);
- float opacity = 1.0f;
- memcpy(p + 64 + 64, &opacity, 4);
- m_readbackUBuf->endFullDynamicBufferUpdateForCurrentFrame();
-
- cb->beginPass(m_readbackRenderTarget, Qt::transparent, { 1.0f, 0 }, rub);
- cb->setGraphicsPipeline(m_readbackPs);
- cb->setViewport(QRhiViewport(0, 0, m_nativeSize.width(), m_nativeSize.height()));
- cb->setShaderResources();
- const QRhiCommandBuffer::VertexInput vbufBinding(m_readbackVBuf, 0);
- cb->setVertexInput(0, 1, &vbufBinding);
- cb->draw(4);
-
- QRhiReadbackDescription readDesc(m_readbackTex);
- QRhiReadbackResult readResult;
- bool readCompleted = false;
- // invoked at latest in the endOffscreenFrame() below
- readResult.completed = [&readCompleted] { readCompleted = true; };
- rub = m_readbackRhi->nextResourceUpdateBatch();
- rub->readBackTexture(readDesc, &readResult);
-
- cb->endPass(rub);
-
- m_readbackRhi->endOffscreenFrame();
-
- if (!readCompleted)
- return false;
-
- // implicit sharing, keep the data alive
- m_readbackImageData = readResult.data;
- // the QImage does not own the data
- m_readbackImage = QImage(reinterpret_cast<const uchar *>(m_readbackImageData.constData()),
- readResult.pixelSize.width(), readResult.pixelSize.height(),
- QImage::Format_ARGB32_Premultiplied);
-
- return true;
-}
-
-void QAndroidTextureVideoOutput::ensureExternalTexture(QRhi *rhi)
-{
- if (!m_graphicsDeleter)
- m_graphicsDeleter = new GraphicsResourceDeleter;
-
- if (!m_externalTex) {
- m_surfaceTexture->detachFromGLContext();
- m_externalTex = rhi->newTexture(QRhiTexture::RGBA8, m_nativeSize, 1, QRhiTexture::ExternalOES);
- if (!m_externalTex->create())
- qWarning("Failed to create native texture object");
- m_surfaceTexture->attachToGLContext(m_externalTex->nativeTexture().object);
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/common/qandroidvideooutput_p.h b/src/multimedia/platform/android/common/qandroidvideooutput_p.h
deleted file mode 100644
index fc85d74fc..000000000
--- a/src/multimedia/platform/android/common/qandroidvideooutput_p.h
+++ /dev/null
@@ -1,213 +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
-
-//
-// 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 <qobject.h>
-#include <qsize.h>
-#include <qmutex.h>
-#include <qreadwritelock.h>
-#include <private/qabstractvideobuffer_p.h>
-#include <qmatrix4x4.h>
-#include <QtGui/private/qrhi_p.h>
-#include <QtGui/qoffscreensurface.h>
-#include <QPixmap>
-
-QT_BEGIN_NAMESPACE
-
-class AndroidSurfaceTexture;
-class AndroidSurfaceHolder;
-class QVideoSink;
-
-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 GraphicsResourceDeleter : public QObject
-{
- Q_OBJECT
-public:
- void deleteResources(const QList<QRhiResource *> &res) { QMetaObject::invokeMethod(this, "deleteResourcesHelper", Qt::AutoConnection, Q_ARG(QList<QRhiResource*>, res)); }
- void deleteRhi(QRhi *rhi, QOffscreenSurface *surf) { QMetaObject::invokeMethod(this, "deleteRhiHelper", Qt::AutoConnection, Q_ARG(QRhi*, rhi), Q_ARG(QOffscreenSurface*, surf)); }
- void deleteThis() { QMetaObject::invokeMethod(this, "deleteThisHelper"); }
-
-private:
- Q_INVOKABLE void deleteResourcesHelper(const QList<QRhiResource *> &res);
- Q_INVOKABLE void deleteRhiHelper(QRhi *rhi, QOffscreenSurface *surf);
- Q_INVOKABLE void deleteThisHelper();
-};
-
-class QAndroidTextureVideoOutput : public QAndroidVideoOutput
-{
- Q_OBJECT
-public:
- explicit QAndroidTextureVideoOutput(QObject *parent = 0);
- ~QAndroidTextureVideoOutput() override;
-
- QVideoSink *surface() const;
- void setSurface(QVideoSink *surface);
-
- AndroidSurfaceTexture *surfaceTexture() override;
-
- bool isReady() override;
- void setVideoSize(const QSize &) override;
- void stop() override;
- void reset() override;
-
- void setSubtitle(const QString &subtitle);
-private Q_SLOTS:
- void onFrameAvailable();
-
-private:
- void initSurfaceTexture();
- bool renderAndReadbackFrame();
- void ensureExternalTexture(QRhi *rhi);
-
- QMutex m_mutex;
- QReadWriteLock m_subtitleLock;
-
- void clearSurfaceTexture();
-
- QVideoSink *m_sink = nullptr;
- QSize m_nativeSize;
-
- AndroidSurfaceTexture *m_surfaceTexture = nullptr;
-
- QRhiTexture *m_externalTex = nullptr;
-
- QRhi *m_readbackRhi = nullptr;
- QOffscreenSurface *m_readbackRhiFallbackSurface = nullptr;
- QRhiTexture *m_readbackSrc = nullptr;
- QRhiTexture *m_readbackTex = nullptr;
- QRhiBuffer *m_readbackVBuf = nullptr;
- QRhiBuffer *m_readbackUBuf = nullptr;
- QRhiSampler *m_externalTexSampler = nullptr;
- QRhiShaderResourceBindings *m_readbackSrb = nullptr;
- QRhiTextureRenderTarget *m_readbackRenderTarget = nullptr;
- QRhiRenderPassDescriptor *m_readbackRpDesc = nullptr;
- QRhiGraphicsPipeline *m_readbackPs = nullptr;
-
- QImage m_readbackImage;
- QByteArray m_readbackImageData;
-
- QString m_subtitleText;
- QPixmap m_subtitlePixmap;
-
- GraphicsResourceDeleter *m_graphicsDeleter = nullptr;
-
- friend class AndroidTextureVideoBuffer;
-};
-
-
-class AndroidTextureVideoBuffer : public QAbstractVideoBuffer
-{
-public:
- AndroidTextureVideoBuffer(QRhi *rhi, QAndroidTextureVideoOutput *output, const QSize &size)
- : QAbstractVideoBuffer(rhi ? QVideoFrame::RhiTextureHandle : QVideoFrame::NoHandle, rhi)
- , m_output(output)
- , m_size(size)
- {
- }
-
- virtual ~AndroidTextureVideoBuffer() {}
-
- QVideoFrame::MapMode mapMode() const override { return m_mapMode; }
-
- MapData map(QVideoFrame::MapMode mode) override;
-
- void unmap() override
- {
- m_image = QImage();
- m_mapMode = QVideoFrame::NotMapped;
- }
-
- quint64 textureHandle(int plane) const override;
-
- QMatrix4x4 externalTextureMatrix() const
- {
- return m_externalMatrix;
- }
-
-private:
- bool updateReadbackFrame();
-
- QVideoFrame::MapMode m_mapMode = QVideoFrame::NotMapped;
- QAndroidTextureVideoOutput *m_output = nullptr;
- QImage m_image;
- QSize m_size;
- mutable QMatrix4x4 m_externalMatrix;
- bool m_textureUpdated = false;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QList<QRhiResource *>)
-Q_DECLARE_METATYPE(QRhi*)
-
-#endif // QANDROIDVIDEOOUTPUT_H
diff --git a/src/multimedia/platform/android/common/qandroidvideosink.cpp b/src/multimedia/platform/android/common/qandroidvideosink.cpp
deleted file mode 100644
index 7cc0fefe4..000000000
--- a/src/multimedia/platform/android/common/qandroidvideosink.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qandroidvideosink_p.h"
-#include <QtGui/private/qrhi_p.h>
-
-#include <QtCore/qdebug.h>
-
-#include <QtCore/qloggingcategory.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(qLcMediaVideoSink, "qt.multimedia.videosink")
-
-QAndroidVideoSink::QAndroidVideoSink(QVideoSink *parent)
- : QPlatformVideoSink(parent)
-{
-}
-
-QAndroidVideoSink::~QAndroidVideoSink()
-{
-}
-
-void QAndroidVideoSink::setRhi(QRhi *rhi)
-{
- if (rhi && rhi->backend() != QRhi::OpenGLES2)
- rhi = nullptr;
- if (m_rhi == rhi)
- return;
-
- m_rhi = rhi;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/common/qandroidvideosink_p.h b/src/multimedia/platform/android/common/qandroidvideosink_p.h
deleted file mode 100644
index d653234f1..000000000
--- a/src/multimedia/platform/android/common/qandroidvideosink_p.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QANDROIDVIDEOSINK_P_H
-#define QANDROIDVIDEOSINK_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qtmultimediaglobal_p.h>
-#include <private/qplatformvideosink_p.h>
-
-#include <qvideosink.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAndroidVideoSink
- : public QPlatformVideoSink
-{
- Q_OBJECT
-public:
- explicit QAndroidVideoSink(QVideoSink *parent = 0);
- ~QAndroidVideoSink();
-
- void setRhi(QRhi *rhi) override;
-
-private:
- QRhi *m_rhi = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/android/mediacapture/qandroidcamera.cpp b/src/multimedia/platform/android/mediacapture/qandroidcamera.cpp
deleted file mode 100644
index 3bcc93564..000000000
--- a/src/multimedia/platform/android/mediacapture/qandroidcamera.cpp
+++ /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 Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** 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 "qandroidcamera_p.h"
-#include "qandroidcamerasession_p.h"
-#include "qandroidcapturesession_p.h"
-#include "qandroidmediacapturesession_p.h"
-#include <qmediadevices.h>
-#include <qcameradevice.h>
-#include <qtimer.h>
-#include "qandroidmultimediautils_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QAndroidCamera::QAndroidCamera(QCamera *camera)
- : QPlatformCamera(camera)
-{
- Q_ASSERT(camera);
-}
-
-QAndroidCamera::~QAndroidCamera()
-{
-}
-
-void QAndroidCamera::setActive(bool active)
-{
- if (m_cameraSession)
- m_cameraSession->setActive(active);
-}
-
-bool QAndroidCamera::isActive() const
-{
- return m_cameraSession ? m_cameraSession->isActive() : false;
-}
-
-void QAndroidCamera::setCamera(const QCameraDevice &camera)
-{
- m_cameraDev = camera;
-
- if (m_cameraSession) {
- int id = 0;
- auto cameras = QMediaDevices::videoInputs();
- for (int i = 0; i < cameras.size(); ++i) {
- if (cameras.at(i) == camera) {
- id = i;
- break;
- }
- }
- if (id != m_cameraSession->getSelectedCameraId()) {
- m_cameraSession->setSelectedCameraId(id);
- reactivateCameraSession();
- }
- }
-}
-
-void QAndroidCamera::reactivateCameraSession()
-{
- if (m_cameraSession->isActive()) {
- if (m_service->captureSession() &&
- m_service->captureSession()->state() == QMediaRecorder::RecordingState) {
- m_service->captureSession()->stop();
- qWarning() << "Changing camera during recording not supported";
- }
- m_cameraSession->setActive(false);
- m_cameraSession->setActive(true);
- }
-}
-
-bool QAndroidCamera::setCameraFormat(const QCameraFormat &format)
-{
- m_cameraFormat = format;
-
- if (m_cameraSession)
- m_cameraSession->setCameraFormat(m_cameraFormat);
-
- return true;
-}
-
-void QAndroidCamera::setCaptureSession(QPlatformMediaCaptureSession *session)
-{
- QAndroidMediaCaptureSession *captureSession = static_cast<QAndroidMediaCaptureSession *>(session);
- if (m_service == captureSession)
- return;
-
- m_service = captureSession;
- if (!m_service) {
- disconnect(m_cameraSession,nullptr,this,nullptr);
- m_cameraSession = nullptr;
- return;
- }
-
- m_cameraSession = m_service->cameraSession();
- Q_ASSERT(m_cameraSession);
- if (!m_cameraFormat.isNull())
- m_cameraSession->setCameraFormat(m_cameraFormat);
-
- setCamera(m_cameraDev);
-
- connect(m_cameraSession, &QAndroidCameraSession::activeChanged, this, &QAndroidCamera::activeChanged);
- connect(m_cameraSession, &QAndroidCameraSession::error, this, &QAndroidCamera::error);
- connect(m_cameraSession, &QAndroidCameraSession::opened, this, &QAndroidCamera::onCameraOpened);
-}
-
-void QAndroidCamera::setFocusMode(QCamera::FocusMode mode)
-{
- if (!m_cameraSession || !m_cameraSession->camera())
- return;
-
- if (isFocusModeSupported(mode)) {
- QString focusMode;
-
- switch (mode) {
- case QCamera::FocusModeHyperfocal:
- focusMode = QLatin1String("edof");
- break;
- case QCamera::FocusModeInfinity: // not 100%, but close
- focusMode = QLatin1String("infinity");
- break;
- case QCamera::FocusModeManual:
- focusMode = QLatin1String("fixed");
- break;
- case QCamera::FocusModeAutoNear:
- focusMode = QLatin1String("macro");
- break;
- case QCamera::FocusModeAuto:
- case QCamera::FocusModeAutoFar:
- if (1) { // ###?
- focusMode = QLatin1String("continuous-video");
- } else {
- focusMode = QLatin1String("continuous-picture");
- }
- break;
- }
-
- m_cameraSession->camera()->setFocusMode(focusMode);
-
- // reset focus position
- m_cameraSession->camera()->cancelAutoFocus();
-
- focusModeChanged(mode);
- }
-}
-
-bool QAndroidCamera::isFocusModeSupported(QCamera::FocusMode mode) const
-{
- return (m_cameraSession && m_cameraSession->camera()) ? m_supportedFocusModes.contains(mode) : false;
-}
-
-void QAndroidCamera::onCameraOpened()
-{
- Q_ASSERT(m_cameraSession);
- connect(m_cameraSession->camera(), &AndroidCamera::previewSizeChanged, this, &QAndroidCamera::setCameraFocusArea);
-
- m_supportedFocusModes.clear();
- m_continuousPictureFocusSupported = false;
- m_continuousVideoFocusSupported = false;
- m_focusPointSupported = false;
-
- QStringList focusModes = m_cameraSession->camera()->getSupportedFocusModes();
- for (int i = 0; i < focusModes.size(); ++i) {
- const QString &focusMode = focusModes.at(i);
- if (focusMode == QLatin1String("continuous-picture")) {
- m_supportedFocusModes << QCamera::FocusModeAuto;
- m_continuousPictureFocusSupported = true;
- } else if (focusMode == QLatin1String("continuous-video")) {
- m_supportedFocusModes << QCamera::FocusModeAuto;
- m_continuousVideoFocusSupported = true;
- } else if (focusMode == QLatin1String("edof")) {
- m_supportedFocusModes << QCamera::FocusModeHyperfocal;
- } else if (focusMode == QLatin1String("fixed")) {
- m_supportedFocusModes << QCamera::FocusModeManual;
- } else if (focusMode == QLatin1String("infinity")) {
- m_supportedFocusModes << QCamera::FocusModeInfinity;
- } else if (focusMode == QLatin1String("macro")) {
- m_supportedFocusModes << QCamera::FocusModeAutoNear;
- }
- }
-
- if (m_cameraSession->camera()->getMaxNumFocusAreas() > 0)
- m_focusPointSupported = true;
-
- auto m = focusMode();
- if (!m_supportedFocusModes.contains(m))
- m = QCamera::FocusModeAuto;
-
- setFocusMode(m);
- setCustomFocusPoint(focusPoint());
-
- if (m_cameraSession->camera()->isZoomSupported()) {
- m_zoomRatios = m_cameraSession->camera()->getZoomRatios();
- qreal maxZoom = m_zoomRatios.last() / qreal(100);
- if (m_maximumZoom != maxZoom) {
- m_maximumZoom = maxZoom;
- }
- zoomTo(1, -1);
- } else {
- m_zoomRatios.clear();
- m_maximumZoom = 1.0;
- }
-
- m_minExposureCompensationIndex = m_cameraSession->camera()->getMinExposureCompensation();
- m_maxExposureCompensationIndex = m_cameraSession->camera()->getMaxExposureCompensation();
- m_exposureCompensationStep = m_cameraSession->camera()->getExposureCompensationStep();
- exposureCompensationRangeChanged(m_minExposureCompensationIndex*m_exposureCompensationStep,
- m_maxExposureCompensationIndex*m_exposureCompensationStep);
-
- m_supportedExposureModes.clear();
- QStringList sceneModes = m_cameraSession->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 << QCamera::ExposureAuto;
- else if (sceneMode == QLatin1String("beach"))
- m_supportedExposureModes << QCamera::ExposureBeach;
- else if (sceneMode == QLatin1String("night"))
- m_supportedExposureModes << QCamera::ExposureNight;
- else if (sceneMode == QLatin1String("portrait"))
- m_supportedExposureModes << QCamera::ExposurePortrait;
- else if (sceneMode == QLatin1String("snow"))
- m_supportedExposureModes << QCamera::ExposureSnow;
- else if (sceneMode == QLatin1String("sports"))
- m_supportedExposureModes << QCamera::ExposureSports;
- else if (sceneMode == QLatin1String("action"))
- m_supportedExposureModes << QCamera::ExposureAction;
- else if (sceneMode == QLatin1String("landscape"))
- m_supportedExposureModes << QCamera::ExposureLandscape;
- else if (sceneMode == QLatin1String("night-portrait"))
- m_supportedExposureModes << QCamera::ExposureNightPortrait;
- else if (sceneMode == QLatin1String("theatre"))
- m_supportedExposureModes << QCamera::ExposureTheatre;
- else if (sceneMode == QLatin1String("sunset"))
- m_supportedExposureModes << QCamera::ExposureSunset;
- else if (sceneMode == QLatin1String("steadyphoto"))
- m_supportedExposureModes << QCamera::ExposureSteadyPhoto;
- else if (sceneMode == QLatin1String("fireworks"))
- m_supportedExposureModes << QCamera::ExposureFireworks;
- else if (sceneMode == QLatin1String("party"))
- m_supportedExposureModes << QCamera::ExposureParty;
- else if (sceneMode == QLatin1String("candlelight"))
- m_supportedExposureModes << QCamera::ExposureCandlelight;
- else if (sceneMode == QLatin1String("barcode"))
- m_supportedExposureModes << QCamera::ExposureBarcode;
- }
- }
-
- setExposureCompensation(exposureCompensation());
- setExposureMode(exposureMode());
-
- isFlashSupported = false;
- isFlashAutoSupported = false;
- isTorchSupported = false;
-
- QStringList flashModes = m_cameraSession->camera()->getSupportedFlashModes();
- for (int i = 0; i < flashModes.size(); ++i) {
- const QString &flashMode = flashModes.at(i);
- if (flashMode == QLatin1String("auto"))
- isFlashAutoSupported = true;
- else if (flashMode == QLatin1String("on"))
- isFlashSupported = true;
- else if (flashMode == QLatin1String("torch"))
- isTorchSupported = true;
- }
-
- setFlashMode(flashMode());
-
- m_supportedWhiteBalanceModes.clear();
- QStringList whiteBalanceModes = m_cameraSession->camera()->getSupportedWhiteBalance();
- for (int i = 0; i < whiteBalanceModes.size(); ++i) {
- const QString &wb = whiteBalanceModes.at(i);
- if (wb == QLatin1String("auto")) {
- m_supportedWhiteBalanceModes.insert(QCamera::WhiteBalanceAuto,
- QStringLiteral("auto"));
- } else if (wb == QLatin1String("cloudy-daylight")) {
- m_supportedWhiteBalanceModes.insert(QCamera::WhiteBalanceCloudy,
- QStringLiteral("cloudy-daylight"));
- } else if (wb == QLatin1String("daylight")) {
- m_supportedWhiteBalanceModes.insert(QCamera::WhiteBalanceSunlight,
- QStringLiteral("daylight"));
- } else if (wb == QLatin1String("fluorescent")) {
- m_supportedWhiteBalanceModes.insert(QCamera::WhiteBalanceFluorescent,
- QStringLiteral("fluorescent"));
- } else if (wb == QLatin1String("incandescent")) {
- m_supportedWhiteBalanceModes.insert(QCamera::WhiteBalanceTungsten,
- QStringLiteral("incandescent"));
- } else if (wb == QLatin1String("shade")) {
- m_supportedWhiteBalanceModes.insert(QCamera::WhiteBalanceShade,
- QStringLiteral("shade"));
- } else if (wb == QLatin1String("twilight")) {
- m_supportedWhiteBalanceModes.insert(QCamera::WhiteBalanceSunset,
- QStringLiteral("twilight"));
- } else if (wb == QLatin1String("warm-fluorescent")) {
- m_supportedWhiteBalanceModes.insert(QCamera::WhiteBalanceFlash,
- QStringLiteral("warm-fluorescent"));
- }
- }
-
-}
-
-//void QAndroidCameraFocusControl::onCameraCaptureModeChanged()
-//{
-// if (m_cameraSession->camera() && m_focusMode == QCamera::FocusModeAudio) {
-// QString focusMode;
-// if ((m_cameraSession->captureMode().testFlag(QCamera::CaptureVideo) && m_continuousVideoFocusSupported)
-// || !m_continuousPictureFocusSupported) {
-// focusMode = QLatin1String("continuous-video");
-// } else {
-// focusMode = QLatin1String("continuous-picture");
-// }
-// m_cameraSession->camera()->setFocusMode(focusMode);
-// m_cameraSession->camera()->cancelAutoFocus();
-// }
-//}
-
-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));
-}
-
-void QAndroidCamera::setCameraFocusArea()
-{
- if (!m_cameraSession)
- return;
-
- QList<QRect> areas;
- auto focusPoint = customFocusPoint();
- if (QRectF(0., 0., 1., 1.).contains(focusPoint)) {
- // in FocusPointAuto mode, leave the area list empty
- // to let the driver choose the focus point.
- QSize viewportSize = m_cameraSession->camera()->previewSize();
-
- if (!viewportSize.isValid())
- return;
-
- // Set up a 50x50 pixel focus area around the focal point
- QSizeF focusSize(50.f / viewportSize.width(), 50.f / viewportSize.height());
- float x = qBound(qreal(0),
- focusPoint.x() - (focusSize.width() / 2),
- 1.f - focusSize.width());
- float y = qBound(qreal(0),
- focusPoint.y() - (focusSize.height() / 2),
- 1.f - focusSize.height());
-
- QRectF area(QPointF(x, y), focusSize);
-
- areas.append(adjustedArea(area));
- }
- m_cameraSession->camera()->setFocusAreas(areas);
-}
-
-void QAndroidCamera::zoomTo(float factor, float rate)
-{
- Q_UNUSED(rate);
-
- if (zoomFactor() == factor)
- return;
-
- if (!m_cameraSession || !m_cameraSession->camera())
- return;
-
- factor = qBound(qreal(1), factor, maxZoomFactor());
- int validZoomIndex = qt_findClosestValue(m_zoomRatios, qRound(factor * 100));
- float newZoom = m_zoomRatios.at(validZoomIndex) / qreal(100);
- m_cameraSession->camera()->setZoom(validZoomIndex);
- zoomFactorChanged(newZoom);
-}
-
-void QAndroidCamera::setFlashMode(QCamera::FlashMode mode)
-{
- if (!m_cameraSession || !m_cameraSession->camera())
- return;
-
- if (!isFlashModeSupported(mode))
- return;
-
- QString flashMode;
- if (mode == QCamera::FlashAuto)
- flashMode = QLatin1String("auto");
- else if (mode == QCamera::FlashOn)
- flashMode = QLatin1String("on");
- else // FlashOff
- flashMode = QLatin1String("off");
-
- m_cameraSession->camera()->setFlashMode(flashMode);
- flashModeChanged(mode);
-}
-
-bool QAndroidCamera::isFlashModeSupported(QCamera::FlashMode mode) const
-{
- if (!m_cameraSession || !m_cameraSession->camera())
- return false;
- switch (mode) {
- case QCamera::FlashOff:
- return true;
- case QCamera::FlashOn:
- return isFlashSupported;
- case QCamera::FlashAuto:
- return isFlashAutoSupported;
- }
-}
-
-bool QAndroidCamera::isFlashReady() const
-{
- // Android doesn't have an API for that
- return true;
-}
-
-void QAndroidCamera::setTorchMode(QCamera::TorchMode mode)
-{
- if (!m_cameraSession)
- return;
- auto *camera = m_cameraSession->camera();
- if (!camera || !isTorchSupported || mode == QCamera::TorchAuto)
- return;
-
- if (mode == QCamera::TorchOn) {
- camera->setFlashMode(QLatin1String("torch"));
- } else if (mode == QCamera::TorchOff) {
- // if torch was enabled, it first needs to be turned off before restoring the flash mode
- camera->setFlashMode(QLatin1String("off"));
- setFlashMode(flashMode());
- }
- torchModeChanged(mode);
-}
-
-bool QAndroidCamera::isTorchModeSupported(QCamera::TorchMode mode) const
-{
- if (!m_cameraSession || !m_cameraSession->camera())
- return false;
- switch (mode) {
- case QCamera::TorchOff:
- return true;
- case QCamera::TorchOn:
- return isTorchSupported;
- case QCamera::TorchAuto:
- return false;
- }
-}
-
-void QAndroidCamera::setExposureMode(QCamera::ExposureMode mode)
-{
- if (exposureMode() == mode)
- return;
-
- if (!m_cameraSession || !m_cameraSession->camera())
- return;
-
- if (!m_supportedExposureModes.contains(mode))
- return;
-
- QString sceneMode;
- switch (mode) {
- case QCamera::ExposureAuto:
- sceneMode = QLatin1String("auto");
- break;
- case QCamera::ExposureSports:
- sceneMode = QLatin1String("sports");
- break;
- case QCamera::ExposurePortrait:
- sceneMode = QLatin1String("portrait");
- break;
- case QCamera::ExposureBeach:
- sceneMode = QLatin1String("beach");
- break;
- case QCamera::ExposureSnow:
- sceneMode = QLatin1String("snow");
- break;
- case QCamera::ExposureNight:
- sceneMode = QLatin1String("night");
- break;
- case QCamera::ExposureAction:
- sceneMode = QLatin1String("action");
- break;
- case QCamera::ExposureLandscape:
- sceneMode = QLatin1String("landscape");
- break;
- case QCamera::ExposureNightPortrait:
- sceneMode = QLatin1String("night-portrait");
- break;
- case QCamera::ExposureTheatre:
- sceneMode = QLatin1String("theatre");
- break;
- case QCamera::ExposureSunset:
- sceneMode = QLatin1String("sunset");
- break;
- case QCamera::ExposureSteadyPhoto:
- sceneMode = QLatin1String("steadyphoto");
- break;
- case QCamera::ExposureFireworks:
- sceneMode = QLatin1String("fireworks");
- break;
- case QCamera::ExposureParty:
- sceneMode = QLatin1String("party");
- break;
- case QCamera::ExposureCandlelight:
- sceneMode = QLatin1String("candlelight");
- break;
- case QCamera::ExposureBarcode:
- sceneMode = QLatin1String("barcode");
- break;
- default:
- sceneMode = QLatin1String("auto");
- mode = QCamera::ExposureAuto;
- break;
- }
-
- m_cameraSession->camera()->setSceneMode(sceneMode);
- exposureModeChanged(mode);
-}
-
-bool QAndroidCamera::isExposureModeSupported(QCamera::ExposureMode mode) const
-{
- return m_supportedExposureModes.contains(mode);
-}
-
-void QAndroidCamera::setExposureCompensation(float bias)
-{
- if (exposureCompensation() == bias || !m_cameraSession || !m_cameraSession->camera())
- return;
-
- int biasIndex = qRound(bias / m_exposureCompensationStep);
- biasIndex = qBound(m_minExposureCompensationIndex, biasIndex, m_maxExposureCompensationIndex);
- float comp = biasIndex * m_exposureCompensationStep;
- m_cameraSession->camera()->setExposureCompensation(biasIndex);
- exposureCompensationChanged(comp);
-}
-
-bool QAndroidCamera::isWhiteBalanceModeSupported(QCamera::WhiteBalanceMode mode) const
-{
- return m_supportedWhiteBalanceModes.contains(mode);
-}
-
-void QAndroidCamera::setWhiteBalanceMode(QCamera::WhiteBalanceMode mode)
-{
- if (!m_cameraSession)
- return;
- auto *camera = m_cameraSession->camera();
- if (!camera)
- return;
- QString wb = m_supportedWhiteBalanceModes.value(mode, QString());
- if (!wb.isEmpty()) {
- camera->setWhiteBalance(wb);
- whiteBalanceModeChanged(mode);
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/mediacapture/qandroidcamera_p.h b/src/multimedia/platform/android/mediacapture/qandroidcamera_p.h
deleted file mode 100644
index e97368698..000000000
--- a/src/multimedia/platform/android/mediacapture/qandroidcamera_p.h
+++ /dev/null
@@ -1,133 +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
-
-//
-// 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 <private/qplatformcamera_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAndroidCameraSession;
-class QAndroidCameraVideoRendererControl;
-class QAndroidMediaCaptureSession;
-
-class QAndroidCamera : public QPlatformCamera
-{
- Q_OBJECT
-public:
- explicit QAndroidCamera(QCamera *camera);
- virtual ~QAndroidCamera();
-
- bool isActive() const override;
- void setActive(bool active) override;
-
- void setCamera(const QCameraDevice &camera) override;
- bool setCameraFormat(const QCameraFormat &format) override;
-
- void setCaptureSession(QPlatformMediaCaptureSession *session) override;
-
- void setFocusMode(QCamera::FocusMode mode) override;
- bool isFocusModeSupported(QCamera::FocusMode mode) const override;
-
- void zoomTo(float factor, float rate) override;
-
- void setFlashMode(QCamera::FlashMode mode) override;
- bool isFlashModeSupported(QCamera::FlashMode mode) const override;
- bool isFlashReady() const override;
-
- void setTorchMode(QCamera::TorchMode mode) override;
- bool isTorchModeSupported(QCamera::TorchMode mode) const override;
-
- void setExposureMode(QCamera::ExposureMode mode) override;
- bool isExposureModeSupported(QCamera::ExposureMode mode) const override;
-
- void setExposureCompensation(float bias) override;
-
- bool isWhiteBalanceModeSupported(QCamera::WhiteBalanceMode mode) const override;
- void setWhiteBalanceMode(QCamera::WhiteBalanceMode mode) override;
-
-private Q_SLOTS:
- void onCameraOpened();
- void setCameraFocusArea();
-
-private:
- void reactivateCameraSession();
-
- QAndroidCameraSession *m_cameraSession = nullptr;
- QAndroidMediaCaptureSession *m_service = nullptr;
-
- QList<QCamera::FocusMode> m_supportedFocusModes;
- bool m_continuousPictureFocusSupported = false;
- bool m_continuousVideoFocusSupported = false;
- bool m_focusPointSupported = false;
-
- float m_maximumZoom;
- QList<int> m_zoomRatios;
-
- QList<QCamera::ExposureMode> m_supportedExposureModes;
- int m_minExposureCompensationIndex;
- int m_maxExposureCompensationIndex;
- qreal m_exposureCompensationStep;
-
- bool isFlashSupported = false;
- bool isFlashAutoSupported = false;
- bool isTorchSupported = false;
- QCameraDevice m_cameraDev;
-
- QMap<QCamera::WhiteBalanceMode, QString> m_supportedWhiteBalanceModes;
- QCameraFormat m_cameraFormat;
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QANDROIDCAMERACONTROL_H
diff --git a/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp b/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp
deleted file mode 100644
index 38b819352..000000000
--- a/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp
+++ /dev/null
@@ -1,794 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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_p.h"
-
-#include "androidcamera_p.h"
-#include "androidmultimediautils_p.h"
-#include "qandroidvideooutput_p.h"
-#include "qandroidmultimediautils_p.h"
-#include <qvideosink.h>
-#include <QtConcurrent/qtconcurrentrun.h>
-#include <qfile.h>
-#include <qguiapplication.h>
-#include <qscreen.h>
-#include <qdebug.h>
-#include <qvideoframe.h>
-#include <private/qplatformimagecapture_p.h>
-#include <private/qmemoryvideobuffer_p.h>
-#include <private/qcameradevice_p.h>
-#include <private/qmediastoragelocation_p.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_GLOBAL_STATIC(QList<QCameraDevice>, g_availableCameras)
-
-QAndroidCameraSession::QAndroidCameraSession(QObject *parent)
- : QObject(parent)
- , m_selectedCamera(0)
- , m_camera(0)
- , m_videoOutput(0)
- , m_savedState(-1)
- , m_previewStarted(false)
- , m_lastImageCaptureId(0)
- , m_readyForCapture(false)
- , m_currentImageCaptureId(-1)
- , m_previewCallback(0)
- , m_keepActive(false)
-{
- if (qApp) {
- connect(qApp, &QGuiApplication::applicationStateChanged,
- this, &QAndroidCameraSession::onApplicationStateChanged);
-
- auto screen = qApp->primaryScreen();
- if (screen) {
- connect(screen, &QScreen::orientationChanged, this,
- &QAndroidCameraSession::updateOrientation);
- enableRotation();
- }
- }
-}
-
-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))
-// applyResolution(m_actualImageSettings.resolution());
-//}
-
-void QAndroidCameraSession::setActive(bool active)
-{
- if (m_active == active)
- return;
-
- m_active = active;
-
- // 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)
- setActiveHelper(active);
- else
- m_savedState = active;
-
- emit activeChanged(m_active);
-}
-
-void QAndroidCameraSession::setActiveHelper(bool active)
-{
- if (!active) {
- stopPreview();
- close();
- } else {
- if (!m_camera && !open()) {
- emit error(QCamera::CameraError, QStringLiteral("Failed to open camera"));
- return;
- }
- startPreview();
- }
-}
-
-void QAndroidCameraSession::updateAvailableCameras()
-{
- g_availableCameras->clear();
-
- const int numCameras = AndroidCamera::getNumberOfCameras();
- for (int i = 0; i < numCameras; ++i) {
- QCameraDevicePrivate *info = new QCameraDevicePrivate;
- AndroidCamera::getCameraInfo(i, info);
-
- if (!info->id.isEmpty()) {
- AndroidCamera::getSupportedFormats(i, info->videoFormats);
- // Add supported picture sizes to the camera info
- AndroidCamera *camera = AndroidCamera::open(i);
- if (camera)
- info->photoResolutions = camera->getSupportedPictureSizes();
- delete camera;
- g_availableCameras->append(info->create());
- }
- }
-}
-
-const QList<QCameraDevice> &QAndroidCameraSession::availableCameras()
-{
- if (g_availableCameras->isEmpty())
- updateAvailableCameras();
-
- return *g_availableCameras;
-}
-
-bool QAndroidCameraSession::open()
-{
- close();
-
- m_camera = AndroidCamera::open(m_selectedCamera);
-
- if (m_camera) {
- connect(m_camera, &AndroidCamera::pictureExposed,
- this, &QAndroidCameraSession::onCameraPictureExposed);
- connect(m_camera, &AndroidCamera::lastPreviewFrameFetched,
- this, &QAndroidCameraSession::onLastPreviewFrameFetched,
- Qt::DirectConnection);
- connect(m_camera, &AndroidCamera::newPreviewFrame,
- this, &QAndroidCameraSession::onNewPreviewFrame,
- Qt::DirectConnection);
- connect(m_camera, &AndroidCamera::pictureCaptured,
- this, &QAndroidCameraSession::onCameraPictureCaptured);
- connect(m_camera, &AndroidCamera::previewStarted,
- this, &QAndroidCameraSession::onCameraPreviewStarted);
- connect(m_camera, &AndroidCamera::previewStopped,
- this, &QAndroidCameraSession::onCameraPreviewStopped);
- connect(m_camera, &AndroidCamera::previewFailedToStart,
- this, &QAndroidCameraSession::onCameraPreviewFailedToStart);
- connect(m_camera, &AndroidCamera::takePictureFailed,
- this, &QAndroidCameraSession::onCameraTakePictureFailed);
-
- if (m_camera->getPreviewFormat() != AndroidCamera::NV21)
- m_camera->setPreviewFormat(AndroidCamera::NV21);
-
- m_camera->notifyNewFrames(m_previewCallback);
-
- emit opened();
- setActive(true);
- }
-
- return m_camera != 0;
-}
-
-void QAndroidCameraSession::close()
-{
- if (!m_camera)
- return;
-
- stopPreview();
-
- m_readyForCapture = false;
- m_currentImageCaptureId = -1;
- m_currentImageCaptureFileName.clear();
- m_actualImageSettings = m_requestedImageSettings;
-
- m_camera->release();
- delete m_camera;
- m_camera = 0;
-
- setActive(false);
-}
-
-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, &QAndroidVideoOutput::readyChanged,
- this, &QAndroidCameraSession::onVideoOutputReady);
- }
- } else {
- m_videoOutput = 0;
- }
-}
-
-void QAndroidCameraSession::setCameraFormat(const QCameraFormat &format)
-{
- m_requestedFpsRange.min = format.minFrameRate();
- m_requestedFpsRange.max = format.maxFrameRate();
- m_requestedPixelFromat = AndroidCamera::AndroidImageFormatFromQtPixelFormat(format.pixelFormat());
-
- m_requestedImageSettings.setResolution(format.resolution());
- m_actualImageSettings.setResolution(format.resolution());
- if (m_readyForCapture)
- applyResolution(m_actualImageSettings.resolution());
-}
-
-void QAndroidCameraSession::applyResolution(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 (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();
-
- 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();
- }
- }
-
- // -- adjust pixel format
-
- AndroidCamera::ImageFormat adjustedPreviewFormat = m_requestedPixelFromat;
- if (adjustedPreviewFormat == AndroidCamera::UnknownImageFormat)
- adjustedPreviewFormat = AndroidCamera::NV21;
-
- // -- adjust FPS
-
- AndroidCamera::FpsRange adjustedFps = m_requestedFpsRange;;
- if (adjustedFps.min == 0 || adjustedFps.max == 0)
- adjustedFps = currentFpsRange;
-
- // -- Set values on camera
-
- if (currentViewfinderResolution != adjustedViewfinderResolution
- || currentPreviewFormat != adjustedPreviewFormat
- || currentFpsRange.min != adjustedFps.min
- || currentFpsRange.max != adjustedFps.max) {
-
- if (m_videoOutput) {
- // fix the resolution of output based on the orientation
- QSize outputResolution = adjustedViewfinderResolution;
- const int rotation = currentCameraRotation();
- if (rotation == 90 || rotation == 270)
- outputResolution.transpose();
- m_videoOutput->setVideoSize(outputResolution);
- }
-
- // 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<QVideoFrameFormat::PixelFormat> QAndroidCameraSession::getSupportedPixelFormats() const
-{
- QList<QVideoFrameFormat::PixelFormat> formats;
-
- if (!m_camera)
- return formats;
-
- const QList<AndroidCamera::ImageFormat> nativeFormats = m_camera->getSupportedPreviewFormats();
-
- formats.reserve(nativeFormats.size());
-
- for (AndroidCamera::ImageFormat nativeFormat : nativeFormats) {
- QVideoFrameFormat::PixelFormat format = AndroidCamera::QtPixelFormatFromAndroidImageFormat(nativeFormat);
- if (format != QVideoFrameFormat::Format_Invalid)
- formats.append(format);
- }
-
- return formats;
-}
-
-QList<AndroidCamera::FpsRange> QAndroidCameraSession::getSupportedPreviewFpsRange() const
-{
- return m_camera ? m_camera->getSupportedPreviewFpsRange() : QList<AndroidCamera::FpsRange>();
-}
-
-
-bool QAndroidCameraSession::startPreview()
-{
- if (!m_camera || !m_videoOutput)
- return false;
-
- if (m_previewStarted)
- return true;
-
- 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;
-
- applyImageSettings();
- applyResolution(m_actualImageSettings.resolution());
-
- AndroidMultimediaUtils::enableOrientationListener(true);
-
- updateOrientation();
-
- m_camera->startPreview();
- m_previewStarted = true;
-
- return true;
-}
-
-void QAndroidCameraSession::stopPreview()
-{
- if (!m_camera || !m_previewStarted)
- return;
-
- 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)
- applyResolution(m_actualImageSettings.resolution());
-}
-
-void QAndroidCameraSession::enableRotation()
-{
- m_rotationEnabled = true;
-}
-
-void QAndroidCameraSession::disableRotation()
-{
- m_rotationEnabled = false;
-}
-
-void QAndroidCameraSession::updateOrientation()
-{
- if (!m_camera || !m_rotationEnabled)
- return;
-
- m_camera->setDisplayOrientation(currentCameraRotation());
- applyResolution(m_actualImageSettings.resolution());
-}
-
-
-int QAndroidCameraSession::currentCameraRotation() const
-{
- if (!m_camera)
- return 0;
-
- auto screen = QGuiApplication::primaryScreen();
- auto screenOrientation = screen->orientation();
- if (screenOrientation == Qt::PrimaryOrientation)
- screenOrientation = screen->primaryOrientation();
-
- int deviceOrientation = 0;
- switch (screenOrientation) {
- case Qt::PrimaryOrientation:
- case Qt::PortraitOrientation:
- break;
- case Qt::LandscapeOrientation:
- deviceOrientation = 90;
- break;
- case Qt::InvertedPortraitOrientation:
- deviceOrientation = 180;
- break;
- case Qt::InvertedLandscapeOrientation:
- deviceOrientation = 270;
- break;
- }
-
- int nativeCameraOrientation = m_camera->getNativeOrientation();
-
- int rotation;
- // subtract natural camera orientation and physical device orientation
- if (m_camera->getFacing() == AndroidCamera::CameraFacingFront) {
- rotation = (nativeCameraOrientation + deviceOrientation) % 360;
- rotation = (360 - rotation) % 360; // compensate the mirror
- } else { // back-facing camera
- rotation = (nativeCameraOrientation - deviceOrientation + 360) % 360;
- }
- return rotation;
-}
-
-void QAndroidCameraSession::setPreviewFormat(AndroidCamera::ImageFormat format)
-{
- if (format == AndroidCamera::UnknownImageFormat)
- return;
-
- m_camera->setPreviewFormat(format);
-}
-
-void QAndroidCameraSession::setPreviewCallback(PreviewCallback *callback)
-{
- m_videoFrameCallbackMutex.lock();
- m_previewCallback = callback;
- if (m_camera)
- m_camera->notifyNewFrames(m_previewCallback);
- m_videoFrameCallbackMutex.unlock();
-}
-
-void QAndroidCameraSession::applyImageSettings()
-{
- if (!m_camera)
- return;
-
- // only supported format right now.
- m_actualImageSettings.setFormat(QImageCapture::JPEG);
-
- const QSize requestedResolution = m_requestedImageSettings.resolution();
- const QList<QSize> supportedResolutions = m_camera->getSupportedPictureSizes();
- if (!requestedResolution.isValid()) {
- // 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 QImageCapture::VeryLowQuality:
- jpegQuality = 20;
- break;
- case QImageCapture::LowQuality:
- jpegQuality = 40;
- break;
- case QImageCapture::NormalQuality:
- jpegQuality = 60;
- break;
- case QImageCapture::HighQuality:
- jpegQuality = 80;
- break;
- case QImageCapture::VeryHighQuality:
- jpegQuality = 100;
- break;
- }
- m_camera->setJpegQuality(jpegQuality);
-}
-
-bool QAndroidCameraSession::isReadyForCapture() const
-{
- return isActive() && m_readyForCapture;
-}
-
-void QAndroidCameraSession::setReadyForCapture(bool ready)
-{
- if (m_readyForCapture == ready)
- return;
-
- m_readyForCapture = ready;
- emit readyForCaptureChanged(ready);
-}
-
-int QAndroidCameraSession::capture(const QString &fileName)
-{
- ++m_lastImageCaptureId;
-
- if (!isReadyForCapture()) {
- emit imageCaptureError(m_lastImageCaptureId, QImageCapture::NotReadyError,
- QPlatformImageCapture::msgCameraNotReady());
- return m_lastImageCaptureId;
- }
-
- setReadyForCapture(false);
-
- m_currentImageCaptureId = m_lastImageCaptureId;
- m_currentImageCaptureFileName = fileName;
-
- applyImageSettings();
- applyResolution(m_actualImageSettings.resolution());
-
- // adjust picture rotation depending on the device orientation
- m_camera->setRotation(currentCameraRotation());
-
- m_camera->takePicture();
-
- return m_lastImageCaptureId;
-}
-
-void QAndroidCameraSession::onCameraTakePictureFailed()
-{
- emit imageCaptureError(m_currentImageCaptureId, QImageCapture::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_camera)
- return;
-
- emit imageExposed(m_currentImageCaptureId);
- m_camera->fetchLastPreviewFrame();
-}
-
-void QAndroidCameraSession::onLastPreviewFrameFetched(const QVideoFrame &frame)
-{
- if (!m_camera)
- return;
-
- (void) 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.toImage().transformed(transform));
-}
-
-void QAndroidCameraSession::onNewPreviewFrame(const QVideoFrame &frame)
-{
- if (!m_camera)
- return;
-
- m_videoFrameCallbackMutex.lock();
-
- if (m_previewCallback)
- m_previewCallback->onFrameAvailable(frame);
-
- m_videoFrameCallbackMutex.unlock();
-}
-
-void QAndroidCameraSession::onCameraPictureCaptured(const QByteArray &data)
-{
- // Loading and saving the captured image can be slow, do it in a separate thread
- (void) QtConcurrent::run(&QAndroidCameraSession::processCapturedImage, this,
- m_currentImageCaptureId,
- data,
- m_actualImageSettings.resolution(),
- /* captureToBuffer = */ false,
- m_currentImageCaptureFileName);
-
- // Preview needs to be restarted after taking a picture
- if (m_camera)
- m_camera->startPreview();
-}
-
-void QAndroidCameraSession::onCameraPreviewStarted()
-{
- setReadyForCapture(true);
-}
-
-void QAndroidCameraSession::onCameraPreviewFailedToStart()
-{
- if (isActive()) {
- 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;
-
- setActive(false);
- setReadyForCapture(false);
- }
-}
-
-void QAndroidCameraSession::onCameraPreviewStopped()
-{
- if (!m_previewStarted)
- setActive(false);
- setReadyForCapture(false);
-}
-
-void QAndroidCameraSession::processCapturedImage(int id,
- const QByteArray &data,
- const QSize &resolution,
- bool captureToBuffer,
- const QString &fileName)
-{
-
-
- if (!captureToBuffer) {
- const QString actualFileName = QMediaStorageLocation::generateFileName(fileName, QStandardPaths::PicturesLocation, 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.
- if (fileName.isEmpty() || QFileInfo(fileName).isRelative())
- AndroidMultimediaUtils::registerMediaFile(actualFileName);
-
- emit imageSaved(id, actualFileName);
- } else {
- emit imageCaptureError(id, QImageCapture::OutOfSpaceError, file.errorString());
- }
- } else {
- const QString errorMessage = tr("Could not open destination file: %1").arg(actualFileName);
- emit imageCaptureError(id, QImageCapture::ResourceError, errorMessage);
- }
- } else {
- QVideoFrame frame(new QMemoryVideoBuffer(data, -1), QVideoFrameFormat(resolution, QVideoFrameFormat::Format_Jpeg));
- emit imageAvailable(id, frame);
- }
-}
-
-void QAndroidCameraSession::onVideoOutputReady(bool ready)
-{
- if (ready && m_active)
- startPreview();
-}
-
-void QAndroidCameraSession::onApplicationStateChanged(Qt::ApplicationState state)
-{
- switch (state) {
- case Qt::ApplicationInactive:
- if (!m_keepActive && m_active) {
- m_savedState = m_active;
- close();
- setActive(false);
- }
- break;
- case Qt::ApplicationActive:
- if (m_savedState != -1) {
- setActiveHelper(m_savedState);
- m_savedState = -1;
- }
- break;
- default:
- break;
- }
-}
-
-bool QAndroidCameraSession::requestCameraPermission()
-{
- m_keepActive = true;
- const bool result = qt_androidRequestCameraPermission();
- m_keepActive = false;
- return result;
-}
-
-void QAndroidCameraSession::setVideoSink(QVideoSink *sink)
-{
- if (m_sink == sink)
- return;
-
- m_sink = sink;
-
- if (m_sink) {
- delete m_textureOutput;
- m_textureOutput = nullptr;
-
- m_textureOutput = new QAndroidTextureVideoOutput(this);
- m_textureOutput->setSurface(m_sink);
- }
-
- setVideoOutput(m_textureOutput);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/mediacapture/qandroidcamerasession_p.h b/src/multimedia/platform/android/mediacapture/qandroidcamerasession_p.h
deleted file mode 100644
index fc3efef26..000000000
--- a/src/multimedia/platform/android/mediacapture/qandroidcamerasession_p.h
+++ /dev/null
@@ -1,196 +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
-
-//
-// 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 <qcamera.h>
-#include <QImageCapture>
-#include <QSet>
-#include <QMutex>
-#include <private/qplatformimagecapture_p.h>
-#include "androidcamera_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QAndroidVideoOutput;
-class QAndroidTextureVideoOutput ;
-class QVideoSink;
-
-class QAndroidCameraSession : public QObject
-{
- Q_OBJECT
-public:
- explicit QAndroidCameraSession(QObject *parent = 0);
- ~QAndroidCameraSession();
-
- static const QList<QCameraDevice> &availableCameras();
-
- void setSelectedCameraId(int cameraId) { m_selectedCamera = cameraId; }
- int getSelectedCameraId() { return m_selectedCamera; }
- AndroidCamera *camera() const { return m_camera; }
-
- bool isActive() const { return m_active; }
- void setActive(bool active);
-
- void applyResolution(const QSize &captureSize = QSize(), bool restartPreview = true);
-
- QAndroidVideoOutput *videoOutput() const { return m_videoOutput; }
- void setVideoOutput(QAndroidVideoOutput *output);
-
- void setCameraFormat(const QCameraFormat &format);
-
- QList<QSize> getSupportedPreviewSizes() const;
- QList<QVideoFrameFormat::PixelFormat> getSupportedPixelFormats() const;
- QList<AndroidCamera::FpsRange> getSupportedPreviewFpsRange() const;
-
- QImageEncoderSettings imageSettings() const { return m_actualImageSettings; }
- void setImageSettings(const QImageEncoderSettings &settings);
-
- bool isReadyForCapture() const;
- void setReadyForCapture(bool ready);
- int capture(const QString &fileName);
-
- int currentCameraRotation() const;
-
- void setPreviewFormat(AndroidCamera::ImageFormat format);
-
- struct PreviewCallback
- {
- virtual void onFrameAvailable(const QVideoFrame &frame) = 0;
- };
- void setPreviewCallback(PreviewCallback *callback);
- bool requestCameraPermission();
-
- void setVideoSink(QVideoSink *surface);
-
- void disableRotation();
- void enableRotation();
-
-Q_SIGNALS:
- void activeChanged(bool);
- void error(int error, const QString &errorString);
- void opened();
-
- void readyForCaptureChanged(bool);
- void imageExposed(int id);
- void imageCaptured(int id, const QImage &preview);
- void imageMetadataAvailable(int id, const QMediaMetaData &key);
- 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 updateOrientation();
-
- 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,
- bool captureToBuffer,
- const QString &fileName);
-
- void setActiveHelper(bool active);
-
- int m_selectedCamera;
- AndroidCamera *m_camera;
- QAndroidVideoOutput *m_videoOutput;
-
- bool m_active = false;
- int m_savedState = -1;
- bool m_previewStarted;
-
- bool m_rotationEnabled = false;
-
- QVideoSink *m_sink = nullptr;
- QAndroidTextureVideoOutput *m_textureOutput = nullptr;
-
- QImageEncoderSettings m_requestedImageSettings;
- QImageEncoderSettings m_actualImageSettings;
- AndroidCamera::FpsRange m_requestedFpsRange;
- AndroidCamera::ImageFormat m_requestedPixelFromat;
-
- int m_lastImageCaptureId;
- bool m_readyForCapture;
- int m_currentImageCaptureId;
- QString m_currentImageCaptureFileName;
-
- QMutex m_videoFrameCallbackMutex;
- PreviewCallback *m_previewCallback;
- bool m_keepActive;
-};
-
-QT_END_NAMESPACE
-
-#endif // QANDROIDCAMERASESSION_H
diff --git a/src/multimedia/platform/android/mediacapture/qandroidcapturesession.cpp b/src/multimedia/platform/android/mediacapture/qandroidcapturesession.cpp
deleted file mode 100644
index 913a75ee9..000000000
--- a/src/multimedia/platform/android/mediacapture/qandroidcapturesession.cpp
+++ /dev/null
@@ -1,472 +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_p.h"
-
-#include "androidcamera_p.h"
-#include "qandroidcamerasession_p.h"
-#include "androidmediaplayer_p.h"
-#include "androidmultimediautils_p.h"
-#include "qandroidmultimediautils_p.h"
-#include "qandroidvideooutput_p.h"
-#include "qandroidglobal_p.h"
-#include <private/qplatformaudioinput_p.h>
-#include <private/qplatformaudiooutput_p.h>
-#include <private/qmediarecorder_p.h>
-#include <private/qmediastoragelocation_p.h>
-#include <QtCore/qmimetype.h>
-
-#include <algorithm>
-
-QT_BEGIN_NAMESPACE
-
-QAndroidCaptureSession::QAndroidCaptureSession()
- : QObject()
- , m_mediaRecorder(0)
- , m_cameraSession(0)
- , m_duration(0)
- , m_state(QMediaRecorder::StoppedState)
- , m_outputFormat(AndroidMediaRecorder::DefaultOutputFormat)
- , m_audioEncoder(AndroidMediaRecorder::DefaultAudioEncoder)
- , m_videoEncoder(AndroidMediaRecorder::DefaultVideoEncoder)
-{
- m_notifyTimer.setInterval(1000);
- connect(&m_notifyTimer, &QTimer::timeout, this, &QAndroidCaptureSession::updateDuration);
-}
-
-QAndroidCaptureSession::~QAndroidCaptureSession()
-{
- stop();
- delete m_mediaRecorder;
-}
-
-void QAndroidCaptureSession::setCameraSession(QAndroidCameraSession *cameraSession)
-{
- if (m_cameraSession) {
- disconnect(m_connOpenCamera);
- disconnect(m_connActiveChangedCamera);
- }
-
- m_cameraSession = cameraSession;
- if (m_cameraSession) {
- m_connOpenCamera = connect(cameraSession, &QAndroidCameraSession::opened,
- this, &QAndroidCaptureSession::onCameraOpened);
- m_connActiveChangedCamera = connect(cameraSession, &QAndroidCameraSession::activeChanged,
- this, [this](bool isActive) {
- if (!isActive)
- stop();
- });
-
- // It requests permission on setAudioInput instead of on start because asking for
- // permission can pause the activity and android can release the surface referenced
- // by camera crashing the app when mediaRecorder tries to use it
- // TODO: https://bugreports.qt.io/browse/QTBUG-96346
- m_cameraSession->requestCameraPermission();
- }
-}
-
-void QAndroidCaptureSession::setAudioInput(QPlatformAudioInput *input)
-{
- m_audioInput = input;
-
- // It requests permission on setAudioInput instead of on start because asking for
- // permission can pause the activity and android can release the surface referenced
- // by camera crashing the app when mediaRecorder tries to use it
- // TODO: https://bugreports.qt.io/browse/QTBUG-96346
- qt_androidRequestRecordingPermission();
-}
-
-void QAndroidCaptureSession::setAudioOutput(QPlatformAudioOutput *output)
-{
- if (m_audioOutput == output)
- return;
-
- m_audioOutput = output;
-
- if (m_audioOutput)
- AndroidMediaPlayer::setAudioOutput(m_audioOutput->device.id());
-}
-
-QMediaRecorder::RecorderState QAndroidCaptureSession::state() const
-{
- return m_state;
-}
-
-void QAndroidCaptureSession::start(QMediaEncoderSettings &settings, const QUrl &outputLocation)
-{
- if (m_state == QMediaRecorder::RecordingState)
- return;
-
- if (m_mediaRecorder) {
- m_mediaRecorder->release();
- delete m_mediaRecorder;
- m_mediaRecorder = nullptr;
- }
-
- if (!m_cameraSession && !m_audioInput) {
- Q_EMIT error(QMediaRecorder::ResourceError, QLatin1String("No devices are set"));
- return;
- }
-
- applySettings(settings);
-
- m_mediaRecorder = new AndroidMediaRecorder;
- connect(m_mediaRecorder, &AndroidMediaRecorder::error, this, &QAndroidCaptureSession::onError);
- connect(m_mediaRecorder, &AndroidMediaRecorder::info, this, &QAndroidCaptureSession::onInfo);
-
- // Set audio/video sources
- if (m_cameraSession) {
- if (!qt_androidCheckCameraPermission()) {
- Q_EMIT error(QMediaRecorder::ResourceError, QLatin1String("Camera permission denied."));
- return;
- }
-
- m_cameraSession->camera()->stopPreviewSynchronous();
- m_cameraSession->applyResolution(settings.videoResolution(), false);
- m_cameraSession->camera()->unlock();
- m_mediaRecorder->setCamera(m_cameraSession->camera());
- m_mediaRecorder->setAudioSource(AndroidMediaRecorder::Camcorder);
- m_mediaRecorder->setVideoSource(AndroidMediaRecorder::Camera);
- }
-
- if (m_audioInput) {
- if (!qt_androidCheckMicrophonePermission()) {
- Q_EMIT error(QMediaRecorder::ResourceError,
- QLatin1String("Microphone permission denied."));
- return;
- }
-
- m_mediaRecorder->setAudioInput(m_audioInput->device.id());
- if (!m_mediaRecorder->isAudioSourceSet())
- m_mediaRecorder->setAudioSource(AndroidMediaRecorder::DefaultAudioSource);
- }
-
- // Set output format
- m_mediaRecorder->setOutputFormat(m_outputFormat);
-
- // Set audio encoder settings
- m_mediaRecorder->setAudioChannels(settings.audioChannelCount());
- m_mediaRecorder->setAudioEncodingBitRate(settings.audioBitRate());
- m_mediaRecorder->setAudioSamplingRate(settings.audioSampleRate());
- m_mediaRecorder->setAudioEncoder(m_audioEncoder);
-
- // Set video encoder settings
- if (m_cameraSession) {
- m_mediaRecorder->setVideoSize(settings.videoResolution());
- m_mediaRecorder->setVideoFrameRate(qRound(settings.videoFrameRate()));
- m_mediaRecorder->setVideoEncodingBitRate(settings.videoBitRate());
- m_mediaRecorder->setVideoEncoder(m_videoEncoder);
-
- m_mediaRecorder->setOrientationHint(m_cameraSession->currentCameraRotation());
- }
-
- QString extension = settings.mimeType().preferredSuffix();
-
- // Set output file
- auto location = outputLocation.toString(QUrl::PreferLocalFile);
- auto filePath = QMediaStorageLocation::generateFileName(
- location, m_cameraSession ? QStandardPaths::MoviesLocation : QStandardPaths::MusicLocation, extension);
-
- m_usedOutputLocation = QUrl::fromLocalFile(filePath);
- m_outputLocationIsStandard = location.isEmpty() || QFileInfo(location).isRelative();
- 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());
-
- m_cameraSession->disableRotation();
- }
-
- 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,
- QMediaRecorderPrivate::msgFailedStartRecording());
- 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);
-}
-
-void QAndroidCaptureSession::stop(bool error)
-{
- if (m_state == QMediaRecorder::StoppedState || m_mediaRecorder == 0)
- return;
-
- m_mediaRecorder->stop();
- m_notifyTimer.stop();
- updateDuration();
- m_elapsedTime.invalidate();
- m_mediaRecorder->release();
- delete m_mediaRecorder;
- m_mediaRecorder = 0;
-
- if (m_cameraSession && m_cameraSession->isActive()) {
- // 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.
- if (m_outputLocationIsStandard)
- AndroidMultimediaUtils::registerMediaFile(m_usedOutputLocation.toLocalFile());
-
- emit actualLocationChanged(m_usedOutputLocation);
- }
-
- m_state = QMediaRecorder::StoppedState;
- emit stateChanged(m_state);
-}
-
-qint64 QAndroidCaptureSession::duration() const
-{
- return m_duration;
-}
-
-void QAndroidCaptureSession::applySettings(QMediaEncoderSettings &settings)
-{
- // container settings
- auto fileFormat = settings.mediaFormat().fileFormat();
- if (!m_cameraSession && fileFormat == QMediaFormat::AAC) {
- m_outputFormat = AndroidMediaRecorder::AAC_ADTS;
- } else if (fileFormat == QMediaFormat::Ogg) {
- m_outputFormat = AndroidMediaRecorder::OGG;
- } else if (fileFormat == QMediaFormat::WebM) {
- m_outputFormat = AndroidMediaRecorder::WEBM;
-// } else if (fileFormat == QLatin1String("3gp")) {
-// m_outputFormat = AndroidMediaRecorder::THREE_GPP;
- } else {
- // fallback to MP4
- m_outputFormat = AndroidMediaRecorder::MPEG_4;
- }
-
- // audio settings
- if (settings.audioChannelCount() <= 0)
- settings.setAudioChannelCount(m_defaultSettings.audioChannels);
- if (settings.audioBitRate() <= 0)
- settings.setAudioBitRate(m_defaultSettings.audioBitRate);
- if (settings.audioSampleRate() <= 0)
- settings.setAudioSampleRate(m_defaultSettings.audioSampleRate);
-
- if (settings.audioCodec() == QMediaFormat::AudioCodec::AAC)
- m_audioEncoder = AndroidMediaRecorder::AAC;
- else if (settings.audioCodec() == QMediaFormat::AudioCodec::Opus)
- m_audioEncoder = AndroidMediaRecorder::OPUS;
- else if (settings.audioCodec() == QMediaFormat::AudioCodec::Vorbis)
- m_audioEncoder = AndroidMediaRecorder::VORBIS;
- else
- m_audioEncoder = m_defaultSettings.audioEncoder;
-
-
- // video settings
- if (m_cameraSession && m_cameraSession->camera()) {
- if (settings.videoResolution().isEmpty()) {
- settings.setVideoResolution(m_defaultSettings.videoResolution);
- } else if (!m_supportedResolutions.contains(settings.videoResolution())) {
- // if the requested resolution is not supported, find the closest one
- QSize reqSize = settings.videoResolution();
- 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);
- settings.setVideoResolution(m_supportedResolutions.at(closestIndex));
- }
-
- if (settings.videoFrameRate() <= 0)
- settings.setVideoFrameRate(m_defaultSettings.videoFrameRate);
- if (settings.videoBitRate() <= 0)
- settings.setVideoBitRate(m_defaultSettings.videoBitRate);
-
- if (settings.videoCodec() == QMediaFormat::VideoCodec::H264)
- m_videoEncoder = AndroidMediaRecorder::H264;
- else if (settings.videoCodec() == QMediaFormat::VideoCodec::H265)
- m_videoEncoder = AndroidMediaRecorder::HEVC;
- else if (settings.videoCodec() == QMediaFormat::VideoCodec::MPEG4)
- m_videoEncoder = AndroidMediaRecorder::MPEG_4_SP;
- else
- m_videoEncoder = m_defaultSettings.videoEncoder;
-
- }
-}
-
-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);
- m_cameraSession->enableRotation();
-}
-
-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());
-}
-
-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
- stop();
- emit error(QMediaRecorder::OutOfSpaceError, QLatin1String("Maximum duration reached."));
- } else if (what == 801) {
- // MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED
- stop();
- emit error(QMediaRecorder::OutOfSpaceError, QLatin1String("Maximum file size reached."));
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/mediacapture/qandroidcapturesession_p.h b/src/multimedia/platform/android/mediacapture/qandroidcapturesession_p.h
deleted file mode 100644
index 16b3c8481..000000000
--- a/src/multimedia/platform/android/mediacapture/qandroidcapturesession_p.h
+++ /dev/null
@@ -1,188 +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
-
-//
-// 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 <qobject.h>
-#include <qmediarecorder.h>
-#include <qurl.h>
-#include <qelapsedtimer.h>
-#include <qtimer.h>
-#include "androidmediarecorder_p.h"
-#include "qandroidmediaencoder_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QAudioInput;
-class QAndroidCameraSession;
-
-class QAndroidCaptureSession : public QObject
-{
- Q_OBJECT
-public:
- explicit QAndroidCaptureSession();
- ~QAndroidCaptureSession();
-
- QList<QSize> supportedResolutions() const { return m_supportedResolutions; }
- QList<qreal> supportedFrameRates() const { return m_supportedFramerates; }
-
- void setCameraSession(QAndroidCameraSession *cameraSession = 0);
- void setAudioInput(QPlatformAudioInput *input);
- void setAudioOutput(QPlatformAudioOutput *output);
-
- QMediaRecorder::RecorderState state() const;
-
- void start(QMediaEncoderSettings &settings, const QUrl &outputLocation);
- void stop(bool error = false);
-
- qint64 duration() const;
-
- QMediaEncoderSettings encoderSettings() { return m_encoderSettings; }
-
- void setMediaEncoder(QAndroidMediaEncoder *encoder) { m_mediaEncoder = encoder; }
-
- void stateChanged(QMediaRecorder::RecorderState state) {
- if (m_mediaEncoder)
- m_mediaEncoder->stateChanged(state);
- }
- void durationChanged(qint64 position)
- {
- if (m_mediaEncoder)
- m_mediaEncoder->durationChanged(position);
- }
- void actualLocationChanged(const QUrl &location)
- {
- if (m_mediaEncoder)
- m_mediaEncoder->actualLocationChanged(location);
- }
- void error(int error, const QString &errorString)
- {
- if (m_mediaEncoder)
- m_mediaEncoder->error(QMediaRecorder::Error(error), errorString);
- }
-
-private Q_SLOTS:
- void updateDuration();
- void onCameraOpened();
-
- void onError(int what, int extra);
- void onInfo(int what, int extra);
-
-private:
- void applySettings(QMediaEncoderSettings &settings);
-
- 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(1280, 720)
- , isNull(true)
- { }
- };
-
- CaptureProfile getProfile(int id);
-
- void restartViewfinder();
-
- QAndroidMediaEncoder *m_mediaEncoder = nullptr;
- AndroidMediaRecorder *m_mediaRecorder;
- QAndroidCameraSession *m_cameraSession;
-
- QPlatformAudioInput *m_audioInput = nullptr;
- QPlatformAudioOutput *m_audioOutput = nullptr;
-
- QElapsedTimer m_elapsedTime;
- QTimer m_notifyTimer;
- qint64 m_duration;
-
- QMediaRecorder::RecorderState m_state;
- QUrl m_usedOutputLocation;
- bool m_outputLocationIsStandard = false;
-
- CaptureProfile m_defaultSettings;
-
- QMediaEncoderSettings m_encoderSettings;
- AndroidMediaRecorder::OutputFormat m_outputFormat;
- AndroidMediaRecorder::AudioEncoder m_audioEncoder;
- AndroidMediaRecorder::VideoEncoder m_videoEncoder;
-
- QList<QSize> m_supportedResolutions;
- QList<qreal> m_supportedFramerates;
-
- QMetaObject::Connection m_connOpenCamera;
- QMetaObject::Connection m_connActiveChangedCamera;
-};
-
-QT_END_NAMESPACE
-
-#endif // QANDROIDCAPTURESESSION_H
diff --git a/src/multimedia/platform/android/mediacapture/qandroidimagecapture.cpp b/src/multimedia/platform/android/mediacapture/qandroidimagecapture.cpp
deleted file mode 100644
index 32e787290..000000000
--- a/src/multimedia/platform/android/mediacapture/qandroidimagecapture.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 "qandroidimagecapture_p.h"
-
-#include "qandroidcamerasession_p.h"
-#include "qandroidmediacapturesession_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QAndroidImageCapture::QAndroidImageCapture(QImageCapture *parent)
- : QPlatformImageCapture(parent)
-{
-}
-
-bool QAndroidImageCapture::isReadyForCapture() const
-{
- return m_session->isReadyForCapture();
-}
-
-int QAndroidImageCapture::capture(const QString &fileName)
-{
- return m_session->capture(fileName);
-}
-
-int QAndroidImageCapture::captureToBuffer()
-{
- // ### implement me!
- const QLatin1String errorMessage("Capturing to buffer not supported.");
- QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
- Q_ARG(int, -1),
- Q_ARG(int, QImageCapture::NotSupportedFeatureError),
- Q_ARG(QString, errorMessage));
- return -1;
-}
-
-QImageEncoderSettings QAndroidImageCapture::imageSettings() const
-{
- return m_session->imageSettings();
-}
-
-void QAndroidImageCapture::setImageSettings(const QImageEncoderSettings &settings)
-{
- m_session->setImageSettings(settings);
-}
-
-void QAndroidImageCapture::setCaptureSession(QPlatformMediaCaptureSession *session)
-{
- QAndroidMediaCaptureSession *captureSession = static_cast<QAndroidMediaCaptureSession *>(session);
- if (m_service == captureSession)
- return;
-
- m_service = captureSession;
- if (!m_service) {
- disconnect(m_session, nullptr, this, nullptr);
- return;
- }
-
- m_session = m_service->cameraSession();
- Q_ASSERT(m_session);
-
- connect(m_session, &QAndroidCameraSession::readyForCaptureChanged,
- this, &QAndroidImageCapture::readyForCaptureChanged);
- connect(m_session, &QAndroidCameraSession::imageExposed,
- this, &QAndroidImageCapture::imageExposed);
- connect(m_session, &QAndroidCameraSession::imageCaptured,
- this, &QAndroidImageCapture::imageCaptured);
- connect(m_session, &QAndroidCameraSession::imageMetadataAvailable,
- this, &QAndroidImageCapture::imageMetadataAvailable);
- connect(m_session, &QAndroidCameraSession::imageAvailable,
- this, &QAndroidImageCapture::imageAvailable);
- connect(m_session, &QAndroidCameraSession::imageSaved,
- this, &QAndroidImageCapture::imageSaved);
- connect(m_session, &QAndroidCameraSession::imageCaptureError,
- this, &QAndroidImageCapture::error);
-}
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/mediacapture/qandroidimagecapture_p.h b/src/multimedia/platform/android/mediacapture/qandroidimagecapture_p.h
deleted file mode 100644
index 83d15445f..000000000
--- a/src/multimedia/platform/android/mediacapture/qandroidimagecapture_p.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 QANDROIDCAMERAIMAGECAPTURECONTROL_H
-#define QANDROIDCAMERAIMAGECAPTURECONTROL_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 <private/qplatformimagecapture_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAndroidCameraSession;
-class QAndroidMediaCaptureSession;
-
-class QAndroidImageCapture : public QPlatformImageCapture
-{
- Q_OBJECT
-public:
- explicit QAndroidImageCapture(QImageCapture *parent = nullptr);
-
- bool isReadyForCapture() const override;
-
- int capture(const QString &fileName) override;
- int captureToBuffer() override;
-
- QImageEncoderSettings imageSettings() const override;
- void setImageSettings(const QImageEncoderSettings &settings) override;
-
- void setCaptureSession(QPlatformMediaCaptureSession *session);
-
-private:
- QAndroidCameraSession *m_session;
- QAndroidMediaCaptureSession *m_service;
-};
-
-QT_END_NAMESPACE
-
-#endif // QANDROIDCAMERAIMAGECAPTURECONTROL_H
diff --git a/src/multimedia/platform/android/mediacapture/qandroidmediacapturesession.cpp b/src/multimedia/platform/android/mediacapture/qandroidmediacapturesession.cpp
deleted file mode 100644
index 94207c8a9..000000000
--- a/src/multimedia/platform/android/mediacapture/qandroidmediacapturesession.cpp
+++ /dev/null
@@ -1,152 +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 "qandroidmediacapturesession_p.h"
-
-#include "qandroidmediaencoder_p.h"
-#include "qandroidcapturesession_p.h"
-#include "qandroidcamera_p.h"
-#include "qandroidcamerasession_p.h"
-#include "qandroidimagecapture_p.h"
-#include "qmediadevices.h"
-#include "qaudiodevice.h"
-
-QT_BEGIN_NAMESPACE
-
-QAndroidMediaCaptureSession::QAndroidMediaCaptureSession()
- : m_captureSession(new QAndroidCaptureSession())
- , m_cameraSession(new QAndroidCameraSession())
-{
-}
-
-QAndroidMediaCaptureSession::~QAndroidMediaCaptureSession()
-{
- delete m_encoder;
- delete m_captureSession;
- delete m_cameraControl;
- delete m_imageCaptureControl;
- delete m_cameraSession;
-}
-
-QPlatformCamera *QAndroidMediaCaptureSession::camera()
-{
- return m_cameraControl;
-}
-
-void QAndroidMediaCaptureSession::setCamera(QPlatformCamera *camera)
-{
- if (camera) {
- m_captureSession->setCameraSession(m_cameraSession);
- } else {
- m_captureSession->setCameraSession(nullptr);
- }
-
- QAndroidCamera *control = static_cast<QAndroidCamera *>(camera);
- if (m_cameraControl == control)
- return;
-
- if (m_cameraControl)
- m_cameraControl->setCaptureSession(nullptr);
-
- m_cameraControl = control;
- if (m_cameraControl)
- m_cameraControl->setCaptureSession(this);
-
- emit cameraChanged();
-}
-
-QPlatformImageCapture *QAndroidMediaCaptureSession::imageCapture()
-{
- return m_imageCaptureControl;
-}
-
-void QAndroidMediaCaptureSession::setImageCapture(QPlatformImageCapture *imageCapture)
-{
- QAndroidImageCapture *control = static_cast<QAndroidImageCapture *>(imageCapture);
- if (m_imageCaptureControl == control)
- return;
-
- if (m_imageCaptureControl)
- m_imageCaptureControl->setCaptureSession(nullptr);
-
- m_imageCaptureControl = control;
- if (m_imageCaptureControl)
- m_imageCaptureControl->setCaptureSession(this);
-}
-
-QPlatformMediaEncoder *QAndroidMediaCaptureSession::mediaEncoder()
-{
- return m_encoder;
-}
-
-void QAndroidMediaCaptureSession::setMediaEncoder(QPlatformMediaEncoder *encoder)
-{
- QAndroidMediaEncoder *control = static_cast<QAndroidMediaEncoder *>(encoder);
-
- if (m_encoder == control)
- return;
-
- if (m_encoder)
- m_encoder->setCaptureSession(nullptr);
-
- m_encoder = control;
- if (m_encoder)
- m_encoder->setCaptureSession(this);
-
- emit encoderChanged();
-
-}
-
-void QAndroidMediaCaptureSession::setAudioInput(QPlatformAudioInput *input)
-{
- m_captureSession->setAudioInput(input);
-}
-
-void QAndroidMediaCaptureSession::setAudioOutput(QPlatformAudioOutput *output)
-{
- m_captureSession->setAudioOutput(output);
-}
-
-void QAndroidMediaCaptureSession::setVideoPreview(QVideoSink *sink)
-{
- m_cameraSession->setVideoSink(sink);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/mediacapture/qandroidmediacapturesession_p.h b/src/multimedia/platform/android/mediacapture/qandroidmediacapturesession_p.h
deleted file mode 100644
index 667fbba7a..000000000
--- a/src/multimedia/platform/android/mediacapture/qandroidmediacapturesession_p.h
+++ /dev/null
@@ -1,102 +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
-
-//
-// 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 <private/qplatformmediacapture_p.h>
-#include <private/qplatformmediaintegration_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAndroidMediaEncoder;
-class QAndroidCaptureSession;
-class QAndroidCamera;
-class QAndroidCameraSession;
-class QAndroidImageCapture;
-
-class QAndroidMediaCaptureSession : public QPlatformMediaCaptureSession
-{
- Q_OBJECT
-
-public:
- explicit QAndroidMediaCaptureSession();
- virtual ~QAndroidMediaCaptureSession();
-
- QPlatformCamera *camera() override;
- void setCamera(QPlatformCamera *camera) override;
-
- QPlatformImageCapture *imageCapture() override;
- void setImageCapture(QPlatformImageCapture *imageCapture) override;
-
- QPlatformMediaEncoder *mediaEncoder() override;
- void setMediaEncoder(QPlatformMediaEncoder *encoder) override;
-
- void setAudioInput(QPlatformAudioInput *input) override;
-
- void setVideoPreview(QVideoSink *sink) override;
-
- void setAudioOutput(QPlatformAudioOutput *output) override;
-
- QAndroidCaptureSession *captureSession() const { return m_captureSession; }
- QAndroidCameraSession *cameraSession() const { return m_cameraSession; }
-
-private:
- QAndroidMediaEncoder *m_encoder = nullptr;
- QAndroidCaptureSession *m_captureSession = nullptr;
- QAndroidCamera *m_cameraControl = nullptr;
- QAndroidCameraSession *m_cameraSession = nullptr;
- QAndroidImageCapture *m_imageCaptureControl = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QANDROIDCAPTURESERVICE_H
diff --git a/src/multimedia/platform/android/mediacapture/qandroidmediaencoder.cpp b/src/multimedia/platform/android/mediacapture/qandroidmediaencoder.cpp
deleted file mode 100644
index 5e7ae990d..000000000
--- a/src/multimedia/platform/android/mediacapture/qandroidmediaencoder.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 "qandroidmediaencoder_p.h"
-#include "qandroidmultimediautils_p.h"
-#include "qandroidcapturesession_p.h"
-#include "qandroidmediacapturesession_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QAndroidMediaEncoder::QAndroidMediaEncoder(QMediaRecorder *parent)
- : QPlatformMediaEncoder(parent)
-{
-}
-
-bool QAndroidMediaEncoder::isLocationWritable(const QUrl &location) const
-{
- return location.isValid()
- && (location.isLocalFile() || location.isRelative());
-}
-
-QMediaRecorder::RecorderState QAndroidMediaEncoder::state() const
-{
- return m_session ? m_session->state() : QMediaRecorder::StoppedState;
-}
-
-qint64 QAndroidMediaEncoder::duration() const
-{
- return m_session ? m_session->duration() : 0;
-
-}
-
-void QAndroidMediaEncoder::record(QMediaEncoderSettings &settings)
-{
- if (m_session)
- m_session->start(settings, outputLocation());
-}
-
-void QAndroidMediaEncoder::stop()
-{
- if (m_session)
- m_session->stop();
-}
-
-void QAndroidMediaEncoder::setOutputLocation(const QUrl &location)
-{
- if (location.isLocalFile()) {
- qt_androidRequestWriteStoragePermission();
- }
- QPlatformMediaEncoder::setOutputLocation(location);
-}
-
-void QAndroidMediaEncoder::setCaptureSession(QPlatformMediaCaptureSession *session)
-{
- QAndroidMediaCaptureSession *captureSession = static_cast<QAndroidMediaCaptureSession *>(session);
- if (m_service == captureSession)
- return;
-
- if (m_service)
- stop();
- if (m_session)
- m_session->setMediaEncoder(nullptr);
-
- m_service = captureSession;
- if (!m_service)
- return;
- m_session = m_service->captureSession();
- Q_ASSERT(m_session);
- m_session->setMediaEncoder(this);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/mediacapture/qandroidmediaencoder_p.h b/src/multimedia/platform/android/mediacapture/qandroidmediaencoder_p.h
deleted file mode 100644
index 6c6160ca9..000000000
--- a/src/multimedia/platform/android/mediacapture/qandroidmediaencoder_p.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 QANDROIDMEDIAENCODER_H
-#define QANDROIDMEDIAENCODER_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 <private/qplatformmediaencoder_p.h>
-#include <private/qplatformmediacapture_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAndroidCaptureSession;
-class QAndroidMediaCaptureSession;
-
-class QAndroidMediaEncoder : public QPlatformMediaEncoder
-{
-public:
- explicit QAndroidMediaEncoder(QMediaRecorder *parent);
-
- bool isLocationWritable(const QUrl &location) const override;
- QMediaRecorder::RecorderState state() const override;
- qint64 duration() const override;
-
- void setCaptureSession(QPlatformMediaCaptureSession *session);
-
- void setOutputLocation(const QUrl &location) override;
- void record(QMediaEncoderSettings &settings) override;
- void stop() override;
-
-private:
- friend class QAndroidCaptureSession;
-
- QAndroidCaptureSession *m_session = nullptr;
- QAndroidMediaCaptureSession *m_service = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QANDROIDMEDIAENCODER_H
diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayer.cpp b/src/multimedia/platform/android/mediaplayer/qandroidmediaplayer.cpp
deleted file mode 100644
index 8ae49715e..000000000
--- a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayer.cpp
+++ /dev/null
@@ -1,983 +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 "qandroidmediaplayer_p.h"
-#include "androidmediaplayer_p.h"
-#include "qandroidvideooutput_p.h"
-#include "qandroidmetadata_p.h"
-#include "qandroidaudiooutput_p.h"
-#include "qaudiooutput.h"
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(lcMediaPlayer, "qt.multimedia.mediaplayer.android")
-
-class StateChangeNotifier
-{
-public:
- StateChangeNotifier(QAndroidMediaPlayer *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:
- QAndroidMediaPlayer *mControl;
- QMediaPlayer::PlaybackState mPreviousState;
- QMediaPlayer::MediaStatus mPreviousMediaStatus;
-};
-
-QAndroidMediaPlayer::QAndroidMediaPlayer(QMediaPlayer *parent)
- : QPlatformMediaPlayer(parent),
- mMediaPlayer(new AndroidMediaPlayer),
- mState(AndroidMediaPlayer::Uninitialized)
-{
- connect(mMediaPlayer, &AndroidMediaPlayer::bufferingChanged, this,
- &QAndroidMediaPlayer::onBufferingChanged);
- connect(mMediaPlayer, &AndroidMediaPlayer::info, this, &QAndroidMediaPlayer::onInfo);
- connect(mMediaPlayer, &AndroidMediaPlayer::error, this, &QAndroidMediaPlayer::onError);
- connect(mMediaPlayer, &AndroidMediaPlayer::stateChanged, this,
- &QAndroidMediaPlayer::onStateChanged);
- connect(mMediaPlayer, &AndroidMediaPlayer::videoSizeChanged, this,
- &QAndroidMediaPlayer::onVideoSizeChanged);
- connect(mMediaPlayer, &AndroidMediaPlayer::progressChanged, this,
- &QAndroidMediaPlayer::positionChanged);
- connect(mMediaPlayer, &AndroidMediaPlayer::durationChanged, this,
- &QAndroidMediaPlayer::durationChanged);
- connect(mMediaPlayer, &AndroidMediaPlayer::tracksInfoChanged, this,
- &QAndroidMediaPlayer::updateTrackInfo);
-}
-
-QAndroidMediaPlayer::~QAndroidMediaPlayer()
-{
- mMediaPlayer->release();
- delete mMediaPlayer;
-}
-
-qint64 QAndroidMediaPlayer::duration() const
-{
- if ((mState & (AndroidMediaPlayer::Prepared
- | AndroidMediaPlayer::Started
- | AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::Stopped
- | AndroidMediaPlayer::PlaybackCompleted)) == 0) {
- return 0;
- }
-
- return mMediaPlayer->getDuration();
-}
-
-qint64 QAndroidMediaPlayer::position() const
-{
- if (mediaStatus() == QMediaPlayer::EndOfMedia)
- return duration();
-
- if ((mState & (AndroidMediaPlayer::Prepared
- | AndroidMediaPlayer::Started
- | AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::PlaybackCompleted))) {
- return mMediaPlayer->getCurrentPosition();
- }
-
- return (mPendingPosition == -1) ? 0 : mPendingPosition;
-}
-
-void QAndroidMediaPlayer::setPosition(qint64 position)
-{
- if (!isSeekable())
- return;
-
- const int seekPosition = (position > INT_MAX) ? INT_MAX : position;
-
- if (seekPosition == this->position())
- return;
-
- StateChangeNotifier notifier(this);
-
- if (mediaStatus() == 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);
-}
-
-void QAndroidMediaPlayer::setVolume(float volume)
-{
- if ((mState & (AndroidMediaPlayer::Idle
- | AndroidMediaPlayer::Initialized
- | AndroidMediaPlayer::Stopped
- | AndroidMediaPlayer::Prepared
- | AndroidMediaPlayer::Started
- | AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::PlaybackCompleted)) == 0) {
- mPendingVolume = volume;
- return;
- }
-
- mMediaPlayer->setVolume(qRound(volume*100.));
- mPendingVolume = -1;
-}
-
-void QAndroidMediaPlayer::setMuted(bool muted)
-{
- if ((mState & (AndroidMediaPlayer::Idle
- | AndroidMediaPlayer::Initialized
- | AndroidMediaPlayer::Stopped
- | AndroidMediaPlayer::Prepared
- | AndroidMediaPlayer::Started
- | AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::PlaybackCompleted)) == 0) {
- mPendingMute = muted;
- return;
- }
-
- mMediaPlayer->setMuted(muted);
- mPendingMute = -1;
-}
-
-QMediaMetaData QAndroidMediaPlayer::metaData() const
-{
- return QAndroidMetaData::extractMetadata(mMediaContent);
-}
-
-float QAndroidMediaPlayer::bufferProgress() const
-{
- return mBufferFilled ? 1. : 0;
-}
-
-bool QAndroidMediaPlayer::isAudioAvailable() const
-{
- return mAudioAvailable;
-}
-
-bool QAndroidMediaPlayer::isVideoAvailable() const
-{
- return mVideoAvailable;
-}
-
-QMediaTimeRange QAndroidMediaPlayer::availablePlaybackRanges() const
-{
- return mAvailablePlaybackRange;
-}
-
-void QAndroidMediaPlayer::updateAvailablePlaybackRanges()
-{
- if (mBuffering) {
- const qint64 pos = position();
- const qint64 end = (duration() / 100) * mBufferPercent;
- mAvailablePlaybackRange.addInterval(pos, end);
- } else if (isSeekable()) {
- mAvailablePlaybackRange = QMediaTimeRange(0, duration());
- } else {
- mAvailablePlaybackRange = QMediaTimeRange();
- }
-
-// #### Q_EMIT availablePlaybackRangesChanged(mAvailablePlaybackRange);
-}
-
-qreal QAndroidMediaPlayer::playbackRate() const
-{
- if (mHasPendingPlaybackRate ||
- (mState & (AndroidMediaPlayer::Initialized
- | AndroidMediaPlayer::Prepared
- | AndroidMediaPlayer::Started
- | AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::PlaybackCompleted
- | AndroidMediaPlayer::Error)) == 0) {
- return mPendingPlaybackRate;
- }
-
- return mMediaPlayer->playbackRate();
-}
-
-void QAndroidMediaPlayer::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 QAndroidMediaPlayer::media() const
-{
- return mMediaContent;
-}
-
-const QIODevice *QAndroidMediaPlayer::mediaStream() const
-{
- return mMediaStream;
-}
-
-void QAndroidMediaPlayer::setMedia(const QUrl &mediaContent,
- QIODevice *stream)
-{
- StateChangeNotifier notifier(this);
-
- mReloadingMedia = (mMediaContent == mediaContent) && !mPendingSetMedia;
-
- if (!mReloadingMedia) {
- mMediaContent = mediaContent;
- mMediaStream = stream;
- }
-
- if (mediaContent.isEmpty()) {
- 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(QNetworkRequest(mediaContent));
- mMediaPlayer->prepareAsync();
- }
-
- resetBufferingProgress();
-
- mReloadingMedia = false;
-}
-
-void QAndroidMediaPlayer::setVideoSink(QVideoSink *sink)
-{
- if (m_videoSink == sink)
- return;
-
- m_videoSink = sink;
-
- if (!m_videoSink) {
- return;
- }
-
- if (mVideoOutput) {
- delete mVideoOutput;
- mVideoOutput = nullptr;
- mMediaPlayer->setDisplay(nullptr);
- }
-
- mVideoOutput = new QAndroidTextureVideoOutput(this);
- connect(mVideoOutput, &QAndroidTextureVideoOutput::readyChanged, this,
- &QAndroidMediaPlayer::onVideoOutputReady);
- connect(mMediaPlayer, &AndroidMediaPlayer::timedTextChanged, mVideoOutput,
- &QAndroidTextureVideoOutput::setSubtitle);
-
- mVideoOutput->setSurface(sink);
-
- if (mVideoOutput->isReady())
- mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture());
-}
-
-void QAndroidMediaPlayer::setAudioOutput(QPlatformAudioOutput *output)
-{
- if (m_audioOutput == output)
- return;
- if (m_audioOutput)
- m_audioOutput->q->disconnect(this);
- m_audioOutput = static_cast<QAndroidAudioOutput *>(output);
- if (m_audioOutput) {
- connect(m_audioOutput->q, &QAudioOutput::deviceChanged, this, &QAndroidMediaPlayer::updateAudioDevice);
- connect(m_audioOutput->q, &QAudioOutput::volumeChanged, this, &QAndroidMediaPlayer::setVolume);
- connect(m_audioOutput->q, &QAudioOutput::mutedChanged, this, &QAndroidMediaPlayer::setMuted);
- updateAudioDevice();
- }
-}
-
-void QAndroidMediaPlayer::updateAudioDevice()
-{
- if (m_audioOutput)
- mMediaPlayer->setAudioOutput(m_audioOutput->device.id());
-}
-
-void QAndroidMediaPlayer::play()
-{
- StateChangeNotifier notifier(this);
-
- // We need to prepare the mediaplayer again.
- if ((mState & AndroidMediaPlayer::Stopped) && !mMediaContent.isEmpty()) {
- setMedia(mMediaContent, mMediaStream);
- }
-
- if (!mMediaContent.isEmpty())
- stateChanged(QMediaPlayer::PlayingState);
-
- if ((mState & (AndroidMediaPlayer::Prepared
- | AndroidMediaPlayer::Started
- | AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::PlaybackCompleted)) == 0) {
- mPendingState = QMediaPlayer::PlayingState;
- return;
- }
-
- mMediaPlayer->play();
-}
-
-void QAndroidMediaPlayer::pause()
-{
- StateChangeNotifier notifier(this);
-
- stateChanged(QMediaPlayer::PausedState);
-
- if ((mState & (AndroidMediaPlayer::Started
- | AndroidMediaPlayer::Paused
- | AndroidMediaPlayer::PlaybackCompleted)) == 0) {
- mPendingState = QMediaPlayer::PausedState;
- return;
- }
-
- mMediaPlayer->pause();
-}
-
-void QAndroidMediaPlayer::stop()
-{
- StateChangeNotifier notifier(this);
-
- stateChanged(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();
-}
-
-bool QAndroidMediaPlayer::isSeekable() const
-{
- return true;
-}
-
-void QAndroidMediaPlayer::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 = state();
- stateChanged(QMediaPlayer::PausedState);
- setMediaStatus(QMediaPlayer::StalledMedia);
- break;
- case AndroidMediaPlayer::MEDIA_INFO_BUFFERING_END:
- if (state() != QMediaPlayer::StoppedState)
- flushPendingStates();
- break;
- case AndroidMediaPlayer::MEDIA_INFO_BAD_INTERLEAVING:
- break;
- case AndroidMediaPlayer::MEDIA_INFO_NOT_SEEKABLE:
- seekableChanged(false);
- break;
- case AndroidMediaPlayer::MEDIA_INFO_METADATA_UPDATE:
- Q_EMIT metaDataChanged();
- break;
- }
-}
-
-void QAndroidMediaPlayer::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::ResourceError;
- break;
- case AndroidMediaPlayer::MEDIA_ERROR_INVALID_STATE:
- errorString = QLatin1String("Error: Invalid state");
- error = QMediaPlayer::ResourceError;
- 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::ResourceError;
- break;
- }
-
- Q_EMIT QPlatformMediaPlayer::error(error, errorString);
-}
-
-void QAndroidMediaPlayer::onBufferingChanged(qint32 percent)
-{
- StateChangeNotifier notifier(this);
-
- mBuffering = percent != 100;
- mBufferPercent = percent;
-
- updateAvailablePlaybackRanges();
-
- if (state() != QMediaPlayer::StoppedState)
- setMediaStatus(mBuffering ? QMediaPlayer::BufferingMedia : QMediaPlayer::BufferedMedia);
-}
-
-void QAndroidMediaPlayer::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 QAndroidMediaPlayer::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 metaDataChanged();
- setAudioAvailable(true);
- flushPendingStates();
- break;
- case AndroidMediaPlayer::Started:
- stateChanged(QMediaPlayer::PlayingState);
- if (mBuffering) {
- setMediaStatus(mBufferPercent == 100 ? QMediaPlayer::BufferedMedia
- : QMediaPlayer::BufferingMedia);
- } else {
- setMediaStatus(QMediaPlayer::BufferedMedia);
- }
- Q_EMIT positionChanged(position());
- break;
- case AndroidMediaPlayer::Paused:
- stateChanged(QMediaPlayer::PausedState);
- break;
- case AndroidMediaPlayer::Error:
- stateChanged(QMediaPlayer::StoppedState);
- setMediaStatus(QMediaPlayer::InvalidMedia);
- mMediaPlayer->release();
- Q_EMIT positionChanged(0);
- break;
- case AndroidMediaPlayer::Stopped:
- stateChanged(QMediaPlayer::StoppedState);
- setMediaStatus(QMediaPlayer::LoadedMedia);
- Q_EMIT positionChanged(0);
- break;
- case AndroidMediaPlayer::PlaybackCompleted:
- stateChanged(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);
- seekableChanged(true);
- }
- break;
- default:
- break;
- }
-
- if ((mState & (AndroidMediaPlayer::Stopped | AndroidMediaPlayer::Uninitialized)) != 0) {
- mMediaPlayer->setDisplay(0);
- if (mVideoOutput) {
- mVideoOutput->stop();
- mVideoOutput->reset();
- }
- }
-}
-
-int QAndroidMediaPlayer::trackCount(TrackType trackType)
-{
- if (!mTracksMetadata.contains(trackType))
- return -1;
-
- auto tracks = mTracksMetadata.value(trackType);
- return tracks.count();
-}
-
-QMediaMetaData QAndroidMediaPlayer::trackMetaData(TrackType trackType, int streamNumber)
-{
- if (!mTracksMetadata.contains(trackType))
- return QMediaMetaData();
-
- auto tracks = mTracksMetadata.value(trackType);
- if (tracks.count() < streamNumber)
- return QMediaMetaData();
-
- QAndroidMetaData trackInfo = tracks.at(streamNumber);
- return static_cast<QMediaMetaData>(trackInfo);
-}
-
-QPlatformMediaPlayer::TrackType convertTrackType(AndroidMediaPlayer::TrackType type)
-{
- switch (type) {
- case AndroidMediaPlayer::TrackType::Video:
- return QPlatformMediaPlayer::TrackType::VideoStream;
- case AndroidMediaPlayer::TrackType::Audio:
- return QPlatformMediaPlayer::TrackType::AudioStream;
- case AndroidMediaPlayer::TrackType::TimedText:
- return QPlatformMediaPlayer::TrackType::SubtitleStream;
- case AndroidMediaPlayer::TrackType::Subtitle:
- return QPlatformMediaPlayer::TrackType::SubtitleStream;
- case AndroidMediaPlayer::TrackType::Unknown:
- case AndroidMediaPlayer::TrackType::Metadata:
- return QPlatformMediaPlayer::TrackType::NTrackTypes;
- }
-
- return QPlatformMediaPlayer::TrackType::NTrackTypes;
-}
-
-int QAndroidMediaPlayer::convertTrackNumber(int androidTrackNumber)
-{
- int trackNumber = androidTrackNumber;
-
- int videoTrackCount = trackCount(QPlatformMediaPlayer::TrackType::VideoStream);
- if (trackNumber <= videoTrackCount)
- return trackNumber;
-
- trackNumber = trackNumber - videoTrackCount;
-
- int audioTrackCount = trackCount(QPlatformMediaPlayer::TrackType::AudioStream);
- if (trackNumber <= audioTrackCount)
- return trackNumber;
-
- trackNumber = trackNumber - audioTrackCount;
-
- auto subtitleTracks = mTracksMetadata.value(QPlatformMediaPlayer::TrackType::SubtitleStream);
- int timedTextCount = 0;
- int subtitleTextCount = 0;
- for (const auto &track : subtitleTracks) {
- if (track.androidTrackType() == 3) // 3 == TimedText
- timedTextCount++;
-
- if (track.androidTrackType() == 4) // 4 == Subtitle
- subtitleTextCount++;
- }
-
- if (trackNumber <= timedTextCount)
- return trackNumber;
-
- trackNumber = trackNumber - timedTextCount;
-
- if (trackNumber <= subtitleTextCount)
- return trackNumber;
-
- return -1;
-}
-
-int QAndroidMediaPlayer::activeTrack(TrackType trackType)
-{
- int androidTrackNumber = -1;
-
- switch (trackType) {
- case QPlatformMediaPlayer::TrackType::VideoStream: {
- if (!mIsVideoTrackEnabled)
- return -1;
- androidTrackNumber = mMediaPlayer->activeTrack(AndroidMediaPlayer::TrackType::Video);
- }
- case QPlatformMediaPlayer::TrackType::AudioStream: {
- if (!mIsAudioTrackEnabled)
- return -1;
-
- androidTrackNumber = mMediaPlayer->activeTrack(AndroidMediaPlayer::TrackType::Audio);
- }
- case QPlatformMediaPlayer::TrackType::SubtitleStream: {
- int timedTextSelectedTrack =
- mMediaPlayer->activeTrack(AndroidMediaPlayer::TrackType::TimedText);
-
- if (timedTextSelectedTrack > -1) {
- androidTrackNumber = timedTextSelectedTrack;
- break;
- }
-
- int subtitleSelectedTrack =
- mMediaPlayer->activeTrack(AndroidMediaPlayer::TrackType::Subtitle);
- if (subtitleSelectedTrack > -1) {
- androidTrackNumber = subtitleSelectedTrack;
- break;
- }
-
- return -1;
- }
- case QPlatformMediaPlayer::TrackType::NTrackTypes:
- return -1;
- }
-
- return convertTrackNumber(androidTrackNumber);
-}
-
-void QAndroidMediaPlayer::disableTrack(TrackType trackType)
-{
- const auto track = activeTrack(trackType);
-
- switch (trackType) {
- case VideoStream: {
- if (track > -1) {
- mMediaPlayer->setDisplay(nullptr);
- mIsVideoTrackEnabled = false;
- }
- break;
- }
- case AudioStream: {
- if (track > -1) {
- mMediaPlayer->setMuted(true);
- mMediaPlayer->blockAudio();
- mIsAudioTrackEnabled = false;
- }
- break;
- }
- case SubtitleStream: {
- // subtitles and timedtext tracks can be selected at the same time so deselect both
- int subtitleSelectedTrack =
- mMediaPlayer->activeTrack(AndroidMediaPlayer::TrackType::Subtitle);
- if (subtitleSelectedTrack > -1)
- mMediaPlayer->deselectTrack(subtitleSelectedTrack);
-
- int timedTextSelectedTrack =
- mMediaPlayer->activeTrack(AndroidMediaPlayer::TrackType::TimedText);
- if (timedTextSelectedTrack > -1)
- mMediaPlayer->deselectTrack(timedTextSelectedTrack);
-
- break;
- }
- case NTrackTypes:
- break;
- }
-}
-
-void QAndroidMediaPlayer::setActiveTrack(TrackType trackType, int streamNumber)
-{
-
- if (!mTracksMetadata.contains(trackType)) {
- qCWarning(lcMediaPlayer)
- << "Trying to set a active track which type has no available tracks.";
- return;
- }
-
- const auto &tracks = mTracksMetadata.value(trackType);
- if (streamNumber > tracks.count()) {
- qCWarning(lcMediaPlayer) << "Trying to set a active track that does not exist.";
- return;
- }
-
- // in case of < 0 deselect tracktype
- if (streamNumber < 0) {
- disableTrack(trackType);
- return;
- }
-
- const auto currentTrack = activeTrack(trackType);
- if (streamNumber == currentTrack) {
- return;
- }
-
- if (trackType == TrackType::VideoStream && !mIsVideoTrackEnabled) {
- // enable video stream
- mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture());
- mIsVideoTrackEnabled = true;
- }
-
- if (trackType == TrackType::AudioStream && !mIsAudioTrackEnabled) {
- // enable audio stream
- mMediaPlayer->unblockAudio();
- mMediaPlayer->setMuted(false);
- mIsAudioTrackEnabled = true;
- }
-
- if (trackType == TrackType::SubtitleStream) {
- // subtitles and timedtext tracks can be selected at the same time so deselect both before
- // selecting a new one
- disableTrack(TrackType::SubtitleStream);
- }
-
- const auto &trackInfo = tracks.at(streamNumber);
- const auto &trackNumber = trackInfo.androidTrackNumber();
- mMediaPlayer->selectTrack(trackNumber);
-}
-
-void QAndroidMediaPlayer::positionChanged(qint64 position)
-{
- QPlatformMediaPlayer::positionChanged(position);
-}
-
-void QAndroidMediaPlayer::durationChanged(qint64 duration)
-{
- QPlatformMediaPlayer::durationChanged(duration);
-}
-
-void QAndroidMediaPlayer::onVideoOutputReady(bool ready)
-{
- if ((mMediaPlayer->display() == 0) && mVideoOutput && ready)
- mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture());
-
- flushPendingStates();
-}
-
-void QAndroidMediaPlayer::setMediaStatus(QMediaPlayer::MediaStatus status)
-{
- mediaStatusChanged(status);
-
- if (status == QMediaPlayer::NoMedia || status == QMediaPlayer::InvalidMedia)
- Q_EMIT durationChanged(0);
-
- if (status == QMediaPlayer::EndOfMedia)
- Q_EMIT positionChanged(position());
-
- updateBufferStatus();
-}
-
-void QAndroidMediaPlayer::setAudioAvailable(bool available)
-{
- if (mAudioAvailable == available)
- return;
-
- mAudioAvailable = available;
- Q_EMIT audioAvailableChanged(mAudioAvailable);
-}
-
-void QAndroidMediaPlayer::setVideoAvailable(bool available)
-{
- if (mVideoAvailable == available)
- return;
-
- if (!available)
- mVideoSize = QSize();
-
- mVideoAvailable = available;
- Q_EMIT videoAvailableChanged(mVideoAvailable);
-}
-
-void QAndroidMediaPlayer::resetBufferingProgress()
-{
- mBuffering = false;
- mBufferPercent = 0;
- mAvailablePlaybackRange = QMediaTimeRange();
-}
-
-void QAndroidMediaPlayer::flushPendingStates()
-{
- if (mPendingSetMedia) {
- setMedia(mMediaContent, 0);
- mPendingSetMedia = false;
- return;
- }
-
- const int newState = mPendingState;
- mPendingState = -1;
-
- if (mPendingPosition != -1)
- setPosition(mPendingPosition);
- if (mPendingVolume >= 0)
- 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 QAndroidMediaPlayer::updateBufferStatus()
-{
- const auto &status = mediaStatus();
- bool bufferFilled = (status == QMediaPlayer::BufferedMedia || status == QMediaPlayer::BufferingMedia);
-
- if (mBufferFilled != bufferFilled) {
- mBufferFilled = bufferFilled;
- Q_EMIT bufferProgressChanged(bufferProgress());
- }
-}
-
-void QAndroidMediaPlayer::updateTrackInfo()
-{
- const auto &androidTracksInfo = mMediaPlayer->tracksInfo();
-
- // prepare mTracksMetadata
- mTracksMetadata[TrackType::VideoStream] = QList<QAndroidMetaData>();
- mTracksMetadata[TrackType::AudioStream] = QList<QAndroidMetaData>();
- mTracksMetadata[TrackType::SubtitleStream] = QList<QAndroidMetaData>();
- mTracksMetadata[TrackType::NTrackTypes] = QList<QAndroidMetaData>();
-
- for (const auto &androidTrackInfo : androidTracksInfo) {
-
- const auto &mediaPlayerType = convertTrackType(androidTrackInfo.trackType);
- auto &tracks = mTracksMetadata[mediaPlayerType];
-
- const QAndroidMetaData metadata(mediaPlayerType, androidTrackInfo.trackType,
- androidTrackInfo.trackNumber, androidTrackInfo.mimeType,
- androidTrackInfo.language);
- tracks.append(metadata);
- }
-
- emit tracksChanged();
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayer_p.h b/src/multimedia/platform/android/mediaplayer/qandroidmediaplayer_p.h
deleted file mode 100644
index b8e187a08..000000000
--- a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayer_p.h
+++ /dev/null
@@ -1,164 +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
-
-//
-// 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 <qglobal.h>
-#include <private/qplatformmediaplayer_p.h>
-#include <private/qandroidmetadata_p.h>
-#include <qsize.h>
-#include <qurl.h>
-
-QT_BEGIN_NAMESPACE
-
-class AndroidMediaPlayer;
-class QAndroidTextureVideoOutput;
-class QAndroidMediaPlayerVideoRendererControl;
-class QAndroidAudioOutput;
-
-class QAndroidMediaPlayer : public QObject, public QPlatformMediaPlayer
-{
- Q_OBJECT
-
-public:
- explicit QAndroidMediaPlayer(QMediaPlayer *parent = 0);
- ~QAndroidMediaPlayer() override;
-
- qint64 duration() const override;
- qint64 position() const override;
- float bufferProgress() const override;
- bool isAudioAvailable() const override;
- bool isVideoAvailable() 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;
-
- QMediaMetaData metaData() const override;
-
- void setVideoSink(QVideoSink *surface) override;
-
- void setAudioOutput(QPlatformAudioOutput *output) override;
- void updateAudioDevice();
-
- void setPosition(qint64 position) override;
- void play() override;
- void pause() override;
- void stop() override;
-
- bool isSeekable() const override;
-
- int trackCount(TrackType trackType) override;
- QMediaMetaData trackMetaData(TrackType trackType, int streamNumber) override;
- int activeTrack(TrackType trackType) override;
- void setActiveTrack(TrackType trackType, int streamNumber) override;
-
-private Q_SLOTS:
- void setVolume(float volume);
- void setMuted(bool muted);
- 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);
- void positionChanged(qint64 position);
- void durationChanged(qint64 duration);
-
-private:
- AndroidMediaPlayer *mMediaPlayer = nullptr;
- QAndroidAudioOutput *m_audioOutput = nullptr;
- QUrl mMediaContent;
- QIODevice *mMediaStream = nullptr;
- QAndroidTextureVideoOutput *mVideoOutput = nullptr;
- QVideoSink *m_videoSink = nullptr;
- int mBufferPercent = -1;
- bool mBufferFilled = false;
- bool mAudioAvailable = false;
- bool mVideoAvailable = false;
- QSize mVideoSize;
- bool mBuffering = false;
- QMediaTimeRange mAvailablePlaybackRange;
- int mState;
- int mPendingState = -1;
- qint64 mPendingPosition = -1;
- bool mPendingSetMedia = false;
- float mPendingVolume = -1;
- int mPendingMute = -1;
- bool mReloadingMedia = false;
- int mActiveStateChangeNotifiers = 0;
- qreal mPendingPlaybackRate = 1.;
- bool mHasPendingPlaybackRate = false; // we need this because the rate can theoretically be negative
- QMap<TrackType, QList<QAndroidMetaData>> mTracksMetadata;
-
- bool mIsVideoTrackEnabled = true;
- bool mIsAudioTrackEnabled = true;
-
- void setMediaStatus(QMediaPlayer::MediaStatus status);
- void setAudioAvailable(bool available);
- void setVideoAvailable(bool available);
- void updateAvailablePlaybackRanges();
- void resetBufferingProgress();
- void flushPendingStates();
- void updateBufferStatus();
- void updateTrackInfo();
- void setSubtitle(QString subtitle);
- void disableTrack(TrackType trackType);
-
- int convertTrackNumber(int androidTrackNumber);
- friend class StateChangeNotifier;
-};
-
-QT_END_NAMESPACE
-
-#endif // QANDROIDMEDIAPLAYERCONTROL_H
diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmetadata.cpp b/src/multimedia/platform/android/mediaplayer/qandroidmetadata.cpp
deleted file mode 100644
index 059b62b52..000000000
--- a/src/multimedia/platform/android/mediaplayer/qandroidmetadata.cpp
+++ /dev/null
@@ -1,202 +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 "qandroidmetadata_p.h"
-
-#include "androidmediametadataretriever_p.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"
-};
-
-QMediaMetaData QAndroidMetaData::extractMetadata(const QUrl &url)
-{
- QMediaMetaData metadata;
-
- if (!url.isEmpty()) {
- AndroidMediaMetadataRetriever retriever;
- if (!retriever.setDataSource(url))
- return metadata;
-
- 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(QLatin1Char('/'), Qt::SkipEmptyParts));
- }
-
- string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Author);
- if (!string.isNull())
- metadata.insert(QMediaMetaData::Author, string.split(QLatin1Char('/'), 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(QLatin1Char('/'), 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(QLatin1Char('(')) && string.endsWith(QLatin1Char(')'))) {
- 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));
-
- }
-
- return metadata;
-}
-
-QLocale::Language getLocaleLanguage(const QString &language)
-{
- // undefined language or uncoded language
- if (language == QLatin1String("und") || language == QStringLiteral("mis"))
- return QLocale::AnyLanguage;
-
- QLocale locale(language);
- if (locale != QLocale::c())
- return locale.language();
-
- return QLocale::codeToLanguage(language.left(2));
-}
-
-QAndroidMetaData::QAndroidMetaData(int trackType, int androidTrackType, int androidTrackNumber,
- const QString &mimeType, const QString &language)
- : mTrackType(trackType),
- mAndroidTrackType(androidTrackType),
- mAndroidTrackNumber(androidTrackNumber)
-{
- insert(QMediaMetaData::MediaType, mimeType);
- insert(QMediaMetaData::Language, getLocaleLanguage(language));
-}
-
-int QAndroidMetaData::trackType() const
-{
- return mTrackType;
-}
-
-int QAndroidMetaData::androidTrackType() const
-{
- return mAndroidTrackType;
-}
-
-int QAndroidMetaData::androidTrackNumber() const
-{
- return mAndroidTrackNumber;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmetadata_p.h b/src/multimedia/platform/android/mediaplayer/qandroidmetadata_p.h
deleted file mode 100644
index 812edb062..000000000
--- a/src/multimedia/platform/android/mediaplayer/qandroidmetadata_p.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 QANDROIDMETADATA_H
-#define QANDROIDMETADATA_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 <qmediametadata.h>
-#include <qurl.h>
-#include <QMutex>
-#include <QVariant>
-
-QT_BEGIN_NAMESPACE
-
-class AndroidMediaMetadataRetriever;
-
-class QAndroidMetaData : public QMediaMetaData
-{
-public:
- static QMediaMetaData extractMetadata(const QUrl &url);
-
- QAndroidMetaData(int trackType, int androidTrackType, int androidTrackNumber,
- const QString &mimeType, const QString &language);
-
- int trackType() const;
- int androidTrackType() const;
- int androidTrackNumber() const;
-
-private:
- int mTrackType;
- int mAndroidTrackType;
- int mAndroidTrackNumber;
-};
-
-QT_END_NAMESPACE
-
-#endif // QANDROIDMETADATA_H
diff --git a/src/multimedia/platform/android/qandroidformatsinfo.cpp b/src/multimedia/platform/android/qandroidformatsinfo.cpp
deleted file mode 100644
index c45610b69..000000000
--- a/src/multimedia/platform/android/qandroidformatsinfo.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qandroidformatsinfo_p.h"
-
-#include <qcoreapplication.h>
-
-QT_BEGIN_NAMESPACE
-
-QAndroidFormatInfo::QAndroidFormatInfo()
-{
- // Audio/Video/Image formats with their decoder/encoder information is documented at
- // https://developer.android.com/guide/topics/media/media-formats
- decoders = {
- { QMediaFormat::AAC, { QMediaFormat::AudioCodec::AAC }, {} },
- { QMediaFormat::MP3, { QMediaFormat::AudioCodec::MP3}, {} },
- { QMediaFormat::Ogg, { QMediaFormat::AudioCodec::Opus, QMediaFormat::AudioCodec::Vorbis },
- {} },
- { QMediaFormat::FLAC, { QMediaFormat::AudioCodec::FLAC }, {} },
- { QMediaFormat::Mpeg4Audio, { QMediaFormat::AudioCodec::AAC, QMediaFormat::AudioCodec::FLAC,
- QMediaFormat::AudioCodec::MP3, QMediaFormat::AudioCodec::Vorbis},
- {} },
- { QMediaFormat::MPEG4, { QMediaFormat::AudioCodec::MP3, QMediaFormat::AudioCodec::AAC,
- QMediaFormat::AudioCodec::FLAC, QMediaFormat::AudioCodec::Vorbis },
- { QMediaFormat::VideoCodec::H264, QMediaFormat::VideoCodec::H265,
- QMediaFormat::VideoCodec::AV1 } },
- { QMediaFormat::Matroska, { QMediaFormat::AudioCodec::MP3, QMediaFormat::AudioCodec::Opus,
- QMediaFormat::AudioCodec::Vorbis },
- { QMediaFormat::VideoCodec::VP8, QMediaFormat::VideoCodec::VP9,
- QMediaFormat::VideoCodec::H264, QMediaFormat::VideoCodec::H265,
- QMediaFormat::VideoCodec::AV1} },
- { QMediaFormat::WebM, { QMediaFormat::AudioCodec::Opus, QMediaFormat::AudioCodec::Vorbis },
- { QMediaFormat::VideoCodec::VP8, QMediaFormat::VideoCodec::VP9} }
- };
-
- // MP3 encoders doesn't seem to be supported by the default Android SDK
- encoders = {
- { QMediaFormat::AAC, { QMediaFormat::AudioCodec::AAC }, {} },
- { QMediaFormat::MP3, {}, {} },
- { QMediaFormat::FLAC, { QMediaFormat::AudioCodec::FLAC }, {} },
- { QMediaFormat::Mpeg4Audio, {QMediaFormat::AudioCodec::AAC, QMediaFormat::AudioCodec::FLAC},
- {} },
- { QMediaFormat::MPEG4, { QMediaFormat::AudioCodec::AAC, QMediaFormat::AudioCodec::FLAC },
- { QMediaFormat::VideoCodec::H264 } }
- };
-
- // Opus encoder available only for Android 10+
- if (QNativeInterface::QAndroidApplication::sdkVersion() >= 29) {
- encoders.append({ QMediaFormat::Ogg, { QMediaFormat::AudioCodec::Opus }, {} });
- encoders.append({ QMediaFormat::Matroska, { QMediaFormat::AudioCodec::MP3,
- QMediaFormat::AudioCodec::Opus },
- { QMediaFormat::VideoCodec::VP8, QMediaFormat::VideoCodec::H264 } });
- encoders.append({ QMediaFormat::WebM, { QMediaFormat::AudioCodec::Opus },
- { QMediaFormat::VideoCodec::VP8 } });
- } else {
- encoders.append({ QMediaFormat::Ogg, {}, {} });
- encoders.append({ QMediaFormat::Matroska, { QMediaFormat::AudioCodec::MP3 },
- { QMediaFormat::VideoCodec::VP8, QMediaFormat::VideoCodec::H264 } });
- encoders.append({ QMediaFormat::WebM, {}, { QMediaFormat::VideoCodec::VP8 } });
- }
-
- imageFormats << QImageCapture::JPEG << QImageCapture::PNG << QImageCapture::WebP;
-}
-
-QAndroidFormatInfo::~QAndroidFormatInfo()
-{
-
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/qandroidformatsinfo_p.h b/src/multimedia/platform/android/qandroidformatsinfo_p.h
deleted file mode 100644
index 8810bb863..000000000
--- a/src/multimedia/platform/android/qandroidformatsinfo_p.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QANDROIDFORMATINFO_H
-#define QANDROIDFORMATINFO_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 <private/qplatformmediaformatinfo_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAndroidFormatInfo : public QPlatformMediaFormatInfo
-{
-public:
- QAndroidFormatInfo();
- ~QAndroidFormatInfo();
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/android/qandroidintegration.cpp b/src/multimedia/platform/android/qandroidintegration.cpp
deleted file mode 100644
index 5299275fa..000000000
--- a/src/multimedia/platform/android/qandroidintegration.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qandroidintegration_p.h"
-#include "qandroidmediadevices_p.h"
-#include "private/qandroidglobal_p.h"
-#include "private/qandroidmediacapturesession_p.h"
-#include "private/androidmediaplayer_p.h"
-#include "private/qandroidcamerasession_p.h"
-#include "private/androidsurfacetexture_p.h"
-#include "private/androidsurfaceview_p.h"
-#include "private/androidcamera_p.h"
-#include "private/qandroidcamera_p.h"
-#include "private/qandroidimagecapture_p.h"
-#include "private/qandroidmediaencoder_p.h"
-#include "private/androidmediarecorder_p.h"
-#include "private/qandroidformatsinfo_p.h"
-#include "private/qandroidmediaplayer_p.h"
-#include "private/qandroidaudiooutput_p.h"
-#include "private/qandroidvideosink_p.h"
-#include "private/qandroidaudiodecoder_p.h"
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(qtAndroidMediaPlugin, "qt.multimedia.android")
-
-QAndroidIntegration::QAndroidIntegration()
-{
-
-}
-
-QAndroidIntegration::~QAndroidIntegration()
-{
- delete m_devices;
- delete m_formatInfo;
-}
-
-QPlatformMediaDevices *QAndroidIntegration::devices()
-{
- if (!m_devices)
- m_devices = new QAndroidMediaDevices();
- return m_devices;
-}
-
-QPlatformAudioDecoder *QAndroidIntegration::createAudioDecoder(QAudioDecoder *decoder)
-{
- return new QAndroidAudioDecoder(decoder);
-}
-
-QPlatformMediaFormatInfo *QAndroidIntegration::formatInfo()
-{
- if (!m_formatInfo)
- m_formatInfo = new QAndroidFormatInfo();
- return m_formatInfo;
-
-}
-
-QPlatformMediaCaptureSession *QAndroidIntegration::createCaptureSession()
-{
- return new QAndroidMediaCaptureSession();
-}
-
-QPlatformMediaPlayer *QAndroidIntegration::createPlayer(QMediaPlayer *player)
-{
- return new QAndroidMediaPlayer(player);
-}
-
-QPlatformCamera *QAndroidIntegration::createCamera(QCamera *camera)
-{
- return new QAndroidCamera(camera);
-}
-
-QPlatformMediaEncoder *QAndroidIntegration::createEncoder(QMediaRecorder *encoder)
-{
- return new QAndroidMediaEncoder(encoder);
-}
-
-QPlatformImageCapture *QAndroidIntegration::createImageCapture(QImageCapture *imageCapture)
-{
- return new QAndroidImageCapture(imageCapture);
-}
-
-QPlatformAudioOutput *QAndroidIntegration::createAudioOutput(QAudioOutput *q)
-{
- return new QAndroidAudioOutput(q);
-}
-
-QPlatformVideoSink *QAndroidIntegration::createVideoSink(QVideoSink *sink)
-{
- return new QAndroidVideoSink(sink);
-}
-
-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;
-
- if (!AndroidMediaPlayer::registerNativeMethods()
- || !AndroidCamera::registerNativeMethods()
- || !AndroidMediaRecorder::registerNativeMethods()
- || !AndroidSurfaceHolder::registerNativeMethods()
- || !QAndroidMediaDevices::registerNativeMethods()) {
- return JNI_ERR;
- }
-
- AndroidSurfaceTexture::registerNativeMethods();
-
- return JNI_VERSION_1_6;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/qandroidintegration_p.h b/src/multimedia/platform/android/qandroidintegration_p.h
deleted file mode 100644
index a56881988..000000000
--- a/src/multimedia/platform/android/qandroidintegration_p.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QANDROIDINTEGRATION_H
-#define QANDROIDINTEGRATION_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 <private/qplatformmediaintegration_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAndroidMediaDevices;
-
-class QAndroidIntegration : public QPlatformMediaIntegration
-{
-public:
- QAndroidIntegration();
- ~QAndroidIntegration();
-
- QPlatformMediaDevices *devices() override;
- QPlatformMediaFormatInfo *formatInfo() override;
-
- QPlatformAudioDecoder *createAudioDecoder(QAudioDecoder *decoder) override;
- QPlatformMediaCaptureSession *createCaptureSession() override;
- QPlatformMediaPlayer *createPlayer(QMediaPlayer *player) override;
- QPlatformCamera *createCamera(QCamera *camera) override;
- QPlatformMediaEncoder *createEncoder(QMediaRecorder *encoder) override;
- QPlatformImageCapture *createImageCapture(QImageCapture *imageCapture) override;
-
- QPlatformAudioOutput *createAudioOutput(QAudioOutput *q) override;
-
- QPlatformVideoSink *createVideoSink(QVideoSink *) override;
-
- QAndroidMediaDevices *m_devices = nullptr;
- QPlatformMediaFormatInfo *m_formatInfo = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/android/qandroidmediadevices.cpp b/src/multimedia/platform/android/qandroidmediadevices.cpp
deleted file mode 100644
index 6737c46c6..000000000
--- a/src/multimedia/platform/android/qandroidmediadevices.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qandroidmediadevices_p.h"
-#include "qmediadevices.h"
-#include "qcameradevice_p.h"
-
-#include "private/qandroidaudiosource_p.h"
-#include "private/qandroidaudiosink_p.h"
-#include "private/qandroidaudiodevice_p.h"
-#include "private/qopenslesengine_p.h"
-#include "private/qplatformmediaintegration_p.h"
-#include "private/qandroidcamerasession_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QAndroidMediaDevices::QAndroidMediaDevices()
- : QPlatformMediaDevices()
-{
-}
-
-QList<QAudioDevice> QAndroidMediaDevices::audioInputs() const
-{
- return QOpenSLESEngine::availableDevices(QAudioDevice::Input);
-}
-
-QList<QAudioDevice> QAndroidMediaDevices::audioOutputs() const
-{
- return QOpenSLESEngine::availableDevices(QAudioDevice::Output);
-}
-
-QList<QCameraDevice> QAndroidMediaDevices::videoInputs() const
-{
- return QAndroidCameraSession::availableCameras();
-}
-
-QPlatformAudioSource *QAndroidMediaDevices::createAudioSource(const QAudioDevice &deviceInfo)
-{
- return new QAndroidAudioSource(deviceInfo.id());
-}
-
-QPlatformAudioSink *QAndroidMediaDevices::createAudioSink(const QAudioDevice &deviceInfo)
-{
- return new QAndroidAudioSink(deviceInfo.id());
-}
-
-void QAndroidMediaDevices::forwardAudioOutputsChanged()
-{
- audioOutputsChanged();
-}
-
-void QAndroidMediaDevices::forwardAudioInputsChanged()
-{
- audioInputsChanged();
-}
-
-static void onAudioInputDevicesUpdated(JNIEnv */*env*/, jobject /*thiz*/)
-{
- static_cast<QAndroidMediaDevices*>(
- QPlatformMediaIntegration::instance()->devices())->forwardAudioInputsChanged();
-}
-
-static void onAudioOutputDevicesUpdated(JNIEnv */*env*/, jobject /*thiz*/)
-{
- static_cast<QAndroidMediaDevices*>(
- QPlatformMediaIntegration::instance()->devices())->forwardAudioOutputsChanged();
-}
-
-bool QAndroidMediaDevices::registerNativeMethods()
-{
- static const JNINativeMethod methods[] = {
- {"onAudioInputDevicesUpdated","()V",(void*)onAudioInputDevicesUpdated},
- {"onAudioOutputDevicesUpdated", "()V",(void*)onAudioOutputDevicesUpdated}
- };
- const int size = std::size(methods);
- return QJniEnvironment().registerNativeMethods(
- "org/qtproject/qt/android/multimedia/QtAudioDeviceManager", methods, size);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/qandroidmediadevices_p.h b/src/multimedia/platform/android/qandroidmediadevices_p.h
deleted file mode 100644
index 734678aad..000000000
--- a/src/multimedia/platform/android/qandroidmediadevices_p.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QANDROIDMEDIADEVICES_H
-#define QANDROIDMEDIADEVICES_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 <private/qplatformmediadevices_p.h>
-#include <qaudio.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAndroidMediaDevices : public QPlatformMediaDevices
-{
-public:
- QAndroidMediaDevices();
-
- QList<QAudioDevice> audioInputs() const override;
- QList<QAudioDevice> audioOutputs() const override;
- QList<QCameraDevice> videoInputs() const override;
- QPlatformAudioSource *createAudioSource(const QAudioDevice &deviceInfo) override;
- QPlatformAudioSink *createAudioSink(const QAudioDevice &deviceInfo) override;
-
- void forwardAudioOutputsChanged();
- void forwardAudioInputsChanged();
- static bool registerNativeMethods();
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/android/wrappers/jni/androidcamera.cpp b/src/multimedia/platform/android/wrappers/jni/androidcamera.cpp
deleted file mode 100644
index e40921f38..000000000
--- a/src/multimedia/platform/android/wrappers/jni/androidcamera.cpp
+++ /dev/null
@@ -1,1747 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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_p.h"
-#include "androidsurfacetexture_p.h"
-#include "androidsurfaceview_p.h"
-#include "qandroidmultimediautils_p.h"
-#include "qandroidglobal_p.h"
-
-#include <qstringlist.h>
-#include <qdebug.h>
-#include <QtCore/qthread.h>
-#include <QtCore/qreadwritelock.h>
-#include <QtCore/qmutex.h>
-#include <QtMultimedia/private/qmemoryvideobuffer_p.h>
-#include <QtCore/qcoreapplication.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 QRect areaToRect(jobject areaObj)
-{
- QJniObject area(areaObj);
- QJniObject 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 QJniObject rectToArea(const QRect &rect)
-{
- QJniObject jrect("android/graphics/Rect",
- "(IIII)V",
- rect.left(), rect.top(), rect.right(), rect.bottom());
-
- QJniObject 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),
- QVideoFrameFormat(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();
- static QList<QSize> getSupportedPreviewSizes(QJniObject &parameters);
-
- Q_INVOKABLE QList<AndroidCamera::FpsRange> getSupportedPreviewFpsRange();
-
- Q_INVOKABLE AndroidCamera::FpsRange getPreviewFpsRange();
- static AndroidCamera::FpsRange getPreviewFpsRange(QJniObject &parameters);
- 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();
- static QList<AndroidCamera::ImageFormat> getSupportedPreviewFormats(QJniObject &parameters);
-
- 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;
- QJniObject m_info;
- QJniObject m_parameters;
- QJniObject m_camera;
- QJniObject 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)
-
-{
- 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");
-}
-
-QJniObject AndroidCamera::getCameraObject()
-{
- Q_D(AndroidCamera);
- return d->m_camera;
-}
-
-int AndroidCamera::getNumberOfCameras()
-{
- if (!qt_androidRequestCameraPermission())
- return 0;
-
- return QJniObject::callStaticMethod<jint>("android/hardware/Camera",
- "getNumberOfCameras");
-}
-
-void AndroidCamera::getCameraInfo(int id, QCameraDevicePrivate *info)
-{
- Q_ASSERT(info);
-
- QJniObject cameraInfo("android/hardware/Camera$CameraInfo");
- QJniObject::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->id = QByteArray("back");
- info->description = QStringLiteral("Rear-facing camera");
- info->position = QCameraDevice::BackFace;
- info->isDefault = true;
- break;
- case AndroidCamera::CameraFacingFront:
- info->id = QByteArray("front");
- info->description = QStringLiteral("Front-facing camera");
- info->position = QCameraDevice::FrontFace;
- break;
- default:
- break;
- }
-}
-
-QVideoFrameFormat::PixelFormat AndroidCamera::QtPixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat format)
-{
- switch (format) {
- case AndroidCamera::NV21:
- return QVideoFrameFormat::Format_NV21;
- case AndroidCamera::YUY2:
- return QVideoFrameFormat::Format_YUYV;
- case AndroidCamera::JPEG:
- return QVideoFrameFormat::Format_Jpeg;
- case AndroidCamera::YV12:
- return QVideoFrameFormat::Format_YV12;
- default:
- return QVideoFrameFormat::Format_Invalid;
- }
-}
-
-AndroidCamera::ImageFormat AndroidCamera::AndroidImageFormatFromQtPixelFormat(QVideoFrameFormat::PixelFormat format)
-{
- switch (format) {
- case QVideoFrameFormat::Format_NV21:
- return AndroidCamera::NV21;
- case QVideoFrameFormat::Format_YUYV:
- return AndroidCamera::YUY2;
- case QVideoFrameFormat::Format_Jpeg:
- return AndroidCamera::JPEG;
- case QVideoFrameFormat::Format_YV12:
- return AndroidCamera::YV12;
- default:
- return AndroidCamera::UnknownImageFormat;
- }
-}
-
-void AndroidCamera::getSupportedFormats(int id, QList<QCameraFormat> &formats)
-{
- QJniObject camera = QJniObject::callStaticObjectMethod("android/hardware/Camera",
- "open",
- "(I)Landroid/hardware/Camera;",
- id);
- if (!camera.isValid())
- return;
-
- QJniObject cameraParams = camera.callObjectMethod("getParameters",
- "()Landroid/hardware/Camera$Parameters;");
- if (!cameraParams.isValid()) {
- camera.callMethod<void>("release");
- return;
- }
- AndroidCamera::FpsRange range = AndroidCameraPrivate::getPreviewFpsRange(cameraParams);
-
- for (const auto &previewSize : AndroidCameraPrivate::getSupportedPreviewSizes(cameraParams))
- {
- for (const auto &previewFormat : AndroidCameraPrivate::getSupportedPreviewFormats(cameraParams))
- {
- QCameraFormatPrivate * format = new QCameraFormatPrivate();
- format->pixelFormat = QtPixelFormatFromAndroidImageFormat(previewFormat);
- format->resolution = previewSize;
- format->minFrameRate = range.min;
- format->maxFrameRate = range.max;
- formats.append(format->create());
- }
- }
-
- camera.callMethod<void>("release");
-}
-
-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;
- QJniEnvironment env;
-
- const bool opened = s_activeCameras & (1 << cameraId);
- if (opened)
- return false;
-
- m_camera = QJniObject::callStaticObjectMethod("android/hardware/Camera",
- "open",
- "(I)Landroid/hardware/Camera;",
- cameraId);
- if (!m_camera.isValid())
- return false;
-
- m_cameraListener = QJniObject(QtCameraListenerClassName, "(I)V", m_cameraId);
- m_info = QJniObject("android/hardware/Camera$CameraInfo");
- m_camera.callStaticMethod<void>("android/hardware/Camera",
- "getCameraInfo",
- "(ILandroid/hardware/Camera$CameraInfo;)V",
- cameraId,
- m_info.object());
-
- QJniObject params = m_camera.callObjectMethod("getParameters",
- "()Landroid/hardware/Camera$Parameters;");
- m_parameters = QJniObject(params);
- s_activeCameras |= 1 << cameraId;
-
- return true;
-}
-
-void AndroidCameraPrivate::release()
-{
- m_previewSize = QSize();
- m_parametersMutex.lock();
- m_parameters = QJniObject();
- m_parametersMutex.unlock();
- if (m_camera.isValid()) {
- m_camera.callMethod<void>("release");
- s_activeCameras &= ~(1 << m_cameraId);
- }
-}
-
-bool AndroidCameraPrivate::lock()
-{
- QJniEnvironment env;
- auto methodId = env->GetMethodID(m_camera.objectClass(), "lock", "()V");
- env->CallVoidMethod(m_camera.object(), methodId);
-
- if (env.checkAndClearExceptions())
- return false;
- return true;
-}
-
-bool AndroidCameraPrivate::unlock()
-{
- QJniEnvironment env;
- auto methodId = env->GetMethodID(m_camera.objectClass(), "unlock", "()V");
- env->CallVoidMethod(m_camera.object(), methodId);
-
- if (env.checkAndClearExceptions())
- return false;
- return true;
-}
-
-bool AndroidCameraPrivate::reconnect()
-{
- QJniEnvironment env;
- auto methodId = env->GetMethodID(m_camera.objectClass(), "reconnect", "()V");
- env->CallVoidMethod(m_camera.object(), methodId);
-
- if (env.checkAndClearExceptions())
- return false;
- return true;
-}
-
-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();
-
- QJniObject 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()
-{
- const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
- return getSupportedPreviewSizes(m_parameters);
-}
-
-QList<QSize> AndroidCameraPrivate::getSupportedPreviewSizes(QJniObject &parameters)
-{
- QList<QSize> list;
-
- if (parameters.isValid()) {
- QJniObject sizeList = parameters.callObjectMethod("getSupportedPreviewSizes",
- "()Ljava/util/List;");
- int count = sizeList.callMethod<jint>("size");
- for (int i = 0; i < count; ++i) {
- QJniObject 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);
-
- QJniEnvironment env;
-
- QList<AndroidCamera::FpsRange> rangeList;
-
- if (m_parameters.isValid()) {
- QJniObject rangeListNative = m_parameters.callObjectMethod("getSupportedPreviewFpsRange",
- "()Ljava/util/List;");
- int count = rangeListNative.callMethod<jint>("size");
-
- rangeList.reserve(count);
-
- for (int i = 0; i < count; ++i) {
- QJniObject 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);
- return getPreviewFpsRange(m_parameters);
-}
-
-AndroidCamera::FpsRange AndroidCameraPrivate::getPreviewFpsRange(QJniObject &parameters)
-{
- QJniEnvironment env;
-
- AndroidCamera::FpsRange range;
-
- if (!parameters.isValid())
- return range;
-
- jintArray jRangeArray = env->NewIntArray(2);
- 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;
-
- QJniEnvironment env;
- m_parameters.callMethod<void>("setPreviewFpsRange", "(II)V", min, max);
-}
-
-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()
-{
- const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
- return getSupportedPreviewFormats(m_parameters);
-}
-
-QList<AndroidCamera::ImageFormat> AndroidCameraPrivate::getSupportedPreviewFormats(QJniObject &parameters)
-{
- QList<AndroidCamera::ImageFormat> list;
-
- if (parameters.isValid()) {
- QJniObject formatList = parameters.callObjectMethod("getSupportedPreviewFormats",
- "()Ljava/util/List;");
- int count = formatList.callMethod<jint>("size");
- for (int i = 0; i < count; ++i) {
- QJniObject 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();
-
- QJniObject 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)
-{
- QJniEnvironment env;
- auto methodId = env->GetMethodID(m_camera.objectClass(), "setPreviewTexture",
- "(Landroid/graphics/SurfaceTexture;)V");
- env->CallVoidMethod(m_camera.object(), methodId, static_cast<jobject>(surfaceTexture));
-
- if (env.checkAndClearExceptions())
- return false;
- return true;
-}
-
-bool AndroidCameraPrivate::setPreviewDisplay(void *surfaceHolder)
-{
- QJniEnvironment env;
- auto methodId = env->GetMethodID(m_camera.objectClass(), "setPreviewDisplay",
- "(Landroid/view/SurfaceHolder;)V");
- env->CallVoidMethod(m_camera.object(), methodId, static_cast<jobject>(surfaceHolder));
-
- if (env.checkAndClearExceptions())
- return false;
- return true;
-}
-
-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()) {
- QJniObject ratioList = m_parameters.callObjectMethod("getZoomRatios",
- "()Ljava/util/List;");
- int count = ratioList.callMethod<jint>("size");
- for (int i = 0; i < count; ++i) {
- QJniObject 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()) {
- QJniObject 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",
- QJniObject::fromString(value).object());
- applyParameters();
-}
-
-QString AndroidCameraPrivate::getFocusMode()
-{
- const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
-
- QString value;
-
- if (m_parameters.isValid()) {
- QJniObject 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",
- QJniObject::fromString(value).object());
- applyParameters();
-}
-
-int AndroidCameraPrivate::getMaxNumFocusAreas()
-{
- 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;
- const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
-
- if (m_parameters.isValid()) {
- QJniObject list = m_parameters.callObjectMethod("getFocusAreas",
- "()Ljava/util/List;");
-
- if (list.isValid()) {
- int count = list.callMethod<jint>("size");
- for (int i = 0; i < count; ++i) {
- QJniObject area = list.callObjectMethod("get",
- "(I)Ljava/lang/Object;",
- i);
-
- areas.append(areaToRect(area.object()));
- }
- }
- }
-
- return areas;
-}
-
-void AndroidCameraPrivate::setFocusAreas(const QList<QRect> &areas)
-{
- const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
-
- if (!m_parameters.isValid() || areas.isEmpty())
- return;
-
- QJniObject list;
-
- if (!areas.isEmpty()) {
- QJniEnvironment env;
- QJniObject 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());
- }
- list = arrayList;
- }
-
- m_parameters.callMethod<void>("setFocusAreas", "(Ljava/util/List;)V", list.object());
-
- applyParameters();
-}
-
-void AndroidCameraPrivate::autoFocus()
-{
- QJniEnvironment env;
- auto methodId = env->GetMethodID(m_camera.objectClass(), "autoFocus",
- "(Landroid/hardware/Camera$AutoFocusCallback;)V");
- env->CallVoidMethod(m_camera.object(), methodId, m_cameraListener.object());
-
- if (!env.checkAndClearExceptions())
- emit autoFocusStarted();
-}
-
-void AndroidCameraPrivate::cancelAutoFocus()
-{
- QJniEnvironment env;
- m_camera.callMethod<void>("cancelAutoFocus");
-}
-
-bool AndroidCameraPrivate::isAutoExposureLockSupported()
-{
- const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
-
- if (!m_parameters.isValid())
- return false;
-
- return m_parameters.callMethod<jboolean>("isAutoExposureLockSupported");
-}
-
-bool AndroidCameraPrivate::getAutoExposureLock()
-{
- 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)
-{
- 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()
-{
- const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
-
- if (!m_parameters.isValid())
- return false;
-
- return m_parameters.callMethod<jboolean>("isAutoWhiteBalanceLockSupported");
-}
-
-bool AndroidCameraPrivate::getAutoWhiteBalanceLock()
-{
- 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)
-{
- 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()) {
- QJniObject 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",
- QJniObject::fromString(value).object());
- applyParameters();
-}
-
-QString AndroidCameraPrivate::getWhiteBalance()
-{
- const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
-
- QString value;
-
- if (m_parameters.isValid()) {
- QJniObject 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",
- QJniObject::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()) {
- QJniObject sizeList = m_parameters.callObjectMethod("getSupportedPictureSizes",
- "()Ljava/util/List;");
- int count = sizeList.callMethod<jint>("size");
- for (int i = 0; i < count; ++i) {
- QJniObject 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()
-{
- setupPreviewFrameCallback();
-
- QJniEnvironment env;
- auto methodId = env->GetMethodID(m_camera.objectClass(), "startPreview", "()V");
- env->CallVoidMethod(m_camera.object(), methodId);
-
- if (env.checkAndClearExceptions())
- emit previewFailedToStart();
- else
- emit previewStarted();
-}
-
-void AndroidCameraPrivate::stopPreview()
-{
- // cancel any pending new frame notification
- m_cameraListener.callMethod<void>("notifyWhenFrameAvailable", "(Z)V", false);
- m_camera.callMethod<void>("stopPreview");
- emit previewStopped();
-}
-
-void AndroidCameraPrivate::takePicture()
-{
- // 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());
-
- QJniEnvironment env;
- auto methodId = env->GetMethodID(m_camera.objectClass(), "takePicture",
- "(Landroid/hardware/Camera$ShutterCallback;"
- "Landroid/hardware/Camera$PictureCallback;"
- "Landroid/hardware/Camera$PictureCallback;)V");
- env->CallVoidMethod(m_camera.object(), methodId, m_cameraListener.object(),
- jobject(0), m_cameraListener.object());
-
- if (env.checkAndClearExceptions())
- 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()
-{
- QJniEnvironment env;
- QJniObject 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),
- QVideoFrameFormat(QSize(width, height),
- qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat(format))));
-
- emit lastPreviewFrameFetched(frame);
-}
-
-void AndroidCameraPrivate::applyParameters()
-{
- QJniEnvironment env;
- m_camera.callMethod<void>("setParameters",
- "(Landroid/hardware/Camera$Parameters;)V",
- m_parameters.object());
-}
-
-QStringList AndroidCameraPrivate::callParametersStringListMethod(const QByteArray &methodName)
-{
- const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
-
- QStringList stringList;
-
- if (m_parameters.isValid()) {
- QJniObject 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) {
- QJniObject string = list.callObjectMethod("get",
- "(I)Ljava/lang/Object;",
- i);
- stringList.append(string.toString());
- }
- }
- }
-
- return stringList;
-}
-
-bool AndroidCamera::registerNativeMethods()
-{
- 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}
- };
-
- const int size = std::size(methods);
- return QJniEnvironment().registerNativeMethods(QtCameraListenerClassName, methods, size);
-}
-
-QT_END_NAMESPACE
-
-#include "androidcamera.moc"
diff --git a/src/multimedia/platform/android/wrappers/jni/androidcamera_p.h b/src/multimedia/platform/android/wrappers/jni/androidcamera_p.h
deleted file mode 100644
index 94c2d3c46..000000000
--- a/src/multimedia/platform/android/wrappers/jni/androidcamera_p.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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
-
-//
-// 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 <qobject.h>
-#include <qsize.h>
-#include <qrect.h>
-#include <QtMultimedia/qcamera.h>
-#include <QtCore/qjniobject.h>
-#include <private/qcameradevice_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QThread;
-
-class AndroidCameraPrivate;
-class AndroidSurfaceTexture;
-class AndroidSurfaceHolder;
-
-class AndroidCamera : public QObject
-{
- Q_OBJECT
-public:
- enum CameraFacing {
- CameraFacingBack = 0,
- CameraFacingFront = 1
- };
- Q_ENUM(CameraFacing)
-
- 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
- };
- Q_ENUM(ImageFormat)
-
- // 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();
- QJniObject getCameraObject();
-
- static int getNumberOfCameras();
- static void getCameraInfo(int id, QCameraDevicePrivate *info);
- static QVideoFrameFormat::PixelFormat QtPixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat);
- static AndroidCamera::ImageFormat AndroidImageFormatFromQtPixelFormat(QVideoFrameFormat::PixelFormat);
- static void getSupportedFormats(int id, QList<QCameraFormat> &formats);
- static bool requestCameraPermission();
-
- static bool registerNativeMethods();
-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;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(AndroidCamera::ImageFormat)
-
-#endif // ANDROIDCAMERA_H
diff --git a/src/multimedia/platform/android/wrappers/jni/androidmediametadataretriever.cpp b/src/multimedia/platform/android/wrappers/jni/androidmediametadataretriever.cpp
deleted file mode 100644
index 733717ae7..000000000
--- a/src/multimedia/platform/android/wrappers/jni/androidmediametadataretriever.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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_p.h"
-
-#include <QtCore/QUrl>
-#include <qdebug.h>
-#include <QtCore/qcoreapplication.h>
-
-QT_BEGIN_NAMESPACE
-
-AndroidMediaMetadataRetriever::AndroidMediaMetadataRetriever()
-{
- m_metadataRetriever = QJniObject("android/media/MediaMetadataRetriever");
-}
-
-AndroidMediaMetadataRetriever::~AndroidMediaMetadataRetriever()
-{
- release();
-}
-
-QString AndroidMediaMetadataRetriever::extractMetadata(MetadataKey key)
-{
- QString value;
-
- QJniObject 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;
-
- QJniEnvironment env;
- if (url.isLocalFile()) { // also includes qrc files (copied to a temp file by QMediaPlayer)
- QJniObject string = QJniObject::fromString(url.path());
- QJniObject fileInputStream("java/io/FileInputStream",
- "(Ljava/lang/String;)V",
- string.object());
-
- if (!fileInputStream.isValid())
- return false;
-
- QJniObject fd = fileInputStream.callObjectMethod("getFD",
- "()Ljava/io/FileDescriptor;");
- if (!fd.isValid()) {
- fileInputStream.callMethod<void>("close");
- return false;
- }
-
- auto methodId = env->GetMethodID(m_metadataRetriever.objectClass(), "setDataSource",
- "(Ljava/io/FileDescriptor;)V");
- env->CallVoidMethod(m_metadataRetriever.object(), methodId, fd.object());
- bool ok = !env.checkAndClearExceptions();
- fileInputStream.callMethod<void>("close");
- if (!ok)
- return false;
- } else if (url.scheme() == QLatin1String("assets")) {
- QJniObject string = QJniObject::fromString(url.path().mid(1)); // remove first '/'
- QJniObject activity(QNativeInterface::QAndroidApplication::context());
- QJniObject assetManager = activity.callObjectMethod("getAssets",
- "()Landroid/content/res/AssetManager;");
- QJniObject assetFd = assetManager.callObjectMethod("openFd",
- "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;",
- string.object());
- if (!assetFd.isValid())
- return false;
-
- QJniObject fd = assetFd.callObjectMethod("getFileDescriptor",
- "()Ljava/io/FileDescriptor;");
- if (!fd.isValid()) {
- assetFd.callMethod<void>("close");
- return false;
- }
-
- auto methodId = env->GetMethodID(m_metadataRetriever.objectClass(), "setDataSource",
- "(Ljava/io/FileDescriptor;JJ)V");
- env->CallVoidMethod(m_metadataRetriever.object(), methodId,
- fd.object(),
- assetFd.callMethod<jlong>("getStartOffset"),
- assetFd.callMethod<jlong>("getLength"));
- bool ok = !env.checkAndClearExceptions();
- assetFd.callMethod<void>("close");
-
- if (!ok)
- return false;
- } else if (url.scheme() != QLatin1String("content")) {
- // On API levels >= 14, only setDataSource(String, Map<String, String>) accepts remote media
- QJniObject string = QJniObject::fromString(url.toString(QUrl::FullyEncoded));
- QJniObject hash("java/util/HashMap");
-
- auto methodId = env->GetMethodID(m_metadataRetriever.objectClass(), "setDataSource",
- "(Ljava/lang/String;Ljava/util/Map;)V");
- env->CallVoidMethod(m_metadataRetriever.object(), methodId,
- string.object(), hash.object());
- if (env.checkAndClearExceptions())
- return false;
- } else {
- // While on API levels < 14, only setDataSource(Context, Uri) is available and works for
- // remote media...
- QJniObject string = QJniObject::fromString(url.toString(QUrl::FullyEncoded));
- QJniObject uri = m_metadataRetriever.callStaticObjectMethod(
- "android/net/Uri",
- "parse",
- "(Ljava/lang/String;)Landroid/net/Uri;",
- string.object());
- if (!uri.isValid())
- return false;
-
- auto methodId = env->GetMethodID(m_metadataRetriever.objectClass(), "setDataSource",
- "(Landroid/content/Context;Landroid/net/Uri;)V");
- env->CallVoidMethod(m_metadataRetriever.object(), methodId,
- QNativeInterface::QAndroidApplication::context(), uri.object());
- if (env.checkAndClearExceptions())
- return false;
- }
-
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/wrappers/jni/androidmediametadataretriever_p.h b/src/multimedia/platform/android/wrappers/jni/androidmediametadataretriever_p.h
deleted file mode 100644
index 69727bbd3..000000000
--- a/src/multimedia/platform/android/wrappers/jni/androidmediametadataretriever_p.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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
-
-//
-// 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 <QtCore/private/qglobal_p.h>
-#include <QtCore/qurl.h>
-#include <QtCore/qjniobject.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();
- QJniObject m_metadataRetriever;
-};
-
-QT_END_NAMESPACE
-
-#endif // ANDROIDMEDIAMETADATARETRIEVER_H
diff --git a/src/multimedia/platform/android/wrappers/jni/androidmediaplayer.cpp b/src/multimedia/platform/android/wrappers/jni/androidmediaplayer.cpp
deleted file mode 100644
index f28622d6c..000000000
--- a/src/multimedia/platform/android/wrappers/jni/androidmediaplayer.cpp
+++ /dev/null
@@ -1,581 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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_p.h"
-#include "androidsurfacetexture_p.h"
-
-#include <QList>
-#include <QReadWriteLock>
-#include <QString>
-#include <QtCore/qcoreapplication.h>
-
-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
-
-Q_LOGGING_CATEGORY(lcAudio, "qt.multimedia.audio")
-
-AndroidMediaPlayer::AndroidMediaPlayer()
- : QObject()
-{
- QWriteLocker locker(rwLock);
- auto context = QNativeInterface::QAndroidApplication::context();
- const jlong id = reinterpret_cast<jlong>(this);
- mMediaPlayer = QJniObject(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 (QNativeInterface::QAndroidApplication::sdkVersion() < 23)
- return rate;
-
- QJniObject player = mMediaPlayer.callObjectMethod("getMediaPlayerHandle",
- "()Landroid/media/MediaPlayer;");
- if (player.isValid()) {
- QJniObject playbackParams = player.callObjectMethod("getPlaybackParams",
- "()Landroid/media/PlaybackParams;");
- if (playbackParams.isValid()) {
- QJniEnvironment env;
- auto methodId = env->GetMethodID(playbackParams.objectClass(), "getSpeed", "()F");
- const qreal speed = env->CallFloatMethod(playbackParams.object(), methodId);
- if (!env.checkAndClearExceptions())
- rate = speed;
- }
- }
-
- return rate;
-}
-
-jobject AndroidMediaPlayer::display()
-{
- return mMediaPlayer.callObjectMethod("display", "()Landroid/view/SurfaceHolder;").object();
-}
-
-AndroidMediaPlayer::TrackInfo convertTrackInfo(int streamNumber, QJniObject androidTrackInfo)
-{
- const QLatin1String unknownMimeType("application/octet-stream");
- const QLatin1String undefinedLanguage("und");
-
- if (!androidTrackInfo.isValid())
- return { streamNumber, AndroidMediaPlayer::TrackType::Unknown, undefinedLanguage,
- unknownMimeType };
-
- QJniEnvironment env;
- auto methodId = env->GetMethodID(androidTrackInfo.objectClass(), "getType", "()I");
- const jint type = env->CallIntMethod(androidTrackInfo.object(), methodId);
- if (env.checkAndClearExceptions())
- return { streamNumber, AndroidMediaPlayer::TrackType::Unknown, undefinedLanguage,
- unknownMimeType };
-
- if (type < 0 || type > 5) {
- return { streamNumber, AndroidMediaPlayer::TrackType::Unknown, undefinedLanguage,
- unknownMimeType };
- }
-
- AndroidMediaPlayer::TrackType trackType = static_cast<AndroidMediaPlayer::TrackType>(type);
-
- auto languageObject = androidTrackInfo.callObjectMethod("getLanguage", "()Ljava/lang/String;");
- QString language = languageObject.isValid() ? languageObject.toString() : undefinedLanguage;
-
- auto mimeTypeObject = androidTrackInfo.callObjectMethod("getMime", "()Ljava/lang/String;");
- QString mimeType = mimeTypeObject.isValid() ? mimeTypeObject.toString() : unknownMimeType;
-
- return { streamNumber, trackType, language, mimeType };
-}
-
-QList<AndroidMediaPlayer::TrackInfo> AndroidMediaPlayer::tracksInfo()
-{
- auto androidTracksInfoObject = mMediaPlayer.callObjectMethod(
- "getAllTrackInfo",
- "()[Lorg/qtproject/qt/android/multimedia/QtAndroidMediaPlayer$TrackInfo;");
-
- if (!androidTracksInfoObject.isValid())
- return QList<AndroidMediaPlayer::TrackInfo>();
-
- auto androidTracksInfo = androidTracksInfoObject.object<jobjectArray>();
- if (!androidTracksInfo)
- return QList<AndroidMediaPlayer::TrackInfo>();
-
- QJniEnvironment environment;
- auto numberofTracks = environment->GetArrayLength(androidTracksInfo);
-
- QList<AndroidMediaPlayer::TrackInfo> tracksInformation;
-
- for (int index = 0; index < numberofTracks; index++) {
- auto androidTrackInformation = environment->GetObjectArrayElement(androidTracksInfo, index);
-
- if (environment.checkAndClearExceptions()) {
- continue;
- }
-
- auto trackInfo = convertTrackInfo(index, androidTrackInformation);
- tracksInformation.insert(index, trackInfo);
-
- environment->DeleteLocalRef(androidTrackInformation);
- }
-
- return tracksInformation;
-}
-
-int AndroidMediaPlayer::activeTrack(TrackType androidTrackType)
-{
- int type = static_cast<int>(androidTrackType);
- return mMediaPlayer.callMethod<jint>("getSelectedTrack", "(I)I", type);
-}
-
-void AndroidMediaPlayer::deselectTrack(int trackNumber)
-{
- mMediaPlayer.callMethod<void>("deselectTrack", "(I)V", trackNumber);
-}
-
-void AndroidMediaPlayer::selectTrack(int trackNumber)
-{
- mMediaPlayer.callMethod<void>("selectTrack", "(I)V", trackNumber);
-}
-
-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)
-{
- if (mAudioBlocked)
- return;
-
- mMediaPlayer.callMethod<void>("mute", "(Z)V", jboolean(mute));
-}
-
-void AndroidMediaPlayer::setDataSource(const QNetworkRequest &request)
-{
- QJniObject string = QJniObject::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",
- QJniObject::fromString(QLatin1String(header)).object(),
- QJniObject::fromString(QLatin1String(value)).object());
- }
-
- mMediaPlayer.callMethod<void>("setDataSource", "(Ljava/lang/String;)V", string.object());
-}
-
-void AndroidMediaPlayer::prepareAsync()
-{
- mMediaPlayer.callMethod<void>("prepareAsync");
-}
-
-void AndroidMediaPlayer::setVolume(int volume)
-{
- if (mAudioBlocked)
- return;
-
- mMediaPlayer.callMethod<void>("setVolume", "(I)V", jint(volume));
-}
-
-void AndroidMediaPlayer::blockAudio()
-{
- mAudioBlocked = true;
-}
-
-void AndroidMediaPlayer::unblockAudio()
-{
- mAudioBlocked = false;
-}
-
-bool AndroidMediaPlayer::setPlaybackRate(qreal rate)
-{
- if (QNativeInterface::QAndroidApplication::sdkVersion() < 23) {
- qWarning() << "Setting the playback rate on a media player requires"
- << "Android 6.0 (API level 23) or later";
- return false;
- }
-
- QJniObject player = mMediaPlayer.callObjectMethod("getMediaPlayerHandle",
- "()Landroid/media/MediaPlayer;");
- if (player.isValid()) {
- QJniObject 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)));
-
- QJniEnvironment env;
- auto methodId = env->GetMethodID(player.objectClass(), "setPlaybackParams",
- "(Landroid/media/PlaybackParams;)V");
- env->CallVoidMethod(player.object(), methodId, playbackParams.object());
-
- if (env.checkAndClearExceptions()) {
- 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);
-}
-
-bool AndroidMediaPlayer::setAudioOutput(const QByteArray &deviceId)
-{
- const bool ret = QJniObject::callStaticMethod<jboolean>(
- "org/qtproject/qt/android/multimedia/QtAudioDeviceManager",
- "setAudioOutput",
- "(I)Z",
- deviceId.toInt());
-
- if (!ret)
- qCWarning(lcAudio) << "Output device not set";
-
- return ret;
-}
-
-#if 0
-void AndroidMediaPlayer::setAudioRole(QAudio::Role role)
-{
- QString r;
- switch (role) {
- case QAudio::MusicRole:
- r = QLatin1String("CONTENT_TYPE_MUSIC");
- break;
- case QAudio::VideoRole:
- r = QLatin1String("CONTENT_TYPE_MOVIE");
- break;
- case QAudio::VoiceCommunicationRole:
- r = QLatin1String("USAGE_VOICE_COMMUNICATION");
- break;
- case QAudio::AlarmRole:
- r = QLatin1String("USAGE_ALARM");
- break;
- case QAudio::NotificationRole:
- r = QLatin1String("USAGE_NOTIFICATION");
- break;
- case QAudio::RingtoneRole:
- r = QLatin1String("USAGE_NOTIFICATION_RINGTONE");
- break;
- case QAudio::AccessibilityRole:
- r = QLatin1String("USAGE_ASSISTANCE_ACCESSIBILITY");
- break;
- case QAudio::SonificationRole:
- r = QLatin1String("CONTENT_TYPE_SONIFICATION");
- break;
- case QAudio::GameRole:
- r = QLatin1String("USAGE_GAME");
- break;
- default:
- return;
- }
-
- int type = 0; // CONTENT_TYPE_UNKNOWN
- int usage = 0; // USAGE_UNKNOWN
-
- 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));
-}
-#endif
-
-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);
-}
-
-static AndroidMediaPlayer *getMediaPlayer(jlong ptr)
-{
- auto mediaplayer = reinterpret_cast<AndroidMediaPlayer *>(ptr);
- if (!mediaplayer || !mediaPlayers->contains(mediaplayer))
- return nullptr;
-
- return mediaplayer;
-}
-
-static void onTrackInfoChangedNative(JNIEnv *env, jobject thiz, jlong ptr)
-{
- Q_UNUSED(env);
- Q_UNUSED(thiz);
-
- QReadLocker locker(rwLock);
- auto mediaplayer = getMediaPlayer(ptr);
- if (!mediaplayer)
- return;
-
- emit mediaplayer->tracksInfoChanged();
-}
-
-static void onTimedTextChangedNative(JNIEnv *env, jobject thiz, jstring timedText, jint time,
- jlong ptr)
-{
- Q_UNUSED(env);
- Q_UNUSED(thiz);
- Q_UNUSED(time);
-
- QReadLocker locker(rwLock);
-
- auto mediaplayer = getMediaPlayer(ptr);
- if (!mediaplayer)
- return;
-
- QString subtitleText;
- if (timedText != nullptr)
- subtitleText = QString::fromUtf8(env->GetStringUTFChars(timedText, 0));
-
- emit mediaplayer->timedTextChanged(subtitleText);
-}
-
-bool AndroidMediaPlayer::registerNativeMethods()
-{
- 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) },
- { "onTrackInfoChangedNative", "(J)V", reinterpret_cast<void *>(onTrackInfoChangedNative) },
- { "onTimedTextChangedNative", "(Ljava/lang/String;IJ)V",
- reinterpret_cast<void *>(onTimedTextChangedNative) }
- };
-
- const int size = std::size(methods);
- return QJniEnvironment().registerNativeMethods(QtAndroidMediaPlayerClassName, methods, size);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/wrappers/jni/androidmediaplayer_p.h b/src/multimedia/platform/android/wrappers/jni/androidmediaplayer_p.h
deleted file mode 100644
index d5cf07f9c..000000000
--- a/src/multimedia/platform/android/wrappers/jni/androidmediaplayer_p.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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
-
-//
-// 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 <QObject>
-#include <QNetworkRequest>
-#include <QtCore/qjniobject.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
- };
-
- enum TrackType { Unknown = 0, Video, Audio, TimedText, Subtitle, Metadata };
-
- struct TrackInfo
- {
- int trackNumber;
- TrackType trackType;
- QString language;
- QString mimeType;
- };
-
- 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);
- static bool setAudioOutput(const QByteArray &deviceId);
- QList<TrackInfo> tracksInfo();
- int activeTrack(TrackType trackType);
- void deselectTrack(int trackNumber);
- void selectTrack(int trackNumber);
-
- static bool registerNativeMethods();
-
- void blockAudio();
- void unblockAudio();
-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);
- void timedTextChanged(QString text);
- void tracksInfoChanged();
-
-private:
- QJniObject mMediaPlayer;
- bool mAudioBlocked = false;
-};
-
-QT_END_NAMESPACE
-
-#endif // ANDROIDMEDIAPLAYER_H
diff --git a/src/multimedia/platform/android/wrappers/jni/androidmediarecorder.cpp b/src/multimedia/platform/android/wrappers/jni/androidmediarecorder.cpp
deleted file mode 100644
index c5cdadbfd..000000000
--- a/src/multimedia/platform/android/wrappers/jni/androidmediarecorder.cpp
+++ /dev/null
@@ -1,344 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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_p.h"
-
-#include "androidcamera_p.h"
-#include "androidsurfacetexture_p.h"
-#include "androidsurfaceview_p.h"
-#include "qandroidglobal_p.h"
-#include "qandroidmultimediautils_p.h"
-#include <qmap.h>
-#include <QtCore/qlogging.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(lcMediaRecorder, "qt.multimedia.mediarecorder.android")
-
-typedef QMap<QString, QJniObject> 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 QJniObject::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, QJniObject>::const_iterator it = g_camcorderProfiles->constFind(key);
-
- if (it != g_camcorderProfiles->constEnd())
- return AndroidCamcorderProfile(*it);
-
- QJniObject camProfile = QJniObject::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 QJniObject &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 = QJniObject("android/media/MediaRecorder");
- if (m_mediaRecorder.isValid()) {
- QJniObject 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()
-{
- QJniEnvironment env;
- auto methodId = env->GetMethodID(m_mediaRecorder.objectClass(), "prepare", "()V");
- env->CallVoidMethod(m_mediaRecorder.object(), methodId);
-
- if (env.checkAndClearExceptions())
- return false;
- return true;
-}
-
-void AndroidMediaRecorder::reset()
-{
- m_mediaRecorder.callMethod<void>("reset");
- m_isAudioSourceSet = false; // Now setAudioSource can be used again.
-}
-
-bool AndroidMediaRecorder::start()
-{
- QJniEnvironment env;
- auto methodId = env->GetMethodID(m_mediaRecorder.objectClass(), "start", "()V");
- env->CallVoidMethod(m_mediaRecorder.object(), methodId);
-
- if (env.checkAndClearExceptions())
- return false;
- return true;
-}
-
-void AndroidMediaRecorder::stop()
-{
- m_mediaRecorder.callMethod<void>("stop");
-}
-
-void AndroidMediaRecorder::setAudioChannels(int numChannels)
-{
- m_mediaRecorder.callMethod<void>("setAudioChannels", "(I)V", numChannels);
-}
-
-void AndroidMediaRecorder::setAudioEncoder(AudioEncoder encoder)
-{
- QJniEnvironment env;
- m_mediaRecorder.callMethod<void>("setAudioEncoder", "(I)V", int(encoder));
-}
-
-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)
-{
- if (!m_isAudioSourceSet) {
- QJniEnvironment env;
- auto methodId = env->GetMethodID(m_mediaRecorder.objectClass(), "setAudioSource", "(I)V");
- env->CallVoidMethod(m_mediaRecorder.object(), methodId, source);
- if (!env.checkAndClearExceptions())
- m_isAudioSourceSet = true;
- } else {
- qCWarning(lcMediaRecorder) << "Audio source already set. Not setting a new source.";
- }
-}
-
-bool AndroidMediaRecorder::isAudioSourceSet() const
-{
- return m_isAudioSourceSet;
-}
-
-bool AndroidMediaRecorder::setAudioInput(const QByteArray &id)
-{
- const bool ret = QJniObject::callStaticMethod<jboolean>(
- "org/qtproject/qt/android/multimedia/QtAudioDeviceManager",
- "setAudioInput",
- "(Landroid/media/MediaRecorder;I)Z",
- m_mediaRecorder.object(),
- id.toInt());
- if (!ret)
- qCWarning(lcMediaRecorder) << "No default input device was set.";
-
- return ret;
-}
-
-void AndroidMediaRecorder::setCamera(AndroidCamera *camera)
-{
- QJniObject cam = camera->getCameraObject();
- m_mediaRecorder.callMethod<void>("setCamera", "(Landroid/hardware/Camera;)V", cam.object());
-}
-
-void AndroidMediaRecorder::setVideoEncoder(VideoEncoder encoder)
-{
- m_mediaRecorder.callMethod<void>("setVideoEncoder", "(I)V", int(encoder));
-}
-
-void AndroidMediaRecorder::setVideoEncodingBitRate(int bitRate)
-{
- m_mediaRecorder.callMethod<void>("setVideoEncodingBitRate", "(I)V", bitRate);
-}
-
-void AndroidMediaRecorder::setVideoFrameRate(int rate)
-{
- m_mediaRecorder.callMethod<void>("setVideoFrameRate", "(I)V", rate);
-}
-
-void AndroidMediaRecorder::setVideoSize(const QSize &size)
-{
- m_mediaRecorder.callMethod<void>("setVideoSize", "(II)V", size.width(), size.height());
-}
-
-void AndroidMediaRecorder::setVideoSource(VideoSource source)
-{
- m_mediaRecorder.callMethod<void>("setVideoSource", "(I)V", int(source));
-}
-
-void AndroidMediaRecorder::setOrientationHint(int degrees)
-{
- m_mediaRecorder.callMethod<void>("setOrientationHint", "(I)V", degrees);
-}
-
-void AndroidMediaRecorder::setOutputFormat(OutputFormat format)
-{
- QJniEnvironment env;
- auto methodId = env->GetMethodID(m_mediaRecorder.objectClass(), "setOutputFormat", "(I)V");
- env->CallVoidMethod(m_mediaRecorder.object(), methodId, format);
- // setAudioSource cannot be set after outputFormat is set.
- if (!env.checkAndClearExceptions())
- m_isAudioSourceSet = true;
-}
-
-void AndroidMediaRecorder::setOutputFile(const QString &path)
-{
- m_mediaRecorder.callMethod<void>("setOutputFile",
- "(Ljava/lang/String;)V",
- QJniObject::fromString(path).object());
-}
-
-void AndroidMediaRecorder::setSurfaceTexture(AndroidSurfaceTexture *texture)
-{
- m_mediaRecorder.callMethod<void>("setPreviewDisplay",
- "(Landroid/view/Surface;)V",
- texture->surface());
-}
-
-void AndroidMediaRecorder::setSurfaceHolder(AndroidSurfaceHolder *holder)
-{
- QJniObject surfaceHolder(holder->surfaceHolder());
- QJniObject surface = surfaceHolder.callObjectMethod("getSurface",
- "()Landroid/view/Surface;");
- if (!surface.isValid())
- return;
-
- m_mediaRecorder.callMethod<void>("setPreviewDisplay",
- "(Landroid/view/Surface;)V",
- surface.object());
-}
-
-bool AndroidMediaRecorder::registerNativeMethods()
-{
- static const JNINativeMethod methods[] = {
- {"notifyError", "(JII)V", (void *)notifyError},
- {"notifyInfo", "(JII)V", (void *)notifyInfo}
- };
-
- const int size = std::size(methods);
- return QJniEnvironment().registerNativeMethods(QtMediaRecorderListenerClassName, methods, size);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/wrappers/jni/androidmediarecorder_p.h b/src/multimedia/platform/android/wrappers/jni/androidmediarecorder_p.h
deleted file mode 100644
index b0f65dd1d..000000000
--- a/src/multimedia/platform/android/wrappers/jni/androidmediarecorder_p.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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
-
-//
-// 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 <qobject.h>
-#include <QtCore/qjniobject.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 QJniObject &camcorderProfile);
- QJniObject m_camcorderProfile;
-};
-
-class AndroidMediaRecorder : public QObject
-{
- Q_OBJECT
-public:
- enum AudioEncoder {
- DefaultAudioEncoder = 0,
- AMR_NB_Encoder = 1,
- AMR_WB_Encoder = 2,
- AAC = 3,
- OPUS = 7,
- VORBIS = 6
- };
-
- 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,
- HEVC = 5
- };
-
- enum VideoSource {
- DefaultVideoSource = 0,
- Camera = 1
- };
-
- enum OutputFormat {
- DefaultOutputFormat = 0,
- THREE_GPP = 1,
- MPEG_4 = 2,
- AMR_NB_Format = 3,
- AMR_WB_Format = 4,
- AAC_ADTS = 6,
- OGG = 11,
- WEBM = 9
- };
-
- 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);
- bool isAudioSourceSet() const;
- bool setAudioInput(const QByteArray &id);
-
- 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 registerNativeMethods();
-
-Q_SIGNALS:
- void error(int what, int extra);
- void info(int what, int extra);
-
-private:
- jlong m_id;
- QJniObject m_mediaRecorder;
- bool m_isAudioSourceSet = false;
-};
-
-QT_END_NAMESPACE
-
-#endif // ANDROIDMEDIARECORDER_H
diff --git a/src/multimedia/platform/android/wrappers/jni/androidmultimediautils.cpp b/src/multimedia/platform/android/wrappers/jni/androidmultimediautils.cpp
deleted file mode 100644
index 1fe482f30..000000000
--- a/src/multimedia/platform/android/wrappers/jni/androidmultimediautils.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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_p.h"
-
-#include <QtCore/qjniobject.h>
-
-QT_BEGIN_NAMESPACE
-
-
-void AndroidMultimediaUtils::enableOrientationListener(bool enable)
-{
- QJniObject::callStaticMethod<void>("org/qtproject/qt/android/multimedia/QtMultimediaUtils",
- "enableOrientationListener",
- "(Z)V",
- enable);
-}
-
-int AndroidMultimediaUtils::getDeviceOrientation()
-{
- return QJniObject::callStaticMethod<jint>("org/qtproject/qt/android/multimedia/QtMultimediaUtils",
- "getDeviceOrientation");
-}
-
-QString AndroidMultimediaUtils::getDefaultMediaDirectory(MediaType type)
-{
- QJniObject path = QJniObject::callStaticObjectMethod(
- "org/qtproject/qt/android/multimedia/QtMultimediaUtils",
- "getDefaultMediaDirectory",
- "(I)Ljava/lang/String;",
- jint(type));
- return path.toString();
-}
-
-void AndroidMultimediaUtils::registerMediaFile(const QString &file)
-{
- QJniObject::callStaticMethod<void>("org/qtproject/qt/android/multimedia/QtMultimediaUtils",
- "registerMediaFile",
- "(Ljava/lang/String;)V",
- QJniObject::fromString(file).object());
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/wrappers/jni/androidmultimediautils_p.h b/src/multimedia/platform/android/wrappers/jni/androidmultimediautils_p.h
deleted file mode 100644
index 8a1fd7328..000000000
--- a/src/multimedia/platform/android/wrappers/jni/androidmultimediautils_p.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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
-
-//
-// 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 <qobject.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/multimedia/platform/android/wrappers/jni/androidsurfacetexture.cpp b/src/multimedia/platform/android/wrappers/jni/androidsurfacetexture.cpp
deleted file mode 100644
index d3a5b56ff..000000000
--- a/src/multimedia/platform/android/wrappers/jni/androidsurfacetexture.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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_p.h"
-#include <QtCore/qmutex.h>
-#include <QtCore/qcoreapplication.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 *));
- m_surfaceTexture = QJniObject("android/graphics/SurfaceTexture", "(I)V", jint(texName));
-
- if (!m_surfaceTexture.isValid())
- return;
-
- const QMutexLocker lock(g_textureMutex());
- g_surfaceTextures->append(jlong(this));
- QJniObject listener(QtSurfaceTextureListenerClassName, "(J)V", jlong(this));
- setOnFrameAvailableListener(listener);
-}
-
-AndroidSurfaceTexture::~AndroidSurfaceTexture()
-{
- if (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;
-
- QJniEnvironment 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()
-{
- 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 = QJniObject("android/view/Surface",
- "(Landroid/graphics/SurfaceTexture;)V",
- m_surfaceTexture.object());
- }
-
- return m_surface.object();
-}
-
-jobject AndroidSurfaceTexture::surfaceHolder()
-{
- if (!m_surfaceHolder.isValid()) {
- m_surfaceHolder = QJniObject("org/qtproject/qt/android/multimedia/QtSurfaceTextureHolder",
- "(Landroid/view/Surface;)V",
- surface());
- }
-
- return m_surfaceHolder.object();
-}
-
-void AndroidSurfaceTexture::attachToGLContext(quint32 texName)
-{
- if (!m_surfaceTexture.isValid())
- return;
-
- m_surfaceTexture.callMethod<void>("attachToGLContext", "(I)V", texName);
-}
-
-void AndroidSurfaceTexture::detachFromGLContext()
-{
- if (!m_surfaceTexture.isValid())
- return;
-
- m_surfaceTexture.callMethod<void>("detachFromGLContext");
-}
-
-bool AndroidSurfaceTexture::registerNativeMethods()
-{
- static const JNINativeMethod methods[] = {
- {"notifyFrameAvailable", "(J)V", (void *)notifyFrameAvailable}
- };
- const int size = std::size(methods);
- if (QJniEnvironment().registerNativeMethods(QtSurfaceTextureListenerClassName, methods, size))
- return false;
-
- return true;
-}
-
-void AndroidSurfaceTexture::setOnFrameAvailableListener(const QJniObject &listener)
-{
- m_surfaceTexture.callMethod<void>("setOnFrameAvailableListener",
- "(Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;)V",
- listener.object());
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/android/wrappers/jni/androidsurfacetexture_p.h b/src/multimedia/platform/android/wrappers/jni/androidsurfacetexture_p.h
deleted file mode 100644
index d31df972b..000000000
--- a/src/multimedia/platform/android/wrappers/jni/androidsurfacetexture_p.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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
-
-//
-// 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 <qobject.h>
-#include <QtCore/qjniobject.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 registerNativeMethods();
-
-Q_SIGNALS:
- void frameAvailable();
-
-private:
- void setOnFrameAvailableListener(const QJniObject &listener);
-
- QJniObject m_surfaceTexture;
- QJniObject m_surface;
- QJniObject m_surfaceHolder;
-};
-
-QT_END_NAMESPACE
-
-#endif // ANDROIDSURFACETEXTURE_H
diff --git a/src/multimedia/platform/android/wrappers/jni/androidsurfaceview.cpp b/src/multimedia/platform/android/wrappers/jni/androidsurfaceview.cpp
deleted file mode 100644
index 33d15a91b..000000000
--- a/src/multimedia/platform/android/wrappers/jni/androidsurfaceview.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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_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(QJniObject object)
- : m_surfaceHolder(object)
- , m_surfaceCreated(false)
-{
- if (!m_surfaceHolder.isValid())
- return;
-
- {
- QMutexLocker locker(shLock());
- surfaceHolders->append(this);
- }
-
- QJniObject 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::registerNativeMethods()
-{
- static const JNINativeMethod methods[] = {
- {"notifySurfaceCreated", "(J)V", (void *)AndroidSurfaceHolder::handleSurfaceCreated},
- {"notifySurfaceDestroyed", "(J)V", (void *)AndroidSurfaceHolder::handleSurfaceDestroyed}
- };
-
- const int size = std::size(methods);
- return QJniEnvironment().registerNativeMethods(QtSurfaceHolderCallbackClassName, methods, size);
-}
-
-AndroidSurfaceView::AndroidSurfaceView()
- : m_window(0)
- , m_surfaceHolder(0)
- , m_pendingVisible(-1)
-{
- QNativeInterface::QAndroidApplication::runOnAndroidMainThread([this] {
- m_surfaceView = QJniObject("android/view/SurfaceView",
- "(Landroid/content/Context;)V",
- QNativeInterface::QAndroidApplication::context());
- }).waitForFinished();
-
- Q_ASSERT(m_surfaceView.isValid());
-
- QJniObject holder = m_surfaceView.callObjectMethod("getHolder",
- "()Landroid/view/SurfaceHolder;");
- if (!holder.isValid()) {
- m_surfaceView = QJniObject();
- } 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/multimedia/platform/android/wrappers/jni/androidsurfaceview_p.h b/src/multimedia/platform/android/wrappers/jni/androidsurfaceview_p.h
deleted file mode 100644
index cd0badc34..000000000
--- a/src/multimedia/platform/android/wrappers/jni/androidsurfaceview_p.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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
-
-//
-// 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 <QtCore/qjniobject.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 registerNativeMethods();
-
-Q_SIGNALS:
- void surfaceCreated();
-
-private:
- AndroidSurfaceHolder(QJniObject object);
-
- static void handleSurfaceCreated(JNIEnv*, jobject, jlong id);
- static void handleSurfaceDestroyed(JNIEnv*, jobject, jlong id);
-
- QJniObject 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:
- QJniObject m_surfaceView;
- QWindow *m_window;
- AndroidSurfaceHolder *m_surfaceHolder;
- int m_pendingVisible;
- QRect m_pendingGeometry;
-};
-
-QT_END_NAMESPACE
-
-#endif // ANDROIDSURFACEVIEW_H
diff --git a/src/multimedia/platform/darwin/audio/avfaudiodecoder.mm b/src/multimedia/platform/darwin/audio/avfaudiodecoder.mm
deleted file mode 100644
index 079c4b39e..000000000
--- a/src/multimedia/platform/darwin/audio/avfaudiodecoder.mm
+++ /dev/null
@@ -1,529 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "avfaudiodecoder_p.h"
-
-#include <QtCore/qmutex.h>
-#include <QtCore/qiodevice.h>
-#include <QMimeDatabase>
-#include "qcoreaudioutils_p.h"
-
-#include <AVFoundation/AVFoundation.h>
-
-#define MAX_BUFFERS_IN_QUEUE 10
-
-QT_USE_NAMESPACE
-
-@interface AVFResourceReaderDelegate : NSObject <AVAssetResourceLoaderDelegate>
-{
- AVFAudioDecoder *m_decoder;
- QMutex m_mutex;
-}
-
--(void)handleNextSampleBuffer:(CMSampleBufferRef)sampleBuffer;
-
--(BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader
- shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest;
-
-@end
-
-@implementation AVFResourceReaderDelegate
-
--(id)initWithDecoder: (AVFAudioDecoder *)decoder {
- if (!(self = [super init]))
- return nil;
-
- m_decoder = decoder;
-
- return self;
-}
-
--(void)dealloc {
- m_decoder = nil;
- [super dealloc];
-}
-
--(void)handleNextSampleBuffer:(CMSampleBufferRef)sampleBuffer
-{
- if (!sampleBuffer)
- return;
-
- // Check format
- CMFormatDescriptionRef formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer);
- if (!formatDescription)
- return;
- const AudioStreamBasicDescription* const asbd = CMAudioFormatDescriptionGetStreamBasicDescription(formatDescription);
- QAudioFormat qtFormat = CoreAudioUtils::toQAudioFormat(*asbd);
- if (qtFormat.sampleFormat() == QAudioFormat::Unknown && asbd->mBitsPerChannel == 8)
- qtFormat.setSampleFormat(QAudioFormat::UInt8);
- if (!qtFormat.isValid())
- return;
-
- // Get the required size to allocate to audioBufferList
- size_t audioBufferListSize = 0;
- OSStatus err = CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer,
- &audioBufferListSize,
- NULL,
- 0,
- NULL,
- NULL,
- kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment,
- NULL);
- if (err != noErr)
- return;
-
- CMBlockBufferRef blockBuffer = NULL;
- AudioBufferList* audioBufferList = (AudioBufferList*) malloc(audioBufferListSize);
- // This ensures the buffers placed in audioBufferList are contiguous
- err = CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer,
- NULL,
- audioBufferList,
- audioBufferListSize,
- NULL,
- NULL,
- kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment,
- &blockBuffer);
- if (err != noErr) {
- free(audioBufferList);
- return;
- }
-
- QByteArray abuf;
- for (UInt32 i = 0; i < audioBufferList->mNumberBuffers; i++)
- {
- AudioBuffer audioBuffer = audioBufferList->mBuffers[i];
- abuf.push_back(QByteArray((const char*)audioBuffer.mData, audioBuffer.mDataByteSize));
- }
-
- free(audioBufferList);
- CFRelease(blockBuffer);
-
- CMTime sampleStartTime = (CMSampleBufferGetPresentationTimeStamp(sampleBuffer));
- float sampleStartTimeSecs = CMTimeGetSeconds(sampleStartTime);
-
- QAudioBuffer audioBuffer;
- audioBuffer = QAudioBuffer(abuf, qtFormat, qint64(sampleStartTimeSecs * 1000000));
- if (!audioBuffer.isValid())
- return;
-
- emit m_decoder->newAudioBuffer(audioBuffer);
-}
-
--(BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader
- shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest
-{
- Q_UNUSED(resourceLoader);
-
- if (![loadingRequest.request.URL.scheme isEqualToString:@"iodevice"])
- return NO;
-
- QMutexLocker locker(&m_mutex);
-
- QIODevice *device = m_decoder->sourceDevice();
- if (!device)
- return NO;
-
- device->seek(loadingRequest.dataRequest.requestedOffset);
- if (loadingRequest.contentInformationRequest) {
- loadingRequest.contentInformationRequest.contentLength = device->size();
- loadingRequest.contentInformationRequest.byteRangeAccessSupported = YES;
- }
-
- if (loadingRequest.dataRequest) {
- NSInteger requestedLength = loadingRequest.dataRequest.requestedLength;
- int maxBytes = qMin(32 * 1024, 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
-
-namespace {
-
-NSDictionary *av_audio_settings_for_format(const QAudioFormat &format)
-{
- float sampleRate = format.sampleRate();
- int nChannels = format.channelCount();
- int sampleSize = format.bytesPerSample() * 8;
- BOOL isFloat = format.sampleFormat() == QAudioFormat::Float;
-
- NSDictionary *audioSettings = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
- [NSNumber numberWithFloat:sampleRate], AVSampleRateKey,
- [NSNumber numberWithInt:nChannels], AVNumberOfChannelsKey,
- [NSNumber numberWithInt:sampleSize], AVLinearPCMBitDepthKey,
- [NSNumber numberWithBool:isFloat], AVLinearPCMIsFloatKey,
- [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
- [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey,
- nil];
-
- return audioSettings;
-}
-
-QAudioFormat qt_format_for_audio_track(AVAssetTrack *track)
-{
- QAudioFormat format;
- CMFormatDescriptionRef desc = (__bridge CMFormatDescriptionRef)track.formatDescriptions[0];
- const AudioStreamBasicDescription* const asbd =
- CMAudioFormatDescriptionGetStreamBasicDescription(desc);
- format = CoreAudioUtils::toQAudioFormat(*asbd);
- // AudioStreamBasicDescription's mBitsPerChannel is 0 for compressed formats
- // In this case set default Int16 sample format
- if (asbd->mBitsPerChannel == 0)
- format.setSampleFormat(QAudioFormat::Int16);
- return format;
-}
-
-}
-
-AVFAudioDecoder::AVFAudioDecoder(QAudioDecoder *parent)
- : QPlatformAudioDecoder(parent)
-{
- m_readingQueue = dispatch_queue_create("reader_queue", DISPATCH_QUEUE_SERIAL);
- m_decodingQueue = dispatch_queue_create("decoder_queue", DISPATCH_QUEUE_SERIAL);
-
- m_readerDelegate = [[AVFResourceReaderDelegate alloc] initWithDecoder:this];
-
- connect(this, &AVFAudioDecoder::readyToRead, this, &AVFAudioDecoder::startReading);
- connect(this, &AVFAudioDecoder::newAudioBuffer, this, &AVFAudioDecoder::handleNewAudioBuffer);
-}
-
-AVFAudioDecoder::~AVFAudioDecoder()
-{
- stop();
-
- [m_readerOutput release];
- m_readerOutput = nil;
-
- [m_reader release];
- m_reader = nil;
-
- [m_readerDelegate release];
- m_readerDelegate = nil;
-
- [m_asset release];
- m_asset = nil;
-
- if (m_readingQueue)
- dispatch_release(m_readingQueue);
- if (m_decodingQueue)
- dispatch_release(m_decodingQueue);
-}
-
-QUrl AVFAudioDecoder::source() const
-{
- return m_source;
-}
-
-void AVFAudioDecoder::setSource(const QUrl &fileName)
-{
- if (!m_device && m_source == fileName)
- return;
-
- stop();
- m_device = nullptr;
- [m_asset release];
- m_asset = nil;
-
- m_source = fileName;
-
- if (!m_source.isEmpty()) {
- NSURL *nsURL = m_source.toNSURL();
- m_asset = [[AVURLAsset alloc] initWithURL:nsURL options:nil];
- }
-
- emit sourceChanged();
-}
-
-QIODevice *AVFAudioDecoder::sourceDevice() const
-{
- return m_device;
-}
-
-void AVFAudioDecoder::setSourceDevice(QIODevice *device)
-{
- if (m_device == device && m_source.isEmpty())
- return;
-
- stop();
- m_source.clear();
- [m_asset release];
- m_asset = nil;
-
- m_device = device;
-
- if (m_device) {
- const QString ext = QMimeDatabase().mimeTypeForData(m_device).preferredSuffix();
- const QString url = "iodevice:///iodevice." + ext;
- NSString *urlString = url.toNSString();
- NSURL *nsURL = [NSURL URLWithString:urlString];
-
- m_asset = [[AVURLAsset alloc] initWithURL:nsURL options:nil];
- [m_asset.resourceLoader setDelegate:m_readerDelegate queue:m_readingQueue];
-
- m_loadingSource = true;
- }
-
- emit sourceChanged();
-}
-
-void AVFAudioDecoder::start()
-{
- Q_ASSERT(!m_buffersAvailable);
- if (isDecoding())
- return;
-
- if (m_position != -1) {
- m_position = -1;
- emit positionChanged(-1);
- }
-
- if (m_device && (!m_device->isOpen() || !m_device->isReadable())) {
- processInvalidMedia(QAudioDecoder::AccessDeniedError, tr("Unable to read from specified device"));
- return;
- }
-
- [m_asset loadValuesAsynchronouslyForKeys:@[@"tracks"] completionHandler:
- ^{
- dispatch_async(m_readingQueue,
- ^{
- NSError *error = nil;
- AVKeyValueStatus status = [m_asset statusOfValueForKey:@"tracks" error:&error];
- if (status != AVKeyValueStatusLoaded) {
- if (status == AVKeyValueStatusFailed) {
- if (error.domain == NSURLErrorDomain)
- processInvalidMedia(QAudioDecoder::ResourceError, QString::fromNSString(error.localizedDescription));
- else
- processInvalidMedia(QAudioDecoder::FormatError, tr("Could not load media source's tracks"));
- }
- return;
- }
- initAssetReader();
- });
- }
- ];
-
- if (m_device && m_loadingSource) {
- setIsDecoding(true);
- return;
- }
-}
-
-void AVFAudioDecoder::stop()
-{
- m_cachedBuffers.clear();
-
- if (m_reader)
- [m_reader cancelReading];
-
- 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);
- }
- setIsDecoding(false);
-}
-
-QAudioFormat AVFAudioDecoder::audioFormat() const
-{
- return m_format;
-}
-
-void AVFAudioDecoder::setAudioFormat(const QAudioFormat &format)
-{
- if (m_format != format) {
- m_format = format;
- emit formatChanged(m_format);
- }
-}
-
-QAudioBuffer AVFAudioDecoder::read()
-{
- if (!m_buffersAvailable)
- return QAudioBuffer();
-
- Q_ASSERT(m_cachedBuffers.size() > 0);
- QAudioBuffer buffer = m_cachedBuffers.takeFirst();
-
- m_position = qint64(buffer.startTime() / 1000);
- emit positionChanged(m_position);
-
- m_buffersAvailable--;
- if (!m_buffersAvailable)
- emit bufferAvailableChanged(false);
- return buffer;
-}
-
-bool AVFAudioDecoder::bufferAvailable() const
-{
- return m_buffersAvailable > 0;
-}
-
-qint64 AVFAudioDecoder::position() const
-{
- return m_position;
-}
-
-qint64 AVFAudioDecoder::duration() const
-{
- return m_duration;
-}
-
-void AVFAudioDecoder::processInvalidMedia(QAudioDecoder::Error errorCode, const QString& errorString)
-{
- stop();
- emit error(int(errorCode), errorString);
-}
-
-void AVFAudioDecoder::initAssetReader()
-{
- if (!m_asset)
- return;
-
- NSArray<AVAssetTrack *> *tracks = [m_asset tracksWithMediaType:AVMediaTypeAudio];
- if (!tracks.count) {
- processInvalidMedia(QAudioDecoder::FormatError, tr("No audio tracks found"));
- return;
- }
- AVAssetTrack *track = [tracks objectAtIndex:0];
-
- // Set format
- QAudioFormat format;
- if (m_format.isValid()) {
- format = m_format;
- } else {
- format = qt_format_for_audio_track(track);
- if (!format.isValid())
- {
- processInvalidMedia(QAudioDecoder::FormatError, tr("Unsupported source format"));
- return;
- }
- }
-
- // Set duration
- qint64 duration = CMTimeGetSeconds(track.timeRange.duration) * 1000;
- if (m_duration != duration) {
- m_duration = duration;
- emit durationChanged(m_duration);
- }
-
- // Initialize asset reader and output
- [m_reader release];
- m_reader = nil;
- [m_readerOutput release];
- m_readerOutput = nil;
-
- NSError *error = nil;
- NSDictionary *audioSettings = av_audio_settings_for_format(format);
- m_readerOutput = [[AVAssetReaderTrackOutput alloc] initWithTrack:track outputSettings:audioSettings];
- m_reader = [[AVAssetReader alloc] initWithAsset:m_asset error:&error];
- if (error) {
- processInvalidMedia(QAudioDecoder::ResourceError, QString::fromNSString(error.localizedDescription));
- return;
- }
- if (![m_reader canAddOutput:m_readerOutput]) {
- processInvalidMedia(QAudioDecoder::ResourceError, tr("Failed to add asset reader output"));
- return;
- }
- [m_reader addOutput:m_readerOutput];
-
- emit readyToRead();
-}
-
-void AVFAudioDecoder::startReading()
-{
- m_loadingSource = false;
-
- // Prepares the receiver for obtaining sample buffers from the asset.
- if (!m_reader || ![m_reader startReading]) {
- processInvalidMedia(QAudioDecoder::ResourceError, tr("Could not start reading"));
- return;
- }
-
- setIsDecoding(true);
-
- // Since copyNextSampleBuffer is synchronous, submit it to an async dispatch queue
- // to run in a separate thread. Call the handleNextSampleBuffer "callback" on another
- // thread when new audio sample is read.
- dispatch_async(m_readingQueue, ^{
- CMSampleBufferRef sampleBuffer;
- while ((sampleBuffer = [m_readerOutput copyNextSampleBuffer])) {
- dispatch_async(m_decodingQueue, ^{
- if (CMSampleBufferDataIsReady(sampleBuffer))
- [m_readerDelegate handleNextSampleBuffer:sampleBuffer];
- CFRelease(sampleBuffer);
- });
- }
- if (m_reader.status == AVAssetReaderStatusCompleted)
- emit finished();
- });
-}
-
-void AVFAudioDecoder::handleNewAudioBuffer(QAudioBuffer buffer)
-{
- Q_ASSERT(m_cachedBuffers.size() <= MAX_BUFFERS_IN_QUEUE);
- m_cachedBuffers.push_back(buffer);
-
- m_buffersAvailable++;
- Q_ASSERT(m_buffersAvailable <= MAX_BUFFERS_IN_QUEUE);
-
- emit bufferAvailableChanged(true);
- emit bufferReady();
-}
diff --git a/src/multimedia/platform/darwin/audio/avfaudiodecoder_p.h b/src/multimedia/platform/darwin/audio/avfaudiodecoder_p.h
deleted file mode 100644
index 73a8cbd38..000000000
--- a/src/multimedia/platform/darwin/audio/avfaudiodecoder_p.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 AVFAUDIODECODER_H
-#define AVFAUDIODECODER_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 <QtMultimedia/private/qtmultimediaglobal_p.h>
-#include <QObject>
-#include <QtCore/qurl.h>
-
-#include "private/qplatformaudiodecoder_p.h"
-#include "qaudiodecoder.h"
-
-#include <dispatch/dispatch.h>
-
-Q_FORWARD_DECLARE_OBJC_CLASS(AVURLAsset);
-Q_FORWARD_DECLARE_OBJC_CLASS(AVAssetReader);
-Q_FORWARD_DECLARE_OBJC_CLASS(AVAssetReaderTrackOutput);
-Q_FORWARD_DECLARE_OBJC_CLASS(AVFResourceReaderDelegate);
-
-QT_BEGIN_NAMESPACE
-
-class AVFAudioDecoder : public QPlatformAudioDecoder
-{
- Q_OBJECT
-
-public:
- AVFAudioDecoder(QAudioDecoder *parent);
- virtual ~AVFAudioDecoder();
-
- QUrl source() const override;
- void setSource(const QUrl &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;
-
-private slots:
- void handleNewAudioBuffer(QAudioBuffer);
- void startReading();
-
-signals:
- void newAudioBuffer(QAudioBuffer);
- void readyToRead();
-
-private:
- void processInvalidMedia(QAudioDecoder::Error errorCode, const QString& errorString);
- void initAssetReader();
-
- QUrl m_source;
- QIODevice *m_device = nullptr;
- QAudioFormat m_format;
-
- int m_buffersAvailable = 0;
- QList<QAudioBuffer> m_cachedBuffers;
-
- qint64 m_position = -1;
- qint64 m_duration = -1;
-
- bool m_loadingSource = false;
-
- AVURLAsset *m_asset = nullptr;
- AVAssetReader *m_reader = nullptr;
- AVAssetReaderTrackOutput *m_readerOutput = nullptr;
- AVFResourceReaderDelegate *m_readerDelegate = nullptr;
- dispatch_queue_t m_readingQueue;
- dispatch_queue_t m_decodingQueue;
-};
-
-QT_END_NAMESPACE
-
-#endif // AVFAUDIODECODER_H
diff --git a/src/multimedia/platform/darwin/audio/qcoreaudiosessionmanager.mm b/src/multimedia/platform/darwin/audio/qcoreaudiosessionmanager.mm
deleted file mode 100644
index 264935d74..000000000
--- a/src/multimedia/platform/darwin/audio/qcoreaudiosessionmanager.mm
+++ /dev/null
@@ -1,473 +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 "qcoreaudiosessionmanager_p.h"
-#import <AVFoundation/AVAudioSession.h>
-#import <Foundation/Foundation.h>
-
-QT_BEGIN_NAMESPACE
-
-@interface CoreAudioSessionObserver : NSObject
-{
- CoreAudioSessionManager *m_sessionManager;
- AVAudioSession *m_audioSession;
-}
-
-@property (readonly, getter=sessionManager) CoreAudioSessionManager *m_sessionManager;
-@property (readonly, getter=audioSession) AVAudioSession *m_audioSession;
-
--(CoreAudioSessionObserver *)initWithAudioSessionManager:(CoreAudioSessionManager *)sessionManager;
-
--(BOOL)activateAudio;
--(BOOL)deactivateAudio;
-
-//Notification handlers
--(void)audioSessionInterruption:(NSNotification *)notification;
--(void)audioSessionRouteChange:(NSNotification *)notification;
--(void)audioSessionMediaServicesWereReset:(NSNotification *)notification;
-
-@end //interface CoreAudioSessionObserver
-
-@implementation CoreAudioSessionObserver
-
-@synthesize m_sessionManager, m_audioSession;
-
--(CoreAudioSessionObserver *)initWithAudioSessionManager:(CoreAudioSessionManager *)sessionManager
-{
- if (!(self = [super init]))
- return nil;
-
- self->m_sessionManager = sessionManager;
- self->m_audioSession = [AVAudioSession sharedInstance];
-
- //Set up observers
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(audioSessionInterruption:)
- name:AVAudioSessionInterruptionNotification
- object:self->m_audioSession];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(audioSessionMediaServicesWereReset:)
- name:AVAudioSessionMediaServicesWereResetNotification
- object:self->m_audioSession];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(audioSessionRouteChange:)
- name:AVAudioSessionRouteChangeNotification
- object:self->m_audioSession];
-
- return self;
-}
-
--(void)dealloc
-{
-#ifdef QT_DEBUG_COREAUDIO
- qDebug() << Q_FUNC_INFO;
-#endif
-
- [[NSNotificationCenter defaultCenter] removeObserver:self
- name:AVAudioSessionInterruptionNotification
- object:self->m_audioSession];
- [[NSNotificationCenter defaultCenter] removeObserver:self
- name:AVAudioSessionMediaServicesWereResetNotification
- object:self->m_audioSession];
- [[NSNotificationCenter defaultCenter] removeObserver:self
- name:AVAudioSessionRouteChangeNotification
- object:self->m_audioSession];
-
- [super dealloc];
-}
-
--(BOOL)activateAudio
-{
- NSError *error = nil;
- BOOL success = [self->m_audioSession setActive:YES error:&error];
- if (![self->m_audioSession setActive:YES error:&error]) {
-#ifdef QT_DEBUG_COREAUDIO
- qDebug("audio session activation failed: %s", [[error localizedDescription] UTF8String]);
- } else {
- qDebug("audio session activated");
-#endif
- }
-
- return success;
-}
-
--(BOOL)deactivateAudio
-{
- NSError *error = nil;
- BOOL success = [m_audioSession setActive:NO error:&error];
-#ifdef QT_DEBUG_COREAUDIO
- if (!success) {
- qDebug("%s", [[error localizedDescription] UTF8String]);
- }
-#endif
- return success;
-}
-
--(void)audioSessionInterruption:(NSNotification *)notification
-{
- NSNumber *type = [[notification userInfo] valueForKey:AVAudioSessionInterruptionTypeKey];
- if ([type intValue] == AVAudioSessionInterruptionTypeBegan) {
-#ifdef QT_DEBUG_COREAUDIO
- qDebug("audioSession Interuption begain");
-#endif
- } else if ([type intValue] == AVAudioSessionInterruptionTypeEnded) {
-#ifdef QT_DEBUG_COREAUDIO
- qDebug("audioSession Interuption ended");
-#endif
- NSNumber *option = [[notification userInfo] valueForKey:AVAudioSessionInterruptionOptionKey];
- if ([option intValue] == AVAudioSessionInterruptionOptionShouldResume) {
-#ifdef QT_DEBUG_COREAUDIO
- qDebug("audioSession is active and immediately ready to be used.");
-#endif
- } else {
- [self activateAudio];
- }
- }
-}
-
--(void)audioSessionMediaServicesWereReset:(NSNotification *)notification
-{
- Q_UNUSED(notification);
-#ifdef QT_DEBUG_COREAUDIO
- qDebug("audioSession Media Services were reset");
-#endif
- //Reactivate audio when this occurs
- [self activateAudio];
-}
-
--(void)audioSessionRouteChange:(NSNotification *)notification
-{
- NSNumber *reason = [[notification userInfo] valueForKey:AVAudioSessionRouteChangeReasonKey];
- NSUInteger reasonEnum = [reason intValue];
-
- if (reasonEnum == AVAudioSessionRouteChangeReasonUnknown) {
-#ifdef QT_DEBUG_COREAUDIO
- qDebug("audioSession route changed. reason: unknown");
-#endif
- } else if (reasonEnum == AVAudioSessionRouteChangeReasonNewDeviceAvailable) {
-#ifdef QT_DEBUG_COREAUDIO
- qDebug("audioSession route changed. reason: new device available");
-#endif
- } else if (reasonEnum == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {
-#ifdef QT_DEBUG_COREAUDIO
- qDebug("audioSession route changed. reason: old device unavailable");
-#endif
- } else if (reasonEnum == AVAudioSessionRouteChangeReasonCategoryChange) {
-#ifdef QT_DEBUG_COREAUDIO
- qDebug("audioSession route changed. reason: category changed");
-#endif
- } else if (reasonEnum == AVAudioSessionRouteChangeReasonOverride) {
-#ifdef QT_DEBUG_COREAUDIO
- qDebug("audioSession route changed. reason: override");
-#endif
- } else if (reasonEnum == AVAudioSessionRouteChangeReasonWakeFromSleep) {
-#ifdef QT_DEBUG_COREAUDIO
- qDebug("audioSession route changed. reason: woken from sleep");
-#endif
- } else if (reasonEnum == AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory) {
-#ifdef QT_DEBUG_COREAUDIO
- qDebug("audioSession route changed. reason: no suitable route for category");
-#endif
- }
-
- m_sessionManager->devicesAvailableChanged();
-}
-
-@end //implementation CoreAudioSessionObserver
-
-CoreAudioSessionManager::CoreAudioSessionManager() :
- QObject(0)
-{
- m_sessionObserver = [[CoreAudioSessionObserver alloc] initWithAudioSessionManager:this];
-}
-
-CoreAudioSessionManager::~CoreAudioSessionManager()
-{
-#ifdef QT_DEBUG_COREAUDIO
- qDebug() << Q_FUNC_INFO;
-#endif
- [m_sessionObserver release];
-}
-
-
-CoreAudioSessionManager &CoreAudioSessionManager::instance()
-{
- static CoreAudioSessionManager instance;
- return instance;
-}
-
-bool CoreAudioSessionManager::setActive(bool active)
-{
- if (active) {
- return [m_sessionObserver activateAudio];
- } else {
- return [m_sessionObserver deactivateAudio];
- }
-}
-
-bool CoreAudioSessionManager::setCategory(CoreAudioSessionManager::AudioSessionCategorys category, CoreAudioSessionManager::AudioSessionCategoryOptions options)
-{
- NSString *targetCategory = nil;
-
- switch (category) {
- case CoreAudioSessionManager::Ambient:
- targetCategory = AVAudioSessionCategoryAmbient;
- break;
- case CoreAudioSessionManager::SoloAmbient:
- targetCategory = AVAudioSessionCategorySoloAmbient;
- break;
- case CoreAudioSessionManager::Playback:
- targetCategory = AVAudioSessionCategoryPlayback;
- break;
- case CoreAudioSessionManager::Record:
- targetCategory = AVAudioSessionCategoryRecord;
- break;
- case CoreAudioSessionManager::PlayAndRecord:
- targetCategory = AVAudioSessionCategoryPlayAndRecord;
- break;
- case CoreAudioSessionManager::AudioProcessing:
-#ifndef Q_OS_TVOS
- targetCategory = AVAudioSessionCategoryAudioProcessing;
-#endif
- break;
- case CoreAudioSessionManager::MultiRoute:
- targetCategory = AVAudioSessionCategoryMultiRoute;
- break;
- }
-
- if (targetCategory == nil)
- return false;
-
- return [[m_sessionObserver audioSession] setCategory:targetCategory
- withOptions:(AVAudioSessionCategoryOptions)options
- error:nil];
-}
-
-bool CoreAudioSessionManager::setMode(CoreAudioSessionManager::AudioSessionModes mode)
-{
- NSString *targetMode = nil;
- switch (mode) {
- case CoreAudioSessionManager::Default:
- targetMode = AVAudioSessionModeDefault;
- break;
- case CoreAudioSessionManager::VoiceChat:
- targetMode = AVAudioSessionModeVoiceChat;
- break;
- case CoreAudioSessionManager::GameChat:
- targetMode = AVAudioSessionModeGameChat;
- break;
- case CoreAudioSessionManager::VideoRecording:
- targetMode = AVAudioSessionModeVideoRecording;
- break;
- case CoreAudioSessionManager::Measurement:
- targetMode = AVAudioSessionModeMeasurement;
- break;
- case CoreAudioSessionManager::MoviePlayback:
- targetMode = AVAudioSessionModeMoviePlayback;
- break;
- }
-
- if (targetMode == nil)
- return false;
-
- return [[m_sessionObserver audioSession] setMode:targetMode error:nil];
-
-}
-
-CoreAudioSessionManager::AudioSessionCategorys CoreAudioSessionManager::category()
-{
- NSString *category = [[m_sessionObserver audioSession] category];
- AudioSessionCategorys localCategory = Ambient;
-
- if (category == AVAudioSessionCategoryAmbient) {
- localCategory = Ambient;
- } else if (category == AVAudioSessionCategorySoloAmbient) {
- localCategory = SoloAmbient;
- } else if (category == AVAudioSessionCategoryPlayback) {
- localCategory = Playback;
- } else if (category == AVAudioSessionCategoryRecord) {
- localCategory = Record;
- } else if (category == AVAudioSessionCategoryPlayAndRecord) {
- localCategory = PlayAndRecord;
-#ifndef Q_OS_TVOS
- } else if (category == AVAudioSessionCategoryAudioProcessing) {
- localCategory = AudioProcessing;
-#endif
- } else if (category == AVAudioSessionCategoryMultiRoute) {
- localCategory = MultiRoute;
- }
-
- return localCategory;
-}
-
-CoreAudioSessionManager::AudioSessionModes CoreAudioSessionManager::mode()
-{
- NSString *mode = [[m_sessionObserver audioSession] mode];
- AudioSessionModes localMode = Default;
-
- if (mode == AVAudioSessionModeDefault) {
- localMode = Default;
- } else if (mode == AVAudioSessionModeVoiceChat) {
- localMode = VoiceChat;
- } else if (mode == AVAudioSessionModeGameChat) {
- localMode = GameChat;
- } else if (mode == AVAudioSessionModeVideoRecording) {
- localMode = VideoRecording;
- } else if (mode == AVAudioSessionModeMeasurement) {
- localMode = Measurement;
- } else if (mode == AVAudioSessionModeMoviePlayback) {
- localMode = MoviePlayback;
- }
-
- return localMode;
-}
-
-QList<QByteArray> CoreAudioSessionManager::inputDevices()
-{
- //TODO: Add support for USB input devices
- //Right now the default behavior on iOS is to have only one input route
- //at a time.
- QList<QByteArray> inputDevices;
- inputDevices << "default";
- return inputDevices;
-}
-
-QList<QByteArray> CoreAudioSessionManager::outputDevices()
-{
- //TODO: Add support for USB output devices
- //Right now the default behavior on iOS is to have only one output route
- //at a time.
- QList<QByteArray> outputDevices;
- outputDevices << "default";
- return outputDevices;
-}
-
-float CoreAudioSessionManager::currentIOBufferDuration()
-{
- return [[m_sessionObserver audioSession] IOBufferDuration];
-}
-
-float CoreAudioSessionManager::preferredSampleRate()
-{
- return [[m_sessionObserver audioSession] preferredSampleRate];
-}
-
-#ifdef QT_DEBUG_COREAUDIO
-QDebug operator<<(QDebug dbg, CoreAudioSessionManager::AudioSessionCategorys category)
-{
- QDebug output = dbg.nospace();
- switch (category) {
- case CoreAudioSessionManager::Ambient:
- output << "AudioSessionCategoryAmbient";
- break;
- case CoreAudioSessionManager::SoloAmbient:
- output << "AudioSessionCategorySoloAmbient";
- break;
- case CoreAudioSessionManager::Playback:
- output << "AudioSessionCategoryPlayback";
- break;
- case CoreAudioSessionManager::Record:
- output << "AudioSessionCategoryRecord";
- break;
- case CoreAudioSessionManager::PlayAndRecord:
- output << "AudioSessionCategoryPlayAndRecord";
- break;
- case CoreAudioSessionManager::AudioProcessing:
- output << "AudioSessionCategoryAudioProcessing";
- break;
- case CoreAudioSessionManager::MultiRoute:
- output << "AudioSessionCategoryMultiRoute";
- break;
- }
- return output;
-}
-
-QDebug operator<<(QDebug dbg, CoreAudioSessionManager::AudioSessionCategoryOptions option)
-{
- QDebug output = dbg.nospace();
- switch (option) {
- case CoreAudioSessionManager::None:
- output << "AudioSessionCategoryOptionNone";
- break;
- case CoreAudioSessionManager::MixWithOthers:
- output << "AudioSessionCategoryOptionMixWithOthers";
- break;
- case CoreAudioSessionManager::DuckOthers:
- output << "AudioSessionCategoryOptionDuckOthers";
- break;
- case CoreAudioSessionManager::AllowBluetooth:
- output << "AudioSessionCategoryOptionAllowBluetooth";
- break;
- case CoreAudioSessionManager::DefaultToSpeaker:
- output << "AudioSessionCategoryOptionDefaultToSpeaker";
- break;
- }
- return output;
-}
-
-QDebug operator<<(QDebug dbg, CoreAudioSessionManager::AudioSessionModes mode)
-{
- QDebug output = dbg.nospace();
- switch (mode) {
- case CoreAudioSessionManager::Default:
- output << "AudioSessionModeDefault";
- break;
- case CoreAudioSessionManager::VoiceChat:
- output << "AudioSessionModeVoiceChat";
- break;
- case CoreAudioSessionManager::GameChat:
- output << "AudioSessionModeGameChat";
- break;
- case CoreAudioSessionManager::VideoRecording:
- output << "AudioSessionModeVideoRecording";
- break;
- case CoreAudioSessionManager::Measurement:
- output << "AudioSessionModeMeasurement";
- break;
- case CoreAudioSessionManager::MoviePlayback:
- output << "AudioSessionModeMoviePlayback";
- break;
- }
- return output;
-}
-#endif
-
-QT_END_NAMESPACE
-
-#include "moc_qcoreaudiosessionmanager_p.cpp"
diff --git a/src/multimedia/platform/darwin/audio/qcoreaudiosessionmanager_p.h b/src/multimedia/platform/darwin/audio/qcoreaudiosessionmanager_p.h
deleted file mode 100644
index 7b2a5294f..000000000
--- a/src/multimedia/platform/darwin/audio/qcoreaudiosessionmanager_p.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** 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 IOSAUDIOSESSIONMANAGER_H
-#define IOSAUDIOSESSIONMANAGER_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 <QObject>
-#ifdef QT_DEBUG_COREAUDIO
-# include <QtCore/QDebug>
-#endif
-
-@class CoreAudioSessionObserver;
-
-QT_BEGIN_NAMESPACE
-
-class CoreAudioSessionManager : public QObject
-{
- Q_OBJECT
-public:
- enum AudioSessionCategorys {
- Ambient,
- SoloAmbient,
- Playback,
- Record,
- PlayAndRecord,
- AudioProcessing,
- MultiRoute
- };
- enum AudioSessionCategoryOptions {
- None = 0,
- MixWithOthers = 1,
- DuckOthers = 2,
- AllowBluetooth = 4,
- DefaultToSpeaker = 8
- };
- enum AudioSessionModes {
- Default,
- VoiceChat,
- GameChat,
- VideoRecording,
- Measurement,
- MoviePlayback
- };
-
- static CoreAudioSessionManager& instance();
-
- bool setActive(bool active);
- bool setCategory(AudioSessionCategorys category, AudioSessionCategoryOptions options = None);
- bool setMode(AudioSessionModes mode);
-
- AudioSessionCategorys category();
- AudioSessionModes mode();
-
- QList<QByteArray> inputDevices();
- QList<QByteArray> outputDevices();
-
- float currentIOBufferDuration();
- float preferredSampleRate();
-
-signals:
- void activeChanged();
- void categoryChanged();
- void modeChanged();
- void routeChanged();
- void devicesAvailableChanged();
-
-private:
- CoreAudioSessionManager();
- ~CoreAudioSessionManager();
- CoreAudioSessionManager(CoreAudioSessionManager const &copy);
- CoreAudioSessionManager& operator =(CoreAudioSessionManager const &copy);
-
- CoreAudioSessionObserver *m_sessionObserver;
-};
-
-#ifdef QT_DEBUG_COREAUDIO
-QDebug operator <<(QDebug dbg, CoreAudioSessionManager::AudioSessionCategorys category);
-QDebug operator <<(QDebug dbg, CoreAudioSessionManager::AudioSessionCategoryOptions option);
-QDebug operator <<(QDebug dbg, CoreAudioSessionManager::AudioSessionModes mode);
-#endif
-
-QT_END_NAMESPACE
-
-#endif // IOSAUDIOSESSIONMANAGER_H
diff --git a/src/multimedia/platform/darwin/audio/qcoreaudioutils.mm b/src/multimedia/platform/darwin/audio/qcoreaudioutils.mm
deleted file mode 100644
index 8faa353c7..000000000
--- a/src/multimedia/platform/darwin/audio/qcoreaudioutils.mm
+++ /dev/null
@@ -1,219 +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 plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** 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 "qcoreaudioutils_p.h"
-#include <mach/mach_time.h>
-
-QT_BEGIN_NAMESPACE
-
-double CoreAudioUtils::sFrequency = 0.0;
-bool CoreAudioUtils::sIsInitialized = false;
-
-void CoreAudioUtils::initialize()
-{
- struct mach_timebase_info timeBaseInfo;
- mach_timebase_info(&timeBaseInfo);
- sFrequency = static_cast<double>(timeBaseInfo.denom) / static_cast<double>(timeBaseInfo.numer);
- sFrequency *= 1000000000.0;
-
- sIsInitialized = true;
-}
-
-
-quint64 CoreAudioUtils::currentTime()
-{
- return mach_absolute_time();
-}
-
-double CoreAudioUtils::frequency()
-{
- if (!sIsInitialized)
- initialize();
- return sFrequency;
-}
-
-QAudioFormat CoreAudioUtils::toQAudioFormat(AudioStreamBasicDescription const& sf)
-{
- QAudioFormat audioFormat;
- // all Darwin HW is little endian, we ignore those formats
- if ((sf.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0 && QSysInfo::ByteOrder != QSysInfo::LittleEndian)
- return audioFormat;
-
- // filter out the formats we're interested in
- QAudioFormat::SampleFormat format = QAudioFormat::Unknown;
- switch (sf.mBitsPerChannel) {
- case 8:
- if ((sf.mFormatFlags & kAudioFormatFlagIsSignedInteger) == 0)
- format = QAudioFormat::UInt8;
- break;
- case 16:
- if ((sf.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0)
- format = QAudioFormat::Int16;
- break;
- case 32:
- if ((sf.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0)
- format = QAudioFormat::Int32;
- else if ((sf.mFormatFlags & kAudioFormatFlagIsFloat) != 0)
- format = QAudioFormat::Float;
- break;
- default:
- break;
- }
-
- audioFormat.setSampleFormat(format);
- audioFormat.setSampleRate(sf.mSampleRate);
- audioFormat.setChannelCount(sf.mChannelsPerFrame);
-
- return audioFormat;
-}
-
-AudioStreamBasicDescription CoreAudioUtils::toAudioStreamBasicDescription(QAudioFormat const& audioFormat)
-{
- AudioStreamBasicDescription sf;
-
- sf.mFormatFlags = kAudioFormatFlagIsPacked;
- sf.mSampleRate = audioFormat.sampleRate();
- sf.mFramesPerPacket = 1;
- sf.mChannelsPerFrame = audioFormat.channelCount();
- sf.mBitsPerChannel = audioFormat.bytesPerSample() * 8;
- sf.mBytesPerFrame = audioFormat.bytesPerFrame();
- sf.mBytesPerPacket = sf.mFramesPerPacket * sf.mBytesPerFrame;
- sf.mFormatID = kAudioFormatLinearPCM;
-
- switch (audioFormat.sampleFormat()) {
- case QAudioFormat::Int16:
- case QAudioFormat::Int32:
- sf.mFormatFlags |= kAudioFormatFlagIsSignedInteger;
- break;
- case QAudioFormat::Float:
- sf.mFormatFlags |= kAudioFormatFlagIsFloat;
- break;
- case QAudioFormat::UInt8:
- /* default */
- case QAudioFormat::Unknown:
- case QAudioFormat::NSampleFormats:
- break;
- }
-
- return sf;
-}
-
-// QAudioRingBuffer
-CoreAudioRingBuffer::CoreAudioRingBuffer(int bufferSize):
- m_bufferSize(bufferSize)
-{
- m_buffer = new char[m_bufferSize];
- reset();
-}
-
-CoreAudioRingBuffer::~CoreAudioRingBuffer()
-{
- delete[] m_buffer;
-}
-
-CoreAudioRingBuffer::Region CoreAudioRingBuffer::acquireReadRegion(int size)
-{
- const int used = m_bufferUsed.fetchAndAddAcquire(0);
-
- if (used > 0) {
- const int readSize = qMin(size, qMin(m_bufferSize - m_readPos, used));
-
- return readSize > 0 ? Region(m_buffer + m_readPos, readSize) : Region(0, 0);
- }
-
- return Region(0, 0);
-}
-
-void CoreAudioRingBuffer::releaseReadRegion(const CoreAudioRingBuffer::Region &region)
-{
- m_readPos = (m_readPos + region.second) % m_bufferSize;
-
- m_bufferUsed.fetchAndAddRelease(-region.second);
-}
-
-CoreAudioRingBuffer::Region CoreAudioRingBuffer::acquireWriteRegion(int size)
-{
- const int free = m_bufferSize - m_bufferUsed.fetchAndAddAcquire(0);
-
- Region output;
-
- if (free > 0) {
- const int writeSize = qMin(size, qMin(m_bufferSize - m_writePos, free));
- output = writeSize > 0 ? Region(m_buffer + m_writePos, writeSize) : Region(0, 0);
- } else {
- output = Region(0, 0);
- }
-#ifdef QT_DEBUG_COREAUDIO
- qDebug("acquireWriteRegion(%d) free: %d returning Region(%p, %d)", size, free, output.first, output.second);
-#endif
- return output;
-}
-void CoreAudioRingBuffer::releaseWriteRegion(const CoreAudioRingBuffer::Region &region)
-{
- m_writePos = (m_writePos + region.second) % m_bufferSize;
-
- m_bufferUsed.fetchAndAddRelease(region.second);
-#ifdef QT_DEBUG_COREAUDIO
- qDebug("releaseWriteRegion(%p,%d): m_writePos:%d", region.first, region.second, m_writePos);
-#endif
-}
-
-int CoreAudioRingBuffer::used() const
-{
- return m_bufferUsed.loadRelaxed();
-}
-
-int CoreAudioRingBuffer::free() const
-{
- return m_bufferSize - m_bufferUsed.loadRelaxed();
-}
-
-int CoreAudioRingBuffer::size() const
-{
- return m_bufferSize;
-}
-
-void CoreAudioRingBuffer::reset()
-{
- m_readPos = 0;
- m_writePos = 0;
- m_bufferUsed.storeRelaxed(0);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/darwin/audio/qcoreaudioutils_p.h b/src/multimedia/platform/darwin/audio/qcoreaudioutils_p.h
deleted file mode 100644
index 4f9d5d327..000000000
--- a/src/multimedia/platform/darwin/audio/qcoreaudioutils_p.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 plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** 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 IOSAUDIOUTILS_H
-#define IOSAUDIOUTILS_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 <CoreAudio/CoreAudioTypes.h>
-
-#include <QtMultimedia/QAudioFormat>
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-class CoreAudioUtils
-{
-public:
- static quint64 currentTime();
- static double frequency();
- static QAudioFormat toQAudioFormat(const AudioStreamBasicDescription& streamFormat);
- static AudioStreamBasicDescription toAudioStreamBasicDescription(QAudioFormat const& audioFormat);
-
-private:
- static void initialize();
- static double sFrequency;
- static bool sIsInitialized;
-};
-
-class CoreAudioRingBuffer
-{
-public:
- typedef QPair<char*, int> Region;
-
- CoreAudioRingBuffer(int bufferSize);
- ~CoreAudioRingBuffer();
-
- Region acquireReadRegion(int size);
- void releaseReadRegion(Region const& region);
- Region acquireWriteRegion(int size);
- void releaseWriteRegion(Region const& region);
-
- int used() const;
- int free() const;
- int size() const;
-
- void reset();
-
-private:
- int m_bufferSize;
- int m_readPos;
- int m_writePos;
- char* m_buffer;
- QAtomicInt m_bufferUsed;
-};
-
-QT_END_NAMESPACE
-
-#endif // IOSAUDIOUTILS_H
diff --git a/src/multimedia/platform/darwin/audio/qdarwinaudiodevice.mm b/src/multimedia/platform/darwin/audio/qdarwinaudiodevice.mm
deleted file mode 100644
index 8fe6f1a2c..000000000
--- a/src/multimedia/platform/darwin/audio/qdarwinaudiodevice.mm
+++ /dev/null
@@ -1,153 +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 "qdarwinaudiodevice_p.h"
-#include "qcoreaudioutils_p.h"
-#include <private/qcore_mac_p.h>
-
-#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
-# include "qcoreaudiosessionmanager_p.h"
-#endif
-
-#include <QtCore/QDataStream>
-#include <QtCore/QDebug>
-#include <QtCore/QSet>
-#include <QIODevice>
-
-QT_BEGIN_NAMESPACE
-
-#if defined(Q_OS_MACOS)
- QCoreAudioDeviceInfo::QCoreAudioDeviceInfo(AudioDeviceID id, const QByteArray &device, QAudioDevice::Mode mode)
- : QAudioDevicePrivate(device, mode),
- m_deviceId(id)
-#else
- QCoreAudioDeviceInfo::QCoreAudioDeviceInfo(const QByteArray &device, QAudioDevice::Mode mode)
- : QAudioDevicePrivate(device, mode)
-#endif
- {
- preferredFormat = determinePreferredFormat();
- description = getDescription();
- minimumSampleRate = 1;
- maximumSampleRate = 96000;
- minimumChannelCount = 1;
- maximumChannelCount = 16;
- supportedSampleFormats << QAudioFormat::UInt8 << QAudioFormat::Int16 << QAudioFormat::Int32 << QAudioFormat::Float;
- }
-
-
-QAudioFormat QCoreAudioDeviceInfo::determinePreferredFormat() const
-{
- QAudioFormat format;
-
-#if defined(Q_OS_MACOS)
- UInt32 propSize = 0;
- AudioObjectPropertyScope audioDevicePropertyScope = mode == QAudioDevice::Input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
- AudioObjectPropertyAddress audioDevicePropertyStreamsAddress = { kAudioDevicePropertyStreams,
- audioDevicePropertyScope,
- kAudioObjectPropertyElementMaster };
-
- if (AudioObjectGetPropertyDataSize(m_deviceId, &audioDevicePropertyStreamsAddress, 0, NULL, &propSize) == noErr) {
-
- const int sc = propSize / sizeof(AudioStreamID);
-
- if (sc > 0) {
- AudioStreamID* streams = new AudioStreamID[sc];
-
- if (AudioObjectGetPropertyData(m_deviceId, &audioDevicePropertyStreamsAddress, 0, NULL, &propSize, streams) == noErr) {
-
- AudioObjectPropertyAddress audioDevicePhysicalFormatPropertyAddress = { kAudioStreamPropertyPhysicalFormat,
- kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster };
-
- for (int i = 0; i < sc; ++i) {
- if (AudioObjectGetPropertyDataSize(streams[i], &audioDevicePhysicalFormatPropertyAddress, 0, NULL, &propSize) == noErr) {
- AudioStreamBasicDescription sf;
-
- if (AudioObjectGetPropertyData(streams[i], &audioDevicePhysicalFormatPropertyAddress, 0, NULL, &propSize, &sf) == noErr) {
- format = CoreAudioUtils::toQAudioFormat(sf);
- break;
- } else {
- qWarning() << "QAudioDevice: Unable to find perferedFormat for stream";
- }
- } else {
- qWarning() << "QAudioDevice: Unable to find size of perferedFormat for stream";
- }
- }
- }
-
- delete[] streams;
- }
- }
- if (!format.isValid())
-#endif
- {
- format.setSampleRate(44100);
- format.setSampleFormat(QAudioFormat::Int16);
- format.setChannelCount(mode == QAudioDevice::Input ? 1 : 2);
- }
-
- return format;
-}
-
-
-QString QCoreAudioDeviceInfo::getDescription() const
-{
-#ifdef Q_OS_MACOS
- CFStringRef name;
- UInt32 size = sizeof(CFStringRef);
- AudioObjectPropertyScope audioPropertyScope = mode == QAudioDevice::Input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
-
- AudioObjectPropertyAddress audioDeviceNamePropertyAddress = { kAudioObjectPropertyName,
- audioPropertyScope,
- kAudioObjectPropertyElementMaster };
-
- if (AudioObjectGetPropertyData(m_deviceId, &audioDeviceNamePropertyAddress, 0, NULL, &size, &name) != noErr) {
- qWarning() << "QAudioDevice: Unable to find device description";
- return QString();
- }
-
- QString s = QString::fromCFString(name);
- CFRelease(name);
- return s;
-#else
- return QString::fromUtf8(id);
-#endif
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/darwin/audio/qdarwinaudiodevice_p.h b/src/multimedia/platform/darwin/audio/qdarwinaudiodevice_p.h
deleted file mode 100644
index 8a1ad502d..000000000
--- a/src/multimedia/platform/darwin/audio/qdarwinaudiodevice_p.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 IOSAUDIODEVICEINFO_H
-#define IOSAUDIODEVICEINFO_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 <qaudiosystem_p.h>
-#include <private/qaudiodevice_p.h>
-
-#if defined(Q_OS_MACOS)
-# include <CoreAudio/CoreAudio.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QCoreAudioDeviceInfo : public QAudioDevicePrivate
-{
-public:
-#if defined(Q_OS_MACOS)
- QCoreAudioDeviceInfo(AudioDeviceID id, const QByteArray &device, QAudioDevice::Mode mode);
-#else
- QCoreAudioDeviceInfo(const QByteArray &device, QAudioDevice::Mode mode);
-#endif
- ~QCoreAudioDeviceInfo() {}
-
- bool isFormatSupported(const QAudioFormat &format) const;
-
-#if defined(Q_OS_MACOS)
- AudioDeviceID deviceID() const { return m_deviceId; }
-#endif
-private:
- QAudioFormat determinePreferredFormat() const;
- QString getDescription() const;
-#if defined(Q_OS_MACOS)
- AudioDeviceID m_deviceId;
-#endif
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/darwin/audio/qdarwinaudiosink.mm b/src/multimedia/platform/darwin/audio/qdarwinaudiosink.mm
deleted file mode 100644
index 5fd5afbdf..000000000
--- a/src/multimedia/platform/darwin/audio/qdarwinaudiosink.mm
+++ /dev/null
@@ -1,691 +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 "qdarwinaudiosink_p.h"
-#include "qcoreaudiosessionmanager_p.h"
-#include "qdarwinaudiodevice_p.h"
-#include "qcoreaudioutils_p.h"
-#include <private/qdarwinmediadevices_p.h>
-#include <qmediadevices.h>
-
-#include <QtCore/QDataStream>
-#include <QtCore/QTimer>
-#include <QtCore/QDebug>
-
-#include <AudioUnit/AudioUnit.h>
-#include <AudioToolbox/AudioToolbox.h>
-#if defined(Q_OS_OSX)
-# include <AudioUnit/AudioComponent.h>
-#endif
-
-#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
-# include <QtMultimedia/private/qaudiohelpers_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-QDarwinAudioSinkBuffer::QDarwinAudioSinkBuffer(int bufferSize, int maxPeriodSize, const QAudioFormat &audioFormat)
- : m_deviceError(false)
- , m_maxPeriodSize(maxPeriodSize)
- , m_device(0)
-{
- m_buffer = new CoreAudioRingBuffer(bufferSize + (bufferSize % maxPeriodSize == 0 ? 0 : maxPeriodSize - (bufferSize % maxPeriodSize)));
- m_bytesPerFrame = audioFormat.bytesPerFrame();
- m_periodTime = m_maxPeriodSize / m_bytesPerFrame * 1000 / audioFormat.sampleRate();
-
- m_fillTimer = new QTimer(this);
- connect(m_fillTimer, SIGNAL(timeout()), SLOT(fillBuffer()));
-}
-
-QDarwinAudioSinkBuffer::~QDarwinAudioSinkBuffer()
-{
- delete m_buffer;
-}
-
-qint64 QDarwinAudioSinkBuffer::readFrames(char *data, qint64 maxFrames)
-{
- bool wecan = true;
- qint64 framesRead = 0;
-
- while (wecan && framesRead < maxFrames) {
- CoreAudioRingBuffer::Region region = m_buffer->acquireReadRegion((maxFrames - framesRead) * m_bytesPerFrame);
-
- if (region.second > 0) {
- // Ensure that we only read whole frames.
- region.second -= region.second % m_bytesPerFrame;
-
- if (region.second > 0) {
- memcpy(data + (framesRead * m_bytesPerFrame), region.first, region.second);
- framesRead += region.second / m_bytesPerFrame;
- } else
- wecan = false; // If there is only a partial frame left we should exit.
- }
- else
- wecan = false;
-
- m_buffer->releaseReadRegion(region);
- }
-
- if (framesRead == 0 && m_deviceError)
- framesRead = -1;
-
- return framesRead;
-}
-
-qint64 QDarwinAudioSinkBuffer::writeBytes(const char *data, qint64 maxSize)
-{
- bool wecan = true;
- qint64 bytesWritten = 0;
-
- maxSize -= maxSize % m_bytesPerFrame;
- while (wecan && bytesWritten < maxSize) {
- CoreAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(maxSize - bytesWritten);
-
- if (region.second > 0) {
- memcpy(region.first, data + bytesWritten, region.second);
- bytesWritten += region.second;
- }
- else
- wecan = false;
-
- m_buffer->releaseWriteRegion(region);
- }
-
- if (bytesWritten > 0)
- emit readyRead();
-
- return bytesWritten;
-}
-
-int QDarwinAudioSinkBuffer::available() const
-{
- return m_buffer->free();
-}
-
-void QDarwinAudioSinkBuffer::reset()
-{
- m_buffer->reset();
- m_device = 0;
- m_deviceError = false;
-}
-
-void QDarwinAudioSinkBuffer::setPrefetchDevice(QIODevice *device)
-{
- if (m_device != device) {
- m_device = device;
- if (m_device != 0)
- fillBuffer();
- }
-}
-
-void QDarwinAudioSinkBuffer::startFillTimer()
-{
- if (m_device != 0)
- m_fillTimer->start(m_buffer->size() / 2 / m_maxPeriodSize * m_periodTime);
-}
-
-void QDarwinAudioSinkBuffer::stopFillTimer()
-{
- m_fillTimer->stop();
-}
-
-void QDarwinAudioSinkBuffer::fillBuffer()
-{
- const int free = m_buffer->free();
- const int writeSize = free - (free % m_maxPeriodSize);
-
- if (writeSize > 0) {
- bool wecan = true;
- int filled = 0;
-
- while (!m_deviceError && wecan && filled < writeSize) {
- CoreAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(writeSize - filled);
-
- if (region.second > 0) {
- region.second = m_device->read(region.first, region.second);
- if (region.second > 0)
- filled += region.second;
- else if (region.second == 0)
- wecan = false;
- else if (region.second < 0) {
- m_fillTimer->stop();
- region.second = 0;
- m_deviceError = true;
- }
- }
- else
- wecan = false;
-
- m_buffer->releaseWriteRegion(region);
- }
-
- if (filled > 0)
- emit readyRead();
- }
-}
-
-QDarwinAudioSinkDevice::QDarwinAudioSinkDevice(QDarwinAudioSinkBuffer *audioBuffer, QObject *parent)
- : QIODevice(parent)
- , m_audioBuffer(audioBuffer)
-{
- open(QIODevice::WriteOnly | QIODevice::Unbuffered);
-}
-
-qint64 QDarwinAudioSinkDevice::readData(char *data, qint64 len)
-{
- Q_UNUSED(data);
- Q_UNUSED(len);
-
- return 0;
-}
-
-qint64 QDarwinAudioSinkDevice::writeData(const char *data, qint64 len)
-{
- return m_audioBuffer->writeBytes(data, len);
-}
-
-QDarwinAudioSink::QDarwinAudioSink(const QAudioDevice &device)
- : m_audioDeviceInfo(device)
-{
- QAudioDevice di = device;
- if (di.isNull())
- di = QMediaDevices::defaultAudioOutput();
-#if defined(Q_OS_MACOS)
- const QCoreAudioDeviceInfo *info = static_cast<const QCoreAudioDeviceInfo *>(di.handle());
- Q_ASSERT(info);
- m_audioDeviceId = info->deviceID();
-#endif
- m_device = di.id();
-
- m_clockFrequency = CoreAudioUtils::frequency() / 1000;
- m_audioThreadState.storeRelaxed(Stopped);
-}
-
-QDarwinAudioSink::~QDarwinAudioSink()
-{
- close();
-}
-
-void QDarwinAudioSink::start(QIODevice *device)
-{
- QIODevice* op = device;
-
- if (!m_audioDeviceInfo.isFormatSupported(m_audioFormat) || !open()) {
- m_stateCode = QAudio::StoppedState;
- m_errorCode = QAudio::OpenError;
- return;
- }
-
- reset();
- m_audioBuffer->reset();
- m_audioBuffer->setPrefetchDevice(op);
-
- if (op == 0) {
- op = m_audioIO;
- m_stateCode = QAudio::IdleState;
- }
- else
- m_stateCode = QAudio::ActiveState;
-
- // Start
- m_pullMode = true;
- m_errorCode = QAudio::NoError;
- m_totalFrames = 0;
-
- if (m_stateCode == QAudio::ActiveState)
- audioThreadStart();
-
- emit stateChanged(m_stateCode);
-}
-
-QIODevice *QDarwinAudioSink::start()
-{
- if (!m_audioDeviceInfo.isFormatSupported(m_audioFormat) || !open()) {
- m_stateCode = QAudio::StoppedState;
- m_errorCode = QAudio::OpenError;
- return m_audioIO;
- }
-
- reset();
- m_audioBuffer->reset();
- m_audioBuffer->setPrefetchDevice(0);
-
- m_stateCode = QAudio::IdleState;
-
- // Start
- m_pullMode = false;
- m_errorCode = QAudio::NoError;
- m_totalFrames = 0;
-
- emit stateChanged(m_stateCode);
-
- return m_audioIO;
-}
-
-void QDarwinAudioSink::stop()
-{
- QMutexLocker lock(&m_mutex);
- if (m_stateCode != QAudio::StoppedState) {
- audioThreadDrain();
-
- m_stateCode = QAudio::StoppedState;
- m_errorCode = QAudio::NoError;
- emit stateChanged(m_stateCode);
- }
-}
-
-void QDarwinAudioSink::reset()
-{
- QMutexLocker lock(&m_mutex);
- if (m_stateCode != QAudio::StoppedState) {
- audioThreadStop();
-
- m_stateCode = QAudio::StoppedState;
- m_errorCode = QAudio::NoError;
- emit stateChanged(m_stateCode);
- }
-}
-
-void QDarwinAudioSink::suspend()
-{
- QMutexLocker lock(&m_mutex);
- if (m_stateCode == QAudio::ActiveState || m_stateCode == QAudio::IdleState) {
- audioThreadStop();
-
- m_stateCode = QAudio::SuspendedState;
- m_errorCode = QAudio::NoError;
- emit stateChanged(m_stateCode);
- }
-}
-
-void QDarwinAudioSink::resume()
-{
- QMutexLocker lock(&m_mutex);
- if (m_stateCode == QAudio::SuspendedState) {
- audioThreadStart();
-
- m_stateCode = m_pullMode ? QAudio::ActiveState : QAudio::IdleState;
- m_errorCode = QAudio::NoError;
- emit stateChanged(m_stateCode);
- }
-}
-
-qsizetype QDarwinAudioSink::bytesFree() const
-{
- return m_audioBuffer->available();
-}
-
-void QDarwinAudioSink::setBufferSize(qsizetype value)
-{
- if (m_stateCode == QAudio::StoppedState)
- m_internalBufferSize = value;
-}
-
-qsizetype QDarwinAudioSink::bufferSize() const
-{
- return m_internalBufferSize;
-}
-
-qint64 QDarwinAudioSink::processedUSecs() const
-{
- return m_totalFrames * 1000000 / m_audioFormat.sampleRate();
-}
-
-QAudio::Error QDarwinAudioSink::error() const
-{
- return m_errorCode;
-}
-
-QAudio::State QDarwinAudioSink::state() const
-{
- return m_stateCode;
-}
-
-void QDarwinAudioSink::setFormat(const QAudioFormat &format)
-{
- if (m_stateCode == QAudio::StoppedState)
- m_audioFormat = format;
-}
-
-QAudioFormat QDarwinAudioSink::format() const
-{
- return m_audioFormat;
-}
-
-void QDarwinAudioSink::setVolume(qreal volume)
-{
- m_cachedVolume = qBound(qreal(0.0), volume, qreal(1.0));
- if (!m_isOpen)
- return;
-
-#if defined(Q_OS_OSX)
- //on OS X the volume can be set directly on the AudioUnit
- if (AudioUnitSetParameter(m_audioUnit,
- kHALOutputParam_Volume,
- kAudioUnitScope_Global,
- 0 /* bus */,
- m_cachedVolume,
- 0) == noErr)
- m_volume = m_cachedVolume;
-#endif
-}
-
-qreal QDarwinAudioSink::volume() const
-{
- return m_cachedVolume;
-}
-
-void QDarwinAudioSink::deviceStopped()
-{
- emit stateChanged(m_stateCode);
-}
-
-void QDarwinAudioSink::inputReady()
-{
- QMutexLocker lock(&m_mutex);
- if (m_stateCode == QAudio::IdleState) {
- audioThreadStart();
-
- m_stateCode = QAudio::ActiveState;
- m_errorCode = QAudio::NoError;
-
- emit stateChanged(m_stateCode);
- }
-}
-
-OSStatus QDarwinAudioSink::renderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
-{
- Q_UNUSED(ioActionFlags);
- Q_UNUSED(inTimeStamp);
- Q_UNUSED(inBusNumber);
- Q_UNUSED(inNumberFrames);
-
- QDarwinAudioSink* d = static_cast<QDarwinAudioSink*>(inRefCon);
-
- const int threadState = d->m_audioThreadState.fetchAndAddAcquire(0);
- if (threadState == Stopped) {
- ioData->mBuffers[0].mDataByteSize = 0;
- d->audioDeviceStop();
- }
- else {
- const UInt32 bytesPerFrame = d->m_streamFormat.mBytesPerFrame;
- qint64 framesRead;
-
- framesRead = d->m_audioBuffer->readFrames((char*)ioData->mBuffers[0].mData,
- ioData->mBuffers[0].mDataByteSize / bytesPerFrame);
-
- if (framesRead > 0) {
- ioData->mBuffers[0].mDataByteSize = framesRead * bytesPerFrame;
- d->m_totalFrames += framesRead;
-
-#if defined(Q_OS_MACOS)
- // If playback is already stopped.
- if (threadState != Running) {
- qreal oldVolume = d->m_cachedVolume;
- // Decrease volume smoothly.
- d->setVolume(d->m_volume / 2);
- d->m_cachedVolume = oldVolume;
- }
-#elif defined(Q_OS_IOS) || defined(Q_OS_TVOS)
- // on iOS we have to adjust the sound volume ourselves
- if (!qFuzzyCompare(d->m_cachedVolume, qreal(1.0f))) {
- QAudioHelperInternal::qMultiplySamples(d->m_cachedVolume,
- d->m_audioFormat,
- ioData->mBuffers[0].mData, /* input */
- ioData->mBuffers[0].mData, /* output */
- ioData->mBuffers[0].mDataByteSize);
- }
-#endif
-
- }
- else {
- ioData->mBuffers[0].mDataByteSize = 0;
- if (framesRead == 0) {
- if (threadState == Draining)
- d->audioDeviceStop();
- else
- d->audioDeviceIdle();
- }
- else
- d->audioDeviceError();
- }
- }
-
- return noErr;
-}
-
-bool QDarwinAudioSink::open()
-{
-#if defined(Q_OS_IOS)
- // Set default category to Ambient (implies MixWithOthers). This makes sure audio stops playing
- // if the screen is locked or if the Silent switch is toggled.
- CoreAudioSessionManager::instance().setCategory(CoreAudioSessionManager::Ambient, CoreAudioSessionManager::None);
- CoreAudioSessionManager::instance().setActive(true);
-#endif
-
- if (m_errorCode != QAudio::NoError)
- return false;
-
- if (m_isOpen) {
- setVolume(m_cachedVolume);
- return true;
- }
-
- AudioComponentDescription componentDescription;
- componentDescription.componentType = kAudioUnitType_Output;
-#if defined(Q_OS_OSX)
- componentDescription.componentSubType = kAudioUnitSubType_HALOutput;
-#else
- componentDescription.componentSubType = kAudioUnitSubType_RemoteIO;
-#endif
- componentDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
- componentDescription.componentFlags = 0;
- componentDescription.componentFlagsMask = 0;
-
- AudioComponent component = AudioComponentFindNext(0, &componentDescription);
- if (component == 0) {
- qWarning() << "QAudioOutput: Failed to find Output component";
- return false;
- }
-
- if (AudioComponentInstanceNew(component, &m_audioUnit) != noErr) {
- qWarning() << "QAudioOutput: Unable to Open Output Component";
- return false;
- }
-
- // register callback
- AURenderCallbackStruct callback;
- callback.inputProc = renderCallback;
- callback.inputProcRefCon = this;
-
- if (AudioUnitSetProperty(m_audioUnit,
- kAudioUnitProperty_SetRenderCallback,
- kAudioUnitScope_Global,
- 0,
- &callback,
- sizeof(callback)) != noErr) {
- qWarning() << "QAudioOutput: Failed to set AudioUnit callback";
- return false;
- }
-
-#if defined(Q_OS_OSX)
- //Set Audio Device
- if (AudioUnitSetProperty(m_audioUnit,
- kAudioOutputUnitProperty_CurrentDevice,
- kAudioUnitScope_Global,
- 0,
- &m_audioDeviceId,
- sizeof(m_audioDeviceId)) != noErr) {
- qWarning() << "QAudioOutput: Unable to use configured device";
- return false;
- }
-#endif
-
- // Set stream format
- m_streamFormat = CoreAudioUtils::toAudioStreamBasicDescription(m_audioFormat);
-
- UInt32 size = sizeof(m_streamFormat);
- if (AudioUnitSetProperty(m_audioUnit,
- kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Input,
- 0,
- &m_streamFormat,
- size) != noErr) {
- qWarning() << "QAudioOutput: Unable to Set Stream information";
- return false;
- }
-
- // Allocate buffer
- UInt32 numberOfFrames = 0;
-#if defined(Q_OS_OSX)
- size = sizeof(UInt32);
- if (AudioUnitGetProperty(m_audioUnit,
- kAudioDevicePropertyBufferFrameSize,
- kAudioUnitScope_Global,
- 0,
- &numberOfFrames,
- &size) != noErr) {
- qWarning() << "QAudioSource: Failed to get audio period size";
- return false;
- }
-#else //iOS
- Float32 bufferSize = CoreAudioSessionManager::instance().currentIOBufferDuration();
- bufferSize *= m_streamFormat.mSampleRate;
- numberOfFrames = bufferSize;
-#endif
-
- m_periodSizeBytes = numberOfFrames * m_streamFormat.mBytesPerFrame;
- if (m_internalBufferSize < m_periodSizeBytes * 2)
- m_internalBufferSize = m_periodSizeBytes * 2;
- else
- m_internalBufferSize -= m_internalBufferSize % m_streamFormat.mBytesPerFrame;
-
- m_audioBuffer = new QDarwinAudioSinkBuffer(m_internalBufferSize, m_periodSizeBytes, m_audioFormat);
- connect(m_audioBuffer, SIGNAL(readyRead()), SLOT(inputReady())); //Pull
-
- m_audioIO = new QDarwinAudioSinkDevice(m_audioBuffer, this);
-
- //Init
- if (AudioUnitInitialize(m_audioUnit)) {
- qWarning() << "QAudioOutput: Failed to initialize AudioUnit";
- return false;
- }
-
- m_isOpen = true;
-
- setVolume(m_cachedVolume);
-
- return true;
-}
-
-void QDarwinAudioSink::close()
-{
- if (m_audioUnit != 0) {
- AudioOutputUnitStop(m_audioUnit);
- AudioUnitUninitialize(m_audioUnit);
- AudioComponentInstanceDispose(m_audioUnit);
- }
-
- delete m_audioBuffer;
-}
-
-void QDarwinAudioSink::audioThreadStart()
-{
- startTimers();
- m_audioThreadState.storeRelaxed(Running);
- AudioOutputUnitStart(m_audioUnit);
-}
-
-void QDarwinAudioSink::audioThreadStop()
-{
- stopTimers();
- if (m_audioThreadState.testAndSetAcquire(Running, Stopped))
- m_threadFinished.wait(&m_mutex, 500);
-}
-
-void QDarwinAudioSink::audioThreadDrain()
-{
- stopTimers();
- if (m_audioThreadState.testAndSetAcquire(Running, Draining))
- m_threadFinished.wait(&m_mutex, 500);
-}
-
-void QDarwinAudioSink::audioDeviceStop()
-{
- AudioOutputUnitStop(m_audioUnit);
- m_audioThreadState.storeRelaxed(Stopped);
- m_threadFinished.wakeOne();
-}
-
-void QDarwinAudioSink::audioDeviceIdle()
-{
- if (m_stateCode == QAudio::ActiveState) {
- QMutexLocker lock(&m_mutex);
- audioDeviceStop();
-
- m_errorCode = QAudio::UnderrunError;
- m_stateCode = QAudio::IdleState;
- QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection);
- }
-}
-
-void QDarwinAudioSink::audioDeviceError()
-{
- if (m_stateCode == QAudio::ActiveState) {
- QMutexLocker lock(&m_mutex);
- audioDeviceStop();
-
- m_errorCode = QAudio::IOError;
- m_stateCode = QAudio::StoppedState;
- QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection);
- }
-}
-
-void QDarwinAudioSink::startTimers()
-{
- m_audioBuffer->startFillTimer();
-}
-
-void QDarwinAudioSink::stopTimers()
-{
- m_audioBuffer->stopFillTimer();
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qdarwinaudiosink_p.cpp"
diff --git a/src/multimedia/platform/darwin/audio/qdarwinaudiosink_p.h b/src/multimedia/platform/darwin/audio/qdarwinaudiosink_p.h
deleted file mode 100644
index bb2c6507f..000000000
--- a/src/multimedia/platform/darwin/audio/qdarwinaudiosink_p.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 IOSAUDIOOUTPUT_H
-#define IOSAUDIOOUTPUT_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 <qaudiosystem_p.h>
-
-#if defined(Q_OS_OSX)
-# include <CoreAudio/CoreAudio.h>
-#endif
-#include <AudioUnit/AudioUnit.h>
-#include <CoreAudio/CoreAudioTypes.h>
-
-#include <QtCore/QIODevice>
-#include <QtCore/QWaitCondition>
-#include <QtCore/QMutex>
-#include <private/qdarwinaudiodevice_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDarwinAudioSinkBuffer;
-class QTimer;
-class QCoreAudioDeviceInfo;
-class CoreAudioRingBuffer;
-
-class QDarwinAudioSinkBuffer : public QObject
-{
- Q_OBJECT
-
-public:
- QDarwinAudioSinkBuffer(int bufferSize, int maxPeriodSize, QAudioFormat const& audioFormat);
- ~QDarwinAudioSinkBuffer();
-
- qint64 readFrames(char *data, qint64 maxFrames);
- qint64 writeBytes(const char *data, qint64 maxSize);
-
- int available() const;
- void reset();
-
- void setPrefetchDevice(QIODevice *device);
-
- void startFillTimer();
- void stopFillTimer();
-
-signals:
- void readyRead();
-
-private slots:
- void fillBuffer();
-
-private:
- bool m_deviceError;
- int m_maxPeriodSize;
- int m_bytesPerFrame;
- int m_periodTime;
- QIODevice *m_device;
- QTimer *m_fillTimer;
- CoreAudioRingBuffer *m_buffer;
-};
-
-class QDarwinAudioSinkDevice : public QIODevice
-{
-public:
- QDarwinAudioSinkDevice(QDarwinAudioSinkBuffer *audioBuffer, QObject *parent);
-
- qint64 readData(char *data, qint64 len);
- qint64 writeData(const char *data, qint64 len);
-
- bool isSequential() const { return true; }
-
-private:
- QDarwinAudioSinkBuffer *m_audioBuffer;
-};
-
-
-class QDarwinAudioSink : public QPlatformAudioSink
-{
- Q_OBJECT
-
-public:
- QDarwinAudioSink(const QAudioDevice &device);
- ~QDarwinAudioSink();
-
- void start(QIODevice *device);
- QIODevice *start();
- void stop();
- void reset();
- void suspend();
- void resume();
- qsizetype bytesFree() const;
- void setBufferSize(qsizetype value);
- qsizetype bufferSize() const;
- qint64 processedUSecs() const;
- QAudio::Error error() const;
- QAudio::State state() const;
- void setFormat(const QAudioFormat &format);
- QAudioFormat format() const;
-
- void setVolume(qreal volume);
- qreal volume() const;
-
-private slots:
- void deviceStopped();
- void inputReady();
-
-private:
- enum {
- Running,
- Draining,
- Stopped
- };
-
- static OSStatus renderCallback(void *inRefCon,
- AudioUnitRenderActionFlags *ioActionFlags,
- const AudioTimeStamp *inTimeStamp,
- UInt32 inBusNumber,
- UInt32 inNumberFrames,
- AudioBufferList *ioData);
-
- bool open();
- void close();
- void audioThreadStart();
- void audioThreadStop();
- void audioThreadDrain();
- void audioDeviceStop();
- void audioDeviceIdle();
- void audioDeviceError();
-
- void startTimers();
- void stopTimers();
-
- QAudioDevice m_audioDeviceInfo;
- QByteArray m_device;
-
- static constexpr int DEFAULT_BUFFER_SIZE = 8 * 1024;
-
- bool m_isOpen = false;
- int m_internalBufferSize = DEFAULT_BUFFER_SIZE;
- int m_periodSizeBytes = 0;
- qint64 m_totalFrames = 0;
- QAudioFormat m_audioFormat;
- QIODevice *m_audioIO = nullptr;
-#if defined(Q_OS_MACOS)
- AudioDeviceID m_audioDeviceId;
-#endif
- AudioUnit m_audioUnit = 0;
- Float64 m_clockFrequency = 0;
- AudioStreamBasicDescription m_streamFormat;
- QDarwinAudioSinkBuffer *m_audioBuffer = nullptr;
- QAtomicInt m_audioThreadState;
- QWaitCondition m_threadFinished;
- QMutex m_mutex;
- qreal m_cachedVolume = 1.;
-#if defined(Q_OS_MACOS)
- qreal m_volume = 1.;
-#endif
- bool m_pullMode = false;
-
- QAudio::Error m_errorCode = QAudio::NoError;
- QAudio::State m_stateCode = QAudio::StoppedState;
-};
-
-QT_END_NAMESPACE
-
-#endif // IOSAUDIOOUTPUT_H
diff --git a/src/multimedia/platform/darwin/audio/qdarwinaudiosource.mm b/src/multimedia/platform/darwin/audio/qdarwinaudiosource.mm
deleted file mode 100644
index 17754518b..000000000
--- a/src/multimedia/platform/darwin/audio/qdarwinaudiosource.mm
+++ /dev/null
@@ -1,977 +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 "qdarwinaudiosource_p.h"
-#include "qcoreaudiosessionmanager_p.h"
-#include "qdarwinaudiodevice_p.h"
-#include "qcoreaudioutils_p.h"
-#include "private/qdarwinmediadevices_p.h"
-#include <qmediadevices.h>
-
-#if defined(Q_OS_OSX)
-# include <AudioUnit/AudioComponent.h>
-#endif
-
-#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
-# include "qcoreaudiosessionmanager_p.h"
-#endif
-
-#include <QtMultimedia/private/qaudiohelpers_p.h>
-#include <QtCore/QDataStream>
-#include <QtCore/QDebug>
-
-QT_BEGIN_NAMESPACE
-
-static const int DEFAULT_BUFFER_SIZE = 4 * 1024;
-
-QCoreAudioBufferList::QCoreAudioBufferList(const AudioStreamBasicDescription &streamFormat)
- : m_owner(false)
- , m_streamDescription(streamFormat)
-{
- const bool isInterleaved = (m_streamDescription.mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
- const int numberOfBuffers = isInterleaved ? 1 : m_streamDescription.mChannelsPerFrame;
-
- m_dataSize = 0;
-
- m_bufferList = reinterpret_cast<AudioBufferList*>(malloc(sizeof(AudioBufferList) +
- (sizeof(AudioBuffer) * numberOfBuffers)));
-
- m_bufferList->mNumberBuffers = numberOfBuffers;
- for (int i = 0; i < numberOfBuffers; ++i) {
- m_bufferList->mBuffers[i].mNumberChannels = isInterleaved ? numberOfBuffers : 1;
- m_bufferList->mBuffers[i].mDataByteSize = 0;
- m_bufferList->mBuffers[i].mData = 0;
- }
-}
-
-QCoreAudioBufferList::QCoreAudioBufferList(const AudioStreamBasicDescription &streamFormat, char *buffer, int bufferSize)
- : m_owner(false)
- , m_streamDescription(streamFormat)
- , m_bufferList(0)
-{
- m_dataSize = bufferSize;
-
- m_bufferList = reinterpret_cast<AudioBufferList*>(malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer)));
-
- m_bufferList->mNumberBuffers = 1;
- m_bufferList->mBuffers[0].mNumberChannels = 1;
- m_bufferList->mBuffers[0].mDataByteSize = m_dataSize;
- m_bufferList->mBuffers[0].mData = buffer;
-}
-
-QCoreAudioBufferList::QCoreAudioBufferList(const AudioStreamBasicDescription &streamFormat, int framesToBuffer)
- : m_owner(true)
- , m_streamDescription(streamFormat)
- , m_bufferList(0)
-{
- const bool isInterleaved = (m_streamDescription.mFormatFlags & kAudioFormatFlagIsNonInterleaved) == 0;
- const int numberOfBuffers = isInterleaved ? 1 : m_streamDescription.mChannelsPerFrame;
-
- m_dataSize = framesToBuffer * m_streamDescription.mBytesPerFrame;
-
- m_bufferList = reinterpret_cast<AudioBufferList*>(malloc(sizeof(AudioBufferList) +
- (sizeof(AudioBuffer) * numberOfBuffers)));
- m_bufferList->mNumberBuffers = numberOfBuffers;
- for (int i = 0; i < numberOfBuffers; ++i) {
- m_bufferList->mBuffers[i].mNumberChannels = isInterleaved ? numberOfBuffers : 1;
- m_bufferList->mBuffers[i].mDataByteSize = m_dataSize;
- m_bufferList->mBuffers[i].mData = malloc(m_dataSize);
- }
-}
-
-QCoreAudioBufferList::~QCoreAudioBufferList()
-{
- if (m_owner) {
- for (UInt32 i = 0; i < m_bufferList->mNumberBuffers; ++i)
- free(m_bufferList->mBuffers[i].mData);
- }
-
- free(m_bufferList);
-}
-
-char *QCoreAudioBufferList::data(int buffer) const
-{
- return static_cast<char*>(m_bufferList->mBuffers[buffer].mData);
-}
-
-qint64 QCoreAudioBufferList::bufferSize(int buffer) const
-{
- return m_bufferList->mBuffers[buffer].mDataByteSize;
-}
-
-int QCoreAudioBufferList::frameCount(int buffer) const
-{
- return m_bufferList->mBuffers[buffer].mDataByteSize / m_streamDescription.mBytesPerFrame;
-}
-
-int QCoreAudioBufferList::packetCount(int buffer) const
-{
- return m_bufferList->mBuffers[buffer].mDataByteSize / m_streamDescription.mBytesPerPacket;
-}
-
-int QCoreAudioBufferList::packetSize() const
-{
- return m_streamDescription.mBytesPerPacket;
-}
-
-void QCoreAudioBufferList::reset()
-{
- for (UInt32 i = 0; i < m_bufferList->mNumberBuffers; ++i) {
- m_bufferList->mBuffers[i].mDataByteSize = m_dataSize;
- m_bufferList->mBuffers[i].mData = 0;
- }
-}
-
-QCoreAudioPacketFeeder::QCoreAudioPacketFeeder(QCoreAudioBufferList *abl)
- : m_audioBufferList(abl)
-{
- m_totalPackets = m_audioBufferList->packetCount();
- m_position = 0;
-}
-
-bool QCoreAudioPacketFeeder::feed(AudioBufferList &dst, UInt32 &packetCount)
-{
- if (m_position == m_totalPackets) {
- dst.mBuffers[0].mDataByteSize = 0;
- packetCount = 0;
- return false;
- }
-
- if (m_totalPackets - m_position < packetCount)
- packetCount = m_totalPackets - m_position;
-
- dst.mBuffers[0].mDataByteSize = packetCount * m_audioBufferList->packetSize();
- dst.mBuffers[0].mData = m_audioBufferList->data() + (m_position * m_audioBufferList->packetSize());
-
- m_position += packetCount;
-
- return true;
-}
-
-bool QCoreAudioPacketFeeder::empty() const
-{
- return m_position == m_totalPackets;
-}
-
-QDarwinAudioSourceBuffer::QDarwinAudioSourceBuffer(int bufferSize, int maxPeriodSize, const AudioStreamBasicDescription &inputFormat, const AudioStreamBasicDescription &outputFormat, QObject *parent)
- : QObject(parent)
- , m_deviceError(false)
- , m_device(0)
- , m_audioConverter(0)
- , m_inputFormat(inputFormat)
- , m_outputFormat(outputFormat)
- , m_volume(qreal(1.0f))
-{
- m_maxPeriodSize = maxPeriodSize;
- m_periodTime = m_maxPeriodSize / m_outputFormat.mBytesPerFrame * 1000 / m_outputFormat.mSampleRate;
-
- m_buffer = new CoreAudioRingBuffer(bufferSize);
-
- m_inputBufferList = new QCoreAudioBufferList(m_inputFormat);
-
- m_flushTimer = new QTimer(this);
- connect(m_flushTimer, SIGNAL(timeout()), SLOT(flushBuffer()));
-
- if (CoreAudioUtils::toQAudioFormat(inputFormat) != CoreAudioUtils::toQAudioFormat(outputFormat)) {
- if (AudioConverterNew(&m_inputFormat, &m_outputFormat, &m_audioConverter) != noErr) {
- qWarning() << "QAudioSource: Unable to create an Audio Converter";
- m_audioConverter = 0;
- }
- }
-
- m_qFormat = CoreAudioUtils::toQAudioFormat(inputFormat); // we adjust volume before conversion
-}
-
-QDarwinAudioSourceBuffer::~QDarwinAudioSourceBuffer()
-{
- delete m_buffer;
-}
-
-qreal QDarwinAudioSourceBuffer::volume() const
-{
- return m_volume;
-}
-
-void QDarwinAudioSourceBuffer::setVolume(qreal v)
-{
- m_volume = v;
-}
-
-qint64 QDarwinAudioSourceBuffer::renderFromDevice(AudioUnit audioUnit, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames)
-{
- const bool pullMode = m_device == 0;
-
- OSStatus err;
- qint64 framesRendered = 0;
-
- m_inputBufferList->reset();
- err = AudioUnitRender(audioUnit,
- ioActionFlags,
- inTimeStamp,
- inBusNumber,
- inNumberFrames,
- m_inputBufferList->audioBufferList());
-
- // adjust volume, if necessary
- if (!qFuzzyCompare(m_volume, qreal(1.0f))) {
- QAudioHelperInternal::qMultiplySamples(m_volume,
- m_qFormat,
- m_inputBufferList->data(), /* input */
- m_inputBufferList->data(), /* output */
- m_inputBufferList->bufferSize());
- }
-
- if (m_audioConverter != 0) {
- QCoreAudioPacketFeeder feeder(m_inputBufferList);
-
- int copied = 0;
- const int available = m_buffer->free();
-
- while (err == noErr && !feeder.empty()) {
- CoreAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(available - copied);
-
- if (region.second == 0)
- break;
-
- AudioBufferList output;
- output.mNumberBuffers = 1;
- output.mBuffers[0].mNumberChannels = 1;
- output.mBuffers[0].mDataByteSize = region.second;
- output.mBuffers[0].mData = region.first;
-
- UInt32 packetSize = region.second / m_outputFormat.mBytesPerPacket;
- err = AudioConverterFillComplexBuffer(m_audioConverter,
- converterCallback,
- &feeder,
- &packetSize,
- &output,
- 0);
- region.second = output.mBuffers[0].mDataByteSize;
- copied += region.second;
-
- m_buffer->releaseWriteRegion(region);
- }
-
- framesRendered += copied / m_outputFormat.mBytesPerFrame;
- }
- else {
- const int available = m_inputBufferList->bufferSize();
- bool wecan = true;
- int copied = 0;
-
- while (wecan && copied < available) {
- CoreAudioRingBuffer::Region region = m_buffer->acquireWriteRegion(available - copied);
-
- if (region.second > 0) {
- memcpy(region.first, m_inputBufferList->data() + copied, region.second);
- copied += region.second;
- }
- else
- wecan = false;
-
- m_buffer->releaseWriteRegion(region);
- }
-
- framesRendered = copied / m_outputFormat.mBytesPerFrame;
- }
-
- if (pullMode && framesRendered > 0)
- emit readyRead();
-
- return framesRendered;
-}
-
-qint64 QDarwinAudioSourceBuffer::readBytes(char *data, qint64 len)
-{
- bool wecan = true;
- qint64 bytesCopied = 0;
-
- len -= len % m_maxPeriodSize;
- while (wecan && bytesCopied < len) {
- CoreAudioRingBuffer::Region region = m_buffer->acquireReadRegion(len - bytesCopied);
-
- if (region.second > 0) {
- memcpy(data + bytesCopied, region.first, region.second);
- bytesCopied += region.second;
- }
- else
- wecan = false;
-
- m_buffer->releaseReadRegion(region);
- }
-
- return bytesCopied;
-}
-
-void QDarwinAudioSourceBuffer::setFlushDevice(QIODevice *device)
-{
- if (m_device != device)
- m_device = device;
-}
-
-void QDarwinAudioSourceBuffer::startFlushTimer()
-{
- if (m_device != 0) {
- // We use the period time for the timer, since that's
- // around the buffer size (pre conversion >.>)
- m_flushTimer->start(qMax(1, m_periodTime));
- }
-}
-
-void QDarwinAudioSourceBuffer::stopFlushTimer()
-{
- m_flushTimer->stop();
-}
-
-void QDarwinAudioSourceBuffer::flush(bool all)
-{
- if (m_device == 0)
- return;
-
- const int used = m_buffer->used();
- const int readSize = all ? used : used - (used % m_maxPeriodSize);
-
- if (readSize > 0) {
- bool wecan = true;
- int flushed = 0;
-
- while (!m_deviceError && wecan && flushed < readSize) {
- CoreAudioRingBuffer::Region region = m_buffer->acquireReadRegion(readSize - flushed);
-
- if (region.second > 0) {
- int bytesWritten = m_device->write(region.first, region.second);
- if (bytesWritten < 0) {
- stopFlushTimer();
- m_deviceError = true;
- }
- else {
- region.second = bytesWritten;
- flushed += bytesWritten;
- wecan = bytesWritten != 0;
- }
- }
- else
- wecan = false;
-
- m_buffer->releaseReadRegion(region);
- }
- }
-}
-
-void QDarwinAudioSourceBuffer::reset()
-{
- m_buffer->reset();
- m_deviceError = false;
-}
-
-int QDarwinAudioSourceBuffer::available() const
-{
- return m_buffer->free();
-}
-
-int QDarwinAudioSourceBuffer::used() const
-{
- return m_buffer->used();
-}
-
-void QDarwinAudioSourceBuffer::flushBuffer()
-{
- flush();
-}
-
-OSStatus QDarwinAudioSourceBuffer::converterCallback(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets, AudioBufferList *ioData, AudioStreamPacketDescription **outDataPacketDescription, void *inUserData)
-{
- Q_UNUSED(inAudioConverter);
- Q_UNUSED(outDataPacketDescription);
-
- QCoreAudioPacketFeeder* feeder = static_cast<QCoreAudioPacketFeeder*>(inUserData);
-
- if (!feeder->feed(*ioData, *ioNumberDataPackets))
- return as_empty;
-
- return noErr;
-}
-
-QDarwinAudioSourceDevice::QDarwinAudioSourceDevice(QDarwinAudioSourceBuffer *audioBuffer, QObject *parent)
- : QIODevice(parent)
- , m_audioBuffer(audioBuffer)
-{
- open(QIODevice::ReadOnly | QIODevice::Unbuffered);
- connect(m_audioBuffer, SIGNAL(readyRead()), SIGNAL(readyRead()));
-}
-
-qint64 QDarwinAudioSourceDevice::readData(char *data, qint64 len)
-{
- return m_audioBuffer->readBytes(data, len);
-}
-
-qint64 QDarwinAudioSourceDevice::writeData(const char *data, qint64 len)
-{
- Q_UNUSED(data);
- Q_UNUSED(len);
-
- return 0;
-}
-
-QDarwinAudioSource::QDarwinAudioSource(const QAudioDevice &device)
- : m_audioDeviceInfo(device)
- , m_isOpen(false)
- , m_internalBufferSize(DEFAULT_BUFFER_SIZE)
- , m_totalFrames(0)
- , m_audioUnit(0)
- , m_clockFrequency(CoreAudioUtils::frequency() / 1000)
- , m_errorCode(QAudio::NoError)
- , m_stateCode(QAudio::StoppedState)
- , m_audioBuffer(nullptr)
- , m_volume(1.0)
-{
- QAudioDevice di = device;
- if (di.isNull())
- di = QMediaDevices::defaultAudioInput();
-#if defined(Q_OS_MACOS)
- const QCoreAudioDeviceInfo *info = static_cast<const QCoreAudioDeviceInfo *>(di.handle());
- Q_ASSERT(info);
- m_audioDeviceId = info->deviceID();
-#endif
- m_device = di.id();
-}
-
-
-QDarwinAudioSource::~QDarwinAudioSource()
-{
- close();
-}
-
-bool QDarwinAudioSource::open()
-{
-#if defined(Q_OS_IOS)
- CoreAudioSessionManager::instance().setCategory(CoreAudioSessionManager::PlayAndRecord, CoreAudioSessionManager::MixWithOthers);
- CoreAudioSessionManager::instance().setActive(true);
-#endif
-
- if (m_isOpen)
- return true;
-
- UInt32 size = 0;
-
- AudioComponentDescription componentDescription;
- componentDescription.componentType = kAudioUnitType_Output;
-#if defined(Q_OS_OSX)
- componentDescription.componentSubType = kAudioUnitSubType_HALOutput;
-#else
- componentDescription.componentSubType = kAudioUnitSubType_RemoteIO;
-#endif
- componentDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
- componentDescription.componentFlags = 0;
- componentDescription.componentFlagsMask = 0;
-
- AudioComponent component = AudioComponentFindNext(0, &componentDescription);
- if (component == 0) {
- qWarning() << "QAudioSource: Failed to find Output component";
- return false;
- }
-
- if (AudioComponentInstanceNew(component, &m_audioUnit) != noErr) {
- qWarning() << "QAudioSource: Unable to Open Output Component";
- return false;
- }
-
- // Set mode
- // switch to input mode
- UInt32 enable = 1;
- if (AudioUnitSetProperty(m_audioUnit,
- kAudioOutputUnitProperty_EnableIO,
- kAudioUnitScope_Input,
- 1,
- &enable,
- sizeof(enable)) != noErr) {
- qWarning() << "QAudioSource: Unable to switch to input mode (Enable Input)";
- return false;
- }
-
- enable = 0;
- if (AudioUnitSetProperty(m_audioUnit,
- kAudioOutputUnitProperty_EnableIO,
- kAudioUnitScope_Output,
- 0,
- &enable,
- sizeof(enable)) != noErr) {
- qWarning() << "QAudioSource: Unable to switch to input mode (Disable output)";
- return false;
- }
-
- // register callback
- AURenderCallbackStruct callback;
- callback.inputProc = inputCallback;
- callback.inputProcRefCon = this;
-
- if (AudioUnitSetProperty(m_audioUnit,
- kAudioOutputUnitProperty_SetInputCallback,
- kAudioUnitScope_Global,
- 0,
- &callback,
- sizeof(callback)) != noErr) {
- qWarning() << "QAudioSource: Failed to set AudioUnit callback";
- return false;
- }
-
-#if defined(Q_OS_OSX)
- //Set Audio Device
- if (AudioUnitSetProperty(m_audioUnit,
- kAudioOutputUnitProperty_CurrentDevice,
- kAudioUnitScope_Global,
- 0,
- &m_audioDeviceId,
- sizeof(m_audioDeviceId)) != noErr) {
- qWarning() << "QAudioSource: Unable to use configured device";
- return false;
- }
-#endif
-
- //set format
- m_streamFormat = CoreAudioUtils::toAudioStreamBasicDescription(m_audioFormat);
-
-#if defined(Q_OS_OSX)
- if (m_audioFormat == m_audioDeviceInfo.preferredFormat()) {
-#endif
-
- m_deviceFormat = m_streamFormat;
- AudioUnitSetProperty(m_audioUnit,
- kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Output,
- 1,
- &m_deviceFormat,
- sizeof(m_deviceFormat));
-#if defined(Q_OS_OSX)
- } else {
- size = sizeof(m_deviceFormat);
- if (AudioUnitGetProperty(m_audioUnit,
- kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Input,
- 1,
- &m_deviceFormat,
- &size) != noErr) {
- qWarning() << "QAudioSource: Unable to retrieve device format";
- return false;
- }
-
- if (AudioUnitSetProperty(m_audioUnit,
- kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Output,
- 1,
- &m_deviceFormat,
- sizeof(m_deviceFormat)) != noErr) {
- qWarning() << "QAudioSource: Unable to set device format";
- return false;
- }
- }
-#endif
-
- //setup buffers
- UInt32 numberOfFrames;
-#if defined(Q_OS_OSX)
- size = sizeof(UInt32);
- if (AudioUnitGetProperty(m_audioUnit,
- kAudioDevicePropertyBufferFrameSize,
- kAudioUnitScope_Global,
- 0,
- &numberOfFrames,
- &size) != noErr) {
- qWarning() << "QAudioSource: Failed to get audio period size";
- return false;
- }
- //BUG: numberOfFrames gets ignored after this point
-
- AudioValueRange bufferRange;
- size = sizeof(AudioValueRange);
-
- if (AudioUnitGetProperty(m_audioUnit,
- kAudioDevicePropertyBufferFrameSizeRange,
- kAudioUnitScope_Global,
- 0,
- &bufferRange,
- &size) != noErr) {
- qWarning() << "QAudioSource: Failed to get audio period size range";
- return false;
- }
-
- // See if the requested buffer size is permissible
- numberOfFrames = qBound((UInt32)bufferRange.mMinimum, m_internalBufferSize / m_streamFormat.mBytesPerFrame, (UInt32)bufferRange.mMaximum);
-
- // Set it back
- if (AudioUnitSetProperty(m_audioUnit,
- kAudioDevicePropertyBufferFrameSize,
- kAudioUnitScope_Global,
- 0,
- &numberOfFrames,
- sizeof(UInt32)) != noErr) {
- qWarning() << "QAudioSource: Failed to set audio buffer size";
- return false;
- }
-#else //iOS
- Float32 bufferSize = CoreAudioSessionManager::instance().currentIOBufferDuration();
- bufferSize *= m_streamFormat.mSampleRate;
- numberOfFrames = bufferSize;
-#endif
-
- // Now allocate a few buffers to be safe.
- m_periodSizeBytes = m_internalBufferSize = numberOfFrames * m_streamFormat.mBytesPerFrame;
-
- {
- QMutexLocker lock(m_audioBuffer);
- m_audioBuffer = new QDarwinAudioSourceBuffer(m_internalBufferSize * 4,
- m_periodSizeBytes,
- m_deviceFormat,
- m_streamFormat,
- this);
-
- m_audioBuffer->setVolume(m_volume);
- }
- m_audioIO = new QDarwinAudioSourceDevice(m_audioBuffer, this);
-
- // Init
- if (AudioUnitInitialize(m_audioUnit) != noErr) {
- qWarning() << "QAudioSource: Failed to initialize AudioUnit";
- return false;
- }
-
- m_isOpen = true;
-
- return m_isOpen;
-
-}
-
-void QDarwinAudioSource::close()
-{
- stop();
- if (m_audioUnit != 0) {
- AudioOutputUnitStop(m_audioUnit);
- AudioUnitUninitialize(m_audioUnit);
- AudioComponentInstanceDispose(m_audioUnit);
- }
-
- delete m_audioBuffer;
- m_audioBuffer = nullptr;
- m_isOpen = false;
-}
-
-void QDarwinAudioSource::start(QIODevice *device)
-{
- QIODevice* op = device;
-
- if (!m_audioDeviceInfo.isFormatSupported(m_audioFormat) || !open()) {
- m_stateCode = QAudio::StoppedState;
- m_errorCode = QAudio::OpenError;
- return;
- }
-
- reset();
- {
- QMutexLocker lock(m_audioBuffer);
- m_audioBuffer->reset();
- m_audioBuffer->setFlushDevice(op);
- }
-
- if (op == 0)
- op = m_audioIO;
-
- // Start
- m_totalFrames = 0;
-
- m_stateCode = QAudio::IdleState;
- m_errorCode = QAudio::NoError;
- emit stateChanged(m_stateCode);
-
- audioThreadStart();
-}
-
-
-QIODevice *QDarwinAudioSource::start()
-{
- QIODevice* op = 0;
-
- if (!m_audioDeviceInfo.isFormatSupported(m_audioFormat) || !open()) {
- m_stateCode = QAudio::StoppedState;
- m_errorCode = QAudio::OpenError;
- return m_audioIO;
- }
-
- reset();
- {
- QMutexLocker lock(m_audioBuffer);
- m_audioBuffer->reset();
- m_audioBuffer->setFlushDevice(op);
- }
-
- if (op == 0)
- op = m_audioIO;
-
- // Start
- m_totalFrames = 0;
-
- m_stateCode = QAudio::IdleState;
- m_errorCode = QAudio::NoError;
- emit stateChanged(m_stateCode);
-
- audioThreadStart();
-
- return op;
-}
-
-
-void QDarwinAudioSource::stop()
-{
- QMutexLocker lock(m_audioBuffer);
- if (m_stateCode != QAudio::StoppedState) {
- audioThreadStop();
- m_audioBuffer->flush(true);
-
- m_errorCode = QAudio::NoError;
- m_stateCode = QAudio::StoppedState;
- QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, m_stateCode));
- }
-}
-
-
-void QDarwinAudioSource::reset()
-{
- QMutexLocker lock(m_audioBuffer);
- if (m_stateCode != QAudio::StoppedState) {
- audioThreadStop();
-
- m_errorCode = QAudio::NoError;
- m_stateCode = QAudio::StoppedState;
- m_audioBuffer->reset();
- QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, m_stateCode));
- }
-}
-
-
-void QDarwinAudioSource::suspend()
-{
- QMutexLocker lock(m_audioBuffer);
- if (m_stateCode == QAudio::ActiveState || m_stateCode == QAudio::IdleState) {
- audioThreadStop();
-
- m_errorCode = QAudio::NoError;
- m_stateCode = QAudio::SuspendedState;
- QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, m_stateCode));
- }
-}
-
-
-void QDarwinAudioSource::resume()
-{
- QMutexLocker lock(m_audioBuffer);
- if (m_stateCode == QAudio::SuspendedState) {
- audioThreadStart();
-
- m_errorCode = QAudio::NoError;
- m_stateCode = QAudio::ActiveState;
- QMetaObject::invokeMethod(this, "stateChanged", Qt::QueuedConnection, Q_ARG(QAudio::State, m_stateCode));
- }
-}
-
-
-qsizetype QDarwinAudioSource::bytesReady() const
-{
- QMutexLocker lock(m_audioBuffer);
- if (!m_audioBuffer)
- return 0;
- return m_audioBuffer->used();
-}
-
-void QDarwinAudioSource::setBufferSize(qsizetype value)
-{
- m_internalBufferSize = value;
-}
-
-
-qsizetype QDarwinAudioSource::bufferSize() const
-{
- return m_internalBufferSize;
-}
-
-qint64 QDarwinAudioSource::processedUSecs() const
-{
- return m_totalFrames * 1000000 / m_audioFormat.sampleRate();
-}
-
-QAudio::Error QDarwinAudioSource::error() const
-{
- return m_errorCode;
-}
-
-
-QAudio::State QDarwinAudioSource::state() const
-{
- return m_stateCode;
-}
-
-
-void QDarwinAudioSource::setFormat(const QAudioFormat &format)
-{
- if (m_stateCode == QAudio::StoppedState)
- m_audioFormat = format;
-}
-
-
-QAudioFormat QDarwinAudioSource::format() const
-{
- return m_audioFormat;
-}
-
-
-void QDarwinAudioSource::setVolume(qreal volume)
-{
- QMutexLocker lock(m_audioBuffer);
- m_volume = volume;
- if (m_audioBuffer)
- m_audioBuffer->setVolume(m_volume);
-}
-
-
-qreal QDarwinAudioSource::volume() const
-{
- return m_volume;
-}
-
-void QDarwinAudioSource::deviceStoppped()
-{
- stopTimers();
- emit stateChanged(m_stateCode);
-}
-
-void QDarwinAudioSource::audioThreadStart()
-{
- startTimers();
- m_audioThreadState.storeRelaxed(Running);
- AudioOutputUnitStart(m_audioUnit);
-}
-
-void QDarwinAudioSource::audioThreadStop()
-{
- stopTimers();
- if (m_audioThreadState.testAndSetAcquire(Running, Stopped))
- m_audioBuffer->wait();
-}
-
-void QDarwinAudioSource::audioDeviceStop()
-{
- AudioOutputUnitStop(m_audioUnit);
- m_audioThreadState.storeRelaxed(Stopped);
- m_audioBuffer->wake();
-}
-
-void QDarwinAudioSource::audioDeviceActive()
-{
- if (m_stateCode == QAudio::IdleState) {
- QMutexLocker lock(m_audioBuffer);
- m_stateCode = QAudio::ActiveState;
- emit stateChanged(m_stateCode);
- }
-}
-
-void QDarwinAudioSource::audioDeviceFull()
-{
- if (m_stateCode == QAudio::ActiveState) {
- QMutexLocker lock(m_audioBuffer);
- m_errorCode = QAudio::UnderrunError;
- m_stateCode = QAudio::IdleState;
- emit stateChanged(m_stateCode);
- }
-}
-
-void QDarwinAudioSource::audioDeviceError()
-{
- if (m_stateCode == QAudio::ActiveState) {
- QMutexLocker lock(m_audioBuffer);
- audioDeviceStop();
-
- m_errorCode = QAudio::IOError;
- m_stateCode = QAudio::StoppedState;
- QMetaObject::invokeMethod(this, "deviceStopped", Qt::QueuedConnection);
- }
-}
-
-void QDarwinAudioSource::startTimers()
-{
- m_audioBuffer->startFlushTimer();
-}
-
-void QDarwinAudioSource::stopTimers()
-{
- m_audioBuffer->stopFlushTimer();
-}
-
-OSStatus QDarwinAudioSource::inputCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData)
-{
- Q_UNUSED(ioData);
-
- QDarwinAudioSource* d = static_cast<QDarwinAudioSource*>(inRefCon);
-
- const int threadState = d->m_audioThreadState.loadAcquire();
- if (threadState == Stopped)
- d->audioDeviceStop();
- else {
- qint64 framesWritten;
-
- {
- QMutexLocker locker(d->m_audioBuffer);
- framesWritten = d->m_audioBuffer->renderFromDevice(d->m_audioUnit,
- ioActionFlags,
- inTimeStamp,
- inBusNumber,
- inNumberFrames);
- }
-
- if (framesWritten > 0) {
- d->m_totalFrames += framesWritten;
- d->audioDeviceActive();
- } else if (framesWritten == 0)
- d->audioDeviceFull();
- else if (framesWritten < 0)
- d->audioDeviceError();
- }
-
- return noErr;
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qdarwinaudiosource_p.cpp"
diff --git a/src/multimedia/platform/darwin/audio/qdarwinaudiosource_p.h b/src/multimedia/platform/darwin/audio/qdarwinaudiosource_p.h
deleted file mode 100644
index 6a14b6a55..000000000
--- a/src/multimedia/platform/darwin/audio/qdarwinaudiosource_p.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 IOSAUDIOINPUT_H
-#define IOSAUDIOINPUT_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 <qaudiosystem_p.h>
-#include <private/qdarwinaudiodevice_p.h>
-
-#include <AudioUnit/AudioUnit.h>
-#include <CoreAudio/CoreAudioTypes.h>
-#include <AudioToolbox/AudioToolbox.h>
-
-#include <QtCore/QIODevice>
-#include <QtCore/QWaitCondition>
-#include <QtCore/QMutex>
-#include <QtCore/QTimer>
-
-QT_BEGIN_NAMESPACE
-
-class CoreAudioRingBuffer;
-class QCoreAudioPacketFeeder;
-class QDarwinAudioSourceBuffer;
-class QDarwinAudioSourceDevice;
-
-class QCoreAudioBufferList
-{
-public:
- QCoreAudioBufferList(AudioStreamBasicDescription const& streamFormat);
- QCoreAudioBufferList(AudioStreamBasicDescription const& streamFormat, char *buffer, int bufferSize);
- QCoreAudioBufferList(AudioStreamBasicDescription const& streamFormat, int framesToBuffer);
-
- ~QCoreAudioBufferList();
-
- AudioBufferList* audioBufferList() const { return m_bufferList; }
- char *data(int buffer = 0) const;
- qint64 bufferSize(int buffer = 0) const;
- int frameCount(int buffer = 0) const;
- int packetCount(int buffer = 0) const;
- int packetSize() const;
- void reset();
-
-private:
- bool m_owner;
- int m_dataSize;
- AudioStreamBasicDescription m_streamDescription;
- AudioBufferList *m_bufferList;
-};
-
-class QCoreAudioPacketFeeder
-{
-public:
- QCoreAudioPacketFeeder(QCoreAudioBufferList *abl);
-
- bool feed(AudioBufferList& dst, UInt32& packetCount);
- bool empty() const;
-
-private:
- UInt32 m_totalPackets;
- UInt32 m_position;
- QCoreAudioBufferList *m_audioBufferList;
-};
-
-class QDarwinAudioSourceBuffer : public QObject
-{
- Q_OBJECT
-
-public:
- QDarwinAudioSourceBuffer(int bufferSize,
- int maxPeriodSize,
- AudioStreamBasicDescription const& inputFormat,
- AudioStreamBasicDescription const& outputFormat,
- QObject *parent);
-
- ~QDarwinAudioSourceBuffer();
-
- qreal volume() const;
- void setVolume(qreal v);
-
- qint64 renderFromDevice(AudioUnit audioUnit,
- AudioUnitRenderActionFlags *ioActionFlags,
- const AudioTimeStamp *inTimeStamp,
- UInt32 inBusNumber,
- UInt32 inNumberFrames);
-
- qint64 readBytes(char *data, qint64 len);
-
- void setFlushDevice(QIODevice *device);
-
- void startFlushTimer();
- void stopFlushTimer();
-
- void flush(bool all = false);
- void reset();
- int available() const;
- int used() const;
-
- void lock() { m_mutex.lock(); }
- void unlock() { m_mutex.unlock(); }
-
- void wait() { m_threadFinished.wait(&m_mutex); }
- void wake() { m_threadFinished.wakeOne(); }
-
-signals:
- void readyRead();
-
-private slots:
- void flushBuffer();
-
-private:
- QMutex m_mutex;
- QWaitCondition m_threadFinished;
-
- bool m_deviceError;
- int m_maxPeriodSize;
- int m_periodTime;
- QIODevice *m_device;
- QTimer *m_flushTimer;
- CoreAudioRingBuffer *m_buffer;
- QCoreAudioBufferList *m_inputBufferList;
- AudioConverterRef m_audioConverter;
- AudioStreamBasicDescription m_inputFormat;
- AudioStreamBasicDescription m_outputFormat;
- QAudioFormat m_qFormat;
- qreal m_volume;
-
- const static OSStatus as_empty = 'qtem';
-
- // Converter callback
- static OSStatus converterCallback(AudioConverterRef inAudioConverter,
- UInt32 *ioNumberDataPackets,
- AudioBufferList *ioData,
- AudioStreamPacketDescription **outDataPacketDescription,
- void *inUserData);
-};
-
-class QDarwinAudioSourceDevice : public QIODevice
-{
- Q_OBJECT
-
-public:
- QDarwinAudioSourceDevice(QDarwinAudioSourceBuffer *audioBuffer, QObject *parent);
-
- qint64 readData(char *data, qint64 len);
- qint64 writeData(const char *data, qint64 len);
-
- bool isSequential() const { return true; }
-
-private:
- QDarwinAudioSourceBuffer *m_audioBuffer;
-};
-
-class QDarwinAudioSource : public QPlatformAudioSource
-{
- Q_OBJECT
-
-public:
- QDarwinAudioSource(const QAudioDevice &device);
- ~QDarwinAudioSource();
-
- void start(QIODevice *device);
- QIODevice *start();
- void stop();
- void reset();
- void suspend();
- void resume();
- qsizetype bytesReady() const;
- void setBufferSize(qsizetype value);
- qsizetype bufferSize() const;
- qint64 processedUSecs() const;
- QAudio::Error error() const;
- QAudio::State state() const;
- void setFormat(const QAudioFormat &format);
- QAudioFormat format() const;
-
- void setVolume(qreal volume);
- qreal volume() const;
-
-private slots:
- void deviceStoppped();
-
-private:
- enum {
- Running,
- Stopped
- };
-
- bool open();
- void close();
-
- void audioThreadStart();
- void audioThreadStop();
-
- void audioDeviceStop();
- void audioDeviceActive();
- void audioDeviceFull();
- void audioDeviceError();
-
- void startTimers();
- void stopTimers();
-
- // Input callback
- static OSStatus inputCallback(void *inRefCon,
- AudioUnitRenderActionFlags *ioActionFlags,
- const AudioTimeStamp *inTimeStamp,
- UInt32 inBusNumber,
- UInt32 inNumberFrames,
- AudioBufferList *ioData);
-
- QAudioDevice m_audioDeviceInfo;
- QByteArray m_device;
- bool m_isOpen;
- int m_periodSizeBytes;
- int m_internalBufferSize;
- qint64 m_totalFrames;
- QAudioFormat m_audioFormat;
- QIODevice *m_audioIO;
- AudioUnit m_audioUnit;
-#if defined(Q_OS_OSX)
- AudioDeviceID m_audioDeviceId;
-#endif
- Float64 m_clockFrequency;
- QAudio::Error m_errorCode;
- QAudio::State m_stateCode;
- QDarwinAudioSourceBuffer *m_audioBuffer;
- QAtomicInt m_audioThreadState;
- AudioStreamBasicDescription m_streamFormat;
- AudioStreamBasicDescription m_deviceFormat;
- qreal m_volume;
-};
-
-QT_END_NAMESPACE
-
-#endif // IOSAUDIOINPUT_H
diff --git a/src/multimedia/platform/darwin/avfvideobuffer.mm b/src/multimedia/platform/darwin/avfvideobuffer.mm
deleted file mode 100644
index 67cd42d50..000000000
--- a/src/multimedia/platform/darwin/avfvideobuffer.mm
+++ /dev/null
@@ -1,315 +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 "avfvideobuffer_p.h"
-#include <private/qrhi_p.h>
-#include <private/qrhimetal_p.h>
-#include <private/qrhigles2_p.h>
-#include <CoreVideo/CVMetalTexture.h>
-#include <CoreVideo/CVMetalTextureCache.h>
-#include <QtGui/qopenglcontext.h>
-
-#include <private/qvideotexturehelper_p.h>
-
-#import <AVFoundation/AVFoundation.h>
-#import <Metal/Metal.h>
-
-QT_USE_NAMESPACE
-
-AVFVideoBuffer::AVFVideoBuffer(AVFVideoSinkInterface *sink, CVImageBufferRef buffer)
- : QAbstractVideoBuffer(sink->rhi() ? QVideoFrame::RhiTextureHandle : QVideoFrame::NoHandle, sink->rhi()),
- sink(sink),
- m_buffer(buffer)
-{
-// m_type = QVideoFrame::NoHandle;
-// qDebug() << "RHI" << rhi;
- CVPixelBufferRetain(m_buffer);
- m_pixelFormat = fromCVVideoPixelFormat(CVPixelBufferGetPixelFormatType(m_buffer));
-}
-
-AVFVideoBuffer::~AVFVideoBuffer()
-{
- AVFVideoBuffer::unmap();
- for (int i = 0; i < 3; ++i)
- if (cvMetalTexture[i])
- CFRelease(cvMetalTexture[i]);
-#if defined(Q_OS_MACOS)
- if (cvOpenGLTexture)
- CVOpenGLTextureRelease(cvOpenGLTexture);
-#elif defined(Q_OS_IOS)
- if (cvOpenGLESTexture)
- CFRelease(cvOpenGLESTexture);
-#endif
- CVPixelBufferRelease(m_buffer);
-}
-
-AVFVideoBuffer::MapData AVFVideoBuffer::map(QVideoFrame::MapMode mode)
-{
- MapData mapData;
-
- if (m_mode == QVideoFrame::NotMapped) {
- CVPixelBufferLockBaseAddress(m_buffer, mode == QVideoFrame::ReadOnly
- ? kCVPixelBufferLock_ReadOnly
- : 0);
- m_mode = mode;
- }
-
- mapData.nPlanes = CVPixelBufferGetPlaneCount(m_buffer);
- Q_ASSERT(mapData.nPlanes <= 3);
-
- if (!mapData.nPlanes) {
- // single plane
- mapData.bytesPerLine[0] = CVPixelBufferGetBytesPerRow(m_buffer);
- mapData.data[0] = static_cast<uchar*>(CVPixelBufferGetBaseAddress(m_buffer));
- mapData.size[0] = CVPixelBufferGetDataSize(m_buffer);
- mapData.nPlanes = mapData.data[0] ? 1 : 0;
- return mapData;
- }
-
- // For a bi-planar or tri-planar format we have to set the parameters correctly:
- for (int i = 0; i < mapData.nPlanes; ++i) {
- mapData.bytesPerLine[i] = CVPixelBufferGetBytesPerRowOfPlane(m_buffer, i);
- mapData.size[i] = mapData.bytesPerLine[i]*CVPixelBufferGetHeightOfPlane(m_buffer, i);
- mapData.data[i] = static_cast<uchar*>(CVPixelBufferGetBaseAddressOfPlane(m_buffer, i));
- }
-
- return mapData;
-}
-
-void AVFVideoBuffer::unmap()
-{
- if (m_mode != QVideoFrame::NotMapped) {
- CVPixelBufferUnlockBaseAddress(m_buffer, m_mode == QVideoFrame::ReadOnly
- ? kCVPixelBufferLock_ReadOnly
- : 0);
- m_mode = QVideoFrame::NotMapped;
- }
-}
-
-static MTLPixelFormat rhiTextureFormatToMetalFormat(QRhiTexture::Format f)
-{
- switch (f) {
- default:
- case QRhiTexture::UnknownFormat:
- return MTLPixelFormatInvalid;
- case QRhiTexture::RGBA8:
- return MTLPixelFormatRGBA8Unorm;
- case QRhiTexture::BGRA8:
- return MTLPixelFormatBGRA8Unorm;
- case QRhiTexture::R8:
- return MTLPixelFormatR8Unorm;
- case QRhiTexture::RG8:
- return MTLPixelFormatRG8Unorm;
- case QRhiTexture::R16:
- return MTLPixelFormatR16Unorm;
- case QRhiTexture::RG16:
- return MTLPixelFormatRG16Unorm;
-
- case QRhiTexture::RGBA16F:
- return MTLPixelFormatRGBA16Float;
- case QRhiTexture::RGBA32F:
- return MTLPixelFormatRGBA32Float;
- case QRhiTexture::R16F:
- return MTLPixelFormatR16Float;
- case QRhiTexture::R32F:
- return MTLPixelFormatR32Float;
- }
-}
-
-
-quint64 AVFVideoBuffer::textureHandle(int plane) const
-{
- auto *textureDescription = QVideoTextureHelper::textureDescription(m_pixelFormat);
- int bufferPlanes = CVPixelBufferGetPlaneCount(m_buffer);
-// qDebug() << "texture handle" << plane << rhi << (rhi->backend() == QRhi::Metal) << bufferPlanes;
- if (plane > 0 && plane >= bufferPlanes)
- return 0;
- if (!rhi)
- return 0;
- if (rhi->backend() == QRhi::Metal) {
- if (!cvMetalTexture[plane]) {
- size_t width = CVPixelBufferGetWidth(m_buffer);
- size_t height = CVPixelBufferGetHeight(m_buffer);
- width = textureDescription->widthForPlane(width, plane);
- height = textureDescription->heightForPlane(height, plane);
-
- // Create a CoreVideo pixel buffer backed Metal texture image from the texture cache.
- auto ret = CVMetalTextureCacheCreateTextureFromImage(
- kCFAllocatorDefault,
- sink->cvMetalTextureCache,
- m_buffer, nil,
- rhiTextureFormatToMetalFormat(textureDescription->textureFormat[plane]),
- width, height,
- plane,
- &cvMetalTexture[plane]);
-
- if (ret != kCVReturnSuccess)
- qWarning() << "texture creation failed" << ret;
-// auto t = CVMetalTextureGetTexture(cvMetalTexture[plane]);
-// qDebug() << " metal texture is" << quint64(cvMetalTexture[plane]) << width << height;
-// qDebug() << " " << t.iosurfacePlane << t.pixelFormat << t.width << t.height;
- }
-
- // Get a Metal texture using the CoreVideo Metal texture reference.
-// qDebug() << " -> " << quint64(CVMetalTextureGetTexture(cvMetalTexture[plane]));
- return cvMetalTexture[plane] ? quint64(CVMetalTextureGetTexture(cvMetalTexture[plane])) : 0;
- } else if (rhi->backend() == QRhi::OpenGLES2) {
-#ifdef Q_OS_MACOS
- CVOpenGLTextureCacheFlush(sink->cvOpenGLTextureCache, 0);
- CVReturn cvret;
- // Create a CVPixelBuffer-backed OpenGL texture image from the texture cache.
- cvret = CVOpenGLTextureCacheCreateTextureFromImage(
- kCFAllocatorDefault,
- sink->cvOpenGLTextureCache,
- m_buffer,
- nil,
- &cvOpenGLTexture);
-
- Q_ASSERT(CVOpenGLTextureGetTarget(cvOpenGLTexture) == GL_TEXTURE_RECTANGLE);
- // Get an OpenGL texture name from the CVPixelBuffer-backed OpenGL texture image.
- return CVOpenGLTextureGetName(cvOpenGLTexture);
-#endif
-#ifdef Q_OS_IOS
- CVOpenGLESTextureCacheFlush(sink->cvOpenGLESTextureCache, 0);
- CVReturn cvret;
- // Create a CVPixelBuffer-backed OpenGL texture image from the texture cache.
- cvret = CVOpenGLESTextureCacheCreateTextureFromImage(
- kCFAllocatorDefault,
- sink->cvOpenGLESTextureCache,
- m_buffer,
- nil,
- GL_TEXTURE_2D,
- GL_RGBA,
- CVPixelBufferGetWidth(m_buffer),
- CVPixelBufferGetHeight(m_buffer),
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- 0,
- &cvOpenGLESTexture);
-
- // Get an OpenGL texture name from the CVPixelBuffer-backed OpenGL texture image.
- return CVOpenGLESTextureGetName(cvOpenGLESTexture);
-#endif
- }
- return 0;
-}
-
-
-QVideoFrameFormat::PixelFormat AVFVideoBuffer::fromCVVideoPixelFormat(unsigned avPixelFormat) const
-{
-#ifdef Q_OS_MACOS
- if (sink->rhi() && sink->rhi()->backend() == QRhi::OpenGLES2) {
- if (avPixelFormat == kCVPixelFormatType_32BGRA)
- return QVideoFrameFormat::Format_SamplerRect;
- else
- qWarning() << "Accelerated macOS OpenGL video supports BGRA only, got CV pixel format" << avPixelFormat;
- }
-#endif
- return fromCVPixelFormat(avPixelFormat);
-}
-
-QVideoFrameFormat::PixelFormat AVFVideoBuffer::fromCVPixelFormat(unsigned avPixelFormat)
-{
- switch (avPixelFormat) {
- case kCVPixelFormatType_32ARGB:
- return QVideoFrameFormat::Format_ARGB8888;
- case kCVPixelFormatType_32BGRA:
- return QVideoFrameFormat::Format_BGRA8888;
- case kCVPixelFormatType_420YpCbCr8Planar:
- case kCVPixelFormatType_420YpCbCr8PlanarFullRange:
- return QVideoFrameFormat::Format_YUV420P;
- case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:
- case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange:
- return QVideoFrameFormat::Format_NV12;
- case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange:
- case kCVPixelFormatType_420YpCbCr10BiPlanarFullRange:
- return QVideoFrameFormat::Format_P010;
- case kCVPixelFormatType_422YpCbCr8:
- return QVideoFrameFormat::Format_UYVY;
- case kCVPixelFormatType_422YpCbCr8_yuvs:
- return QVideoFrameFormat::Format_YUYV;
- case kCVPixelFormatType_OneComponent8:
- return QVideoFrameFormat::Format_Y8;
- case q_kCVPixelFormatType_OneComponent16:
- return QVideoFrameFormat::Format_Y16;
-
- case kCMVideoCodecType_JPEG:
- case kCMVideoCodecType_JPEG_OpenDML:
- return QVideoFrameFormat::Format_Jpeg;
- default:
- return QVideoFrameFormat::Format_Invalid;
- }
-}
-
-bool AVFVideoBuffer::toCVPixelFormat(QVideoFrameFormat::PixelFormat qtFormat, unsigned &conv)
-{
- switch (qtFormat) {
- case QVideoFrameFormat::Format_ARGB8888:
- conv = kCVPixelFormatType_32ARGB;
- break;
- case QVideoFrameFormat::Format_BGRA8888:
- conv = kCVPixelFormatType_32BGRA;
- break;
- case QVideoFrameFormat::Format_YUV420P:
- conv = kCVPixelFormatType_420YpCbCr8PlanarFullRange;
- break;
- case QVideoFrameFormat::Format_NV12:
- conv = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange;
- break;
- case QVideoFrameFormat::Format_P010:
- conv = kCVPixelFormatType_420YpCbCr10BiPlanarFullRange;
- break;
- case QVideoFrameFormat::Format_UYVY:
- conv = kCVPixelFormatType_422YpCbCr8;
- break;
- case QVideoFrameFormat::Format_YUYV:
- conv = kCVPixelFormatType_422YpCbCr8_yuvs;
- break;
- case QVideoFrameFormat::Format_Y8:
- conv = kCVPixelFormatType_OneComponent8;
- break;
- case QVideoFrameFormat::Format_Y16:
- conv = q_kCVPixelFormatType_OneComponent16;
- break;
- default:
- return false;
- }
-
- return true;
-}
diff --git a/src/multimedia/platform/darwin/avfvideobuffer_p.h b/src/multimedia/platform/darwin/avfvideobuffer_p.h
deleted file mode 100644
index 61590115b..000000000
--- a/src/multimedia/platform/darwin/avfvideobuffer_p.h
+++ /dev/null
@@ -1,112 +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 AVFVIDEOBUFFER_H
-#define AVFVIDEOBUFFER_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 <QtMultimedia/qvideoframe.h>
-#include <private/qabstractvideobuffer_p.h>
-
-#include <QtCore/qobject.h>
-#include <QtCore/qmutex.h>
-#include <private/avfvideosink_p.h>
-
-#include <CoreVideo/CVBase.h>
-#include <CoreVideo/CVPixelBuffer.h>
-#include <CoreVideo/CVImageBuffer.h>
-
-#import "Metal/Metal.h"
-#import "MetalKit/MetalKit.h"
-
-enum {
- // macOS 10.14 doesn't define this pixel format yet
- q_kCVPixelFormatType_OneComponent16 = 'L016'
-};
-
-QT_BEGIN_NAMESPACE
-
-struct AVFMetalTexture;
-class AVFVideoBuffer : public QAbstractVideoBuffer
-{
-public:
- AVFVideoBuffer(AVFVideoSinkInterface *sink, CVImageBufferRef buffer);
- ~AVFVideoBuffer();
-
- QVideoFrameFormat::PixelFormat fromCVVideoPixelFormat(unsigned avPixelFormat) const;
-
- static QVideoFrameFormat::PixelFormat fromCVPixelFormat(unsigned avPixelFormat);
- static bool toCVPixelFormat(QVideoFrameFormat::PixelFormat qtFormat, unsigned &conv);
-
-
- QVideoFrame::MapMode mapMode() const { return m_mode; }
- MapData map(QVideoFrame::MapMode mode);
- void unmap();
-
- virtual quint64 textureHandle(int plane) const;
-
-private:
- AVFVideoSinkInterface *sink = nullptr;
-
- mutable CVMetalTextureRef cvMetalTexture[3] = {};
-
-#if defined(Q_OS_MACOS)
- mutable CVOpenGLTextureRef cvOpenGLTexture = nullptr;
-#elif defined(Q_OS_IOS)
- mutable CVOpenGLESTextureRef cvOpenGLESTexture = nullptr;
-#endif
-
- CVImageBufferRef m_buffer = nullptr;
- QVideoFrame::MapMode m_mode = QVideoFrame::NotMapped;
- QVideoFrameFormat::PixelFormat m_pixelFormat = QVideoFrameFormat::Format_Invalid;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/darwin/avfvideosink.mm b/src/multimedia/platform/darwin/avfvideosink.mm
deleted file mode 100644
index ac4367140..000000000
--- a/src/multimedia/platform/darwin/avfvideosink.mm
+++ /dev/null
@@ -1,212 +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 "avfvideosink_p.h"
-
-#include <private/qrhi_p.h>
-#include <private/qrhimetal_p.h>
-#include <private/qrhigles2_p.h>
-#include <QtGui/qopenglcontext.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
-
-AVFVideoSink::AVFVideoSink(QVideoSink *parent)
- : QPlatformVideoSink(parent)
-{
-}
-
-AVFVideoSink::~AVFVideoSink()
-{
-}
-
-void AVFVideoSink::setRhi(QRhi *rhi)
-{
- if (m_rhi == rhi)
- return;
- m_rhi = rhi;
- if (m_interface)
- m_interface->setRhi(rhi);
-}
-
-void AVFVideoSink::setNativeSize(QSize size)
-{
- if (size == nativeSize())
- return;
- QPlatformVideoSink::setNativeSize(size);
- if (m_interface)
- m_interface->nativeSizeChanged();
-}
-
-void AVFVideoSink::setVideoSinkInterface(AVFVideoSinkInterface *interface)
-{
- m_interface = interface;
- if (m_interface)
- m_interface->setRhi(m_rhi);
-}
-
-AVFVideoSinkInterface::~AVFVideoSinkInterface()
-{
- if (m_layer)
- [m_layer release];
- freeTextureCaches();
-}
-
-void AVFVideoSinkInterface::freeTextureCaches()
-{
- if (cvMetalTextureCache)
- CFRelease(cvMetalTextureCache);
- cvMetalTextureCache = nullptr;
-#if defined(Q_OS_MACOS)
- if (cvOpenGLTextureCache)
- CFRelease(cvOpenGLTextureCache);
- cvOpenGLTextureCache = nullptr;
-#elif defined(Q_OS_IOS)
- if (cvOpenGLESTextureCache)
- CFRelease(cvOpenGLESTextureCache);
- cvOpenGLESTextureCache = nullptr;
-#endif
-}
-
-void AVFVideoSinkInterface::setVideoSink(AVFVideoSink *sink)
-{
- if (sink == m_sink)
- return;
-
- m_sink = sink;
- if (m_sink) {
- m_sink->setVideoSinkInterface(this);
- reconfigure();
- }
-}
-
-void AVFVideoSinkInterface::setRhi(QRhi *rhi)
-{
- if (m_rhi == rhi)
- return;
- freeTextureCaches();
- m_rhi = rhi;
-
- if (!rhi)
- return;
- if (rhi->backend() == QRhi::Metal) {
- const auto *metal = static_cast<const QRhiMetalNativeHandles *>(rhi->nativeHandles());
-
- // Create a Metal Core Video texture cache from the pixel buffer.
- Q_ASSERT(!cvMetalTextureCache);
- if (CVMetalTextureCacheCreate(
- kCFAllocatorDefault,
- nil,
- (id<MTLDevice>)metal->dev,
- nil,
- &cvMetalTextureCache) != kCVReturnSuccess) {
- qWarning() << "Metal texture cache creation failed";
- m_rhi = nullptr;
- }
- } else if (rhi->backend() == QRhi::OpenGLES2) {
-#ifdef Q_OS_MACOS
- const auto *gl = static_cast<const QRhiGles2NativeHandles *>(rhi->nativeHandles());
-
- auto nsGLContext = gl->context->nativeInterface<QNativeInterface::QCocoaGLContext>()->nativeContext();
- auto nsGLPixelFormat = nsGLContext.pixelFormat.CGLPixelFormatObj;
-
- // Create an OpenGL CoreVideo texture cache from the pixel buffer.
- if (CVOpenGLTextureCacheCreate(
- kCFAllocatorDefault,
- nullptr,
- reinterpret_cast<CGLContextObj>(nsGLContext.CGLContextObj),
- nsGLPixelFormat,
- nil,
- &cvOpenGLTextureCache)) {
- qWarning() << "OpenGL texture cache creation failed";
- m_rhi = nullptr;
- }
-#endif
-#ifdef Q_OS_IOS
- // Create an OpenGL CoreVideo texture cache from the pixel buffer.
- if (CVOpenGLESTextureCacheCreate(
- kCFAllocatorDefault,
- nullptr,
- [EAGLContext currentContext],
- nullptr,
- &cvOpenGLESTextureCache)) {
- qWarning() << "OpenGL texture cache creation failed";
- m_rhi = nullptr;
- }
-#endif
- }
-}
-
-void AVFVideoSinkInterface::setLayer(CALayer *layer)
-{
- if (layer == m_layer)
- return;
-
- if (m_layer)
- [m_layer release];
-
- m_layer = layer;
- if (m_layer)
- [m_layer retain];
-
- reconfigure();
-}
-
-void AVFVideoSinkInterface::updateLayerBounds()
-{
- if (!m_layer)
- return;
- [CATransaction begin];
- [CATransaction setDisableActions: YES]; // disable animation/flicks
- m_layer.frame = QRectF(0, 0, nativeSize().width(), nativeSize().height()).toCGRect();
- m_layer.bounds = m_layer.frame;
- [CATransaction commit];
-}
-
-#include "moc_avfvideosink_p.cpp"
diff --git a/src/multimedia/platform/darwin/avfvideosink_p.h b/src/multimedia/platform/darwin/avfvideosink_p.h
deleted file mode 100644
index d25efdfc7..000000000
--- a/src/multimedia/platform/darwin/avfvideosink_p.h
+++ /dev/null
@@ -1,129 +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
-
-//
-// 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 "private/qplatformvideosink_p.h"
-
-Q_FORWARD_DECLARE_OBJC_CLASS(CALayer);
-Q_FORWARD_DECLARE_OBJC_CLASS(AVPlayerLayer);
-Q_FORWARD_DECLARE_OBJC_CLASS(AVCaptureVideoPreviewLayer);
-
-#include <CoreVideo/CVBase.h>
-#include <CoreVideo/CVPixelBuffer.h>
-#include <CoreVideo/CVImageBuffer.h>
-
-#import "Metal/Metal.h"
-#import "MetalKit/MetalKit.h"
-
-QT_BEGIN_NAMESPACE
-
-class AVFVideoSinkInterface;
-
-class AVFVideoSink : public QPlatformVideoSink
-{
- Q_OBJECT
-
-public:
- AVFVideoSink(QVideoSink *parent = nullptr);
- virtual ~AVFVideoSink();
-
- // QPlatformVideoSink interface
-public:
- void setRhi(QRhi *rhi) override;
-
- void setNativeSize(QSize size);
-
- void setVideoSinkInterface(AVFVideoSinkInterface *interface);
-
-private:
- AVFVideoSinkInterface *m_interface = nullptr;
- QRhi *m_rhi = nullptr;
-};
-
-class AVFVideoSinkInterface
-{
-public:
- ~AVFVideoSinkInterface();
-
- void setVideoSink(AVFVideoSink *sink);
-
-
- virtual void reconfigure() = 0;
- virtual void setRhi(QRhi *);
- QRhi *rhi() const { return m_rhi; }
-
- virtual void setLayer(CALayer *layer);
-
- void updateLayerBounds();
- void nativeSizeChanged() { updateLayerBounds(); }
- QSize nativeSize() const { return m_sink->nativeSize(); }
-
- CVMetalTextureCacheRef cvMetalTextureCache = nullptr;
-#if defined(Q_OS_MACOS)
- CVOpenGLTextureCacheRef cvOpenGLTextureCache = nullptr;
-#elif defined(Q_OS_IOS)
- CVOpenGLESTextureCacheRef cvOpenGLESTextureCache = nullptr;
-#endif
-private:
- void freeTextureCaches();
-
-protected:
-
- AVFVideoSink *m_sink = nullptr;
- QRhi *m_rhi = nullptr;
- CALayer *m_layer = nullptr;
-};
-
-
-QT_END_NAMESPACE
-
-#endif // AVFVIDEOWINDOWCONTROL_H
diff --git a/src/multimedia/platform/darwin/camera/avfaudiopreviewdelegate.mm b/src/multimedia/platform/darwin/camera/avfaudiopreviewdelegate.mm
deleted file mode 100644
index 27261b8a0..000000000
--- a/src/multimedia/platform/darwin/camera/avfaudiopreviewdelegate.mm
+++ /dev/null
@@ -1,134 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "avfcamerasession_p.h"
-#include "avfaudiopreviewdelegate_p.h"
-
-QT_USE_NAMESPACE
-
-@implementation AVFAudioPreviewDelegate
-{
-@private
- AVSampleBufferAudioRenderer *m_audioRenderer;
- AVFCameraSession *m_session;
- AVSampleBufferRenderSynchronizer *m_audioBufferSynchronizer;
- dispatch_queue_t m_audioPreviewQueue;
-}
-
-- (id)init
-{
- if (self = [super init]) {
- m_session = nil;
- m_audioBufferSynchronizer = [[AVSampleBufferRenderSynchronizer alloc] init];
- m_audioRenderer = [[AVSampleBufferAudioRenderer alloc] init];
- [m_audioBufferSynchronizer addRenderer:m_audioRenderer];
- return self;
- }
- return nil;
-}
-
-- (void)captureOutput:(AVCaptureOutput *)captureOutput
- didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
- fromConnection:(AVCaptureConnection *)connection
-{
- Q_UNUSED(connection);
- Q_ASSERT(m_session);
-
- if (!CMSampleBufferDataIsReady(sampleBuffer)) {
- qWarning() << Q_FUNC_INFO << "sample buffer is not ready, skipping.";
- return;
- }
-
- CFRetain(sampleBuffer);
-
- dispatch_async(m_audioPreviewQueue, ^{
- [self renderAudioSampleBuffer:sampleBuffer];
- CFRelease(sampleBuffer);
- });
-}
-
-- (void)renderAudioSampleBuffer:(CMSampleBufferRef)sampleBuffer
-{
- Q_ASSERT(sampleBuffer);
- Q_ASSERT(m_session);
-
- if (m_audioBufferSynchronizer && m_audioRenderer) {
- [m_audioRenderer enqueueSampleBuffer:sampleBuffer];
- if (m_audioBufferSynchronizer.rate == 0)
- [m_audioBufferSynchronizer setRate:1 time:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)];
- }
-}
-
-- (void)resetAudioPreviewDelegate
-{
- [m_session->audioOutput() setSampleBufferDelegate:self queue:m_audioPreviewQueue];
-}
-
-- (void)setupWithCaptureSession: (AVFCameraSession*)session
- audioOutputDevice: (NSString*)deviceId
-{
- m_session = session;
-
- m_audioPreviewQueue = dispatch_queue_create("audio-preview-queue", nullptr);
- [m_session->audioOutput() setSampleBufferDelegate:self queue:m_audioPreviewQueue];
-#ifdef Q_OS_MACOS
- m_audioRenderer.audioOutputDeviceUniqueID = deviceId;
-#endif
-}
-
-- (void)setVolume: (float)volume
-{
- m_audioRenderer.volume = volume;
-}
-
-- (void)setMuted: (bool)muted
-{
- m_audioRenderer.muted = muted;
-}
-
--(void)dealloc {
- m_session = nil;
- [m_audioRenderer release];
- [m_audioBufferSynchronizer release];
- dispatch_release(m_audioPreviewQueue);
-
- [super dealloc];
-}
-
-@end
diff --git a/src/multimedia/platform/darwin/camera/avfaudiopreviewdelegate_p.h b/src/multimedia/platform/darwin/camera/avfaudiopreviewdelegate_p.h
deleted file mode 100644
index e993637dd..000000000
--- a/src/multimedia/platform/darwin/camera/avfaudiopreviewdelegate_p.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 AVFAUDIOPREVIEWDELEGATE_P_H
-#define AVFAUDIOPREVIEWDELEGATE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-
-#include <AVFoundation/AVFoundation.h>
-
-QT_BEGIN_NAMESPACE
-
-class AVFCameraSession;
-
-QT_END_NAMESPACE
-
-@interface AVFAudioPreviewDelegate : NSObject<AVCaptureAudioDataOutputSampleBufferDelegate>
-
-- (id)init;
-- (void)setupWithCaptureSession: (AVFCameraSession*)session
- audioOutputDevice: (NSString*)deviceId;
-- (void)renderAudioSampleBuffer:(CMSampleBufferRef)sampleBuffer;
-- (void)resetAudioPreviewDelegate;
-- (void)setVolume: (float)volume;
-- (void)setMuted: (bool)muted;
-
-@end
-
-#endif // AVFAUDIOPREVIEWDELEGATE_P_H
diff --git a/src/multimedia/platform/darwin/camera/avfcamera.mm b/src/multimedia/platform/darwin/camera/avfcamera.mm
deleted file mode 100644
index ede3c49eb..000000000
--- a/src/multimedia/platform/darwin/camera/avfcamera.mm
+++ /dev/null
@@ -1,1004 +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_p.h"
-#include "avfcamera_p.h"
-#include "avfcamerasession_p.h"
-#include "avfcameraservice_p.h"
-#include "avfcamerautility_p.h"
-#include "avfcamerarenderer_p.h"
-#include <qmediacapturesession.h>
-
-QT_USE_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, QCamera::ExposureMode mode,
- AVCaptureExposureMode &avMode)
-{
- // Test if mode supported and convert.
- Q_ASSERT(captureDevice);
-
- if (mode == QCamera::ExposureAuto) {
- if ([captureDevice isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) {
- avMode = AVCaptureExposureModeContinuousAutoExposure;
- return true;
- }
- }
-
- if (mode == QCamera::ExposureManual) {
- if ([captureDevice isExposureModeSupported:AVCaptureExposureModeCustom]) {
- avMode = AVCaptureExposureModeCustom;
- return true;
- }
- }
-
- return false;
-}
-
-#endif // defined(Q_OS_IOS)
-
-} // Unnamed namespace.
-
-
-AVFCamera::AVFCamera(QCamera *camera)
- : QPlatformCamera(camera)
-{
- Q_ASSERT(camera);
-}
-
-AVFCamera::~AVFCamera()
-{
-}
-
-bool AVFCamera::isActive() const
-{
- return m_active;
-}
-
-void AVFCamera::setActive(bool active)
-{
- if (m_active == active)
- return;
- if (m_cameraDevice.isNull() && active)
- return;
-
- m_active = active;
- if (m_session)
- m_session->setActive(active);
-
- if (active)
- updateCameraConfiguration();
- Q_EMIT activeChanged(m_active);
-}
-
-void AVFCamera::setCamera(const QCameraDevice &camera)
-{
- if (m_cameraDevice == camera)
- return;
- m_cameraDevice = camera;
- if (m_session)
- m_session->setActiveCamera(camera);
- setCameraFormat({});
-}
-
-bool AVFCamera::setCameraFormat(const QCameraFormat &format)
-{
- if (!format.isNull() && !m_cameraDevice.videoFormats().contains(format))
- return false;
-
- m_cameraFormat = format.isNull() ? findBestCameraFormat(m_cameraDevice) : format;
-
- if (m_session)
- m_session->setCameraFormat(m_cameraFormat);
-
- return true;
-}
-
-void AVFCamera::setCaptureSession(QPlatformMediaCaptureSession *session)
-{
- AVFCameraService *captureSession = static_cast<AVFCameraService *>(session);
- if (m_service == captureSession)
- return;
-
- if (m_session) {
- m_session->disconnect(this);
- m_session->setActiveCamera({});
- m_session->setCameraFormat({});
- }
-
- m_service = captureSession;
- if (!m_service) {
- m_session = nullptr;
- return;
- }
-
- m_session = m_service->session();
- Q_ASSERT(m_session);
-
- m_session->setActiveCamera(m_cameraDevice);
- m_session->setCameraFormat(m_cameraFormat);
- m_session->setActive(m_active);
-}
-
-AVCaptureConnection *AVFCamera::videoConnection() const
-{
- if (!m_session || !m_session->videoOutput() || !m_session->videoOutput()->videoDataOutput())
- return nil;
-
- return [m_session->videoOutput()->videoDataOutput() connectionWithMediaType:AVMediaTypeVideo];
-}
-
-AVCaptureDevice *AVFCamera::device() const
-{
- AVCaptureDevice *device = nullptr;
- QByteArray deviceId = m_cameraDevice.id();
- if (!deviceId.isEmpty()) {
- device = [AVCaptureDevice deviceWithUniqueID:
- [NSString stringWithUTF8String:
- deviceId.constData()]];
- }
- return device;
-}
-
-#ifdef Q_OS_IOS
-namespace
-{
-
-bool qt_focus_mode_supported(QCamera::FocusMode mode)
-{
- // Check if QCamera::FocusMode has counterpart in AVFoundation.
-
- // AVFoundation has 'Manual', 'Auto' and 'Continuous',
- // where 'Manual' is actually 'Locked' + writable property 'lensPosition'.
- return mode == QCamera::FocusModeAuto
- || mode == QCamera::FocusModeManual;
-}
-
-AVCaptureFocusMode avf_focus_mode(QCamera::FocusMode requestedMode)
-{
- switch (requestedMode) {
- case QCamera::FocusModeHyperfocal:
- case QCamera::FocusModeInfinity:
- case QCamera::FocusModeManual:
- return AVCaptureFocusModeLocked;
- default:
- return AVCaptureFocusModeContinuousAutoFocus;
- }
-
-}
-
-}
-#endif
-
-void AVFCamera::setFocusMode(QCamera::FocusMode mode)
-{
-#ifdef Q_OS_IOS
- if (focusMode() == mode)
- return;
-
- AVCaptureDevice *captureDevice = device();
- if (!captureDevice) {
- if (qt_focus_mode_supported(mode)) {
- focusModeChanged(mode);
- } 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);
- } else {
- qDebugCamera() << Q_FUNC_INFO << "focus mode not supported";
- return;
- }
-
- Q_EMIT focusModeChanged(mode);
-#else
- Q_UNUSED(mode);
-#endif
-}
-
-bool AVFCamera::isFocusModeSupported(QCamera::FocusMode mode) const
-{
-#ifdef Q_OS_IOS
- AVCaptureDevice *captureDevice = device();
- if (captureDevice) {
- AVCaptureFocusMode avMode = avf_focus_mode(mode);
- switch (mode) {
- case QCamera::FocusModeAuto:
- case QCamera::FocusModeHyperfocal:
- case QCamera::FocusModeInfinity:
- case QCamera::FocusModeManual:
- return [captureDevice isFocusModeSupported:avMode];
- case QCamera::FocusModeAutoNear:
- Q_FALLTHROUGH();
- case QCamera::FocusModeAutoFar:
- return captureDevice.autoFocusRangeRestrictionSupported
- && [captureDevice isFocusModeSupported:avMode];
- }
- }
-#endif
- return mode == QCamera::FocusModeAuto; // stupid builtin webcam doesn't do any focus handling, but hey it's usually focused :)
-}
-
-void AVFCamera::setCustomFocusPoint(const QPointF &point)
-{
- if (customFocusPoint() == point)
- return;
-
- if (!QRectF(0.f, 0.f, 1.f, 1.f).contains(point)) {
- // ### release custom focus point, tell the camera to focus where it wants...
- qDebugCamera() << Q_FUNC_INFO << "invalid focus point (out of range)";
- return;
- }
-
- AVCaptureDevice *captureDevice = device();
- if (!captureDevice)
- return;
-
- if ([captureDevice isFocusPointOfInterestSupported]) {
- const AVFConfigurationLock lock(captureDevice);
- if (!lock) {
- qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration";
- return;
- }
-
- const CGPoint focusPOI = CGPointMake(point.x(), point.y());
- [captureDevice setFocusPointOfInterest:focusPOI];
- if (focusMode() != QCamera::FocusModeAuto)
- [captureDevice setFocusMode:AVCaptureFocusModeAutoFocus];
-
- customFocusPointChanged(point);
- }
-}
-
-void AVFCamera::setFocusDistance(float d)
-{
-#ifdef Q_OS_IOS
- AVCaptureDevice *captureDevice = device();
- if (!captureDevice)
- return;
-
- if (captureDevice.lockingFocusWithCustomLensPositionSupported) {
- qDebugCamera() << Q_FUNC_INFO << "Setting custom focus distance not supported\n";
- return;
- }
-
- {
- AVFConfigurationLock lock(captureDevice);
- if (!lock) {
- qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration";
- return;
- }
- [captureDevice setFocusModeLockedWithLensPosition:d completionHandler:nil];
- }
- focusDistanceChanged(d);
-#else
- Q_UNUSED(d);
-#endif
-}
-
-void AVFCamera::updateCameraConfiguration()
-{
- AVCaptureDevice *captureDevice = device();
- if (!captureDevice) {
- qDebugCamera() << Q_FUNC_INFO << "capture device is nil in 'active' state";
- return;
- }
-
- const AVFConfigurationLock lock(captureDevice);
- if (!lock) {
- qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration";
- return;
- }
-
- if ([captureDevice isFocusPointOfInterestSupported]) {
- auto point = customFocusPoint();
- const CGPoint focusPOI = CGPointMake(point.x(), point.y());
- [captureDevice setFocusPointOfInterest:focusPOI];
- }
-
-#ifdef Q_OS_IOS
- if (focusMode() != QCamera::FocusModeAuto) {
- const AVCaptureFocusMode avMode = avf_focus_mode(focusMode());
- if (captureDevice.focusMode != avMode) {
- if ([captureDevice isFocusModeSupported:avMode]) {
- [captureDevice setFocusMode:avMode];
- } else {
- qDebugCamera() << Q_FUNC_INFO << "focus mode not supported";
- }
- }
- }
-
- if (!captureDevice.activeFormat) {
- qDebugCamera() << Q_FUNC_INFO << "camera state is active, but active format is nil";
- return;
- }
-
- minimumZoomFactorChanged(captureDevice.minAvailableVideoZoomFactor);
- maximumZoomFactorChanged(captureDevice.maxAvailableVideoZoomFactor);
-
- captureDevice.videoZoomFactor = zoomFactor();
-
- CMTime newDuration = AVCaptureExposureDurationCurrent;
- bool setCustomMode = false;
-
- float exposureTime = manualExposureTime();
- if (exposureTime > 0
- && !qt_exposure_duration_equal(captureDevice, exposureTime)) {
- newDuration = CMTimeMakeWithSeconds(exposureTime, 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;
- int iso = manualIsoSensitivity();
- if (iso > 0 && !qt_iso_equal(captureDevice, iso)) {
- newISO = iso;
- if (!qt_check_ISO_value(captureDevice, newISO)) {
- qDebugCamera() << Q_FUNC_INFO << "requested ISO value is out of range";
- return;
- }
- setCustomMode = true;
- }
-
- float bias = exposureCompensation();
- if (bias != 0 && !qt_exposure_bias_equal(captureDevice, bias)) {
- // TODO: mixed fpns.
- if (bias < captureDevice.minExposureTargetBias || bias > captureDevice.maxExposureTargetBias) {
- qDebugCamera() << Q_FUNC_INFO << "exposure compensation value is"
- << "out of range";
- return;
- }
- [captureDevice setExposureTargetBias:bias completionHandler:nil];
- }
-
- // 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) {
- [captureDevice setExposureModeCustomWithDuration:newDuration
- ISO:newISO
- completionHandler:nil];
- return;
- }
-
- QCamera::ExposureMode qtMode = exposureMode();
- AVCaptureExposureMode avMode = AVCaptureExposureModeContinuousAutoExposure;
- if (!qt_convert_exposure_mode(captureDevice, qtMode, avMode)) {
- qDebugCamera() << Q_FUNC_INFO << "requested exposure mode is not supported";
- return;
- }
-
- captureDevice.exposureMode = avMode;
-#endif
-
- isFlashSupported = isFlashAutoSupported = false;
- isTorchSupported = isTorchAutoSupported = false;
-
- if (captureDevice.hasFlash) {
- if ([captureDevice isFlashModeSupported:AVCaptureFlashModeOn])
- isFlashSupported = true;
- if ([captureDevice isFlashModeSupported:AVCaptureFlashModeAuto])
- isFlashAutoSupported = true;
- }
-
- if (captureDevice.hasTorch) {
- if ([captureDevice isTorchModeSupported:AVCaptureTorchModeOn])
- isTorchSupported = true;
- if ([captureDevice isTorchModeSupported:AVCaptureTorchModeAuto])
- isTorchAutoSupported = true;
- }
-
- applyFlashSettings();
- flashReadyChanged(isFlashSupported);
-}
-
-void AVFCamera::updateCameraProperties()
-{
- QCamera::Features features;
- AVCaptureDevice *captureDevice = device();
-
-#ifdef Q_OS_IOS
- features = QCamera::Feature::ColorTemperature | QCamera::Feature::ExposureCompensation |
- QCamera::Feature::IsoSensitivity | QCamera::Feature::ManualExposureTime;
-
- if (captureDevice && [captureDevice isLockingFocusWithCustomLensPositionSupported])
- features |= QCamera::Feature::FocusDistance;
-#endif
-
- if (captureDevice && [captureDevice isFocusPointOfInterestSupported])
- features |= QCamera::Feature::CustomFocusPoint;
-
- supportedFeaturesChanged(features);
-}
-
-void AVFCamera::zoomTo(float factor, float rate)
-{
- Q_UNUSED(factor);
- Q_UNUSED(rate);
-
-#ifdef Q_OS_IOS
- if (zoomFactor() == factor)
- return;
-
- AVCaptureDevice *captureDevice = device();
- if (!captureDevice || !captureDevice.activeFormat)
- return;
-
- factor = qBound(captureDevice.minAvailableVideoZoomFactor, factor, captureDevice.maxAvailableVideoZoomFactor);
-
- const AVFConfigurationLock lock(captureDevice);
- if (!lock) {
- qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration";
- return;
- }
-
- if (rate < 0)
- captureDevice.videoZoomFactor = factor;
- else
- [AVCaptureDevice rampToVideoZoomFactor:factor withRate:rate];
-#endif
-}
-
-void AVFCamera::setFlashMode(QCamera::FlashMode mode)
-{
- if (flashMode() == mode)
- return;
-
- if (isActive() && !isFlashModeSupported(mode)) {
- qDebugCamera() << Q_FUNC_INFO << "unsupported mode" << mode;
- return;
- }
-
- flashModeChanged(mode);
-
- if (!isActive())
- return;
-
- applyFlashSettings();
-}
-
-bool AVFCamera::isFlashModeSupported(QCamera::FlashMode mode) const
-{
- if (mode == QCamera::FlashOff)
- return true;
- else if (mode == QCamera::FlashOn)
- return isFlashSupported;
- else //if (mode == QCamera::FlashAuto)
- return isFlashAutoSupported;
-}
-
-bool AVFCamera::isFlashReady() const
-{
- if (!isActive())
- return false;
-
- AVCaptureDevice *captureDevice = device();
- if (!captureDevice)
- return false;
-
- if (!captureDevice.hasFlash)
- return false;
-
- if (!isFlashModeSupported(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."
- return [captureDevice isFlashAvailable];
-#endif
-
- return true;
-}
-
-void AVFCamera::setTorchMode(QCamera::TorchMode mode)
-{
- if (torchMode() == mode)
- return;
-
- if (isActive() && !isTorchModeSupported(mode)) {
- qDebugCamera() << Q_FUNC_INFO << "unsupported torch mode" << mode;
- return;
- }
-
- torchModeChanged(mode);
-
- if (!isActive())
- return;
-
- applyFlashSettings();
-}
-
-bool AVFCamera::isTorchModeSupported(QCamera::TorchMode mode) const
-{
- if (mode == QCamera::TorchOff)
- return true;
- else if (mode == QCamera::TorchOn)
- return isTorchSupported;
- else //if (mode == QCamera::TorchAuto)
- return isTorchAutoSupported;
-}
-
-void AVFCamera::setExposureMode(QCamera::ExposureMode qtMode)
-{
-#ifdef Q_OS_IOS
- if (qtMode != QCamera::ExposureAuto && qtMode != QCamera::ExposureManual) {
- qDebugCamera() << Q_FUNC_INFO << "exposure mode not supported";
- return;
- }
-
- AVCaptureDevice *captureDevice = device();
- if (!captureDevice) {
- exposureModeChanged(qtMode);
- return;
- }
-
- AVCaptureExposureMode avMode = AVCaptureExposureModeContinuousAutoExposure;
- if (!qt_convert_exposure_mode(captureDevice, qtMode, avMode)) {
- qDebugCamera() << Q_FUNC_INFO << "exposure mode not supported";
- return;
- }
-
- const AVFConfigurationLock lock(captureDevice);
- if (!lock) {
- qDebugCamera() << Q_FUNC_INFO << "failed to lock a capture device"
- << "for configuration";
- return;
- }
-
- [captureDevice setExposureMode:avMode];
- exposureModeChanged(qtMode);
-#else
- Q_UNUSED(qtMode);
-#endif
-}
-
-bool AVFCamera::isExposureModeSupported(QCamera::ExposureMode mode) const
-{
- if (mode == QCamera::ExposureAuto)
- return true;
- if (mode != QCamera::ExposureManual)
- return false;
-
- if (@available(macOS 10.15, *)) {
- AVCaptureDevice *captureDevice = device();
- return captureDevice && [captureDevice isExposureModeSupported:AVCaptureExposureModeCustom];
- }
-
- return false;
-}
-
-void AVFCamera::applyFlashSettings()
-{
- Q_ASSERT(isActive());
-
- AVCaptureDevice *captureDevice = device();
- if (!captureDevice) {
- qDebugCamera() << Q_FUNC_INFO << "no capture device found";
- return;
- }
-
-
- const AVFConfigurationLock lock(captureDevice);
-
- if (captureDevice.hasFlash) {
- auto mode = flashMode();
- if (mode == QCamera::FlashOff) {
- captureDevice.flashMode = AVCaptureFlashModeOff;
- } else {
-#ifdef Q_OS_IOS
- if (![captureDevice isFlashAvailable]) {
- qDebugCamera() << Q_FUNC_INFO << "flash is not available at the moment";
- return;
- }
-#endif
- if (mode == QCamera::FlashOn)
- captureDevice.flashMode = AVCaptureFlashModeOn;
- else if (mode == QCamera::FlashAuto)
- captureDevice.flashMode = AVCaptureFlashModeAuto;
- }
- }
-
- if (captureDevice.hasTorch) {
- auto mode = torchMode();
- if (mode == QCamera::TorchOff) {
- captureDevice.torchMode = AVCaptureTorchModeOff;
- } else {
-#ifdef Q_OS_IOS
- if (![captureDevice isTorchAvailable]) {
- qDebugCamera() << Q_FUNC_INFO << "torch is not available at the moment";
- return;
- }
-#endif
- if (mode == QCamera::TorchOn)
- captureDevice.torchMode = AVCaptureTorchModeOn;
- else if (mode == QCamera::TorchAuto)
- captureDevice.torchMode = AVCaptureTorchModeAuto;
- }
- }
-}
-
-
-void AVFCamera::setExposureCompensation(float bias)
-{
-#ifdef Q_OS_IOS
- AVCaptureDevice *captureDevice = device();
- if (!captureDevice) {
- exposureCompensationChanged(bias);
- return;
- }
-
- bias = qBound(captureDevice.minExposureTargetBias, bias, captureDevice.maxExposureTargetBias);
-
- const AVFConfigurationLock lock(captureDevice);
- if (!lock) {
- qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration";
- return;
- }
-
- [captureDevice setExposureTargetBias:bias completionHandler:nil];
- exposureCompensationChanged(bias);
-#else
- Q_UNUSED(bias);
-#endif
-}
-
-void AVFCamera::setManualExposureTime(float value)
-{
-#ifdef Q_OS_IOS
- if (value < 0) {
- setExposureMode(QCamera::ExposureAuto);
- return;
- }
-
- AVCaptureDevice *captureDevice = device();
- if (!captureDevice) {
- exposureTimeChanged(value);
- return;
- }
-
- const CMTime newDuration = CMTimeMakeWithSeconds(value, captureDevice.exposureDuration.timescale);
- if (!qt_check_exposure_duration(captureDevice, newDuration)) {
- qDebugCamera() << Q_FUNC_INFO << "shutter speed value is out of range";
- return;
- }
-
- const AVFConfigurationLock lock(captureDevice);
- if (!lock) {
- qDebugCamera() << Q_FUNC_INFO << "failed to lock for configuration";
- return;
- }
-
- // Setting the shutter speed (exposure duration in Apple's terms,
- // since there is no shutter actually) will also reset
- // exposure mode into custom mode.
- [captureDevice setExposureModeCustomWithDuration:newDuration
- ISO:AVCaptureISOCurrent
- completionHandler:nil];
-
- exposureTimeChanged(value);
-
-#else
- Q_UNUSED(value);
-#endif
-}
-
-float AVFCamera::exposureTime() const
-{
-#ifdef Q_OS_IOS
- AVCaptureDevice *captureDevice = device();
- if (!captureDevice)
- return -1.;
- auto duration = captureDevice.exposureDuration;
- return CMTimeGetSeconds(duration);
-#else
- return -1;
-#endif
-}
-
-#ifdef Q_OS_IOS
-namespace {
-
-void avf_convert_white_balance_mode(QCamera::WhiteBalanceMode qtMode,
- AVCaptureWhiteBalanceMode &avMode)
-{
- if (qtMode == QCamera::WhiteBalanceAuto)
- avMode = AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance;
- else
- avMode = AVCaptureWhiteBalanceModeLocked;
-}
-
-bool avf_set_white_balance_mode(AVCaptureDevice *captureDevice,
- AVCaptureWhiteBalanceMode avMode)
-{
- Q_ASSERT(captureDevice);
-
- const bool lock = [captureDevice lockForConfiguration:nil];
- if (!lock) {
- qDebug() << "Failed to lock a capture device for configuration\n";
- return false;
- }
-
- captureDevice.whiteBalanceMode = avMode;
- [captureDevice unlockForConfiguration];
- return true;
-}
-
-bool avf_convert_temp_and_tint_to_wb_gains(AVCaptureDevice *captureDevice,
- float temp, float tint, AVCaptureWhiteBalanceGains &wbGains)
-{
- Q_ASSERT(captureDevice);
-
- AVCaptureWhiteBalanceTemperatureAndTintValues wbTTValues = {
- .temperature = temp,
- .tint = tint
- };
- wbGains = [captureDevice deviceWhiteBalanceGainsForTemperatureAndTintValues:wbTTValues];
-
- if (wbGains.redGain >= 1.0 && wbGains.redGain <= captureDevice.maxWhiteBalanceGain
- && wbGains.greenGain >= 1.0 && wbGains.greenGain <= captureDevice.maxWhiteBalanceGain
- && wbGains.blueGain >= 1.0 && wbGains.blueGain <= captureDevice.maxWhiteBalanceGain)
- return true;
-
- return false;
-}
-
-bool avf_set_white_balance_gains(AVCaptureDevice *captureDevice,
- AVCaptureWhiteBalanceGains wbGains)
-{
- const bool lock = [captureDevice lockForConfiguration:nil];
- if (!lock) {
- qDebug() << "Failed to lock a capture device for configuration\n";
- return false;
- }
-
- [captureDevice setWhiteBalanceModeLockedWithDeviceWhiteBalanceGains:wbGains
- completionHandler:nil];
- [captureDevice unlockForConfiguration];
- return true;
-}
-
-}
-
-bool AVFCamera::isWhiteBalanceModeSupported(QCamera::WhiteBalanceMode mode) const
-{
- if (mode == QCamera::WhiteBalanceAuto)
- return true;
- AVCaptureDevice *captureDevice = device();
- if (!captureDevice)
- return false;
- return [captureDevice isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeLocked];
-}
-
-void AVFCamera::setWhiteBalanceMode(QCamera::WhiteBalanceMode mode)
-{
- if (!isWhiteBalanceModeSupported(mode))
- return;
-
- AVCaptureDevice *captureDevice = device();
- Q_ASSERT(captureDevice);
-
- const AVFConfigurationLock lock(captureDevice);
- if (!lock) {
- qDebugCamera() << Q_FUNC_INFO << "failed to lock a capture device"
- << "for configuration";
- return;
- }
-
- AVCaptureWhiteBalanceMode avMode;
- avf_convert_white_balance_mode(mode, avMode);
- avf_set_white_balance_mode(captureDevice, avMode);
-
- if (mode == QCamera::WhiteBalanceAuto || mode == QCamera::WhiteBalanceManual) {
- whiteBalanceModeChanged(mode);
- return;
- }
-
- const int colorTemp = colorTemperatureForWhiteBalance(mode);
- AVCaptureWhiteBalanceGains wbGains;
- if (avf_convert_temp_and_tint_to_wb_gains(captureDevice, colorTemp, 0., wbGains)
- && avf_set_white_balance_gains(captureDevice, wbGains))
- whiteBalanceModeChanged(mode);
-}
-
-void AVFCamera::setColorTemperature(int colorTemp)
-{
- if (colorTemp == 0) {
- colorTemperatureChanged(colorTemp);
- return;
- }
-
- AVCaptureDevice *captureDevice = device();
- if (!captureDevice || ![captureDevice isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeLocked])
- return;
-
- const AVFConfigurationLock lock(captureDevice);
- if (!lock) {
- qDebugCamera() << Q_FUNC_INFO << "failed to lock a capture device"
- << "for configuration";
- return;
- }
-
- AVCaptureWhiteBalanceGains wbGains;
- if (avf_convert_temp_and_tint_to_wb_gains(captureDevice, colorTemp, 0., wbGains)
- && avf_set_white_balance_gains(captureDevice, wbGains))
- colorTemperatureChanged(colorTemp);
-}
-#endif
-
-void AVFCamera::setManualIsoSensitivity(int value)
-{
-#ifdef Q_OS_IOS
- if (value < 0) {
- setExposureMode(QCamera::ExposureAuto);
- return;
- }
-
- AVCaptureDevice *captureDevice = device();
- if (!captureDevice) {
- isoSensitivityChanged(value);
- return;
- }
-
- if (!qt_check_ISO_value(captureDevice, value)) {
- qDebugCamera() << Q_FUNC_INFO << "ISO value is out of range";
- return;
- }
-
- const AVFConfigurationLock lock(captureDevice);
- if (!lock) {
- qDebugCamera() << Q_FUNC_INFO << "failed to lock a capture device"
- << "for configuration";
- return;
- }
-
- // Setting the ISO will also reset
- // exposure mode to the custom mode.
- [captureDevice setExposureModeCustomWithDuration:AVCaptureExposureDurationCurrent
- ISO:value
- completionHandler:nil];
-
- isoSensitivityChanged(value);
-#else
- Q_UNUSED(value);
-#endif
-}
-
-int AVFCamera::isoSensitivity() const
-{
- return manualIsoSensitivity();
-}
-
-
-#include "moc_avfcamera_p.cpp"
diff --git a/src/multimedia/platform/darwin/camera/avfcamera_p.h b/src/multimedia/platform/darwin/camera/avfcamera_p.h
deleted file mode 100644
index 950d0131b..000000000
--- a/src/multimedia/platform/darwin/camera/avfcamera_p.h
+++ /dev/null
@@ -1,139 +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 AVFCAMERA_H
-#define AVFCAMERA_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 <QtCore/qobject.h>
-
-#include <private/qplatformcamera_p.h>
-
-Q_FORWARD_DECLARE_OBJC_CLASS(AVCaptureDeviceFormat);
-Q_FORWARD_DECLARE_OBJC_CLASS(AVCaptureConnection);
-Q_FORWARD_DECLARE_OBJC_CLASS(AVCaptureDevice);
-
-QT_BEGIN_NAMESPACE
-
-class AVFCameraSession;
-class AVFCameraService;
-class AVFCameraSession;
-
-class AVFCamera : public QPlatformCamera
-{
-Q_OBJECT
-public:
- AVFCamera(QCamera *camera);
- ~AVFCamera();
-
- bool isActive() const override;
- void setActive(bool activce) override;
-
- void setCamera(const QCameraDevice &camera) override;
- bool setCameraFormat(const QCameraFormat &format) override;
-
- void setCaptureSession(QPlatformMediaCaptureSession *) override;
-
- void setFocusMode(QCamera::FocusMode mode) override;
- bool isFocusModeSupported(QCamera::FocusMode mode) const override;
-
- void setCustomFocusPoint(const QPointF &point) override;
-
- void setFocusDistance(float d) override;
- void zoomTo(float factor, float rate) override;
-
- void setFlashMode(QCamera::FlashMode mode) override;
- bool isFlashModeSupported(QCamera::FlashMode mode) const override;
- bool isFlashReady() const override;
-
- void setTorchMode(QCamera::TorchMode mode) override;
- bool isTorchModeSupported(QCamera::TorchMode mode) const override;
-
- void setExposureMode(QCamera::ExposureMode) override;
- bool isExposureModeSupported(QCamera::ExposureMode mode) const override;
-
- void setExposureCompensation(float bias) override;
- void setManualIsoSensitivity(int value) override;
- virtual int isoSensitivity() const override;
- void setManualExposureTime(float value) override;
- virtual float exposureTime() const override;
-
-#ifdef Q_OS_IOS
- // not supported on macOS
- bool isWhiteBalanceModeSupported(QCamera::WhiteBalanceMode mode) const override;
- void setWhiteBalanceMode(QCamera::WhiteBalanceMode /*mode*/) override;
- void setColorTemperature(int /*temperature*/) override;
-#endif
-
- AVCaptureConnection *videoConnection() const;
- AVCaptureDevice *device() const;
-
-private:
- void updateCameraConfiguration();
- void updateCameraProperties();
- void applyFlashSettings();
-
- friend class AVFCameraSession;
- AVFCameraService *m_service = nullptr;
- AVFCameraSession *m_session = nullptr;
-
- QCameraDevice m_cameraDevice;
- QCameraFormat m_cameraFormat;
-
- bool m_active = false;
-
- bool isFlashSupported = false;
- bool isFlashAutoSupported = false;
- bool isTorchSupported = false;
- bool isTorchAutoSupported = false;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/darwin/camera/avfcameradebug_p.h b/src/multimedia/platform/darwin/camera/avfcameradebug_p.h
deleted file mode 100644
index 616e53d99..000000000
--- a/src/multimedia/platform/darwin/camera/avfcameradebug_p.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 AVFDEBUG_H
-#define AVFDEBUG_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 "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/multimedia/platform/darwin/camera/avfcamerarenderer.mm b/src/multimedia/platform/darwin/camera/avfcamerarenderer.mm
deleted file mode 100644
index 016ee3333..000000000
--- a/src/multimedia/platform/darwin/camera/avfcamerarenderer.mm
+++ /dev/null
@@ -1,298 +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 "avfcamerarenderer_p.h"
-#include "avfcamerasession_p.h"
-#include "avfcameraservice_p.h"
-#include "avfcameradebug_p.h"
-#include "avfcamera_p.h"
-#include <private/avfvideosink_p.h>
-#include <private/avfvideobuffer_p.h>
-#include "qvideosink.h"
-
-#import <AVFoundation/AVFoundation.h>
-
-#ifdef Q_OS_IOS
-#include <QtGui/qopengl.h>
-#endif
-
-#include <private/qabstractvideobuffer_p.h>
-
-#include <QtMultimedia/qvideoframeformat.h>
-
-QT_USE_NAMESPACE
-
-@interface AVFCaptureFramesDelegate : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate>
-
-- (AVFCaptureFramesDelegate *) initWithRenderer:(AVFCameraRenderer*)renderer;
-
-- (void) captureOutput:(AVCaptureOutput *)captureOutput
- didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
- fromConnection:(AVCaptureConnection *)connection;
-
-@end
-
-@implementation AVFCaptureFramesDelegate
-{
-@private
- AVFCameraRenderer *m_renderer;
-}
-
-- (AVFCaptureFramesDelegate *) initWithRenderer:(AVFCameraRenderer*)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);
- QVideoFrameFormat::PixelFormat format =
- AVFVideoBuffer::fromCVPixelFormat(CVPixelBufferGetPixelFormatType(imageBuffer));
- if (format == QVideoFrameFormat::Format_Invalid)
- return;
-
- QVideoFrame frame(new AVFVideoBuffer(m_renderer, imageBuffer),
- QVideoFrameFormat(QSize(width, height), format));
-
- m_renderer->syncHandleViewfinderFrame(frame);
-}
-
-@end
-
-AVFCameraRenderer::AVFCameraRenderer(QObject *parent)
- : QObject(parent)
-{
- m_viewfinderFramesDelegate = [[AVFCaptureFramesDelegate alloc] initWithRenderer:this];
- connect(&m_orientationHandler, &QVideoOutputOrientationHandler::orientationChanged,
- this, &AVFCameraRenderer::deviceOrientationChanged);
-}
-
-AVFCameraRenderer::~AVFCameraRenderer()
-{
- [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
-}
-
-void AVFCameraRenderer::reconfigure()
-{
- QMutexLocker lock(&m_vfMutex);
-
- // ### This is a hack, need to use a reliable way to determine the size and not use the preview layer
- if (m_layer)
- m_sink->setNativeSize(QSize(m_layer.bounds.size.width, m_layer.bounds.size.height));
- nativeSizeChanged();
- deviceOrientationChanged();
-}
-
-void AVFCameraRenderer::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 AVFCameraRenderer::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;
-
- deviceOrientationChanged();
-}
-
-void AVFCameraRenderer::deviceOrientationChanged(int angle)
-{
- AVCaptureConnection *connection = [m_videoDataOutput connectionWithMediaType:AVMediaTypeVideo];
- if (connection == nil || !m_cameraSession->videoCaptureDevice())
- return;
-
- if (!connection.supportsVideoOrientation)
- return;
-
- if (angle < 0)
- angle = m_orientationHandler.currentOrientation();
-
- AVCaptureVideoOrientation orientation = AVCaptureVideoOrientationPortrait;
- switch (angle) {
- default:
- break;
- case 90:
- orientation = AVCaptureVideoOrientationLandscapeRight;
- break;
- case 180:
- // this keeps the last orientation, don't do anything
- return;
- case 270:
- orientation = AVCaptureVideoOrientationLandscapeLeft;
- break;
- }
-
- connection.videoOrientation = orientation;
-}
-
-//can be called from non main thread
-void AVFCameraRenderer::syncHandleViewfinderFrame(const QVideoFrame &frame)
-{
- Q_EMIT newViewfinderFrame(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;
-}
-
-AVCaptureVideoDataOutput *AVFCameraRenderer::videoDataOutput() const
-{
- return m_videoDataOutput;
-}
-
-AVFCaptureFramesDelegate *AVFCameraRenderer::captureDelegate() const
-{
- return m_viewfinderFramesDelegate;
-}
-
-void AVFCameraRenderer::resetCaptureDelegate() const
-{
- [m_videoDataOutput setSampleBufferDelegate:m_viewfinderFramesDelegate queue:m_delegateQueue];
-}
-
-void AVFCameraRenderer::handleViewfinderFrame()
-{
- QVideoFrame frame;
- {
- QMutexLocker lock(&m_vfMutex);
- frame = m_lastViewfinderFrame;
- m_lastViewfinderFrame = QVideoFrame();
- }
-
- if (m_sink && frame.isValid()) {
- // ### pass format to surface
- QVideoFrameFormat format = frame.surfaceFormat();
- if (m_needsHorizontalMirroring)
- format.setMirrored(true);
-
- m_sink->setVideoFrame(frame);
- }
-}
-
-void AVFCameraRenderer::setPixelFormat(const QVideoFrameFormat::PixelFormat pixelFormat)
-{
- // Default to 32ARGB/32BGRA pixel formats on the viewfinder, in case the requested
- // format can't be used (shouldn't happen unless the developers sets a wrong camera
- // format on the camera).
- unsigned avPixelFormat = kCVPixelFormatType_32ARGB;
-#ifdef Q_OS_IOS
- avPixelFormat = kCVPixelFormatType_32BGRA;
-#endif
- if (!AVFVideoBuffer::toCVPixelFormat(pixelFormat, avPixelFormat))
- qWarning() << "QCamera::setCameraFormat: couldn't convert requested pixel format, using ARGB32";
- qDebug() << "setPixelFormat" << pixelFormat << Qt::hex << avPixelFormat;
-
- bool isSupported = false;
- NSArray *supportedPixelFormats = m_videoDataOutput.availableVideoCVPixelFormatTypes;
- for (NSNumber *currentPixelFormat in supportedPixelFormats)
- {
- if ([currentPixelFormat unsignedIntValue] == avPixelFormat) {
- isSupported = true;
- break;
- }
- }
-
- if (isSupported) {
- NSDictionary* outputSettings = @{
- (NSString *)kCVPixelBufferPixelFormatTypeKey: [NSNumber numberWithUnsignedInt:avPixelFormat],
- (NSString *)kCVPixelBufferMetalCompatibilityKey: @true
- };
- m_videoDataOutput.videoSettings = outputSettings;
- } else {
- qWarning() << "QCamera::setCameraFormat: requested pixel format not supported. Did you use a camera format from another camera?";
- }
-}
-
-#include "moc_avfcamerarenderer_p.cpp"
-
diff --git a/src/multimedia/platform/darwin/camera/avfcamerarenderer_p.h b/src/multimedia/platform/darwin/camera/avfcamerarenderer_p.h
deleted file mode 100644
index 9455f593d..000000000
--- a/src/multimedia/platform/darwin/camera/avfcamerarenderer_p.h
+++ /dev/null
@@ -1,129 +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 AVFCAMERARENDERER_H
-#define AVFCAMERARENDERER_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 <QtCore/qobject.h>
-#include <QtMultimedia/qvideoframe.h>
-#include <QtCore/qmutex.h>
-#include <private/avfvideosink_p.h>
-#include <private/qvideooutputorientationhandler_p.h>
-
-#include <CoreVideo/CVBase.h>
-#include <CoreVideo/CVPixelBuffer.h>
-#include <CoreVideo/CVImageBuffer.h>
-#ifdef Q_OS_IOS
-#include <CoreVideo/CVOpenGLESTexture.h>
-#include <CoreVideo/CVOpenGLESTextureCache.h>
-#endif
-
-#include <dispatch/dispatch.h>
-
-Q_FORWARD_DECLARE_OBJC_CLASS(AVFCaptureFramesDelegate);
-Q_FORWARD_DECLARE_OBJC_CLASS(AVCaptureVideoDataOutput);
-
-QT_BEGIN_NAMESPACE
-
-class AVFCameraSession;
-class AVFCameraService;
-class AVFCameraRenderer;
-class AVFVideoSink;
-
-class AVFCameraRenderer : public QObject, public AVFVideoSinkInterface
-{
-Q_OBJECT
-public:
- AVFCameraRenderer(QObject *parent = nullptr);
- ~AVFCameraRenderer();
-
- void reconfigure() override;
-
- void configureAVCaptureSession(AVFCameraSession *cameraSession);
- void syncHandleViewfinderFrame(const QVideoFrame &frame);
-
- AVCaptureVideoDataOutput *videoDataOutput() const;
-
- AVFCaptureFramesDelegate *captureDelegate() const;
- void resetCaptureDelegate() const;
-
- void setPixelFormat(const QVideoFrameFormat::PixelFormat format);
-
-Q_SIGNALS:
- void newViewfinderFrame(const QVideoFrame &frame);
-
-private Q_SLOTS:
- void handleViewfinderFrame();
- void updateCaptureConnection();
-public Q_SLOTS:
- void deviceOrientationChanged(int angle = -1);
-
-private:
- AVFCaptureFramesDelegate *m_viewfinderFramesDelegate = nullptr;
- AVFCameraSession *m_cameraSession = nullptr;
- AVCaptureVideoDataOutput *m_videoDataOutput = nullptr;
-
- bool m_needsHorizontalMirroring = false;
-
-#ifdef Q_OS_IOS
- CVOpenGLESTextureCacheRef m_textureCache = nullptr;
-#endif
-
- QVideoFrame m_lastViewfinderFrame;
- QMutex m_vfMutex;
- dispatch_queue_t m_delegateQueue;
- QVideoOutputOrientationHandler m_orientationHandler;
-
- friend class CVImageVideoBuffer;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/darwin/camera/avfcameraservice.mm b/src/multimedia/platform/darwin/camera/avfcameraservice.mm
deleted file mode 100644
index 2d37a4117..000000000
--- a/src/multimedia/platform/darwin/camera/avfcameraservice.mm
+++ /dev/null
@@ -1,201 +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_p.h"
-#include "avfcamera_p.h"
-#include "avfcamerasession_p.h"
-#include "avfimagecapture_p.h"
-#include "avfcamerarenderer_p.h"
-#include "avfimagecapture_p.h"
-#include "avfmediaencoder_p.h"
-#include <qmediadevices.h>
-#include <private/qplatformaudioinput_p.h>
-#include <private/qplatformaudiooutput_p.h>
-#include <qaudioinput.h>
-#include <qaudiooutput.h>
-
-QT_USE_NAMESPACE
-
-AVFCameraService::AVFCameraService()
-{
- m_session = new AVFCameraSession(this);
-}
-
-AVFCameraService::~AVFCameraService()
-{
- if (m_session)
- delete m_session;
-}
-
-QPlatformCamera *AVFCameraService::camera()
-{
- return m_cameraControl;
-}
-
-void AVFCameraService::setCamera(QPlatformCamera *camera)
-{
- AVFCamera *control = static_cast<AVFCamera *>(camera);
- if (m_cameraControl == control)
- return;
-
- if (m_cameraControl)
- m_cameraControl->setCaptureSession(nullptr);
-
- m_cameraControl = control;
- emit cameraChanged();
-
- if (m_cameraControl)
- m_cameraControl->setCaptureSession(this);
-}
-
-QPlatformImageCapture *AVFCameraService::imageCapture()
-{
- return m_imageCaptureControl;
-}
-
-void AVFCameraService::setImageCapture(QPlatformImageCapture *imageCapture)
-{
- AVFImageCapture *control = static_cast<AVFImageCapture *>(imageCapture);
- if (m_imageCaptureControl == control)
- return;
-
- if (m_imageCaptureControl)
- m_imageCaptureControl->setCaptureSession(nullptr);
-
- m_imageCaptureControl = control;
- if (m_imageCaptureControl)
- m_imageCaptureControl->setCaptureSession(this);
-}
-
-QPlatformMediaEncoder *AVFCameraService::mediaEncoder()
-{
- return m_encoder;
-}
-
-void AVFCameraService::setMediaEncoder(QPlatformMediaEncoder *encoder)
-{
- AVFMediaEncoder *control = static_cast<AVFMediaEncoder *>(encoder);
- if (m_encoder == control)
- return;
-
- if (m_encoder)
- m_encoder->setCaptureSession(nullptr);
-
- m_encoder = control;
- if (m_encoder)
- m_encoder->setCaptureSession(this);
-
- emit encoderChanged();
-}
-
-void AVFCameraService::setAudioInput(QPlatformAudioInput *input)
-{
- if (m_audioInput == input)
- return;
- if (m_audioInput)
- m_audioInput->q->disconnect(this);
-
- m_audioInput = input;
-
- if (input) {
- connect(m_audioInput->q, &QAudioInput::destroyed, this, &AVFCameraService::audioInputDestroyed);
- connect(m_audioInput->q, &QAudioInput::deviceChanged, this, &AVFCameraService::audioInputChanged);
- connect(m_audioInput->q, &QAudioInput::mutedChanged, this, &AVFCameraService::setAudioInputMuted);
- connect(m_audioInput->q, &QAudioInput::volumeChanged, this, &AVFCameraService::setAudioInputVolume);
- }
- audioInputChanged();
-}
-
-void AVFCameraService::setAudioOutput(QPlatformAudioOutput *output)
-{
- if (m_audioOutput == output)
- return;
- if (m_audioOutput)
- m_audioOutput->q->disconnect(this);
-
- m_audioOutput = output;
-
- if (m_audioOutput) {
- connect(m_audioOutput->q, &QAudioOutput::destroyed, this, &AVFCameraService::audioOutputDestroyed);
- connect(m_audioOutput->q, &QAudioOutput::deviceChanged, this, &AVFCameraService::audioOutputChanged);
- connect(m_audioOutput->q, &QAudioOutput::mutedChanged, this, &AVFCameraService::setAudioOutputMuted);
- connect(m_audioOutput->q, &QAudioOutput::volumeChanged, this, &AVFCameraService::setAudioOutputVolume);
- }
- audioOutputChanged();
-}
-
-void AVFCameraService::audioInputChanged()
-{
- m_session->updateAudioInput();
-}
-
-void AVFCameraService::audioOutputChanged()
-{
- m_session->updateAudioOutput();
-}
-
-void AVFCameraService::setAudioInputMuted(bool muted)
-{
- m_session->setAudioInputMuted(muted);
-}
-
-void AVFCameraService::setAudioInputVolume(float volume)
-{
- m_session->setAudioInputVolume(volume);
-}
-
-void AVFCameraService::setAudioOutputMuted(bool muted)
-{
- m_session->setAudioOutputMuted(muted);
-}
-
-void AVFCameraService::setAudioOutputVolume(float volume)
-{
- m_session->setAudioOutputVolume(volume);
-}
-
-void AVFCameraService::setVideoPreview(QVideoSink *sink)
-{
- m_session->setVideoSink(sink);
-}
-
-#include "moc_avfcameraservice_p.cpp"
diff --git a/src/multimedia/platform/darwin/camera/avfcameraservice_p.h b/src/multimedia/platform/darwin/camera/avfcameraservice_p.h
deleted file mode 100644
index 462c957b4..000000000
--- a/src/multimedia/platform/darwin/camera/avfcameraservice_p.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 AVFCAMERASERVICE_H
-#define AVFCAMERASERVICE_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 <QtCore/qobject.h>
-#include <QtCore/qset.h>
-#include <private/qplatformmediacapture_p.h>
-
-Q_FORWARD_DECLARE_OBJC_CLASS(AVCaptureDevice);
-
-QT_BEGIN_NAMESPACE
-class QPlatformCamera;
-class QPlatformMediaEncoder;
-class AVFCamera;
-class AVFImageCapture;
-class AVFCameraSession;
-class AVFMediaEncoder;
-
-class AVFCameraService : public QPlatformMediaCaptureSession
-{
- Q_OBJECT
-public:
- AVFCameraService();
- ~AVFCameraService();
-
- QPlatformCamera *camera() override;
- void setCamera(QPlatformCamera *camera) override;
-
- QPlatformImageCapture *imageCapture() override;
- void setImageCapture(QPlatformImageCapture *imageCapture) override;
-
- QPlatformMediaEncoder *mediaEncoder() override;
- void setMediaEncoder(QPlatformMediaEncoder *encoder) override;
-
- void setAudioInput(QPlatformAudioInput *) override;
- void setAudioOutput(QPlatformAudioOutput *) override;
-
- void setVideoPreview(QVideoSink *sink) override;
-
- AVFCameraSession *session() const { return m_session; }
- AVFCamera *avfCameraControl() const { return m_cameraControl; }
- AVFMediaEncoder *recorderControl() const { return m_encoder; }
- AVFImageCapture *avfImageCaptureControl() const { return m_imageCaptureControl; }
-
- QPlatformAudioInput *audioInput() { return m_audioInput; }
- QPlatformAudioOutput *audioOutput() { return m_audioOutput; }
-
-public Q_SLOTS:
- void audioInputDestroyed() { setAudioInput(nullptr); }
- void audioInputChanged();
- void audioOutputDestroyed() { setAudioOutput(nullptr); }
- void audioOutputChanged();
-
- void setAudioInputMuted(bool muted);
- void setAudioInputVolume(float volume);
- void setAudioOutputMuted(bool muted);
- void setAudioOutputVolume(float volume);
-
-private:
- QPlatformAudioInput *m_audioInput = nullptr;
- QPlatformAudioOutput *m_audioOutput = nullptr;
-
- AVFCameraSession *m_session = nullptr;
- AVFCamera *m_cameraControl = nullptr;
- AVFMediaEncoder *m_encoder = nullptr;
- AVFImageCapture *m_imageCaptureControl = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/darwin/camera/avfcamerasession.mm b/src/multimedia/platform/darwin/camera/avfcamerasession.mm
deleted file mode 100644
index 4a6d4ddeb..000000000
--- a/src/multimedia/platform/darwin/camera/avfcamerasession.mm
+++ /dev/null
@@ -1,521 +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_p.h"
-#include "avfcamerasession_p.h"
-#include "avfcameraservice_p.h"
-#include "avfcamera_p.h"
-#include "avfcamerarenderer_p.h"
-#include "avfimagecapture_p.h"
-#include "avfmediaencoder_p.h"
-#include "avfcamerautility_p.h"
-#include <private/avfvideosink_p.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Foundation/Foundation.h>
-
-#include <QtCore/qdatetime.h>
-#include <QtCore/qurl.h>
-#include <QtCore/qelapsedtimer.h>
-
-#include <private/qplatformaudioinput_p.h>
-#include <private/qplatformaudiooutput_p.h>
-
-#include <QtCore/qdebug.h>
-
-QT_USE_NAMESPACE
-
-@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_defaultCodec(0)
-{
- m_captureSession = [[AVCaptureSession alloc] init];
- m_observer = [[AVFCameraSessionObserver alloc] initWithCameraSession:this];
-}
-
-AVFCameraSession::~AVFCameraSession()
-{
- if (m_videoInput) {
- [m_captureSession removeInput:m_videoInput];
- [m_videoInput release];
- }
-
- if (m_audioInput) {
- [m_captureSession removeInput:m_audioInput];
- [m_audioInput release];
- }
-
- if (m_audioOutput) {
- [m_captureSession removeOutput:m_audioOutput];
- [m_audioOutput release];
- }
-
- if (m_videoOutput)
- delete m_videoOutput;
-
- [m_observer release];
- [m_captureSession release];
-}
-
-void AVFCameraSession::setActiveCamera(const QCameraDevice &info)
-{
- if (m_activeCameraDevice != info) {
- m_activeCameraDevice = info;
-
- auto recorder = m_service->recorderControl();
- if (recorder && recorder->state() == QMediaRecorder::RecordingState)
- recorder->toggleRecord(false);
-
- [m_captureSession beginConfiguration];
-
- attachVideoInputDevice();
- if (!m_activeCameraDevice.isNull() && !m_videoOutput) {
- setVideoOutput(new AVFCameraRenderer(this));
- connect(m_videoOutput, &AVFCameraRenderer::newViewfinderFrame,
- this, &AVFCameraSession::newViewfinderFrame);
- updateVideoOutput();
- }
- m_videoOutput->deviceOrientationChanged();
-
- [m_captureSession commitConfiguration];
-
- if (recorder && recorder->state() == QMediaRecorder::RecordingState)
- recorder->toggleRecord(true);
- }
-}
-
-void AVFCameraSession::setCameraFormat(const QCameraFormat &format)
-{
- if (m_cameraFormat == format)
- return;
- m_cameraFormat = format;
-
- AVCaptureDevice *captureDevice = videoCaptureDevice();
- if (!captureDevice)
- return;
-
- AVCaptureDeviceFormat *newFormat = qt_convert_to_capture_device_format(captureDevice, format);
- if (newFormat) {
- qt_set_active_format(captureDevice, newFormat, false);
- if (m_videoOutput)
- m_videoOutput->setPixelFormat(format.pixelFormat());
- }
-}
-
-void AVFCameraSession::setVideoOutput(AVFCameraRenderer *output)
-{
- if (m_videoOutput == output)
- return;
-
- delete m_videoOutput;
- m_videoOutput = output;
- if (output)
- output->configureAVCaptureSession(this);
-}
-
-void AVFCameraSession::addAudioCapture()
-{
- if (!m_audioOutput) {
- m_audioOutput = [[AVCaptureAudioDataOutput alloc] init];
- if (m_audioOutput && [m_captureSession canAddOutput:m_audioOutput]) {
- [m_captureSession addOutput:m_audioOutput];
- } else {
- qWarning() << Q_FUNC_INFO << "failed to add audio output";
- }
- }
-}
-
-AVCaptureDevice *AVFCameraSession::videoCaptureDevice() const
-{
- if (m_videoInput)
- return m_videoInput.device;
-
- return nullptr;
-}
-
-AVCaptureDevice *AVFCameraSession::audioCaptureDevice() const
-{
- if (m_audioInput)
- return m_audioInput.device;
-
- return nullptr;
-}
-
-void AVFCameraSession::setAudioInputVolume(float volume)
-{
- m_inputVolume = volume;
-
- if (m_inputMuted)
- volume = 0.0;
-
-#ifdef Q_OS_MACOS
- AVCaptureConnection *audioInputConnection = [m_audioOutput connectionWithMediaType:AVMediaTypeAudio];
- NSArray<AVCaptureAudioChannel *> *audioChannels = audioInputConnection.audioChannels;
- if (audioChannels) {
- for (AVCaptureAudioChannel *channel in audioChannels) {
- channel.volume = volume;
- }
- }
-#endif
-}
-
-void AVFCameraSession::setAudioInputMuted(bool muted)
-{
- m_inputMuted = muted;
- setAudioInputVolume(m_inputVolume);
-}
-
-void AVFCameraSession::setAudioOutputVolume(float volume)
-{
- if (m_audioPreviewDelegate)
- [m_audioPreviewDelegate setVolume:volume];
-}
-
-void AVFCameraSession::setAudioOutputMuted(bool muted)
-{
- if (m_audioPreviewDelegate)
- [m_audioPreviewDelegate setMuted:muted];
-}
-
-bool AVFCameraSession::isActive() const
-{
- return m_active;
-}
-
-void AVFCameraSession::setActive(bool active)
-{
- if (m_active == active)
- return;
-
- m_active = active;
-
- qDebugCamera() << Q_FUNC_INFO << m_active << " -> " << active;
-
- if (active) {
- if (!m_activeCameraDevice.isNull()) {
- Q_EMIT readyToConfigureConnections();
- m_defaultCodec = 0;
- defaultCodec();
- }
-
- applyImageEncoderSettings();
-
- // According to the doc, the capture device must be locked before
- // startRunning to prevent the format we set to be overridden by the
- // session preset.
- [videoCaptureDevice() lockForConfiguration:nil];
- [m_captureSession startRunning];
- [videoCaptureDevice() unlockForConfiguration];
- } else {
- [m_captureSession stopRunning];
- }
-}
-
-void AVFCameraSession::processRuntimeError()
-{
- qWarning() << tr("Runtime camera error");
- m_active = false;
- 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);
- }
-}
-
-void AVFCameraSession::processSessionStopped()
-{
- qDebugCamera() << Q_FUNC_INFO;
- if (m_active) {
- m_active = false;
- Q_EMIT activeChanged(m_active);
- }
-}
-
-AVCaptureDevice *AVFCameraSession::createVideoCaptureDevice()
-{
- AVCaptureDevice *device = nullptr;
-
- QByteArray deviceId = m_activeCameraDevice.id();
- if (!deviceId.isEmpty()) {
- device = [AVCaptureDevice deviceWithUniqueID:
- [NSString stringWithUTF8String:
- deviceId.constData()]];
- }
-
- return device;
-}
-
-AVCaptureDevice *AVFCameraSession::createAudioCaptureDevice()
-{
- AVCaptureDevice *device = nullptr;
-
- QByteArray deviceId = m_service->audioInput() ? m_service->audioInput()->device.id()
- : QByteArray();
- if (!deviceId.isEmpty())
- device = [AVCaptureDevice deviceWithUniqueID: [NSString stringWithUTF8String:deviceId.constData()]];
-
- return device;
-}
-
-void AVFCameraSession::attachVideoInputDevice()
-{
- if (m_videoInput) {
- [m_captureSession removeInput:m_videoInput];
- [m_videoInput release];
- m_videoInput = nullptr;
- }
-
- AVCaptureDevice *videoDevice = createVideoCaptureDevice();
- if (videoDevice) {
- 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_videoInput retain];
- [m_captureSession addInput:m_videoInput];
- } else {
- qWarning() << "Failed to connect video device input";
- m_activeCameraDevice = QCameraDevice();
- }
- }
- } else {
- m_activeCameraDevice = QCameraDevice();
- }
-}
-
-void AVFCameraSession::attachAudioInputDevice()
-{
- if (m_audioInput) {
- [m_captureSession removeInput:m_audioInput];
- [m_audioInput release];
- m_audioInput = nullptr;
- }
-
- AVCaptureDevice *audioDevice = createAudioCaptureDevice();
- if (audioDevice) {
- NSError *error = nil;
- m_audioInput = [AVCaptureDeviceInput
- deviceInputWithDevice:audioDevice
- error:&error];
-
- if (!m_audioInput) {
- qWarning() << "Failed to create audio device input";
- } else {
- if ([m_captureSession canAddInput:m_audioInput]) {
- [m_audioInput retain];
- [m_captureSession addInput:m_audioInput];
- } else {
- qWarning() << "Failed to connect audio device input";
- }
- }
- }
-}
-
-bool AVFCameraSession::applyImageEncoderSettings()
-{
- if (AVFImageCapture *control = m_service->avfImageCaptureControl())
- return control->applySettings();
-
- return false;
-}
-
-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::setVideoSink(QVideoSink *sink)
-{
- auto *videoSink = sink ? static_cast<AVFVideoSink *>(sink->platformVideoSink()) : nullptr;
-
- if (m_videoSink == videoSink)
- return;
-
- m_videoSink = videoSink;
-
- updateVideoOutput();
-}
-
-void AVFCameraSession::updateAudioInput()
-{
- auto recorder = m_service->recorderControl();
- if (recorder && recorder->state() == QMediaRecorder::RecordingState)
- recorder->toggleRecord(false);
-
- [m_captureSession beginConfiguration];
- if (m_audioOutput) {
- AVCaptureConnection *lastConnection = [m_audioOutput connectionWithMediaType:AVMediaTypeAudio];
- [m_captureSession removeConnection:lastConnection];
- }
- attachAudioInputDevice();
- if (m_audioInput)
- addAudioCapture();
- [m_captureSession commitConfiguration];
-
- if (recorder && recorder->state() == QMediaRecorder::RecordingState)
- recorder->toggleRecord(true);
-}
-
-void AVFCameraSession::updateAudioOutput()
-{
- QByteArray deviceId = m_service->audioOutput()
- ? m_service->audioOutput()->device.id()
- : QByteArray();
-
- [m_audioPreviewDelegate release];
- m_audioPreviewDelegate = nil;
- if (!deviceId.isEmpty()) {
- m_audioPreviewDelegate = [[AVFAudioPreviewDelegate alloc] init];
- [m_audioPreviewDelegate setupWithCaptureSession:this
- audioOutputDevice:[NSString stringWithUTF8String:
- deviceId.constData()]];
- }
-}
-
-void AVFCameraSession::updateVideoOutput()
-{
- if (m_videoOutput) {
- m_videoOutput->setVideoSink(m_videoSink);
- if (m_videoSink) {
- AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:m_captureSession];
- m_videoOutput->setLayer(previewLayer);
- }
- }
-}
-
-#include "moc_avfcamerasession_p.cpp"
diff --git a/src/multimedia/platform/darwin/camera/avfcamerasession_p.h b/src/multimedia/platform/darwin/camera/avfcamerasession_p.h
deleted file mode 100644
index e461b809c..000000000
--- a/src/multimedia/platform/darwin/camera/avfcamerasession_p.h
+++ /dev/null
@@ -1,162 +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
-
-//
-// 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 <QtCore/qmutex.h>
-#include <QtMultimedia/qcamera.h>
-#include <QVideoFrame>
-#include <qcameradevice.h>
-#include "avfaudiopreviewdelegate_p.h"
-
-#import <AVFoundation/AVFoundation.h>
-
-@class AVFCameraSessionObserver;
-
-QT_BEGIN_NAMESPACE
-
-class AVFCamera;
-class AVFCameraService;
-class AVFCameraRenderer;
-class AVFVideoSink;
-class QVideoSink;
-
-class AVFCameraSession : public QObject
-{
- Q_OBJECT
-public:
- AVFCameraSession(AVFCameraService *service, QObject *parent = nullptr);
- ~AVFCameraSession();
-
- QCameraDevice activecameraDevice() const { return m_activeCameraDevice; }
- void setActiveCamera(const QCameraDevice &info);
-
- void setCameraFormat(const QCameraFormat &format);
-
- AVFCameraRenderer *videoOutput() const { return m_videoOutput; }
- AVCaptureAudioDataOutput *audioOutput() const { return m_audioOutput; }
- AVFAudioPreviewDelegate *audioPreviewDelegate() const { return m_audioPreviewDelegate; }
-
-
- AVCaptureSession *captureSession() const { return m_captureSession; }
- AVCaptureDevice *videoCaptureDevice() const;
- AVCaptureDevice *audioCaptureDevice() const;
-
- bool isActive() const;
-
- FourCharCode defaultCodec();
-
- AVCaptureDeviceInput *videoInput() const { return m_videoInput; }
- AVCaptureDeviceInput *audioInput() const { return m_audioInput; }
-
- void setVideoSink(QVideoSink *sink);
-
- void updateAudioInput();
- void updateAudioOutput();
-
-public Q_SLOTS:
- void setActive(bool active);
-
- void setAudioInputVolume(float volume);
- void setAudioInputMuted(bool muted);
- void setAudioOutputMuted(bool muted);
- void setAudioOutputVolume(float volume);
-
- void processRuntimeError();
- void processSessionStarted();
- void processSessionStopped();
-
-Q_SIGNALS:
- void readyToConfigureConnections();
- void activeChanged(bool);
- void error(int error, const QString &errorString);
- void newViewfinderFrame(const QVideoFrame &frame);
-
-private:
- void setVideoOutput(AVFCameraRenderer *output);
- void updateVideoOutput();
-
- void addAudioCapture();
-
- AVCaptureDevice *createVideoCaptureDevice();
- AVCaptureDevice *createAudioCaptureDevice();
- void attachVideoInputDevice();
- void attachAudioInputDevice();
-
- bool applyImageEncoderSettings();
-
- QCameraDevice m_activeCameraDevice;
- QCameraFormat m_cameraFormat;
-
- AVFCameraService *m_service;
- AVCaptureSession *m_captureSession;
- AVFCameraSessionObserver *m_observer;
-
- AVFCameraRenderer *m_videoOutput = nullptr;
- AVFVideoSink *m_videoSink = nullptr;
-
- AVCaptureDeviceInput *m_videoInput = nullptr;
- AVCaptureDeviceInput *m_audioInput = nullptr;
-
- AVCaptureAudioDataOutput *m_audioOutput = nullptr;
- AVFAudioPreviewDelegate *m_audioPreviewDelegate = nullptr;
-
- bool m_active = false;
-
- float m_inputVolume = 1.0;
- bool m_inputMuted = false;
-
- FourCharCode m_defaultCodec;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/darwin/camera/avfcamerautility.mm b/src/multimedia/platform/darwin/camera/avfcamerautility.mm
deleted file mode 100644
index 444162523..000000000
--- a/src/multimedia/platform/darwin/camera/avfcamerautility.mm
+++ /dev/null
@@ -1,714 +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_p.h"
-#include "avfcameradebug_p.h"
-
-#include <QtCore/qvector.h>
-#include <QtCore/qpair.h>
-#include <private/qmultimediautils_p.h>
-#include "private/avfvideobuffer_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.
-
-AVCaptureDeviceFormat *qt_convert_to_capture_device_format(AVCaptureDevice *captureDevice,
- const QCameraFormat &cameraFormat)
-{
- AVCaptureDeviceFormat *newFormat = nil;
- NSArray<AVCaptureDeviceFormat *> *formats = captureDevice.formats;
- for (AVCaptureDeviceFormat *format in formats) {
- CMFormatDescriptionRef formatDesc = format.formatDescription;
- CMVideoDimensions dim = CMVideoFormatDescriptionGetDimensions(formatDesc);
- FourCharCode formatCodec = CMVideoFormatDescriptionGetCodecType(formatDesc);
- if (AVFVideoBuffer::fromCVPixelFormat(formatCodec) == cameraFormat.pixelFormat()
- && cameraFormat.resolution().width() == dim.width
- && cameraFormat.resolution().height() == dim.height) {
- for (AVFrameRateRange *frameRateRange in format.videoSupportedFrameRateRanges) {
- if (frameRateRange.minFrameRate >= cameraFormat.minFrameRate()
- && frameRateRange.maxFrameRate <= cameraFormat.maxFrameRate()) {
- newFormat = format;
- break;
- }
- }
- }
- if (newFormat)
- break;
- }
- return newFormat;
-}
-
-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_format_supports_framerate(AVCaptureDeviceFormat *format, qreal fps)
-{
- if (format && fps > qreal(0)) {
- const qreal epsilon = 0.1;
- for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) {
- if (fps >= range.minFrameRate - epsilon && fps <= range.maxFrameRate + epsilon)
- return true;
- }
- }
-
- return false;
-}
-
-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;
-}
-
-QList<AudioValueRange> qt_supported_sample_rates_for_format(int codecId)
-{
- QList<AudioValueRange> result;
- UInt32 format = codecId;
- UInt32 size;
- OSStatus err = AudioFormatGetPropertyInfo(
- kAudioFormatProperty_AvailableEncodeSampleRates,
- sizeof(format),
- &format,
- &size);
-
- if (err != noErr)
- return result;
-
- UInt32 numRanges = size / sizeof(AudioValueRange);
- AudioValueRange sampleRanges[numRanges];
-
- err = AudioFormatGetProperty(kAudioFormatProperty_AvailableEncodeSampleRates,
- sizeof(format),
- &format,
- &size,
- sampleRanges);
- if (err != noErr)
- return result;
-
- for (UInt32 i = 0; i < numRanges; i++)
- result << sampleRanges[i];
-
- return result;
-}
-
-QList<AudioValueRange> qt_supported_bit_rates_for_format(int codecId)
-{
- QList<AudioValueRange> result;
- UInt32 format = codecId;
- UInt32 size;
- OSStatus err = AudioFormatGetPropertyInfo(
- kAudioFormatProperty_AvailableEncodeBitRates,
- sizeof(format),
- &format,
- &size);
-
- if (err != noErr)
- return result;
-
- UInt32 numRanges = size / sizeof(AudioValueRange);
- AudioValueRange bitRanges[numRanges];
-
- err = AudioFormatGetProperty(kAudioFormatProperty_AvailableEncodeBitRates,
- sizeof(format),
- &format,
- &size,
- bitRanges);
- if (err != noErr)
- return result;
-
- for (UInt32 i = 0; i < numRanges; i++)
- result << bitRanges[i];
-
- return result;
-}
-
-std::optional<QList<UInt32>> qt_supported_channel_counts_for_format(int codecId)
-{
- QList<UInt32> result;
- AudioStreamBasicDescription sf = {};
- sf.mFormatID = codecId;
- UInt32 size;
- OSStatus err = AudioFormatGetPropertyInfo(
- kAudioFormatProperty_AvailableEncodeNumberChannels,
- sizeof(sf),
- &sf,
- &size);
-
- if (err != noErr)
- return result;
-
- // From Apple's docs:
- // A value of 0xFFFFFFFF indicates that any number of channels may be encoded.
- if (int(size) == -1)
- return std::nullopt;
-
- UInt32 numCounts = size / sizeof(UInt32);
- UInt32 channelCounts[numCounts];
-
- err = AudioFormatGetProperty(kAudioFormatProperty_AvailableEncodeNumberChannels,
- sizeof(sf),
- &sf,
- &size,
- channelCounts);
- if (err != noErr)
- return result;
-
- for (UInt32 i = 0; i < numCounts; i++)
- result << channelCounts[i];
-
- return result;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/darwin/camera/avfcamerautility_p.h b/src/multimedia/platform/darwin/camera/avfcamerautility_p.h
deleted file mode 100644
index 26a023be9..000000000
--- a/src/multimedia/platform/darwin/camera/avfcamerautility_p.h
+++ /dev/null
@@ -1,201 +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
-
-//
-// 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 <QtCore/qglobal.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qpair.h>
-#include <QtCore/qsize.h>
-
-#include "qcameradevice.h"
-
-#include <CoreAudio/CoreAudioTypes.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);
-
-AVCaptureDeviceFormat *qt_convert_to_capture_device_format(AVCaptureDevice *captureDevice,
- const QCameraFormat &format);
-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_format_supports_framerate(AVCaptureDeviceFormat *format, qreal 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);
-
-QList<AudioValueRange> qt_supported_sample_rates_for_format(int codecId);
-QList<AudioValueRange> qt_supported_bit_rates_for_format(int codecId);
-std::optional<QList<UInt32>> qt_supported_channel_counts_for_format(int codecId);
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/darwin/camera/avfimagecapture.mm b/src/multimedia/platform/darwin/camera/avfimagecapture.mm
deleted file mode 100644
index a397fe418..000000000
--- a/src/multimedia/platform/darwin/camera/avfimagecapture.mm
+++ /dev/null
@@ -1,416 +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_p.h"
-#include "avfimagecapture_p.h"
-#include "avfcameraservice_p.h"
-#include "avfcamerautility_p.h"
-#include "avfcamera_p.h"
-#include "avfcamerasession_p.h"
-#include "avfcamerarenderer_p.h"
-#include "qmediastoragelocation_p.h"
-#include <private/qplatformimagecapture_p.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>
-
-#import <AVFoundation/AVFoundation.h>
-
-QT_USE_NAMESPACE
-
-AVFImageCapture::AVFImageCapture(QImageCapture *parent)
- : QPlatformImageCapture(parent)
-{
- m_stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
-
- NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:
- AVVideoCodecTypeJPEG, AVVideoCodecKey, nil];
-
- [m_stillImageOutput setOutputSettings:outputSettings];
- [outputSettings release];
-}
-
-AVFImageCapture::~AVFImageCapture()
-{
- [m_stillImageOutput release];
-}
-
-bool AVFImageCapture::isReadyForCapture() const
-{
- return m_cameraControl && m_videoConnection && m_cameraControl->isActive();
-}
-
-void AVFImageCapture::updateReadyStatus()
-{
- if (m_ready != isReadyForCapture()) {
- m_ready = !m_ready;
- qDebugCamera() << "ReadyToCapture status changed:" << m_ready;
- Q_EMIT readyForCaptureChanged(m_ready);
- }
-}
-
-int AVFImageCapture::doCapture(const QString &actualFileName)
-{
- if (!m_session) {
- QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
- Q_ARG(int, m_lastCaptureId),
- Q_ARG(int, QImageCapture::ResourceError),
- Q_ARG(QString, QPlatformImageCapture::msgImageCaptureNotSet()));
- return m_lastCaptureId;
- }
- if (!isReadyForCapture()) {
- QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
- Q_ARG(int, m_lastCaptureId),
- Q_ARG(int, QImageCapture::NotReadyError),
- Q_ARG(QString, QPlatformImageCapture::msgCameraNotReady()));
- return m_lastCaptureId;
- }
- m_lastCaptureId++;
-
- bool captureToBuffer = actualFileName.isEmpty();
-
- CaptureRequest request = { m_lastCaptureId, QSharedPointer<QSemaphore>::create()};
- m_requestsMutex.lock();
- m_captureRequests.enqueue(request);
- m_requestsMutex.unlock();
-
- QString fileName(actualFileName);
-
- [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(QChar(u' '));
- qDebugCamera() << "Image capture failed:" << errorMessage;
-
- QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
- Q_ARG(int, request.captureId),
- Q_ARG(int, QImageCapture::ResourceError),
- Q_ARG(QString, errorMessage));
- return;
- }
-
- // Wait for the preview to be generated before saving the JPEG (but only
- // if we have AVFCameraRenderer 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_session->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 (captureToBuffer) {
- QBuffer data(&jpgData);
- QImageReader reader(&data, "JPEG");
- QSize size = reader.size();
- QVideoFrame frame(new QMemoryVideoBuffer(QByteArray(jpgData.constData(), jpgData.size()), -1),
- QVideoFrameFormat(size, QVideoFrameFormat::Format_Jpeg));
- QMetaObject::invokeMethod(this, "imageAvailable", Qt::QueuedConnection,
- Q_ARG(int, request.captureId),
- Q_ARG(QVideoFrame, frame));
- } else {
- QFile f(fileName);
- if (f.open(QFile::WriteOnly)) {
- if (f.write(jpgData) != -1) {
- QMetaObject::invokeMethod(this, "imageSaved", Qt::QueuedConnection,
- Q_ARG(int, request.captureId),
- Q_ARG(QString, fileName));
- } else {
- QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
- Q_ARG(int, request.captureId),
- Q_ARG(int, QImageCapture::OutOfSpaceError),
- Q_ARG(QString, f.errorString()));
- }
- } else {
- QString errorMessage = tr("Could not open destination file:\n%1").arg(fileName);
- QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
- Q_ARG(int, request.captureId),
- Q_ARG(int, QImageCapture::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, QImageCapture::ResourceError),
- Q_ARG(QString, errorMessage));
- }
- }];
-
- return request.captureId;
-}
-
-int AVFImageCapture::capture(const QString &fileName)
-{
- auto actualFileName = QMediaStorageLocation::generateFileName(fileName, QStandardPaths::PicturesLocation, QLatin1String("jpg"));
-
- qDebugCamera() << "Capture image to" << actualFileName;
- return doCapture(actualFileName);
-}
-
-int AVFImageCapture::captureToBuffer()
-{
- return doCapture(QString());
-}
-
-void AVFImageCapture::onNewViewfinderFrame(const QVideoFrame &frame)
-{
- QMutexLocker locker(&m_requestsMutex);
-
- if (m_captureRequests.isEmpty())
- return;
-
- CaptureRequest request = m_captureRequests.dequeue();
- Q_EMIT imageExposed(request.captureId);
-
- (void) QtConcurrent::run(&AVFImageCapture::makeCapturePreview, this,
- request,
- frame,
- 0 /* rotation */);
-}
-
-void AVFImageCapture::onCameraChanged()
-{
- if (m_service)
- m_cameraControl = static_cast<AVFCamera *>(m_service->camera());
- else
- m_cameraControl = nullptr;
-
- if (m_cameraControl)
- connect(m_cameraControl, SIGNAL(activeChanged(bool)), this, SLOT(updateReadyStatus()));
-}
-
-void AVFImageCapture::makeCapturePreview(CaptureRequest request,
- const QVideoFrame &frame,
- int rotation)
-{
- QTransform transform;
- transform.rotate(rotation);
-
- Q_EMIT imageCaptured(request.captureId, frame.toImage().transformed(transform));
-
- request.previewReady->release();
-}
-
-void AVFImageCapture::updateCaptureConnection()
-{
- if (m_session && m_session->videoCaptureDevice()) {
- qDebugCamera() << Q_FUNC_INFO;
- AVCaptureSession *captureSession = m_session->captureSession();
-
- if (![captureSession.outputs containsObject:m_stillImageOutput]) {
- if ([captureSession canAddOutput:m_stillImageOutput]) {
- [captureSession beginConfiguration];
- // 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];
- [captureSession commitConfiguration];
- updateReadyStatus();
- }
- } else {
- m_videoConnection = [m_stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
- }
- }
-}
-
-
-QImageEncoderSettings AVFImageCapture::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->avfImageCaptureControl() || !m_service->avfImageCaptureControl()->stillImageOutput()) {
- qDebugCamera() << Q_FUNC_INFO << "no still image output";
- return settings;
- }
-
- AVCaptureStillImageOutput *stillImageOutput = m_service->avfImageCaptureControl()->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.setFormat(QImageCapture::JPEG);
-
- return settings;
-}
-
-void AVFImageCapture::setImageSettings(const QImageEncoderSettings &settings)
-{
- if (m_settings == settings)
- return;
-
- m_settings = settings;
- applySettings();
-}
-
-bool AVFImageCapture::applySettings()
-{
- if (!videoCaptureDeviceIsValid())
- return false;
-
- AVFCameraSession *session = m_service->session();
- if (!session)
- return false;
-
- if (!m_service->imageCapture()
- || !m_service->avfImageCaptureControl()->stillImageOutput()) {
- qDebugCamera() << Q_FUNC_INFO << "no still image output";
- return false;
- }
-
- if (m_settings.format() != QImageCapture::UnspecifiedFormat && m_settings.format() != QImageCapture::JPEG) {
- qDebugCamera() << Q_FUNC_INFO << "unsupported format:" << m_settings.format();
- 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->avfImageCaptureControl()->stillImageOutput();
- if (res == qt_device_format_high_resolution(captureDevice.activeFormat))
- imageOutput.highResolutionStillImageOutputEnabled = YES;
- else
- imageOutput.highResolutionStillImageOutputEnabled = NO;
-#endif
-
- return activeFormatChanged;
-}
-
-void AVFImageCapture::setCaptureSession(QPlatformMediaCaptureSession *session)
-{
- AVFCameraService *captureSession = static_cast<AVFCameraService *>(session);
- if (m_service == captureSession)
- return;
-
- m_service = captureSession;
- if (!m_service) {
- m_session->disconnect(this);
- if (m_cameraControl)
- m_cameraControl->disconnect(this);
- m_session = nullptr;
- m_cameraControl = nullptr;
- m_videoConnection = nil;
- return;
- }
-
- m_session = m_service->session();
- Q_ASSERT(m_session);
-
- connect(m_service, &AVFCameraService::cameraChanged, this, &AVFImageCapture::onCameraChanged);
- connect(m_session, SIGNAL(readyToConfigureConnections()), SLOT(updateCaptureConnection()));
- connect(m_session, &AVFCameraSession::newViewfinderFrame,
- this, &AVFImageCapture::onNewViewfinderFrame);
-
- updateCaptureConnection();
- updateReadyStatus();
- onCameraChanged();
-}
-
-bool AVFImageCapture::videoCaptureDeviceIsValid() const
-{
- if (!m_service || !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;
-}
-
-#include "moc_avfimagecapture_p.cpp"
diff --git a/src/multimedia/platform/darwin/camera/avfimagecapture_p.h b/src/multimedia/platform/darwin/camera/avfimagecapture_p.h
deleted file mode 100644
index ef11bd70f..000000000
--- a/src/multimedia/platform/darwin/camera/avfimagecapture_p.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 AVFCAMERAIMAGECAPTURE_H
-#define AVFCAMERAIMAGECAPTURE_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.
-//
-
-#import <AVFoundation/AVFoundation.h>
-
-#include <QtCore/qqueue.h>
-#include <QtCore/qsemaphore.h>
-#include <QtCore/qsharedpointer.h>
-#include <private/qplatformimagecapture_p.h>
-#include "avfcamerasession_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class AVFImageCapture : public QPlatformImageCapture
-{
-Q_OBJECT
-public:
- struct CaptureRequest {
- int captureId;
- QSharedPointer<QSemaphore> previewReady;
- };
-
- AVFImageCapture(QImageCapture *parent = nullptr);
- ~AVFImageCapture();
-
- bool isReadyForCapture() const override;
-
- AVCaptureStillImageOutput *stillImageOutput() const {return m_stillImageOutput;}
-
- int doCapture(const QString &fileName);
- int capture(const QString &fileName) override;
- int captureToBuffer() override;
-
- QImageEncoderSettings imageSettings() const override;
- void setImageSettings(const QImageEncoderSettings &settings) override;
- bool applySettings();
-
- void setCaptureSession(QPlatformMediaCaptureSession *session);
-
-private Q_SLOTS:
- void updateCaptureConnection();
- void updateReadyStatus();
- void onNewViewfinderFrame(const QVideoFrame &frame);
- void onCameraChanged();
-
-private:
- void makeCapturePreview(CaptureRequest request, const QVideoFrame &frame, int rotation);
- bool videoCaptureDeviceIsValid() const;
-
- AVFCameraService *m_service = nullptr;
- AVFCameraSession *m_session = nullptr;
- AVFCamera *m_cameraControl = nullptr;
- bool m_ready = false;
- int m_lastCaptureId = 0;
- AVCaptureStillImageOutput *m_stillImageOutput;
- AVCaptureConnection *m_videoConnection = nullptr;
-
- QMutex m_requestsMutex;
- QQueue<CaptureRequest> m_captureRequests;
- QImageEncoderSettings m_settings;
-};
-
-Q_DECLARE_TYPEINFO(AVFImageCapture::CaptureRequest, Q_PRIMITIVE_TYPE);
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/darwin/camera/avfmediaassetwriter.mm b/src/multimedia/platform/darwin/camera/avfmediaassetwriter.mm
deleted file mode 100644
index ed90dbd07..000000000
--- a/src/multimedia/platform/darwin/camera/avfmediaassetwriter.mm
+++ /dev/null
@@ -1,579 +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 "avfmediaencoder_p.h"
-#include "avfcamerarenderer_p.h"
-#include "avfmediaassetwriter_p.h"
-#include "avfcameraservice_p.h"
-#include "avfcamerasession_p.h"
-#include "avfcameradebug_p.h"
-#include <private/qdarwinformatsinfo_p.h>
-#include <private/avfmetadata_p.h>
-
-#include <QtCore/qmetaobject.h>
-#include <QtCore/qatomic.h>
-
-QT_USE_NAMESPACE
-
-namespace {
-
-bool qt_capture_session_isValid(AVFCameraService *service)
-{
- if (!service || !service->session())
- return false;
-
- AVFCameraSession *session = service->session();
- if (!session->captureSession())
- return false;
-
- return true;
-}
-
-enum WriterState
-{
- WriterStateIdle,
- WriterStateActive,
- WriterStatePaused,
- WriterStateAborted
-};
-
-using AVFAtomicInt64 = QAtomicInteger<qint64>;
-
-} // unnamed namespace
-
-@interface QT_MANGLE_NAMESPACE(AVFMediaAssetWriter) (PrivateAPI)
-- (bool)addWriterInputs;
-- (void)setQueues;
-- (void)updateDuration:(CMTime)newTimeStamp;
-- (CMSampleBufferRef)adjustTime:(CMSampleBufferRef)sample by:(CMTime)offset;
-@end
-
-@implementation QT_MANGLE_NAMESPACE(AVFMediaAssetWriter)
-{
-@private
- AVFCameraService *m_service;
-
- AVFScopedPointer<AVAssetWriterInput> m_cameraWriterInput;
- AVFScopedPointer<AVAssetWriterInput> m_audioWriterInput;
-
- // 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;
-
- AVFMediaEncoder *m_delegate;
-
- bool m_setStartTime;
-
- QAtomicInt m_state;
-
- bool m_writeFirstAudioBuffer;
-
- CMTime m_startTime;
- CMTime m_lastTimeStamp;
- CMTime m_lastVideoTimestamp;
- CMTime m_lastAudioTimestamp;
- CMTime m_timeOffset;
- bool m_adjustTime;
-
- NSDictionary *m_audioSettings;
- NSDictionary *m_videoSettings;
-
- AVFAtomicInt64 m_durationInMs;
-}
-
-- (id)initWithDelegate:(AVFMediaEncoder *)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_lastAudioTimestamp = kCMTimeInvalid;
- m_lastVideoTimestamp = kCMTimeInvalid;
- m_timeOffset = kCMTimeInvalid;
- m_adjustTime = false;
- m_durationInMs.storeRelaxed(0);
- m_audioSettings = nil;
- m_videoSettings = nil;
- m_writeFirstAudioBuffer = false;
- }
-
- return self;
-}
-
-- (bool)setupWithFileURL:(NSURL *)fileURL
- cameraService:(AVFCameraService *)service
- audioSettings:(NSDictionary *)audioSettings
- videoSettings:(NSDictionary *)videoSettings
- fileFormat:(QMediaFormat::FileFormat)fileFormat
- transform:(CGAffineTransform)transform
-{
- Q_ASSERT(fileURL);
-
- if (!qt_capture_session_isValid(service)) {
- qDebugCamera() << Q_FUNC_INFO << "invalid capture session";
- return false;
- }
-
- m_service = service;
- m_audioSettings = audioSettings;
- m_videoSettings = videoSettings;
-
- AVFCameraSession *session = m_service->session();
-
- 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;
- }
-
- if (session->videoOutput() && session->videoOutput()->videoDataOutput()) {
- 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(QOS_CLASS_USER_INITIATED, 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";
- if (!m_videoQueue)
- return false;
- // But we still can write video!
- }
-
- auto fileType = QDarwinFormatInfo::avFileTypeForContainerFormat(fileFormat);
- m_assetWriter.reset([[AVAssetWriter alloc] initWithURL:fileURL
- fileType:fileType
- error:nil]);
- if (!m_assetWriter) {
- qDebugCamera() << Q_FUNC_INFO << "failed to create asset writer";
- return false;
- }
-
- bool audioCaptureOn = false;
- if (m_audioQueue)
- audioCaptureOn = session->audioOutput() != nil;
-
- if (!m_videoQueue)
- m_writeFirstAudioBuffer = true;
-
- if (![self addWriterInputs]) {
- m_assetWriter.reset();
- return false;
- }
-
- if (m_cameraWriterInput)
- m_cameraWriterInput.data().transform = transform;
-
- [self setMetaData:fileType];
-
- // Ready to start ...
- return true;
-}
-
-- (void)setMetaData:(AVFileType)fileType
-{
- m_assetWriter.data().metadata = AVFMetaData::toAVMetadataForFormat(m_delegate->metaData(), fileType);
-}
-
-- (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 && m_state.loadAcquire() != WriterStatePaused)
- 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:
- if (m_videoQueue)
- 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];
- 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.
- if (m_videoQueue)
- 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)pause
-{
- if (m_state.loadAcquire() != WriterStateActive)
- return;
- if ([m_assetWriter status] != AVAssetWriterStatusWriting)
- return;
-
- m_state.storeRelease(WriterStatePaused);
- m_adjustTime = true;
-}
-
-- (void)resume
-{
- if (m_state.loadAcquire() != WriterStatePaused)
- return;
- if ([m_assetWriter status] != AVAssetWriterStatusWriting)
- return;
-
- m_state.storeRelease(WriterStateActive);
-}
-
-- (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;
-}
-
-- (CMSampleBufferRef)adjustTime:(CMSampleBufferRef)sample by:(CMTime)offset
-{
- CMItemCount count;
- CMSampleBufferGetSampleTimingInfoArray(sample, 0, nil, &count);
- CMSampleTimingInfo* timingInfo = (CMSampleTimingInfo*) malloc(sizeof(CMSampleTimingInfo) * count);
- CMSampleBufferGetSampleTimingInfoArray(sample, count, timingInfo, &count);
- for (CMItemCount i = 0; i < count; i++)
- {
- timingInfo[i].decodeTimeStamp = CMTimeSubtract(timingInfo[i].decodeTimeStamp, offset);
- timingInfo[i].presentationTimeStamp = CMTimeSubtract(timingInfo[i].presentationTimeStamp, offset);
- }
- CMSampleBufferRef updatedBuffer;
- CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault, sample, count, timingInfo, &updatedBuffer);
- free(timingInfo);
- return updatedBuffer;
-}
-
-- (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];
- }
- }
-}
-
-- (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];
- }
- }
-}
-
-- (void)captureOutput:(AVCaptureOutput *)captureOutput
- didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
- fromConnection:(AVCaptureConnection *)connection
-{
- Q_UNUSED(connection);
- Q_ASSERT(m_service && m_service->session());
-
- if (m_state.loadAcquire() != WriterStateActive && m_state.loadAcquire() != WriterStatePaused)
- return;
-
- if (!CMSampleBufferDataIsReady(sampleBuffer)) {
- qWarning() << Q_FUNC_INFO << "sample buffer is not ready, skipping.";
- return;
- }
-
- CFRetain(sampleBuffer);
-
- bool isVideoBuffer = true;
- isVideoBuffer = (captureOutput != m_service->session()->audioOutput());
- if (isVideoBuffer) {
- // Find renderercontrol's delegate and invoke its method to
- // show updated viewfinder's frame.
- if (m_service->session()->videoOutput()) {
- NSObject<AVCaptureVideoDataOutputSampleBufferDelegate> *vfDelegate =
- (NSObject<AVCaptureVideoDataOutputSampleBufferDelegate> *)m_service->session()->videoOutput()->captureDelegate();
- if (vfDelegate) {
- AVCaptureOutput *output = nil;
- AVCaptureConnection *connection = nil;
- [vfDelegate captureOutput:output didOutputSampleBuffer:sampleBuffer fromConnection:connection];
- }
- }
- } else {
- if (m_service->session()->audioOutput()) {
- NSObject<AVCaptureAudioDataOutputSampleBufferDelegate> *audioPreviewDelegate =
- (NSObject<AVCaptureAudioDataOutputSampleBufferDelegate> *)m_service->session()->audioPreviewDelegate();
- if (audioPreviewDelegate) {
- AVCaptureOutput *output = nil;
- AVCaptureConnection *connection = nil;
- [audioPreviewDelegate captureOutput:output didOutputSampleBuffer:sampleBuffer fromConnection:connection];
- }
- }
- }
-
- if (m_state.loadAcquire() != WriterStateActive) {
- CFRelease(sampleBuffer);
- return;
- }
-
- if (m_adjustTime) {
- CMTime currentTimestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
- CMTime lastTimestamp = isVideoBuffer ? m_lastVideoTimestamp : m_lastAudioTimestamp;
-
- if (!CMTIME_IS_INVALID(lastTimestamp)) {
- if (!CMTIME_IS_INVALID(m_timeOffset))
- currentTimestamp = CMTimeSubtract(currentTimestamp, m_timeOffset);
-
- CMTime pauseDuration = CMTimeSubtract(currentTimestamp, lastTimestamp);
-
- if (m_timeOffset.value == 0)
- m_timeOffset = pauseDuration;
- else
- m_timeOffset = CMTimeAdd(m_timeOffset, pauseDuration);
- }
- m_lastVideoTimestamp = kCMTimeInvalid;
- m_adjustTime = false;
- }
-
- if (m_timeOffset.value > 0) {
- CFRelease(sampleBuffer);
- sampleBuffer = [self adjustTime:sampleBuffer by:m_timeOffset];
- }
-
- CMTime currentTimestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
- CMTime currentDuration = CMSampleBufferGetDuration(sampleBuffer);
- if (currentDuration.value > 0)
- currentTimestamp = CMTimeAdd(currentTimestamp, currentDuration);
-
- if (isVideoBuffer)
- {
- m_lastVideoTimestamp = currentTimestamp;
- dispatch_async(m_writerQueue, ^{
- [self writeVideoSampleBuffer:sampleBuffer];
- m_writeFirstAudioBuffer = true;
- CFRelease(sampleBuffer);
- });
- } else if (m_writeFirstAudioBuffer) {
- m_lastAudioTimestamp = currentTimestamp;
- dispatch_async(m_writerQueue, ^{
- [self writeAudioSampleBuffer:sampleBuffer];
- CFRelease(sampleBuffer);
- });
- }
-}
-
-- (bool)addWriterInputs
-{
- Q_ASSERT(m_service && m_service->session());
- Q_ASSERT(m_assetWriter.data());
-
- AVFCameraSession *session = m_service->session();
-
- if (m_videoQueue)
- {
- Q_ASSERT(session->videoOutput() && session->videoOutput()->videoDataOutput());
- m_cameraWriterInput.reset([[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo
- outputSettings:m_videoSettings
- sourceFormatHint: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 (session->audioOutput()) {
- CMFormatDescriptionRef sourceFormat = session->audioCaptureDevice()
- ? session->audioCaptureDevice().activeFormat.formatDescription
- : 0;
- m_audioWriterInput.reset([[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeAudio
- outputSettings:m_audioSettings
- sourceFormatHint:sourceFormat]);
- if (!m_audioWriterInput) {
- qWarning() << Q_FUNC_INFO << "failed to create audio writer input";
- // But we still can record video.
- if (!m_cameraWriterInput)
- return false;
- } else if ([m_assetWriter canAddInput:m_audioWriterInput]) {
- [m_assetWriter addInput:m_audioWriterInput];
- m_audioWriterInput.data().expectsMediaDataInRealTime = YES;
- } else {
- qWarning() << Q_FUNC_INFO << "failed to add audio writer input";
- m_audioWriterInput.reset();
- if (!m_cameraWriterInput)
- return false;
- // We can (still) write video though ...
- }
- }
-
- return true;
-}
-
-- (void)setQueues
-{
- Q_ASSERT(m_service && m_service->session());
- if (m_videoQueue) {
- Q_ASSERT(m_service->session()->videoOutput()
- && m_service->session()->videoOutput()->videoDataOutput());
- [m_service->session()->videoOutput()->videoDataOutput() setSampleBufferDelegate:self queue:m_videoQueue];
- }
-
- if (m_service->session()->audioOutput()) {
- Q_ASSERT(m_audioQueue);
- [m_service->session()->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;
-
- m_delegate->updateDuration([self durationInMs]);
- }
-}
-
-- (qint64)durationInMs
-{
- return m_durationInMs.loadAcquire();
-}
-
-@end
diff --git a/src/multimedia/platform/darwin/camera/avfmediaassetwriter_p.h b/src/multimedia/platform/darwin/camera/avfmediaassetwriter_p.h
deleted file mode 100644
index 6691b66a1..000000000
--- a/src/multimedia/platform/darwin/camera/avfmediaassetwriter_p.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 AVFMEDIAASSETWRITER_H
-#define AVFMEDIAASSETWRITER_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 "avfcamerautility_p.h"
-#include "qmediaformat.h"
-
-#include <QtCore/qglobal.h>
-
-#include <AVFoundation/AVFoundation.h>
-
-QT_BEGIN_NAMESPACE
-
-class AVFMediaEncoder;
-class AVFCameraService;
-
-QT_END_NAMESPACE
-
-@interface QT_MANGLE_NAMESPACE(AVFMediaAssetWriter) : NSObject<AVCaptureVideoDataOutputSampleBufferDelegate,
- AVCaptureAudioDataOutputSampleBufferDelegate>
-- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(AVFMediaEncoder) *)delegate;
-
-- (bool)setupWithFileURL:(NSURL *)fileURL
- cameraService:(QT_PREPEND_NAMESPACE(AVFCameraService) *)service
- audioSettings:(NSDictionary *)audioSettings
- videoSettings:(NSDictionary *)videoSettings
- fileFormat:(QMediaFormat::FileFormat)fileFormat
- transform:(CGAffineTransform)transform;
-
-// This to be called from the recorder control's thread:
-- (void)start;
-- (void)stop;
-- (void)pause;
-- (void)resume;
-// This to be called from the recorder control's dtor:
-- (void)abort;
-- (qint64)durationInMs;
-
-@end
-
-#endif // AVFMEDIAASSETWRITER_H
diff --git a/src/multimedia/platform/darwin/camera/avfmediaencoder.mm b/src/multimedia/platform/darwin/camera/avfmediaencoder.mm
deleted file mode 100644
index 83e9c6d3d..000000000
--- a/src/multimedia/platform/darwin/camera/avfmediaencoder.mm
+++ /dev/null
@@ -1,649 +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 "avfmediaencoder_p.h"
-#include "avfcamerarenderer_p.h"
-#include "avfcamerasession_p.h"
-#include "avfcamera_p.h"
-#include "avfcameraservice_p.h"
-#include "avfcameradebug_p.h"
-#include "avfcamerautility_p.h"
-#include "qaudiodevice.h"
-
-#include "qmediadevices.h"
-#include "qmediastoragelocation_p.h"
-#include "private/qmediarecorder_p.h"
-#include "private/qdarwinformatsinfo_p.h"
-#include "private/qplatformaudiooutput_p.h"
-
-#include <QtCore/qmath.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qmimetype.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;
-}
-
-}
-
-AVFMediaEncoder::AVFMediaEncoder(QMediaRecorder *parent)
- : QObject(parent)
- , QPlatformMediaEncoder(parent)
- , m_state(QMediaRecorder::StoppedState)
- , m_duration(0)
- , m_audioSettings(nil)
- , m_videoSettings(nil)
- //, m_restoreFPS(-1, -1)
-{
- m_writer.reset([[QT_MANGLE_NAMESPACE(AVFMediaAssetWriter) alloc] initWithDelegate:this]);
- if (!m_writer) {
- qDebugCamera() << Q_FUNC_INFO << "failed to create an asset writer";
- return;
- }
-}
-
-AVFMediaEncoder::~AVFMediaEncoder()
-{
- [m_writer abort];
-
- if (m_audioSettings)
- [m_audioSettings release];
- if (m_videoSettings)
- [m_videoSettings release];
-}
-
-bool AVFMediaEncoder::isLocationWritable(const QUrl &location) const
-{
- return location.scheme() == QLatin1String("file") || location.scheme().isEmpty();
-}
-
-QMediaRecorder::RecorderState AVFMediaEncoder::state() const
-{
- return m_state;
-}
-
-qint64 AVFMediaEncoder::duration() const
-{
- return m_duration;
-}
-
-void AVFMediaEncoder::updateDuration(qint64 duration)
-{
- m_duration = duration;
- durationChanged(m_duration);
-}
-
-static NSDictionary *avfAudioSettings(const QMediaEncoderSettings &encoderSettings)
-{
- NSMutableDictionary *settings = [NSMutableDictionary dictionary];
-
- int codecId = QDarwinFormatInfo::audioFormatForCodec(encoderSettings.mediaFormat().audioCodec());
- [settings setObject:[NSNumber numberWithInt:codecId] forKey:AVFormatIDKey];
-
- // Setting AVEncoderQualityKey is not allowed when format ID is alac or lpcm
- if (codecId != kAudioFormatAppleLossless && codecId != kAudioFormatLinearPCM
- && encoderSettings.encodingMode() == QMediaRecorder::ConstantQualityEncoding) {
- int quality;
- switch (encoderSettings.quality()) {
- case QMediaRecorder::VeryLowQuality:
- quality = AVAudioQualityMin;
- break;
- case QMediaRecorder::LowQuality:
- quality = AVAudioQualityLow;
- break;
- case QMediaRecorder::HighQuality:
- quality = AVAudioQualityHigh;
- break;
- case QMediaRecorder::VeryHighQuality:
- quality = AVAudioQualityMax;
- break;
- case QMediaRecorder::NormalQuality:
- default:
- quality = AVAudioQualityMedium;
- break;
- }
- [settings setObject:[NSNumber numberWithInt:quality] forKey:AVEncoderAudioQualityKey];
- } else {
- bool isBitRateSupported = false;
- int bitRate = encoderSettings.audioBitRate();
- if (bitRate > 0) {
- QList<AudioValueRange> bitRates = qt_supported_bit_rates_for_format(codecId);
- for (int i = 0; i < bitRates.count(); i++) {
- if (bitRate >= bitRates[i].mMinimum &&
- bitRate <= bitRates[i].mMaximum) {
- isBitRateSupported = true;
- break;
- }
- }
- if (isBitRateSupported)
- [settings setObject:[NSNumber numberWithInt:encoderSettings.audioBitRate()]
- forKey:AVEncoderBitRateKey];
- }
- }
-
- int sampleRate = encoderSettings.audioSampleRate();
- bool isSampleRateSupported = false;
- if (sampleRate >= 8000 && sampleRate <= 192000) {
- QList<AudioValueRange> sampleRates = qt_supported_sample_rates_for_format(codecId);
- for (int i = 0; i < sampleRates.count(); i++) {
- if (sampleRate >= sampleRates[i].mMinimum && sampleRate <= sampleRates[i].mMaximum) {
- isSampleRateSupported = true;
- break;
- }
- }
- }
-
- int channelCount = encoderSettings.audioChannelCount();
- bool isChannelCountSupported = false;
- if (channelCount > 0) {
- std::optional<QList<UInt32>> channelCounts = qt_supported_channel_counts_for_format(codecId);
- // An std::nullopt result indicates that
- // any number of channels can be encoded.
- if (channelCounts == std::nullopt) {
- isChannelCountSupported = true;
- } else {
- for (int i = 0; i < channelCounts.value().count(); i++) {
- if ((UInt32)channelCount == channelCounts.value()[i]) {
- isChannelCountSupported = true;
- break;
- }
- }
- }
- }
-
-#ifdef Q_OS_IOS
- // Some keys are mandatory only on iOS
- if (!isSampleRateSupported) {
- sampleRate = 44100;
- isSampleRateSupported = true;
- }
- if (!isChannelCountSupported) {
- channelCount = 2;
- isChannelCountSupported = true;
- }
-
- if (codecId == kAudioFormatAppleLossless)
- [settings setObject:[NSNumber numberWithInt:24] forKey:AVEncoderBitDepthHintKey];
-
- if (codecId == kAudioFormatLinearPCM) {
- [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];
- }
-#endif
- if (isSampleRateSupported)
- [settings setObject:[NSNumber numberWithInt:sampleRate] forKey:AVSampleRateKey];
- if (isChannelCountSupported)
- [settings setObject:[NSNumber numberWithInt:channelCount] forKey:AVNumberOfChannelsKey];
-
- return settings;
-}
-
-NSDictionary *avfVideoSettings(QMediaEncoderSettings &encoderSettings, AVCaptureDevice *device, AVCaptureConnection *connection, QSize nativeSize)
-{
- if (!device)
- return nil;
-
-
- // ### re-add needFpsChange
-// AVFPSRange currentFps = qt_current_framerates(device, connection);
-
- NSMutableDictionary *videoSettings = [NSMutableDictionary dictionary];
-
- // -- Codec
-
- // AVVideoCodecKey is the only mandatory key
- auto codec = encoderSettings.mediaFormat().videoCodec();
- NSString *c = QDarwinFormatInfo::videoFormatForCodec(codec);
- [videoSettings setObject:c forKey:AVVideoCodecKey];
- [c release];
-
- // -- Resolution
-
- int w = encoderSettings.videoResolution().width();
- int h = encoderSettings.videoResolution().height();
-
- if (AVCaptureDeviceFormat *currentFormat = device.activeFormat) {
- CMFormatDescriptionRef formatDesc = currentFormat.formatDescription;
- CMVideoDimensions dim = CMVideoFormatDescriptionGetDimensions(formatDesc);
- FourCharCode formatCodec = CMVideoFormatDescriptionGetCodecType(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)
- && encoderSettings.videoFrameRate() > 0
- && !qt_format_supports_framerate(currentFormat, encoderSettings.videoFrameRate())) {
-
- newFormat = qt_find_best_framerate_match(device,
- formatCodec,
- encoderSettings.videoFrameRate());
-
- } else if (w > 0 && h > 0) {
- AVCaptureDeviceFormat *f = qt_find_best_resolution_match(device,
- encoderSettings.videoResolution(),
- formatCodec);
-
- 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, false /*### !needFpsChange*/)) {
- 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;
-
- bool isPortrait = nativeSize.width() < nativeSize.height();
- // Make sure the video has the right aspect ratio
- if (isPortrait && h < w)
- qSwap(w, h);
- else if (!isPortrait && w < h)
- qSwap(w, h);
-
- encoderSettings.setVideoResolution(QSize(w, h));
- } else {
- w = nativeSize.width();
- h = nativeSize.height();
- encoderSettings.setVideoResolution(nativeSize);
- }
- [videoSettings setObject:[NSNumber numberWithInt:w] forKey:AVVideoWidthKey];
- [videoSettings setObject:[NSNumber numberWithInt:h] forKey:AVVideoHeightKey];
-
- // -- FPS
-
- if (true /*needFpsChange*/) {
- const qreal fps = encoderSettings.videoFrameRate();
- qt_set_framerate_limits(device, connection, fps, fps);
- }
- encoderSettings.setVideoFrameRate(qt_current_framerates(device, connection).second);
-
- // -- Codec Settings
-
- NSMutableDictionary *codecProperties = [NSMutableDictionary dictionary];
- int bitrate = -1;
- float quality = -1.f;
-
- if (encoderSettings.encodingMode() == QMediaRecorder::ConstantQualityEncoding) {
- if (encoderSettings.quality() != QMediaRecorder::NormalQuality) {
- if (codec != QMediaFormat::VideoCodec::MotionJPEG) {
- qWarning("ConstantQualityEncoding is not supported for MotionJPEG");
- } else {
- switch (encoderSettings.quality()) {
- case QMediaRecorder::VeryLowQuality:
- quality = 0.f;
- break;
- case QMediaRecorder::LowQuality:
- quality = 0.25f;
- break;
- case QMediaRecorder::HighQuality:
- quality = 0.75f;
- break;
- case QMediaRecorder::VeryHighQuality:
- quality = 1.f;
- break;
- default:
- quality = -1.f; // NormalQuality, let the system decide
- break;
- }
- }
- }
- } else if (encoderSettings.encodingMode() == QMediaRecorder::AverageBitRateEncoding){
- if (codec != QMediaFormat::VideoCodec::H264 && codec != QMediaFormat::VideoCodec::H265)
- qWarning() << "AverageBitRateEncoding is not supported for codec" << QMediaFormat::videoCodecName(codec);
- else
- bitrate = encoderSettings.videoBitRate();
- } 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 AVFMediaEncoder::applySettings(QMediaEncoderSettings &settings)
-{
- AVFCameraSession *session = m_service->session();
-
- // audio settings
- m_audioSettings = avfAudioSettings(settings);
- if (m_audioSettings)
- [m_audioSettings retain];
-
- // video settings
- AVCaptureDevice *device = session->videoCaptureDevice();
- if (!device)
- return;
- const AVFConfigurationLock lock(device); // prevents activeFormat from being overridden
- AVCaptureConnection *conn = [session->videoOutput()->videoDataOutput() connectionWithMediaType:AVMediaTypeVideo];
- auto nativeSize = session->videoOutput()->nativeSize();
- m_videoSettings = avfVideoSettings(settings, device, conn, nativeSize);
- if (m_videoSettings)
- [m_videoSettings retain];
-}
-
-void AVFMediaEncoder::unapplySettings()
-{
- if (m_audioSettings) {
- [m_audioSettings release];
- m_audioSettings = nil;
- }
- if (m_videoSettings) {
- [m_videoSettings release];
- m_videoSettings = nil;
- }
-}
-
-void AVFMediaEncoder::setMetaData(const QMediaMetaData &metaData)
-{
- m_metaData = metaData;
-}
-
-QMediaMetaData AVFMediaEncoder::metaData() const
-{
- return m_metaData;
-}
-
-void AVFMediaEncoder::setCaptureSession(QPlatformMediaCaptureSession *session)
-{
- AVFCameraService *captureSession = static_cast<AVFCameraService *>(session);
- if (m_service == captureSession)
- return;
-
- if (m_service)
- stop();
-
- m_service = captureSession;
- if (!m_service)
- return;
-
- connect(m_service, &AVFCameraService::cameraChanged, this, &AVFMediaEncoder::onCameraChanged);
- onCameraChanged();
-}
-
-void AVFMediaEncoder::record(QMediaEncoderSettings &settings)
-{
- if (!m_service || !m_service->session()) {
- qWarning() << Q_FUNC_INFO << "Encoder is not set to a capture session";
- return;
- }
-
- if (!m_writer) {
- qDebugCamera() << Q_FUNC_INFO << "Invalid recorder";
- return;
- }
-
- if (QMediaRecorder::RecordingState == m_state)
- return;
-
- m_service->session()->setActive(true);
- const bool audioOnly = settings.videoCodec() == QMediaFormat::VideoCodec::Unspecified;
- AVCaptureSession *session = m_service->session()->captureSession();
- float rotation = 0;
-
- if (!audioOnly) {
- AVFCamera *cameraControl = m_service->avfCameraControl();
- if (!cameraControl || !cameraControl->isActive()) {
- qDebugCamera() << Q_FUNC_INFO << "can not start record while camera is not active";
- Q_EMIT error(QMediaRecorder::ResourceError,
- QMediaRecorderPrivate::msgFailedStartRecording());
- return;
- }
- }
-
- const QString path(outputLocation().scheme() == QLatin1String("file") ?
- outputLocation().path() : outputLocation().toString());
- const QUrl fileURL(QUrl::fromLocalFile(QMediaStorageLocation::generateFileName(path,
- audioOnly ? QStandardPaths::MusicLocation : QStandardPaths::MoviesLocation,
- settings.mimeType().preferredSuffix())));
-
- 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;
- }
-
- applySettings(settings);
-
- QVideoOutputOrientationHandler::setIsRecording(true);
-
- // We stop session now so that no more frames for renderer's queue
- // generated, will restart in assetWriterStarted.
- [session stopRunning];
-
- if ([m_writer setupWithFileURL:nsFileURL
- cameraService:m_service
- audioSettings:m_audioSettings
- videoSettings:m_videoSettings
- fileFormat:settings.fileFormat()
- transform:CGAffineTransformMakeRotation(qDegreesToRadians(rotation))]) {
-
- m_state = QMediaRecorder::RecordingState;
-
- Q_EMIT actualLocationChanged(fileURL);
- Q_EMIT stateChanged(m_state);
-
- // 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,
- QMediaRecorderPrivate::msgFailedStartRecording());
- }
-}
-
-void AVFMediaEncoder::pause()
-{
- if (!m_service || !m_service->session() || state() != QMediaRecorder::RecordingState)
- return;
-
- toggleRecord(false);
- m_state = QMediaRecorder::PausedState;
- stateChanged(m_state);
-}
-
-void AVFMediaEncoder::resume()
-{
- if (!m_service || !m_service->session() || state() != QMediaRecorder::PausedState)
- return;
-
- toggleRecord(true);
- m_state = QMediaRecorder::RecordingState;
- stateChanged(m_state);
-}
-
-void AVFMediaEncoder::stop()
-{
- if (m_state != QMediaRecorder::StoppedState) {
- // Do not check the camera status, we can stop if we started.
- stopWriter();
- }
- QVideoOutputOrientationHandler::setIsRecording(false);
-}
-
-
-void AVFMediaEncoder::toggleRecord(bool enable)
-{
- if (!m_service || !m_service->session())
- return;
-
- if (!enable)
- [m_writer pause];
- else
- [m_writer resume];
-}
-
-void AVFMediaEncoder::assetWriterStarted()
-{
-}
-
-void AVFMediaEncoder::assetWriterFinished()
-{
- Q_ASSERT(m_service && m_service->session());
- AVFCameraSession *session = m_service->session();
-
- const QMediaRecorder::RecorderState lastState = m_state;
-
- unapplySettings();
-
- if (session->videoOutput()) {
- session->videoOutput()->resetCaptureDelegate();
- }
- if (session->audioPreviewDelegate()) {
- [session->audioPreviewDelegate() resetAudioPreviewDelegate];
- }
- [session->captureSession() startRunning];
-
- m_state = QMediaRecorder::StoppedState;
- if (m_state != lastState)
- Q_EMIT stateChanged(m_state);
-}
-
-void AVFMediaEncoder::onCameraChanged()
-{
- if (m_service && m_service->avfCameraControl()) {
- AVFCamera *cameraControl = m_service->avfCameraControl();
- connect(cameraControl, SIGNAL(activeChanged(bool)),
- SLOT(cameraActiveChanged(bool)));
- }
-}
-
-void AVFMediaEncoder::cameraActiveChanged(bool active)
-{
- Q_ASSERT(m_service);
- AVFCamera *cameraControl = m_service->avfCameraControl();
- Q_ASSERT(cameraControl);
-
- if (!active) {
- return stopWriter();
- }
-}
-
-void AVFMediaEncoder::stopWriter()
-{
- [m_writer stop];
-}
-
-#include "moc_avfmediaencoder_p.cpp"
diff --git a/src/multimedia/platform/darwin/camera/avfmediaencoder_p.h b/src/multimedia/platform/darwin/camera/avfmediaencoder_p.h
deleted file mode 100644
index 9e80c4c13..000000000
--- a/src/multimedia/platform/darwin/camera/avfmediaencoder_p.h
+++ /dev/null
@@ -1,131 +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 AVFMEDIAENCODER_H
-#define AVFMEDIAENCODER_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 "avfmediaassetwriter_p.h"
-#include "avfcamerautility_p.h"
-#include "qaudiodevice.h"
-
-#include <private/qplatformmediaencoder_p.h>
-#include <private/qplatformmediacapture_p.h>
-#include <QtMultimedia/qmediametadata.h>
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qurl.h>
-
-#include <AVFoundation/AVFoundation.h>
-
-QT_BEGIN_NAMESPACE
-
-class AVFCameraService;
-class QString;
-class QUrl;
-
-class AVFMediaEncoder : public QObject, public QPlatformMediaEncoder
-{
- Q_OBJECT
-public:
- AVFMediaEncoder(QMediaRecorder *parent);
- ~AVFMediaEncoder() override;
-
- bool isLocationWritable(const QUrl &location) const override;
-
- QMediaRecorder::RecorderState state() const override;
-
- qint64 duration() const override;
-
- void record(QMediaEncoderSettings &settings) override;
- void pause() override;
- void resume() override;
- void stop() override;
-
- void setMetaData(const QMediaMetaData &) override;
- QMediaMetaData metaData() const override;
-
- AVFCameraService *cameraService() const { return m_service; }
-
- void setCaptureSession(QPlatformMediaCaptureSession *session);
-
- void updateDuration(qint64 duration);
-
- void toggleRecord(bool enable);
-
-private:
- void applySettings(QMediaEncoderSettings &settings);
- void unapplySettings();
-
- Q_INVOKABLE void assetWriterStarted();
- Q_INVOKABLE void assetWriterFinished();
-
-private Q_SLOTS:
- void onCameraChanged();
- void cameraActiveChanged(bool);
-
-private:
- void stopWriter();
-
- AVFCameraService *m_service = nullptr;
- AVFScopedPointer<QT_MANGLE_NAMESPACE(AVFMediaAssetWriter)> m_writer;
-
- QMediaRecorder::RecorderState m_state;
-
- QMediaMetaData m_metaData;
-
- qint64 m_duration;
-
- NSDictionary *m_audioSettings;
- NSDictionary *m_videoSettings;
-};
-
-QT_END_NAMESPACE
-
-#endif // AVFMEDIAENCODER_H
diff --git a/src/multimedia/platform/darwin/common/avfmetadata.mm b/src/multimedia/platform/darwin/common/avfmetadata.mm
deleted file mode 100644
index ea95bcea6..000000000
--- a/src/multimedia/platform/darwin/common/avfmetadata.mm
+++ /dev/null
@@ -1,398 +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 "avfmetadata_p.h"
-#include <private/qdarwinformatsinfo_p.h>
-
-#include <QtCore/qbuffer.h>
-#include <QtCore/qiodevice.h>
-#include <QtCore/qdatetime.h>
-#include <QtCore/qlocale.h>
-#include <QtCore/qurl.h>
-#include <QImage>
-
-#if QT_HAS_INCLUDE(<AppKit/AppKit.h>)
-#include <AppKit/AppKit.h>
-#endif
-
-#include <CoreFoundation/CoreFoundation.h>
-
-QT_USE_NAMESPACE
-
-struct AVMetadataIDs {
- AVMetadataIdentifier common;
- AVMetadataIdentifier iTunes;
- AVMetadataIdentifier quickTime;
- AVMetadataIdentifier ID3;
- AVMetadataIdentifier quickTimeUserData;
- AVMetadataIdentifier isoUserData;
-};
-
-const AVMetadataIDs keyToAVMetaDataID[] = {
- // Title
- { AVMetadataCommonIdentifierTitle, AVMetadataIdentifieriTunesMetadataSongName,
- AVMetadataIdentifierQuickTimeMetadataTitle,
- AVMetadataIdentifierID3MetadataTitleDescription,
- nil, AVMetadata3GPUserDataKeyTitle },
- // Author
- { AVMetadataCommonIdentifierAuthor,AVMetadataIdentifieriTunesMetadataAuthor,
- AVMetadataIdentifierQuickTimeMetadataAuthor, nil,
- AVMetadataQuickTimeUserDataKeyAuthor, AVMetadata3GPUserDataKeyAuthor },
- // Comment
- { nil, AVMetadataIdentifieriTunesMetadataUserComment,
- AVMetadataIdentifierQuickTimeMetadataComment, AVMetadataIdentifierID3MetadataComments,
- AVMetadataQuickTimeUserDataKeyComment, nil },
- // Description
- { AVMetadataCommonIdentifierDescription,AVMetadataIdentifieriTunesMetadataDescription,
- AVMetadataIdentifierQuickTimeMetadataDescription, nil,
- AVMetadataQuickTimeUserDataKeyDescription, AVMetadata3GPUserDataKeyDescription },
- // Genre
- { nil, AVMetadataIdentifieriTunesMetadataUserGenre,
- AVMetadataIdentifierQuickTimeMetadataGenre, nil,
- AVMetadataQuickTimeUserDataKeyGenre, AVMetadata3GPUserDataKeyGenre },
- // Date
- { AVMetadataCommonIdentifierCreationDate, AVMetadataIdentifieriTunesMetadataReleaseDate,
- AVMetadataIdentifierQuickTimeMetadataCreationDate, AVMetadataIdentifierID3MetadataDate,
- AVMetadataQuickTimeUserDataKeyCreationDate, AVMetadataISOUserDataKeyDate },
- // Language
- { AVMetadataCommonIdentifierLanguage, nil, nil, AVMetadataIdentifierID3MetadataLanguage, nil, nil },
- // Publisher
- { AVMetadataCommonIdentifierPublisher, AVMetadataIdentifieriTunesMetadataPublisher,
- AVMetadataIdentifierQuickTimeMetadataPublisher, AVMetadataIdentifierID3MetadataPublisher, nil, nil },
- // Copyright
- { AVMetadataCommonIdentifierCopyrights, AVMetadataIdentifieriTunesMetadataCopyright,
- AVMetadataIdentifierQuickTimeMetadataCopyright, AVMetadataIdentifierID3MetadataCopyright,
- AVMetadataQuickTimeUserDataKeyCopyright, AVMetadataISOUserDataKeyCopyright },
- // Url
- { nil, nil, nil, AVMetadataIdentifierID3MetadataOfficialAudioSourceWebpage, nil, nil },
- // Duration
- { nil, nil, nil, AVMetadataIdentifierID3MetadataLength, nil, nil },
- // MediaType
- { AVMetadataCommonIdentifierType, nil, nil, AVMetadataIdentifierID3MetadataContentType, nil, nil },
- // FileFormat
- { nil, nil, nil, AVMetadataIdentifierID3MetadataFileType, nil, nil },
- // AudioBitRate
- { nil, nil, nil, nil, nil, nil },
- // AudioCodec
- { nil, nil, nil, nil, nil, nil },
- // VideoBitRate
- { nil, nil, nil, nil, nil, nil },
- // VideoCodec
- { nil, nil, nil, nil, nil, nil },
- // VideoFrameRate
- { nil, nil, AVMetadataIdentifierQuickTimeMetadataCameraFrameReadoutTime, nil, nil, nil },
- // AlbumTitle
- { AVMetadataCommonIdentifierAlbumName, AVMetadataIdentifieriTunesMetadataAlbum,
- AVMetadataIdentifierQuickTimeMetadataAlbum, AVMetadataIdentifierID3MetadataAlbumTitle,
- AVMetadataQuickTimeUserDataKeyAlbum, AVMetadata3GPUserDataKeyAlbumAndTrack },
- // AlbumArtist
- { nil, AVMetadataIdentifieriTunesMetadataAlbumArtist, nil, nil,
- AVMetadataQuickTimeUserDataKeyArtist, AVMetadata3GPUserDataKeyPerformer },
- // ContributingArtist
- { AVMetadataCommonIdentifierArtist, AVMetadataIdentifieriTunesMetadataArtist,
- AVMetadataIdentifierQuickTimeMetadataArtist, nil, nil, nil },
- // TrackNumber
- { nil, AVMetadataIdentifieriTunesMetadataTrackNumber,
- nil, AVMetadataIdentifierID3MetadataTrackNumber, nil, nil },
- // Composer
- { nil, AVMetadataIdentifieriTunesMetadataComposer,
- AVMetadataIdentifierQuickTimeMetadataComposer, AVMetadataIdentifierID3MetadataComposer, nil, nil },
- // LeadPerformer
- { nil, AVMetadataIdentifieriTunesMetadataPerformer,
- AVMetadataIdentifierQuickTimeMetadataPerformer, AVMetadataIdentifierID3MetadataLeadPerformer, nil, nil },
- // ThumbnailImage
- { nil, nil, nil, AVMetadataIdentifierID3MetadataAttachedPicture, nil, nil },
- // CoverArtImage
- { AVMetadataCommonIdentifierArtwork, AVMetadataIdentifieriTunesMetadataCoverArt,
- AVMetadataIdentifierQuickTimeMetadataArtwork, nil, nil, nil },
- // Orientation
- { nil, nil, AVMetadataIdentifierQuickTimeMetadataDirectionFacing, nil, nil, nil },
- // Resolution
- { nil, nil, nil, nil, nil, nil }
-};
-
-static AVMetadataIdentifier toIdentifier(QMediaMetaData::Key key, AVMetadataKeySpace keySpace)
-{
- static_assert(sizeof(keyToAVMetaDataID)/sizeof(AVMetadataIDs) == QMediaMetaData::Key::Resolution + 1);
-
- AVMetadataIdentifier identifier = nil;
- if ([keySpace isEqualToString:AVMetadataKeySpaceiTunes]) {
- identifier = keyToAVMetaDataID[key].iTunes;
- } else if ([keySpace isEqualToString:AVMetadataKeySpaceID3]) {
- identifier = keyToAVMetaDataID[key].ID3;
- } else if ([keySpace isEqualToString:AVMetadataKeySpaceQuickTimeMetadata]) {
- identifier = keyToAVMetaDataID[key].quickTime;
- } else {
- identifier = keyToAVMetaDataID[key].common;
- }
- return identifier;
-}
-
-static std::optional<QMediaMetaData::Key> toKey(AVMetadataItem *item)
-{
- static_assert(sizeof(keyToAVMetaDataID)/sizeof(AVMetadataIDs) == QMediaMetaData::Key::Resolution + 1);
-
- // The item identifier may be different than the ones we support,
- // so check by common key first, as it will get the metadata
- // irrespective of the format.
- AVMetadataKey commonKey = item.commonKey;
- if (commonKey.length != 0) {
- if ([commonKey isEqualToString:AVMetadataCommonKeyTitle]) {
- return QMediaMetaData::Title;
- } else if ([commonKey isEqualToString:AVMetadataCommonKeyDescription]) {
- return QMediaMetaData::Description;
- } else if ([commonKey isEqualToString:AVMetadataCommonKeyPublisher]) {
- return QMediaMetaData::Publisher;
- } else if ([commonKey isEqualToString:AVMetadataCommonKeyCreationDate]) {
- return QMediaMetaData::Date;
- } else if ([commonKey isEqualToString:AVMetadataCommonKeyType]) {
- return QMediaMetaData::MediaType;
- } else if ([commonKey isEqualToString:AVMetadataCommonKeyLanguage]) {
- return QMediaMetaData::Language;
- } else if ([commonKey isEqualToString:AVMetadataCommonKeyCopyrights]) {
- return QMediaMetaData::Copyright;
- } else if ([commonKey isEqualToString:AVMetadataCommonKeyAlbumName]) {
- return QMediaMetaData::AlbumTitle;
- } else if ([commonKey isEqualToString:AVMetadataCommonKeyAuthor]) {
- return QMediaMetaData::Author;
- } else if ([commonKey isEqualToString:AVMetadataCommonKeyArtist]) {
- return QMediaMetaData::ContributingArtist;
- }
- }
-
- // Check by identifier if no common key found
- // No need to check for the common keySpace since there's no common key
- enum keySpaces { iTunes, QuickTime, QuickTimeUserData, IsoUserData, ID3, Other } itemKeySpace;
- itemKeySpace = Other;
- AVMetadataKeySpace keySpace = [item keySpace];
- AVMetadataIdentifier identifier = [item identifier];
-
- if ([keySpace isEqualToString:AVMetadataKeySpaceiTunes]) {
- itemKeySpace = iTunes;
- } else if ([keySpace isEqualToString:AVMetadataKeySpaceQuickTimeMetadata]) {
- itemKeySpace = QuickTime;
- } else if ([keySpace isEqualToString:AVMetadataKeySpaceQuickTimeUserData]) {
- itemKeySpace = QuickTimeUserData;
- } else if ([keySpace isEqualToString:AVMetadataKeySpaceISOUserData]) {
- itemKeySpace = IsoUserData;
- } else if (([keySpace isEqualToString:AVMetadataKeySpaceID3])) {
- itemKeySpace = ID3;
- }
-
- for (int key = 0; key < QMediaMetaData::Resolution + 1; key++) {
- AVMetadataIdentifier idForKey = nil;
- switch (itemKeySpace) {
- case iTunes:
- idForKey = keyToAVMetaDataID[key].iTunes;
- break;
- case QuickTime:
- idForKey = keyToAVMetaDataID[key].quickTime;
- break;
- case ID3:
- idForKey = keyToAVMetaDataID[key].ID3;
- break;
- case QuickTimeUserData:
- idForKey = keyToAVMetaDataID[key].quickTimeUserData;
- break;
- case IsoUserData:
- idForKey = keyToAVMetaDataID[key].isoUserData;
- break;
- default:
- break;
- }
-
- if ([identifier isEqualToString:idForKey])
- return QMediaMetaData::Key(key);
- }
-
- return std::nullopt;
-}
-
-static QMediaMetaData fromAVMetadata(NSArray *metadataItems)
-{
- QMediaMetaData metadata;
-
- for (AVMetadataItem* item in metadataItems) {
- auto key = toKey(item);
- if (!key)
- continue;
-
- const QString value = QString::fromNSString([item stringValue]);
- if (!value.isNull())
- metadata.insert(*key, value);
- }
- return metadata;
-}
-
-QMediaMetaData AVFMetaData::fromAsset(AVAsset *asset)
-{
-#ifdef QT_DEBUG_AVF
- qDebug() << Q_FUNC_INFO;
-#endif
- QMediaMetaData metadata = fromAVMetadata([asset metadata]);
-
- // add duration
- const CMTime time = [asset duration];
- const qint64 duration = static_cast<qint64>(float(time.value) / float(time.timescale) * 1000.0f);
- metadata.insert(QMediaMetaData::Duration, duration);
-
- return metadata;
-}
-
-QMediaMetaData AVFMetaData::fromAssetTrack(AVAssetTrack *asset)
-{
- QMediaMetaData metadata = fromAVMetadata([asset metadata]);
- if (metadata.value(QMediaMetaData::Language).isNull()) {
- auto *languageCode = asset.languageCode;
- if (languageCode) {
- // languageCode is encoded as ISO 639-2, which QLocale does not handle.
- // Convert it to 639-1 first.
- auto id = CFLocaleCreateCanonicalLanguageIdentifierFromString(kCFAllocatorDefault,
- (__bridge CFStringRef)languageCode);
- QString lang = QString::fromCFString(id);
- CFRelease(id);
- metadata.insert(QMediaMetaData::Language, QLocale::codeToLanguage(lang));
- }
- }
- return metadata;
-}
-
-static AVMutableMetadataItem *setAVMetadataItemForKey(QMediaMetaData::Key key, const QVariant &value,
- AVMetadataKeySpace keySpace = AVMetadataKeySpaceCommon)
-{
- AVMetadataIdentifier identifier = toIdentifier(key, keySpace);
- if (!identifier.length)
- return nil;
-
- AVMutableMetadataItem *item = [AVMutableMetadataItem metadataItem];
- item.keySpace = keySpace;
- item.identifier = identifier;
-
- switch (key) {
- case QMediaMetaData::ThumbnailImage:
- case QMediaMetaData::CoverArtImage: {
-#if defined(Q_OS_MACOS)
- QImage img = value.value<QImage>();
- if (!img.isNull()) {
- QByteArray arr;
- QBuffer buffer(&arr);
- buffer.open(QIODevice::WriteOnly);
- img.save(&buffer);
- NSData *data = arr.toNSData();
- NSImage *nsImg = [[NSImage alloc] initWithData:data];
- item.value = nsImg;
- [nsImg release];
- }
-#endif
- break;
- }
- case QMediaMetaData::FileFormat: {
- QMediaFormat::FileFormat qtFormat = value.value<QMediaFormat::FileFormat>();
- AVFileType avFormat = QDarwinFormatInfo::avFileTypeForContainerFormat(qtFormat);
- item.value = avFormat;
- break;
- }
- case QMediaMetaData::Language: {
- QString lang = QLocale::languageToCode(value.value<QLocale::Language>());
- if (!lang.isEmpty())
- item.value = lang.toNSString();
- break;
- }
- default: {
- switch (value.typeId()) {
- case QMetaType::QString: {
- item.value = value.toString().toNSString();
- break;
- }
- case QMetaType::Int: {
- item.value = [NSNumber numberWithInt:value.toInt()];
- break;
- }
- case QMetaType::LongLong: {
- item.value = [NSNumber numberWithLongLong:value.toLongLong()];
- break;
- }
- case QMetaType::Double: {
- item.value = [NSNumber numberWithDouble:value.toDouble()];
- break;
- }
- case QMetaType::QDate:
- case QMetaType::QDateTime: {
- item.value = value.toDateTime().toNSDate();
- break;
- }
- case QMetaType::QUrl: {
- item.value = value.toUrl().toNSURL();
- break;
- }
- default:
- break;
- }
- }
- }
-
- return item;
-}
-
-NSMutableArray<AVMetadataItem *> *AVFMetaData::toAVMetadataForFormat(QMediaMetaData metadata, AVFileType format)
-{
- NSMutableArray<AVMetadataKeySpace> *keySpaces = [NSMutableArray<AVMetadataKeySpace> array];
- if (format == AVFileTypeAppleM4A) {
- [keySpaces addObject:AVMetadataKeySpaceiTunes];
- } else if (format == AVFileTypeMPEGLayer3) {
- [keySpaces addObject:AVMetadataKeySpaceID3];
- [keySpaces addObject:AVMetadataKeySpaceiTunes];
- } else if (format == AVFileTypeQuickTimeMovie) {
- [keySpaces addObject:AVMetadataKeySpaceQuickTimeMetadata];
- } else {
- [keySpaces addObject:AVMetadataKeySpaceCommon];
- }
- NSMutableArray<AVMetadataItem *> *avMetaDataArr = [NSMutableArray array];
- for (const auto &key : metadata.keys()) {
- for (NSUInteger i = 0; i < [keySpaces count]; i++) {
- const QVariant &value = metadata.value(key);
- // set format-specific metadata
- AVMetadataItem *item = setAVMetadataItemForKey(key, value, keySpaces[i]);
- if (item)
- [avMetaDataArr addObject:item];
- }
- }
- return avMetaDataArr;
-}
-
diff --git a/src/multimedia/platform/darwin/common/avfmetadata_p.h b/src/multimedia/platform/darwin/common/avfmetadata_p.h
deleted file mode 100644
index e983be531..000000000
--- a/src/multimedia/platform/darwin/common/avfmetadata_p.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 AVFMEDIAPLAYERMETADATACONTROL_H
-#define AVFMEDIAPLAYERMETADATACONTROL_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 <QtMultimedia/QMediaMetaData>
-#include <QtCore/qvariant.h>
-
-#import <AVFoundation/AVFoundation.h>
-
-QT_BEGIN_NAMESPACE
-
-class AVFMediaPlayer;
-
-class AVFMetaData
-{
-public:
- static QMediaMetaData fromAsset(AVAsset *asset);
- static QMediaMetaData fromAssetTrack(AVAssetTrack *asset);
- static NSMutableArray<AVMetadataItem *> *toAVMetadataForFormat(QMediaMetaData metaData, AVFileType format);
-};
-
-QT_END_NAMESPACE
-
-#endif // AVFMEDIAPLAYERMETADATACONTROL_H
diff --git a/src/multimedia/platform/darwin/mediaplayer/avfdisplaylink.mm b/src/multimedia/platform/darwin/mediaplayer/avfdisplaylink.mm
deleted file mode 100644
index 64b625f0e..000000000
--- a/src/multimedia/platform/darwin/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_p.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/multimedia/platform/darwin/mediaplayer/avfdisplaylink_p.h b/src/multimedia/platform/darwin/mediaplayer/avfdisplaylink_p.h
deleted file mode 100644
index 6b95e1e07..000000000
--- a/src/multimedia/platform/darwin/mediaplayer/avfdisplaylink_p.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 AVFDISPLAYLINK_H
-#define AVFDISPLAYLINK_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 <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/multimedia/platform/darwin/mediaplayer/avfmediaplayer.mm b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayer.mm
deleted file mode 100644
index 2cd61a42e..000000000
--- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayer.mm
+++ /dev/null
@@ -1,1161 +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 "avfmediaplayer_p.h"
-#include "avfmediaplayer_p.h"
-#include "avfvideorenderercontrol_p.h"
-#include <private/avfvideosink_p.h>
-#include <private/avfmetadata_p.h>
-
-#include "qaudiooutput.h"
-#include "qplatformaudiooutput_p.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 *AVFMediaPlayerObserverRateObservationContext = &AVFMediaPlayerObserverRateObservationContext;
-static void *AVFMediaPlayerObserverStatusObservationContext = &AVFMediaPlayerObserverStatusObservationContext;
-static void *AVFMediaPlayerObserverPresentationSizeContext = &AVFMediaPlayerObserverPresentationSizeContext;
-static void *AVFMediaPlayerObserverBufferLikelyToKeepUpContext = &AVFMediaPlayerObserverBufferLikelyToKeepUpContext;
-static void *AVFMediaPlayerObserverTracksContext = &AVFMediaPlayerObserverTracksContext;
-static void *AVFMediaPlayerObserverCurrentItemObservationContext = &AVFMediaPlayerObserverCurrentItemObservationContext;
-static void *AVFMediaPlayerObserverCurrentItemDurationObservationContext = &AVFMediaPlayerObserverCurrentItemDurationObservationContext;
-
-@interface AVFMediaPlayerObserver : 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) AVFMediaPlayer* m_session;
-@property (retain) AVPlayerItemTrack *videoTrack;
-
-- (AVFMediaPlayerObserver *) initWithMediaPlayerSession:(AVFMediaPlayer *)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) 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 AVFMediaPlayerObserver
-{
-@private
- AVFMediaPlayer *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;
-
-- (AVFMediaPlayerObserver *) initWithMediaPlayerSession:(AVFMediaPlayer *)session
-{
- if (!(self = [super init]))
- return nil;
-
- m_session = session;
- m_bufferIsLikelyToKeepUp = FALSE;
-
- m_playerLayer = [AVPlayerLayer playerLayerWithPlayer:nil];
- [m_playerLayer retain];
- m_playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
- m_playerLayer.anchorPoint = CGPointMake(0.0f, 0.0f);
- 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 AVFMediaPlayerObserver *blockSelf = self;
- QPointer<AVFMediaPlayer> 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:@"presentationSize"];
- [m_playerItem removeObserver:self forKeyPath:AVF_STATUS_KEY];
- [m_playerItem removeObserver:self forKeyPath:AVF_BUFFER_LIKELY_KEEP_UP_KEY];
- [m_playerItem removeObserver:self forKeyPath:AVF_TRACKS_KEY];
-
- [[NSNotificationCenter defaultCenter] removeObserver:self
- name:AVPlayerItemDidPlayToEndTimeNotification
- 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.player = nil;
-#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:AVFMediaPlayerObserverStatusObservationContext];
-
- [m_playerItem addObserver:self
- forKeyPath:@"presentationSize"
- options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
- context:AVFMediaPlayerObserverPresentationSizeContext];
-
- [m_playerItem addObserver:self
- forKeyPath:AVF_BUFFER_LIKELY_KEEP_UP_KEY
- options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
- context:AVFMediaPlayerObserverBufferLikelyToKeepUpContext];
-
- [m_playerItem addObserver:self
- forKeyPath:AVF_TRACKS_KEY
- options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
- context:AVFMediaPlayerObserverTracksContext];
-
- //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];
-
- //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) {
- auto *audioOutput = m_session->m_audioOutput;
- m_player.volume = (audioOutput ? audioOutput->volume : 1.);
- m_player.muted = (audioOutput ? audioOutput->muted : true);
- }
-
- //Assign the output layer to the new player
- m_playerLayer.player = m_player;
-
- //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:AVFMediaPlayerObserverCurrentItemObservationContext];
-
- //Observe the AVPlayer "rate" property to update the scrubber control.
- [m_player addObserver:self
- forKeyPath:AVF_RATE_KEY
- options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
- context:AVFMediaPlayerObserverRateObservationContext];
-
- //Observe the duration for getting the buffer state
- [m_player addObserver:self
- forKeyPath:AVF_CURRENT_ITEM_DURATION_KEY
- options:0
- context:AVFMediaPlayerObserverCurrentItemDurationObservationContext];
-#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) observeValueForKeyPath:(NSString*) path
- ofObject:(id)object
- change:(NSDictionary*)change
- context:(void*)context
-{
- //AVPlayerItem "status" property value observer.
- if (context == AVFMediaPlayerObserverStatusObservationContext)
- {
- 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 == AVFMediaPlayerObserverPresentationSizeContext) {
- QSize size(m_playerItem.presentationSize.width, m_playerItem.presentationSize.height);
- QMetaObject::invokeMethod(m_session, "nativeSizeChanged", Qt::AutoConnection, Q_ARG(QSize, size));
- } else if (context == AVFMediaPlayerObserverBufferLikelyToKeepUpContext)
- {
- 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));
- }
- }
- else if (context == AVFMediaPlayerObserverTracksContext)
- {
- QMetaObject::invokeMethod(m_session, "updateTracks", Qt::AutoConnection);
- }
- //AVPlayer "rate" property value observer.
- else if (context == AVFMediaPlayerObserverRateObservationContext)
- {
- //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 == AVFMediaPlayerObserverCurrentItemObservationContext)
- {
- AVPlayerItem *newPlayerItem = [change objectForKey:NSKeyValueChangeNewKey];
- if (m_playerItem != newPlayerItem)
- m_playerItem = newPlayerItem;
- }
- else if (context == AVFMediaPlayerObserverCurrentItemDurationObservationContext)
- {
- 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];
- [m_playerLayer 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
-
-AVFMediaPlayer::AVFMediaPlayer(QMediaPlayer *player)
- : QObject(player)
- , QPlatformMediaPlayer(player)
- , m_state(QMediaPlayer::StoppedState)
- , m_mediaStatus(QMediaPlayer::NoMedia)
- , m_mediaStream(nullptr)
- , m_tryingAsync(false)
- , m_rate(1.0)
- , m_requestedPosition(-1)
- , m_duration(0)
- , m_bufferProgress(0)
- , m_videoAvailable(false)
- , m_audioAvailable(false)
- , m_seekable(false)
-{
- m_observer = [[AVFMediaPlayerObserver alloc] initWithMediaPlayerSession:this];
- connect(&m_playbackTimer, &QTimer::timeout, this, &AVFMediaPlayer::processPositionChange);
- setVideoOutput(new AVFVideoRendererControl(this));
-}
-
-AVFMediaPlayer::~AVFMediaPlayer()
-{
-#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).
- [m_observer detatchSession];
- [static_cast<AVFMediaPlayerObserver*>(m_observer) release];
-}
-
-void AVFMediaPlayer::setVideoSink(QVideoSink *sink)
-{
- m_videoSink = sink ? static_cast<AVFVideoSink *>(sink->platformVideoSink()): nullptr;
- m_videoOutput->setVideoSink(m_videoSink);
-}
-
-void AVFMediaPlayer::setVideoOutput(AVFVideoRendererControl *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<AVFMediaPlayerObserver*>(m_observer) playerLayer]);
-}
-
-AVAsset *AVFMediaPlayer::currentAssetHandle()
-{
-#ifdef QT_DEBUG_AVF
- qDebug() << Q_FUNC_INFO;
-#endif
- AVAsset *currentAsset = [[static_cast<AVFMediaPlayerObserver*>(m_observer) playerItem] asset];
- return currentAsset;
-}
-
-QMediaPlayer::PlaybackState AVFMediaPlayer::state() const
-{
- return m_state;
-}
-
-QMediaPlayer::MediaStatus AVFMediaPlayer::mediaStatus() const
-{
- return m_mediaStatus;
-}
-
-QUrl AVFMediaPlayer::media() const
-{
- return m_resources;
-}
-
-QIODevice *AVFMediaPlayer::mediaStream() const
-{
- return m_mediaStream;
-}
-
-static void setURL(AVFMediaPlayerObserver *observer, const QByteArray &url, const QString &mimeType = QString())
-{
- NSString *urlString = [NSString stringWithUTF8String:url.constData()];
- NSURL *nsurl = [NSURL URLWithString:urlString];
- [observer setURL:nsurl mimeType:[NSString stringWithUTF8String:mimeType.toLatin1().constData()]];
-}
-
-static void setStreamURL(AVFMediaPlayerObserver *observer, const QByteArray &url)
-{
- setURL(observer, QByteArrayLiteral("iodevice://") + url, QFileInfo(QString::fromUtf8(url)).suffix());
-}
-
-void AVFMediaPlayer::setMedia(const QUrl &content, QIODevice *stream)
-{
-#ifdef QT_DEBUG_AVF
- qDebug() << Q_FUNC_INFO << content.request().url();
-#endif
-
- [static_cast<AVFMediaPlayerObserver*>(m_observer) unloadMedia];
-
- m_resources = content;
- resetStream(stream);
-
- setAudioAvailable(false);
- setVideoAvailable(false);
- setSeekable(false);
- m_requestedPosition = -1;
- Q_EMIT positionChanged(position());
- if (m_duration != 0) {
- m_duration = 0;
- Q_EMIT durationChanged(0);
- }
- if (!m_metaData.isEmpty()) {
- m_metaData.clear();
- metaDataChanged();
- }
-
- const QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatus;
- const QMediaPlayer::PlaybackState oldState = m_state;
-
- if (!m_mediaStream && content.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.toEncoded());
- } else {
- //Load AVURLAsset
- //initialize asset using content's URL
- setURL(m_observer, m_resources.toEncoded());
- }
-
- m_state = QMediaPlayer::StoppedState;
- if (m_state != oldState)
- Q_EMIT stateChanged(m_state);
-}
-
-qint64 AVFMediaPlayer::position() const
-{
- AVPlayerItem *playerItem = [static_cast<AVFMediaPlayerObserver*>(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 AVFMediaPlayer::duration() const
-{
-#ifdef QT_DEBUG_AVF
- qDebug() << Q_FUNC_INFO;
-#endif
- return m_duration;
-}
-
-float AVFMediaPlayer::bufferProgress() const
-{
-#ifdef QT_DEBUG_AVF
- qDebug() << Q_FUNC_INFO;
-#endif
- return m_bufferProgress/100.;
-}
-
-void AVFMediaPlayer::setAudioAvailable(bool available)
-{
- if (m_audioAvailable == available)
- return;
-
- m_audioAvailable = available;
- Q_EMIT audioAvailableChanged(available);
-}
-
-bool AVFMediaPlayer::isAudioAvailable() const
-{
- return m_audioAvailable;
-}
-
-void AVFMediaPlayer::setVideoAvailable(bool available)
-{
- if (m_videoAvailable == available)
- return;
-
- m_videoAvailable = available;
- Q_EMIT videoAvailableChanged(available);
-}
-
-bool AVFMediaPlayer::isVideoAvailable() const
-{
- return m_videoAvailable;
-}
-
-bool AVFMediaPlayer::isSeekable() const
-{
- return m_seekable;
-}
-
-void AVFMediaPlayer::setSeekable(bool seekable)
-{
- if (m_seekable == seekable)
- return;
-
- m_seekable = seekable;
- Q_EMIT seekableChanged(seekable);
-}
-
-QMediaTimeRange AVFMediaPlayer::availablePlaybackRanges() const
-{
- AVPlayerItem *playerItem = [static_cast<AVFMediaPlayerObserver*>(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 AVFMediaPlayer::playbackRate() const
-{
- return m_rate;
-}
-
-void AVFMediaPlayer::setAudioOutput(QPlatformAudioOutput *output)
-{
- if (m_audioOutput == output)
- return;
- if (m_audioOutput)
- m_audioOutput->q->disconnect(this);
- m_audioOutput = output;
- if (m_audioOutput) {
- connect(m_audioOutput->q, &QAudioOutput::deviceChanged, this, &AVFMediaPlayer::audioOutputChanged);
- connect(m_audioOutput->q, &QAudioOutput::volumeChanged, this, &AVFMediaPlayer::setVolume);
- connect(m_audioOutput->q, &QAudioOutput::mutedChanged, this, &AVFMediaPlayer::setMuted);
- //connect(m_audioOutput->q, &QAudioOutput::audioRoleChanged, this, &AVFMediaPlayer::setAudioRole);
- }
- audioOutputChanged();
- setMuted(m_audioOutput ? m_audioOutput->muted : true);
- setVolume(m_audioOutput ? m_audioOutput->volume : 1.);
-}
-
-QMediaMetaData AVFMediaPlayer::metaData() const
-{
- return m_metaData;
-}
-
-void AVFMediaPlayer::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<AVFMediaPlayerObserver*>(m_observer) player];
- if (player && m_state == QMediaPlayer::PlayingState)
- [player setRate:m_rate];
-
- Q_EMIT playbackRateChanged(m_rate);
-}
-
-void AVFMediaPlayer::setPosition(qint64 pos)
-{
-#ifdef QT_DEBUG_AVF
- qDebug() << Q_FUNC_INFO << pos;
-#endif
-
- if (pos == position())
- return;
-
- AVPlayerItem *playerItem = [static_cast<AVFMediaPlayerObserver*>(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 AVFMediaPlayer::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_videoSink)
- m_videoOutput->setLayer([static_cast<AVFMediaPlayerObserver*>(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<AVFMediaPlayerObserver*>(m_observer) player] setRate:m_rate];
- }
-
- m_state = QMediaPlayer::PlayingState;
- processLoadStateChange();
-
- Q_EMIT stateChanged(m_state);
- m_playbackTimer.start(100);
-}
-
-void AVFMediaPlayer::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_videoSink)
- m_videoOutput->setLayer([static_cast<AVFMediaPlayerObserver*>(m_observer) playerLayer]);
-
- [[static_cast<AVFMediaPlayerObserver*>(m_observer) player] pause];
-
- // Reset media status if the current status is EndOfMedia
- if (m_mediaStatus == QMediaPlayer::EndOfMedia)
- setPosition(0);
-
- Q_EMIT positionChanged(position());
- Q_EMIT stateChanged(m_state);
- m_playbackTimer.stop();
-}
-
-void AVFMediaPlayer::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<AVFMediaPlayerObserver*>(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 stateChanged((m_state = QMediaPlayer::StoppedState));
- m_playbackTimer.stop();
-}
-
-void AVFMediaPlayer::setVolume(float volume)
-{
-#ifdef QT_DEBUG_AVF
- qDebug() << Q_FUNC_INFO << volume;
-#endif
-
- AVPlayer *player = [static_cast<AVFMediaPlayerObserver*>(m_observer) player];
- if (player)
- player.volume = volume;
-}
-
-void AVFMediaPlayer::setMuted(bool muted)
-{
-#ifdef QT_DEBUG_AVF
- qDebug() << Q_FUNC_INFO << muted;
-#endif
-
- AVPlayer *player = [static_cast<AVFMediaPlayerObserver*>(m_observer) player];
- if (player)
- player.muted = muted;
-}
-
-void AVFMediaPlayer::audioOutputChanged()
-{
-#ifdef Q_OS_MACOS
- AVPlayer *player = [static_cast<AVFMediaPlayerObserver*>(m_observer) player];
- if (!m_audioOutput || m_audioOutput->device.id().isEmpty()) {
- player.audioOutputDeviceUniqueID = nil;
- if (!m_audioOutput)
- player.muted = true;
- } else {
- NSString *str = QString::fromUtf8(m_audioOutput->device.id()).toNSString();
- player.audioOutputDeviceUniqueID = str;
- }
-#endif
-}
-
-void AVFMediaPlayer::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;
-
- if (m_videoOutput)
- m_videoOutput->setLayer(nullptr);
-
- Q_EMIT mediaStatusChanged(m_mediaStatus);
- Q_EMIT stateChanged(m_state);
-}
-
-void AVFMediaPlayer::processLoadStateChange(QMediaPlayer::PlaybackState newState)
-{
- AVPlayerStatus currentStatus = [[static_cast<AVFMediaPlayerObserver*>(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 = [m_observer playerItem];
-
- // get the meta data
- m_metaData = AVFMetaData::fromAsset(playerItem.asset);
- Q_EMIT metaDataChanged();
- updateTracks();
-
- if (playerItem) {
- setSeekable([[playerItem seekableTimeRanges] count] > 0);
-
- // Get the native size of the video, and reset the bounds of the player layer
- AVPlayerLayer *playerLayer = [m_observer playerLayer];
- if (m_observer.videoTrack && playerLayer) {
- if (!playerLayer.bounds.size.width || !playerLayer.bounds.size.height) {
- playerLayer.bounds = CGRectMake(0.0f, 0.0f,
- m_observer.videoTrack.assetTrack.naturalSize.width,
- m_observer.videoTrack.assetTrack.naturalSize.height);
- }
- }
-
- 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<AVFMediaPlayerObserver*>(m_observer) player]) {
- // Setting the rate is enough to start playback, no need to call play()
- [[static_cast<AVFMediaPlayerObserver*>(m_observer) player] setRate:m_rate];
- m_playbackTimer.start();
- }
-}
-
-
-void AVFMediaPlayer::processLoadStateChange()
-{
- processLoadStateChange(m_state);
-}
-
-
-void AVFMediaPlayer::processLoadStateFailure()
-{
- Q_EMIT stateChanged((m_state = QMediaPlayer::StoppedState));
-}
-
-void AVFMediaPlayer::processBufferStateChange(int bufferProgress)
-{
- if (bufferProgress == m_bufferProgress)
- return;
-
- auto status = m_mediaStatus;
- // Buffered -> unbuffered.
- if (!bufferProgress) {
- status = QMediaPlayer::StalledMedia;
- } else if (status == QMediaPlayer::StalledMedia) {
- status = QMediaPlayer::BufferedMedia;
- // Resume playback.
- if (m_state == QMediaPlayer::PlayingState) {
- [[static_cast<AVFMediaPlayerObserver*>(m_observer) player] setRate:m_rate];
- m_playbackTimer.start();
- }
- }
-
- if (m_mediaStatus != status)
- Q_EMIT mediaStatusChanged(m_mediaStatus = status);
-
- m_bufferProgress = bufferProgress;
- Q_EMIT bufferProgressChanged(bufferProgress/100.);
-}
-
-void AVFMediaPlayer::processDurationChange(qint64 duration)
-{
- if (duration == m_duration)
- return;
-
- m_duration = duration;
- Q_EMIT durationChanged(duration);
-}
-
-void AVFMediaPlayer::processPositionChange()
-{
- if (m_state == QMediaPlayer::StoppedState)
- return;
-
- Q_EMIT positionChanged(position());
-}
-
-void AVFMediaPlayer::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 AVFMediaPlayer::streamReady()
-{
- setStreamURL(m_observer, m_resources.toEncoded());
-}
-
-void AVFMediaPlayer::streamDestroyed()
-{
- resetStream(nullptr);
-}
-
-void AVFMediaPlayer::updateTracks()
-{
- for (int i = 0; i < QPlatformMediaPlayer::NTrackTypes; ++i) {
- tracks[i].clear();
- nativeTracks[i].clear();
- }
- AVPlayerItem *playerItem = [m_observer playerItem];
- if (playerItem) {
- // Check each track for audio and video content
- NSArray *tracks = playerItem.tracks;
- for (AVPlayerItemTrack *track in tracks) {
- AVAssetTrack *assetTrack = track.assetTrack;
- if (assetTrack) {
- int qtTrack = -1;
- if ([assetTrack.mediaType isEqualToString:AVMediaTypeAudio]) {
- qtTrack = QPlatformMediaPlayer::AudioStream;
- setAudioAvailable(true);
- } else if ([assetTrack.mediaType isEqualToString:AVMediaTypeVideo]) {
- qtTrack = QPlatformMediaPlayer::VideoStream;
- setVideoAvailable(true);
- if (!m_observer.videoTrack)
- m_observer.videoTrack = track;
- }
- else if ([assetTrack.mediaType isEqualToString:AVMediaTypeSubtitle]) {
- qtTrack = QPlatformMediaPlayer::SubtitleStream;
- }
- if (qtTrack != -1) {
- QMediaMetaData metaData = AVFMetaData::fromAssetTrack(assetTrack);
- this->tracks[qtTrack].append(metaData);
- nativeTracks[qtTrack].append(track);
- }
- }
- }
- }
- Q_EMIT tracksChanged();
-}
-
-void AVFMediaPlayer::setActiveTrack(QPlatformMediaPlayer::TrackType type, int index)
-{
- const auto &t = nativeTracks[type];
- for (int i = 0; i < t.count(); ++i)
- t.at(i).enabled = (i == index);
-}
-
-int AVFMediaPlayer::activeTrack(QPlatformMediaPlayer::TrackType type)
-{
- const auto &t = nativeTracks[type];
- for (int i = 0; i < t.count(); ++i)
- if (t.at(i).enabled)
- return i;
- return -1;
-}
-
-int AVFMediaPlayer::trackCount(QPlatformMediaPlayer::TrackType type)
-{
- return nativeTracks[type].count();
-}
-
-QMediaMetaData AVFMediaPlayer::trackMetaData(QPlatformMediaPlayer::TrackType type, int trackNumber)
-{
- const auto &t = tracks[type];
- if (trackNumber < 0 || trackNumber >= t.count())
- return QMediaMetaData();
- return t.at(trackNumber);
-}
-
-void AVFMediaPlayer::resetStream(QIODevice *stream)
-{
- if (m_mediaStream) {
- disconnect(m_mediaStream, &QIODevice::readyRead, this, &AVFMediaPlayer::streamReady);
- disconnect(m_mediaStream, &QIODevice::destroyed, this, &AVFMediaPlayer::streamDestroyed);
- }
-
- m_mediaStream = stream;
-
- if (m_mediaStream) {
- connect(m_mediaStream, &QIODevice::readyRead, this, &AVFMediaPlayer::streamReady);
- connect(m_mediaStream, &QIODevice::destroyed, this, &AVFMediaPlayer::streamDestroyed);
- }
-}
-
-void AVFMediaPlayer::nativeSizeChanged(QSize size)
-{
- if (!m_videoSink)
- return;
- m_videoSink->setNativeSize(size);
-}
diff --git a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayer_p.h b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayer_p.h
deleted file mode 100644
index 4bd082c1c..000000000
--- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayer_p.h
+++ /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 Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** 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 AVFMEDIAPLAYER_H
-#define AVFMEDIAPLAYER_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 <QtCore/QObject>
-#include <QtCore/QByteArray>
-#include <QtCore/QSet>
-#include <QtCore/QResource>
-#include <QtCore/QUrl>
-#include <QtCore/QTimer>
-
-#include <private/qplatformmediaplayer_p.h>
-#include <QtMultimedia/QMediaPlayer>
-
-Q_FORWARD_DECLARE_OBJC_CLASS(AVAsset);
-Q_FORWARD_DECLARE_OBJC_CLASS(AVPlayerItemTrack);
-Q_FORWARD_DECLARE_OBJC_CLASS(AVFMediaPlayerObserver);
-
-QT_BEGIN_NAMESPACE
-
-class AVFMediaPlayer;
-class AVFVideoRendererControl;
-class AVFVideoSink;
-
-class AVFMediaPlayer : public QObject, public QPlatformMediaPlayer
-{
- Q_OBJECT
-public:
- AVFMediaPlayer(QMediaPlayer *parent);
- virtual ~AVFMediaPlayer();
-
- void setVideoSink(QVideoSink *sink) override;
- void setVideoOutput(AVFVideoRendererControl *output);
- AVAsset *currentAssetHandle();
-
- QMediaPlayer::PlaybackState state() const override;
- QMediaPlayer::MediaStatus mediaStatus() const override;
-
- QUrl media() const override;
- QIODevice *mediaStream() const override;
- void setMedia(const QUrl &content, QIODevice *stream) override;
-
- qint64 position() const override;
- qint64 duration() const override;
-
- float bufferProgress() const override;
-
- bool isAudioAvailable() const override;
- bool isVideoAvailable() const override;
-
- bool isSeekable() const override;
- QMediaTimeRange availablePlaybackRanges() const override;
-
- qreal playbackRate() const override;
-
- void setAudioOutput(QPlatformAudioOutput *output) override;
- QPlatformAudioOutput *m_audioOutput = nullptr;
-
- QMediaMetaData metaData() const override;
-
-public Q_SLOTS:
- void setPlaybackRate(qreal rate) override;
- void nativeSizeChanged(QSize size);
-
- void setPosition(qint64 pos) override;
-
- void play() override;
- void pause() override;
- void stop() override;
-
- void setVolume(float volume);
- void setMuted(bool muted);
- void audioOutputChanged();
-
- void processEOS();
- void processLoadStateChange(QMediaPlayer::PlaybackState newState);
- void processPositionChange();
- void processMediaLoadError();
-
- void processLoadStateChange();
- void processLoadStateFailure();
-
- void processBufferStateChange(int bufferProgress);
-
- void processDurationChange(qint64 duration);
-
- void streamReady();
- void streamDestroyed();
- void updateTracks();
- void setActiveTrack(QPlatformMediaPlayer::TrackType type, int index) override;
- int activeTrack(QPlatformMediaPlayer::TrackType type) override;
- int trackCount(TrackType) override;
- QMediaMetaData trackMetaData(TrackType type, int trackNumber) override;
-
-public:
- QList<QMediaMetaData> tracks[QPlatformMediaPlayer::NTrackTypes];
- QList<AVPlayerItemTrack *> nativeTracks[QPlatformMediaPlayer::NTrackTypes];
-
-private:
- void setAudioAvailable(bool available);
- void setVideoAvailable(bool available);
- void setSeekable(bool seekable);
- void resetStream(QIODevice *stream = nullptr);
-
- AVFVideoRendererControl *m_videoOutput = nullptr;
- AVFVideoSink *m_videoSink = nullptr;
-
- QMediaPlayer::PlaybackState m_state;
- QMediaPlayer::MediaStatus m_mediaStatus;
- QIODevice *m_mediaStream;
- QUrl m_resources;
- QMediaMetaData m_metaData;
-
- bool m_tryingAsync;
- qreal m_rate;
- qint64 m_requestedPosition;
-
- qint64 m_duration;
- int m_bufferProgress;
- bool m_videoAvailable;
- bool m_audioAvailable;
- bool m_seekable;
-
- AVFMediaPlayerObserver *m_observer;
-
- QTimer m_playbackTimer;
-};
-
-QT_END_NAMESPACE
-
-#endif // AVFMEDIAPLAYER_H
diff --git a/src/multimedia/platform/darwin/mediaplayer/avfvideorenderercontrol.mm b/src/multimedia/platform/darwin/mediaplayer/avfvideorenderercontrol.mm
deleted file mode 100644
index 1b3985688..000000000
--- a/src/multimedia/platform/darwin/mediaplayer/avfvideorenderercontrol.mm
+++ /dev/null
@@ -1,272 +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_p.h"
-#include "avfdisplaylink_p.h"
-#include <private/avfvideobuffer_p.h>
-
-#include <private/qabstractvideobuffer_p.h>
-#include <QtMultimedia/qvideoframeformat.h>
-
-#include <private/avfvideosink_p.h>
-#include <QtGui/private/qrhi_p.h>
-
-#include <QtCore/qdebug.h>
-
-#import <AVFoundation/AVFoundation.h>
-#include <CoreVideo/CVPixelBuffer.h>
-#include <CoreVideo/CVImageBuffer.h>
-
-QT_USE_NAMESPACE
-
-@interface SubtitleDelegate : NSObject <AVPlayerItemLegibleOutputPushDelegate>
-{
- AVFVideoRendererControl *m_renderer;
-}
-
-- (void)legibleOutput:(AVPlayerItemLegibleOutput *)output
- didOutputAttributedStrings:(NSArray<NSAttributedString *> *)strings
- nativeSampleBuffers:(NSArray *)nativeSamples
- forItemTime:(CMTime)itemTime;
-
-@end
-
-@implementation SubtitleDelegate
-
--(id)initWithRenderer: (AVFVideoRendererControl *)renderer
-{
- if (!(self = [super init]))
- return nil;
-
- m_renderer = renderer;
-
- return self;
-}
-
-- (void)legibleOutput:(AVPlayerItemLegibleOutput *)output
- didOutputAttributedStrings:(NSArray<NSAttributedString *> *)strings
- nativeSampleBuffers:(NSArray *)nativeSamples
- forItemTime:(CMTime)itemTime
-{
- QString text;
- for (NSAttributedString *s : strings) {
- if (!text.isEmpty())
- text += QChar::LineSeparator;
- text += QString::fromNSString(s.string);
- }
- m_renderer->setSubtitleText(text);
-}
-
-@end
-
-
-AVFVideoRendererControl::AVFVideoRendererControl(QObject *parent)
- : QObject(parent)
-{
- 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();
- if (m_videoOutput)
- [m_videoOutput release];
- if (m_subtitleOutput)
- [m_subtitleOutput release];
- if (m_subtitleDelegate)
- [m_subtitleDelegate release];
-}
-
-void AVFVideoRendererControl::reconfigure()
-{
-#ifdef QT_DEBUG_AVF
- qDebug() << "reconfigure";
-#endif
- if (!m_layer) {
- m_displayLink->stop();
- return;
- }
-
- QMutexLocker locker(&m_mutex);
-
- m_displayLink->start();
-
- nativeSizeChanged();
-}
-
-void AVFVideoRendererControl::setLayer(CALayer *layer)
-{
- if (m_layer == layer)
- return;
-
- AVPlayerLayer *plLayer = playerLayer();
- if (plLayer) {
- if (m_videoOutput)
- [[[plLayer player] currentItem] removeOutput:m_videoOutput];
-
- if (m_subtitleOutput)
- [[[plLayer player] currentItem] removeOutput:m_subtitleOutput];
- }
-
- if (!layer && m_sink)
- m_sink->setVideoFrame(QVideoFrame());
-
- AVFVideoSinkInterface::setLayer(layer);
-}
-
-void AVFVideoRendererControl::updateVideoFrame(const CVTimeStamp &ts)
-{
- Q_UNUSED(ts);
-
- if (!m_sink)
- return;
-
- if (!m_layer)
- return;
-
- auto *layer = playerLayer();
- if (!layer.readyForDisplay)
- return;
- nativeSizeChanged();
-
- QVideoFrame frame;
- size_t width, height;
- CVPixelBufferRef pixelBuffer = copyPixelBufferFromLayer(width, height);
- if (!pixelBuffer)
- return;
- AVFVideoBuffer *buffer = new AVFVideoBuffer(this, pixelBuffer);
- auto fmt = buffer->fromCVVideoPixelFormat(CVPixelBufferGetPixelFormatType(pixelBuffer));
-// qDebug() << "Got pixelbuffer with format" << fmt << Qt::hex << CVPixelBufferGetPixelFormatType(pixelBuffer);
- CVPixelBufferRelease(pixelBuffer);
-
- QVideoFrameFormat format(QSize(width, height), fmt);
-
- frame = QVideoFrame(buffer, format);
- m_sink->setVideoFrame(frame);
-}
-
-static NSDictionary* const AVF_OUTPUT_SETTINGS = @{
- (NSString *)kCVPixelBufferPixelFormatTypeKey: @[
- @(kCVPixelFormatType_32BGRA),
- @(kCVPixelFormatType_32RGBA),
- @(kCVPixelFormatType_422YpCbCr8),
- @(kCVPixelFormatType_422YpCbCr8_yuvs),
- @(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange),
- @(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange),
- @(kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange),
- @(kCVPixelFormatType_420YpCbCr10BiPlanarFullRange),
- @(kCVPixelFormatType_OneComponent8),
- @(q_kCVPixelFormatType_OneComponent16),
- @(kCVPixelFormatType_420YpCbCr8Planar),
- @(kCVPixelFormatType_420YpCbCr8PlanarFullRange)
- ],
- (NSString *)kCVPixelBufferMetalCompatibilityKey: @true
-};
-
-// The OpengGL texture cache can apparently only handle single plane formats, so lets simply restrict to BGRA
-static NSDictionary* const AVF_OUTPUT_SETTINGS_OPENGL = @{
- (NSString *)kCVPixelBufferPixelFormatTypeKey: @[
- @(kCVPixelFormatType_32BGRA),
- ],
- (NSString *)kCVPixelBufferOpenGLCompatibilityKey: @true
-};
-
-CVPixelBufferRef AVFVideoRendererControl::copyPixelBufferFromLayer(size_t& width, size_t& height)
-{
- AVPlayerLayer *layer = playerLayer();
- //Is layer valid
- if (!layer) {
-#ifdef QT_DEBUG_AVF
- qWarning("copyPixelBufferFromLayer: invalid layer");
-#endif
- return nullptr;
- }
-
- AVPlayerItem * item = [[layer player] currentItem];
-
- if (!m_videoOutput) {
- auto *settings = (m_rhi && m_rhi->backend() == QRhi::OpenGLES2) ? AVF_OUTPUT_SETTINGS_OPENGL : AVF_OUTPUT_SETTINGS;
- m_videoOutput = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:settings];
- [m_videoOutput setDelegate:nil queue:nil];
- }
- if (!m_subtitleOutput) {
- m_subtitleOutput = [[AVPlayerItemLegibleOutput alloc] init];
- m_subtitleDelegate = [[SubtitleDelegate alloc] initWithRenderer:this];
- [m_subtitleOutput setDelegate:m_subtitleDelegate queue:dispatch_get_main_queue()];
- }
- if (![item.outputs containsObject:m_videoOutput])
- [item addOutput:m_videoOutput];
- if (![item.outputs containsObject:m_subtitleOutput])
- [item addOutput:m_subtitleOutput];
-
- CFTimeInterval currentCAFrameTime = CACurrentMediaTime();
- CMTime currentCMFrameTime = [m_videoOutput itemTimeForHostTime:currentCAFrameTime];
- // happens when buffering / loading
- if (CMTimeCompare(currentCMFrameTime, kCMTimeZero) < 0) {
- return nullptr;
- }
-
- if (![m_videoOutput hasNewPixelBufferForItemTime:currentCMFrameTime])
- 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);
-// auto f = CVPixelBufferGetPixelFormatType(pixelBuffer);
-// char fmt[5];
-// memcpy(fmt, &f, 4);
-// fmt[4] = 0;
-// qDebug() << "copyPixelBuffer" << f << fmt << width << height;
- return pixelBuffer;
-}
-
-#include "moc_avfvideorenderercontrol_p.cpp"
diff --git a/src/multimedia/platform/darwin/mediaplayer/avfvideorenderercontrol_p.h b/src/multimedia/platform/darwin/mediaplayer/avfvideorenderercontrol_p.h
deleted file mode 100644
index ce0ec0738..000000000
--- a/src/multimedia/platform/darwin/mediaplayer/avfvideorenderercontrol_p.h
+++ /dev/null
@@ -1,103 +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
-
-//
-// 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 <QtCore/QObject>
-#include <QtCore/QMutex>
-#include <QtCore/QSize>
-
-#include <private/avfvideosink_p.h>
-
-#include <CoreVideo/CVBase.h>
-#include <CoreVideo/CVPixelBuffer.h>
-
-Q_FORWARD_DECLARE_OBJC_CLASS(CALayer);
-Q_FORWARD_DECLARE_OBJC_CLASS(AVPlayerItemVideoOutput);
-Q_FORWARD_DECLARE_OBJC_CLASS(AVPlayerItemLegibleOutput);
-Q_FORWARD_DECLARE_OBJC_CLASS(SubtitleDelegate);
-
-QT_BEGIN_NAMESPACE
-
-class AVFDisplayLink;
-
-class AVFVideoRendererControl : public QObject, public AVFVideoSinkInterface
-{
- Q_OBJECT
-public:
- explicit AVFVideoRendererControl(QObject *parent = nullptr);
- virtual ~AVFVideoRendererControl();
-
- // AVFVideoSinkInterface
- void reconfigure() override;
- void setLayer(CALayer *layer) override;
-
- void setSubtitleText(const QString &subtitle)
- {
- m_sink->setSubtitleText(subtitle);
- }
-private Q_SLOTS:
- void updateVideoFrame(const CVTimeStamp &ts);
-
-private:
- AVPlayerLayer *playerLayer() const { return static_cast<AVPlayerLayer *>(m_layer); }
- CVPixelBufferRef copyPixelBufferFromLayer(size_t& width, size_t& height);
-
- QMutex m_mutex;
- AVFDisplayLink *m_displayLink = nullptr;
- AVPlayerItemVideoOutput *m_videoOutput = nullptr;
- AVPlayerItemLegibleOutput *m_subtitleOutput = nullptr;
- SubtitleDelegate *m_subtitleDelegate = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // AVFVIDEORENDERERCONTROL_H
diff --git a/src/multimedia/platform/darwin/qdarwinformatsinfo.mm b/src/multimedia/platform/darwin/qdarwinformatsinfo.mm
deleted file mode 100644
index 9d27a843d..000000000
--- a/src/multimedia/platform/darwin/qdarwinformatsinfo.mm
+++ /dev/null
@@ -1,246 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qdarwinformatsinfo_p.h"
-#include <AVFoundation/AVFoundation.h>
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-static struct {
- const char *name;
- QMediaFormat::FileFormat value;
-} mediaContainerMap[] = {
- { "video/x-ms-asf", QMediaFormat::WMV },
- { "video/avi", QMediaFormat::AVI },
- { "video/x-matroska", QMediaFormat::Matroska },
- { "video/mp4", QMediaFormat::MPEG4 },
- { "video/quicktime", QMediaFormat::QuickTime },
- { "video/ogg", QMediaFormat::Ogg },
- { "audio/mp3", QMediaFormat::MP3 },
- { nullptr, QMediaFormat::UnspecifiedFormat }
-};
-
-static struct {
- const char *name;
- QMediaFormat::VideoCodec value;
-} videoCodecMap[] = {
- // See CMVideoCodecType for the four character code names of codecs
- { "; codecs=\"mp1v\"", QMediaFormat::VideoCodec::MPEG1 },
- { "; codecs=\"mp2v\"", QMediaFormat::VideoCodec::MPEG2 },
- { "; codecs=\"mp4v\"", QMediaFormat::VideoCodec::MPEG4 },
- { "; codecs=\"avc1\"", QMediaFormat::VideoCodec::H264 },
- { "; codecs=\"hvc1\"", QMediaFormat::VideoCodec::H265 },
- { "; codecs=\"vp09\"", QMediaFormat::VideoCodec::VP9 },
- { "; codecs=\"av01\"", QMediaFormat::VideoCodec::AV1 }, // ### ????
- { "; codecs=\"jpeg\"", QMediaFormat::VideoCodec::MotionJPEG },
- { nullptr, QMediaFormat::VideoCodec::Unspecified }
-};
-
-static struct {
- const char *name;
- QMediaFormat::AudioCodec value;
-} audioCodecMap[] = {
- // AudioFile.h
- // ### The next two entries do not work, probably because they contain non a space and period and AVFoundation doesn't like that
- // We know they are supported on all Apple platforms, so we'll add them manually below
-// { "; codecs=\".mp3\"", QMediaFormat::AudioCodec::MP3 },
-// { "; codecs=\"aac \"", QMediaFormat::AudioCodec::AAC },
- { "; codecs=\"ac-3\"", QMediaFormat::AudioCodec::AC3 },
- { "; codecs=\"ec-3\"", QMediaFormat::AudioCodec::EAC3 },
- { "; codecs=\"flac\"", QMediaFormat::AudioCodec::FLAC },
- { "; codecs=\"alac\"", QMediaFormat::AudioCodec::ALAC },
- { "; codecs=\"opus\"", QMediaFormat::AudioCodec::Opus },
- { nullptr, QMediaFormat::AudioCodec::Unspecified },
-};
-
-QDarwinFormatInfo::QDarwinFormatInfo()
-{
- auto avtypes = [AVURLAsset audiovisualMIMETypes];
- for (AVFileType filetype in avtypes) {
- auto *m = mediaContainerMap;
- while (m->name) {
- if (strcmp(filetype.UTF8String, m->name)) {
- ++m;
- continue;
- }
-
- QList<QMediaFormat::VideoCodec> video;
- QList<QMediaFormat::AudioCodec> audio;
-
- auto *v = videoCodecMap;
- while (v->name) {
- QByteArray extendedMimetype = m->name;
- extendedMimetype += v->name;
- if ([AVURLAsset isPlayableExtendedMIMEType:[NSString stringWithUTF8String:extendedMimetype.constData()]])
- video << v->value;
- ++v;
- }
-
- auto *a = audioCodecMap;
- while (a->name) {
- QByteArray extendedMimetype = m->name;
- extendedMimetype += a->name;
- if ([AVURLAsset isPlayableExtendedMIMEType:[NSString stringWithUTF8String:extendedMimetype.constData()]])
- audio << a->value;
- ++a;
- }
- // Added manually, see comment in the list above
- if (m->value <= QMediaFormat::AAC)
- audio << QMediaFormat::AudioCodec::AAC;
- if (m->value < QMediaFormat::AAC || m->value == QMediaFormat::MP3)
- audio << QMediaFormat::AudioCodec::MP3;
-
- decoders << CodecMap{ m->value, audio, video };
- ++m;
- }
- }
-
- // seems AVFoundation only supports those for encoding
- encoders = {
- { QMediaFormat::MPEG4,
- { QMediaFormat::AudioCodec::AAC, QMediaFormat::AudioCodec::ALAC },
- { QMediaFormat::VideoCodec::H264, QMediaFormat::VideoCodec::H265, QMediaFormat::VideoCodec::MotionJPEG } },
- { QMediaFormat::QuickTime,
- { QMediaFormat::AudioCodec::AAC, QMediaFormat::AudioCodec::ALAC },
- { QMediaFormat::VideoCodec::H264, QMediaFormat::VideoCodec::H265, QMediaFormat::VideoCodec::MotionJPEG } },
- { QMediaFormat::Mpeg4Audio,
- { QMediaFormat::AudioCodec::AAC },
- {} },
- { QMediaFormat::Wave,
- { QMediaFormat::AudioCodec::Wave },
- {} },
- };
-
- // ###
- imageFormats << QImageCapture::JPEG;
-}
-
-QDarwinFormatInfo::~QDarwinFormatInfo()
-{
-}
-
-int QDarwinFormatInfo::audioFormatForCodec(QMediaFormat::AudioCodec codec)
-{
- int codecId = kAudioFormatMPEG4AAC;
- switch (codec) {
- case QMediaFormat::AudioCodec::Unspecified:
- case QMediaFormat::AudioCodec::DolbyTrueHD:
- case QMediaFormat::AudioCodec::Vorbis:
- case QMediaFormat::AudioCodec::WMA:
- // Unsupported, shouldn't happen. Fall back to AAC
- case QMediaFormat::AudioCodec::AAC:
- codecId = kAudioFormatMPEG4AAC;
- break;
- case QMediaFormat::AudioCodec::MP3:
- codecId = kAudioFormatMPEGLayer3;
- break;
- case QMediaFormat::AudioCodec::AC3:
- codecId = kAudioFormatAC3;
- break;
- case QMediaFormat::AudioCodec::EAC3:
- codecId = kAudioFormatEnhancedAC3;
- break;
- case QMediaFormat::AudioCodec::FLAC:
- codecId = kAudioFormatFLAC;
- break;
- case QMediaFormat::AudioCodec::ALAC:
- codecId = kAudioFormatAppleLossless;
- break;
- case QMediaFormat::AudioCodec::Opus:
- codecId = kAudioFormatOpus;
- break;
- case QMediaFormat::AudioCodec::Wave:
- codecId = kAudioFormatLinearPCM;
- }
- return codecId;
-}
-
-NSString *QDarwinFormatInfo::videoFormatForCodec(QMediaFormat::VideoCodec codec)
-{
- const char *c = "hvc1"; // fallback is H265
- switch (codec) {
- case QMediaFormat::VideoCodec::Unspecified:
- case QMediaFormat::VideoCodec::VP8:
- case QMediaFormat::VideoCodec::H265:
- case QMediaFormat::VideoCodec::AV1:
- case QMediaFormat::VideoCodec::Theora:
- case QMediaFormat::VideoCodec::WMV:
- break;
-
- case QMediaFormat::VideoCodec::MPEG1:
- c = "mp1v";
- break;
- case QMediaFormat::VideoCodec::MPEG2:
- c = "mp2v";
- break;
- case QMediaFormat::VideoCodec::MPEG4:
- c = "mp4v";
- break;
- case QMediaFormat::VideoCodec::H264:
- c = "avc1";
- break;
- case QMediaFormat::VideoCodec::VP9:
- c = "vp09";
- break;
- case QMediaFormat::VideoCodec::MotionJPEG:
- c = "jpeg";
- }
- return [NSString stringWithUTF8String:c];
-}
-
-NSString *QDarwinFormatInfo::avFileTypeForContainerFormat(QMediaFormat::FileFormat container)
-{
- switch (container) {
- case QMediaFormat::MPEG4:
- return AVFileTypeMPEG4;
- case QMediaFormat::QuickTime:
- return AVFileTypeQuickTimeMovie;
- case QMediaFormat::MP3:
- return AVFileTypeMPEGLayer3;
- case QMediaFormat::Mpeg4Audio:
- return AVFileTypeAppleM4A;
- case QMediaFormat::Wave:
- return AVFileTypeWAVE;
- default:
- return AVFileTypeQuickTimeMovie;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/darwin/qdarwinformatsinfo_p.h b/src/multimedia/platform/darwin/qdarwinformatsinfo_p.h
deleted file mode 100644
index 79e33b6f4..000000000
--- a/src/multimedia/platform/darwin/qdarwinformatsinfo_p.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QDARWINFORMATINFO_H
-#define QDARWINFORMATINFO_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 <private/qplatformmediaformatinfo_p.h>
-#include <qlist.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDarwinMediaDevices;
-
-class QDarwinFormatInfo : public QPlatformMediaFormatInfo
-{
-public:
- QDarwinFormatInfo();
- ~QDarwinFormatInfo();
-
- static int audioFormatForCodec(QMediaFormat::AudioCodec codec);
- static NSString *videoFormatForCodec(QMediaFormat::VideoCodec codec);
- static NSString *avFileTypeForContainerFormat(QMediaFormat::FileFormat fileType);
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/darwin/qdarwinintegration.mm b/src/multimedia/platform/darwin/qdarwinintegration.mm
deleted file mode 100644
index 372ce9e81..000000000
--- a/src/multimedia/platform/darwin/qdarwinintegration.mm
+++ /dev/null
@@ -1,113 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qdarwinintegration_p.h"
-#include "qdarwinmediadevices_p.h"
-#include <private/avfmediaplayer_p.h>
-#include <private/avfcameraservice_p.h>
-#include <private/avfcamera_p.h>
-#include <private/avfimagecapture_p.h>
-#include <private/avfmediaencoder_p.h>
-#include <private/qdarwinformatsinfo_p.h>
-#include <private/avfvideosink_p.h>
-#include <private/avfaudiodecoder_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QDarwinIntegration::QDarwinIntegration()
-{
-
-}
-
-QDarwinIntegration::~QDarwinIntegration()
-{
- delete m_devices;
- delete m_formatInfo;
-}
-
-QPlatformMediaDevices *QDarwinIntegration::devices()
-{
- if (!m_devices)
- m_devices = new QDarwinMediaDevices();
- return m_devices;
-}
-
-QPlatformMediaFormatInfo *QDarwinIntegration::formatInfo()
-{
- if (!m_formatInfo)
- m_formatInfo = new QDarwinFormatInfo();
- return m_formatInfo;
-}
-
-QPlatformAudioDecoder *QDarwinIntegration::createAudioDecoder(QAudioDecoder *decoder)
-{
- return new AVFAudioDecoder(decoder);
-}
-
-QPlatformMediaCaptureSession *QDarwinIntegration::createCaptureSession()
-{
- return new AVFCameraService;
-}
-
-QPlatformMediaPlayer *QDarwinIntegration::createPlayer(QMediaPlayer *player)
-{
- return new AVFMediaPlayer(player);
-}
-
-QPlatformCamera *QDarwinIntegration::createCamera(QCamera *camera)
-{
- return new AVFCamera(camera);
-}
-
-QPlatformMediaEncoder *QDarwinIntegration::createEncoder(QMediaRecorder *encoder)
-{
- return new AVFMediaEncoder(encoder);
-}
-
-QPlatformImageCapture *QDarwinIntegration::createImageCapture(QImageCapture *imageCapture)
-{
- return new AVFImageCapture(imageCapture);
-}
-
-QPlatformVideoSink *QDarwinIntegration::createVideoSink(QVideoSink *sink)
-{
- return new AVFVideoSink(sink);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/darwin/qdarwinintegration_p.h b/src/multimedia/platform/darwin/qdarwinintegration_p.h
deleted file mode 100644
index 946300761..000000000
--- a/src/multimedia/platform/darwin/qdarwinintegration_p.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QDARWININTEGRATION_H
-#define QDARWININTEGRATION_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 <private/qplatformmediaintegration_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QDarwinMediaDevices;
-
-class QDarwinIntegration : public QPlatformMediaIntegration
-{
-public:
- QDarwinIntegration();
- ~QDarwinIntegration();
-
- QPlatformMediaDevices *devices() override;
- QPlatformMediaFormatInfo *formatInfo() override;
-
- QPlatformAudioDecoder *createAudioDecoder(QAudioDecoder *) override;
- QPlatformMediaCaptureSession *createCaptureSession() override;
- QPlatformMediaPlayer *createPlayer(QMediaPlayer *player) override;
- QPlatformCamera *createCamera(QCamera *camera) override;
- QPlatformMediaEncoder *createEncoder(QMediaRecorder *) override;
- QPlatformImageCapture *createImageCapture(QImageCapture *) override;
-
- QPlatformVideoSink *createVideoSink(QVideoSink *) override;
-
- QDarwinMediaDevices *m_devices = nullptr;
- QPlatformMediaFormatInfo *m_formatInfo = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/darwin/qdarwinmediadevices.mm b/src/multimedia/platform/darwin/qdarwinmediadevices.mm
deleted file mode 100644
index b7bb6e7f9..000000000
--- a/src/multimedia/platform/darwin/qdarwinmediadevices.mm
+++ /dev/null
@@ -1,348 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qdarwinmediadevices_p.h"
-#include "qmediadevices.h"
-#include "qcameradevice_p.h"
-#include "qaudiodevice_p.h"
-#include "private/qdarwinaudiodevice_p.h"
-#include "private/qdarwinaudiosource_p.h"
-#include "private/qdarwinaudiosink_p.h"
-#include "private/avfcamera_p.h"
-#include "private/avfcamerautility_p.h"
-#include "private/avfvideobuffer_p.h"
-
-#include <CoreVideo/CoreVideo.h>
-#import <AVFoundation/AVFoundation.h>
-
-#if defined(Q_OS_IOS) || defined(Q_OS_TVOS)
-#include "private/qcoreaudiosessionmanager_p.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#if defined(Q_OS_MACOS)
-AudioDeviceID defaultAudioDevice(QAudioDevice::Mode mode)
-{
- AudioDeviceID audioDevice;
- UInt32 size = sizeof(audioDevice);
- const AudioObjectPropertySelector selector = (mode == QAudioDevice::Output) ? kAudioHardwarePropertyDefaultOutputDevice
- : kAudioHardwarePropertyDefaultInputDevice;
- AudioObjectPropertyAddress defaultDevicePropertyAddress = { selector,
- kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster };
-
- if (AudioObjectGetPropertyData(kAudioObjectSystemObject,
- &defaultDevicePropertyAddress,
- 0, NULL, &size, &audioDevice) != noErr) {
- qWarning("QAudioDevice: Unable to find default %s device", (mode == QAudioDevice::Output) ? "output" : "input");
- return 0;
- }
-
- return audioDevice;
-}
-
-static QByteArray uniqueId(AudioDeviceID device, QAudioDevice::Mode mode)
-{
- CFStringRef name;
- UInt32 size = sizeof(CFStringRef);
-
- AudioObjectPropertyScope audioPropertyScope = mode == QAudioDevice::Input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
-
- AudioObjectPropertyAddress audioDeviceNamePropertyAddress = { kAudioDevicePropertyDeviceUID,
- audioPropertyScope,
- kAudioObjectPropertyElementMaster };
-
- if (AudioObjectGetPropertyData(device, &audioDeviceNamePropertyAddress, 0, NULL, &size, &name) != noErr) {
- qWarning() << "QAudioDevice: Unable to get device UID";
- return QByteArray();
- }
-
- QString s = QString::fromCFString(name);
- CFRelease(name);
- return s.toUtf8();
-}
-
-QList<QAudioDevice> availableAudioDevices(QAudioDevice::Mode mode)
-{
-
- QList<QAudioDevice> devices;
-
- AudioDeviceID defaultDevice = defaultAudioDevice(mode);
- if (defaultDevice != 0)
- devices << (new QCoreAudioDeviceInfo(defaultDevice, uniqueId(defaultDevice, mode), mode))->create();
-
- UInt32 propSize = 0;
- AudioObjectPropertyAddress audioDevicesPropertyAddress = { kAudioHardwarePropertyDevices,
- kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster };
-
- if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
- &audioDevicesPropertyAddress,
- 0, NULL, &propSize) == noErr) {
-
- const int dc = propSize / sizeof(AudioDeviceID);
-
- if (dc > 0) {
- AudioDeviceID* audioDevices = new AudioDeviceID[dc];
-
- if (AudioObjectGetPropertyData(kAudioObjectSystemObject, &audioDevicesPropertyAddress, 0, NULL, &propSize, audioDevices) == noErr) {
- for (int i = 0; i < dc; ++i) {
- if (audioDevices[i] == defaultDevice)
- continue;
-
- AudioStreamBasicDescription sf;
- UInt32 size = sizeof(AudioStreamBasicDescription);
- AudioObjectPropertyAddress audioDeviceStreamFormatPropertyAddress = { kAudioDevicePropertyStreamFormat,
- (mode == QAudioDevice::Input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput),
- kAudioObjectPropertyElementMaster };
-
- if (AudioObjectGetPropertyData(audioDevices[i], &audioDeviceStreamFormatPropertyAddress, 0, NULL, &size, &sf) == noErr)
- devices << (new QCoreAudioDeviceInfo(audioDevices[i], uniqueId(audioDevices[i], mode), mode))->create();
- }
- }
-
- delete[] audioDevices;
- }
- }
-
- return devices;
-}
-
-static OSStatus
-audioDeviceChangeListener(AudioObjectID, UInt32, const AudioObjectPropertyAddress*, void* ptr)
-{
- QDarwinMediaDevices *m = static_cast<QDarwinMediaDevices *>(ptr);
- m->updateAudioDevices();
- return 0;
-}
-#endif
-
-
-QDarwinMediaDevices::QDarwinMediaDevices()
- : QPlatformMediaDevices()
-{
- NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
- m_deviceConnectedObserver = [notificationCenter addObserverForName:AVCaptureDeviceWasConnectedNotification
- object:nil
- queue:[NSOperationQueue mainQueue]
- usingBlock:^(NSNotification *) {
- this->updateCameraDevices();
- this->updateAudioDevices();
- }];
-
- m_deviceDisconnectedObserver = [notificationCenter addObserverForName:AVCaptureDeviceWasDisconnectedNotification
- object:nil
- queue:[NSOperationQueue mainQueue]
- usingBlock:^(NSNotification *) {
- this->updateCameraDevices();
- this->updateAudioDevices();
- }];
-
-#ifdef Q_OS_MACOS
- OSStatus err = noErr;
- AudioObjectPropertyAddress *audioDevicesAddress = new AudioObjectPropertyAddress{ kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
- m_audioDevicesProperty = audioDevicesAddress;
- err = AudioObjectAddPropertyListener(kAudioObjectSystemObject, audioDevicesAddress, audioDeviceChangeListener, this);
- if (err)
- qDebug("error on AudioObjectAddPropertyListener");
-#else
- // ### This should use the audio session manager
-#endif
- updateCameraDevices();
- updateAudioDevices();
-}
-
-
-QDarwinMediaDevices::~QDarwinMediaDevices()
-{
- NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
- [notificationCenter removeObserver:(id)m_deviceConnectedObserver];
- [notificationCenter removeObserver:(id)m_deviceDisconnectedObserver];
-
-#ifdef Q_OS_MACOS
- AudioObjectRemovePropertyListener(kAudioObjectSystemObject, (AudioObjectPropertyAddress *)m_audioDevicesProperty, audioDeviceChangeListener, this);
-#endif
-}
-
-QList<QAudioDevice> QDarwinMediaDevices::audioInputs() const
-{
-#ifdef Q_OS_IOS
- // TODO: Support Bluetooth and USB devices
- QList<QAudioDevice> devices;
- AVCaptureDeviceDiscoverySession *captureDeviceDiscoverySession = [AVCaptureDeviceDiscoverySession
- discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInMicrophone]
- mediaType:AVMediaTypeAudio
- position:AVCaptureDevicePositionUnspecified];
-
- NSArray *captureDevices = [captureDeviceDiscoverySession devices];
- for (AVCaptureDevice *device in captureDevices)
- devices << (new QCoreAudioDeviceInfo(QString::fromNSString(device.uniqueID).toUtf8(), QAudioDevice::Input))->create();
- return devices;
-#else
- return availableAudioDevices(QAudioDevice::Input);
-#endif
-}
-
-QList<QAudioDevice> QDarwinMediaDevices::audioOutputs() const
-{
-#ifdef Q_OS_IOS
- QList<QAudioDevice> devices;
- devices.append((new QCoreAudioDeviceInfo("default", QAudioDevice::Output))->create());
- return devices;
-#else
- return availableAudioDevices(QAudioDevice::Output);
-#endif
-}
-
-QList<QCameraDevice> QDarwinMediaDevices::videoInputs() const
-{
- return m_cameraDevices;
-}
-
-void QDarwinMediaDevices::updateCameraDevices()
-{
-#ifdef Q_OS_IOS
- // Cameras can't change dynamically on iOS. Update only once.
- if (!m_cameraDevices.isEmpty())
- return;
-#endif
-
- QList<QCameraDevice> cameras;
-
- AVCaptureDevice *defaultDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
- NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
-
- for (AVCaptureDevice *device in videoDevices) {
-
- QCameraDevicePrivate *info = new QCameraDevicePrivate;
- if (defaultDevice && [defaultDevice.uniqueID isEqualToString:device.uniqueID])
- info->isDefault = true;
- info->id = QByteArray([[device uniqueID] UTF8String]);
- info->description = QString::fromNSString([device localizedName]);
-
- QSet<QSize> photoResolutions;
- QList<QCameraFormat> videoFormats;
-
- for (AVCaptureDeviceFormat *format in device.formats) {
- if (![format.mediaType isEqualToString:AVMediaTypeVideo])
- continue;
-
- auto dimensions = CMVideoFormatDescriptionGetDimensions(format.formatDescription);
- QSize resolution(dimensions.width, dimensions.height);
- photoResolutions.insert(resolution);
-
- float maxFrameRate = 0;
- float minFrameRate = 1.e6;
-
- auto encoding = CMVideoFormatDescriptionGetCodecType(format.formatDescription);
- auto pixelFormat = AVFVideoBuffer::fromCVPixelFormat(encoding);
- // Ignore pixel formats we can't handle
- if (pixelFormat == QVideoFrameFormat::Format_Invalid)
- continue;
-
- for (AVFrameRateRange *frameRateRange in format.videoSupportedFrameRateRanges) {
- if (frameRateRange.minFrameRate < minFrameRate)
- minFrameRate = frameRateRange.minFrameRate;
- if (frameRateRange.maxFrameRate > maxFrameRate)
- maxFrameRate = frameRateRange.maxFrameRate;
- }
-
-#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())
- photoResolutions.insert(hrRes);
-#endif
-
- auto *f = new QCameraFormatPrivate{
- QSharedData(),
- pixelFormat,
- resolution,
- minFrameRate,
- maxFrameRate
- };
- videoFormats << f->create();
- }
- info->videoFormats = videoFormats;
- info->photoResolutions = photoResolutions.values();
-
- cameras.append(info->create());
- }
-
- if (cameras != m_cameraDevices) {
- m_cameraDevices = cameras;
- videoInputsChanged();
- }
-}
-
-
-void QDarwinMediaDevices::updateAudioDevices()
-{
-#ifdef Q_OS_MACOS
- QList<QAudioDevice> inputs = availableAudioDevices(QAudioDevice::Input);
- if (m_audioInputs != inputs) {
- m_audioInputs = inputs;
- audioInputsChanged();
- }
-
- QList<QAudioDevice> outputs = availableAudioDevices(QAudioDevice::Output);
- if (m_audioOutputs!= outputs) {
- m_audioOutputs = outputs;
- audioOutputsChanged();
- }
-#endif
-}
-
-QPlatformAudioSource *QDarwinMediaDevices::createAudioSource(const QAudioDevice &info)
-{
- return new QDarwinAudioSource(info);
-}
-
-QPlatformAudioSink *QDarwinMediaDevices::createAudioSink(const QAudioDevice &info)
-{
- return new QDarwinAudioSink(info);
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/darwin/qdarwinmediadevices_p.h b/src/multimedia/platform/darwin/qdarwinmediadevices_p.h
deleted file mode 100644
index 0c3515f2b..000000000
--- a/src/multimedia/platform/darwin/qdarwinmediadevices_p.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QDARWINMEDIADEVICES_H
-#define QDARWINMEDIADEVICES_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 <private/qplatformmediadevices_p.h>
-#include <qelapsedtimer.h>
-#include <qcameradevice.h>
-
-Q_FORWARD_DECLARE_OBJC_CLASS(NSObject);
-Q_FORWARD_DECLARE_OBJC_CLASS(AVCaptureDeviceDiscoverySession);
-
-QT_BEGIN_NAMESPACE
-
-class QCameraDevice;
-
-class QDarwinMediaDevices : public QPlatformMediaDevices
-{
-public:
- QDarwinMediaDevices();
- ~QDarwinMediaDevices();
-
- QList<QAudioDevice> audioInputs() const override;
- QList<QAudioDevice> audioOutputs() const override;
- QList<QCameraDevice> videoInputs() const override;
- QPlatformAudioSource *createAudioSource(const QAudioDevice &info) override;
- QPlatformAudioSink *createAudioSink(const QAudioDevice &info) override;
-
- void updateCameraDevices();
- void updateAudioDevices();
-
-private:
- QList<QCameraDevice> m_cameraDevices;
- QList<QAudioDevice> m_audioInputs;
- QList<QAudioDevice> m_audioOutputs;
-
- NSObject *m_deviceConnectedObserver;
- NSObject *m_deviceDisconnectedObserver;
-#ifdef Q_OS_MACOS
- void *m_audioDevicesProperty;
-#endif
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder.cpp b/src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder.cpp
deleted file mode 100644
index dc44a1c38..000000000
--- a/src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder.cpp
+++ /dev/null
@@ -1,558 +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 "qgstreameraudiodecoder_p.h"
-#include "private/qgstreamermessage_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;
-
-
-
-QGstreamerAudioDecoder::QGstreamerAudioDecoder(QAudioDecoder *parent)
- : QPlatformAudioDecoder(parent),
- m_playbin(GST_PIPELINE_CAST(QGstElement("playbin", "playbin").element()))
-{
- if (m_playbin.isNull()) {
- // ### set error
- return;
- }
-
- // Sort out messages
- m_playbin.installMessageFilter(this);
-
- // Set the rest of the pipeline up
- setAudioFlags(true);
-
- m_audioConvert = QGstElement("audioconvert", "audioconvert");
-
- m_outputBin = QGstBin("audio-output-bin");
- m_outputBin.add(m_audioConvert);
-
- // add ghostpad
- m_outputBin.addGhostPad(m_audioConvert, "sink");
-
- g_object_set(m_playbin.object(), "audio-sink", m_outputBin.element(), NULL);
- g_signal_connect(m_playbin.object(), "deep-notify::source", (GCallback) &QGstreamerAudioDecoder::configureAppSrcElement, (gpointer)this);
-
- // Set volume to 100%
- gdouble volume = 1.0;
- m_playbin.set("volume", volume);
-}
-
-QGstreamerAudioDecoder::~QGstreamerAudioDecoder()
-{
- if (m_playbin.isNull())
- return;
-
- stop();
-
-#if QT_CONFIG(gstreamer_app)
- delete m_appSrc;
-#endif
-}
-
-#if QT_CONFIG(gstreamer_app)
-void QGstreamerAudioDecoder::configureAppSrcElement(GObject* object, GObject *orig, GParamSpec *pspec, QGstreamerAudioDecoder *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);
-
- auto *qAppSrc = self->appsrc();
- qAppSrc->setExternalAppSrc(appsrc);
- qAppSrc->setup(self->mDevice);
-
- g_object_unref(G_OBJECT(appsrc));
-}
-#endif
-
-bool QGstreamerAudioDecoder::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) == m_playbin.object()) {
- 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
-
- bool isDecoding = false;
- switch (newState) {
- case GST_STATE_VOID_PENDING:
- case GST_STATE_NULL:
- case GST_STATE_READY:
- break;
- case GST_STATE_PLAYING:
- isDecoding = true;
- break;
- case GST_STATE_PAUSED:
- isDecoding = true;
-
- //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;
- }
-
- setIsDecoding(isDecoding);
- }
- break;
-
- case GST_MESSAGE_EOS:
- finished();
- 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;
-}
-
-QUrl QGstreamerAudioDecoder::source() const
-{
- return mSource;
-}
-
-void QGstreamerAudioDecoder::setSource(const QUrl &fileName)
-{
- stop();
- mDevice = nullptr;
- delete m_appSrc;
- m_appSrc = nullptr;
-
- bool isSignalRequired = (mSource != fileName);
- mSource = fileName;
- if (isSignalRequired)
- emit sourceChanged();
-}
-
-QIODevice *QGstreamerAudioDecoder::sourceDevice() const
-{
- return mDevice;
-}
-
-void QGstreamerAudioDecoder::setSourceDevice(QIODevice *device)
-{
- stop();
- mSource.clear();
- bool isSignalRequired = (mDevice != device);
- mDevice = device;
- if (isSignalRequired)
- emit sourceChanged();
-}
-
-void QGstreamerAudioDecoder::start()
-{
- if (m_playbin.isNull()) {
- processInvalidMedia(QAudioDecoder::ResourceError, QLatin1String("Playbin element is not valid"));
- return;
- }
-
- addAppSink();
-
- if (!mSource.isEmpty()) {
- m_playbin.set("uri", mSource.toEncoded().constData());
- } else if (mDevice) {
- // make sure we can read from device
- if (!mDevice->isOpen() || !mDevice->isReadable()) {
- processInvalidMedia(QAudioDecoder::AccessDeniedError, QLatin1String("Unable to read from specified device"));
- return;
- }
-
- if (!m_appSrc)
- m_appSrc = new QGstAppSrc(this);
-
- m_playbin.set("uri", "appsrc://");
- } else {
- return;
- }
-
- // Set audio format
- if (m_appSink) {
- if (mFormat.isValid()) {
- setAudioFlags(false);
- QGstMutableCaps caps = QGstUtils::capsForAudioFormat(mFormat);
- gst_app_sink_set_caps(m_appSink, caps.get());
- } else {
- // We want whatever the native audio format is
- setAudioFlags(true);
- gst_app_sink_set_caps(m_appSink, nullptr);
- }
- }
-
- if (m_playbin.setState(GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
- qWarning() << "GStreamer; Unable to start decoding process";
- m_playbin.dumpGraph("failed");
- return;
- }
-}
-
-void QGstreamerAudioDecoder::stop()
-{
- if (m_playbin.isNull())
- return;
-
- m_playbin.setState(GST_STATE_NULL);
- removeAppSink();
-
- // 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);
- }
-
- setIsDecoding(false);
-}
-
-QAudioFormat QGstreamerAudioDecoder::audioFormat() const
-{
- return mFormat;
-}
-
-void QGstreamerAudioDecoder::setAudioFormat(const QAudioFormat &format)
-{
- if (mFormat != format) {
- mFormat = format;
- emit formatChanged(mFormat);
- }
-}
-
-QAudioBuffer QGstreamerAudioDecoder::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 = nullptr;
- 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 QGstreamerAudioDecoder::bufferAvailable() const
-{
- QMutexLocker locker(&m_buffersMutex);
- return m_buffersAvailable > 0;
-}
-
-qint64 QGstreamerAudioDecoder::position() const
-{
- return m_position;
-}
-
-qint64 QGstreamerAudioDecoder::duration() const
-{
- return m_duration;
-}
-
-void QGstreamerAudioDecoder::processInvalidMedia(QAudioDecoder::Error errorCode, const QString& errorString)
-{
- stop();
- emit error(int(errorCode), errorString);
-}
-
-GstFlowReturn QGstreamerAudioDecoder::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()."
- QGstreamerAudioDecoder *decoder = reinterpret_cast<QGstreamerAudioDecoder*>(user_data);
-
- int buffersAvailable;
- {
- QMutexLocker locker(&decoder->m_buffersMutex);
- buffersAvailable = decoder->m_buffersAvailable;
- decoder->m_buffersAvailable++;
- Q_ASSERT(decoder->m_buffersAvailable <= MAX_BUFFERS_IN_QUEUE);
- }
-
- if (!buffersAvailable)
- decoder->bufferAvailableChanged(true);
- decoder->bufferReady();
- return GST_FLOW_OK;
-}
-
-void QGstreamerAudioDecoder::setAudioFlags(bool wantNativeAudio)
-{
- if (m_playbin.isNull())
- return;
-
- int flags = m_playbin.getInt("flags");
- // 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;
- m_playbin.set("flags", flags);
-}
-
-void QGstreamerAudioDecoder::addAppSink()
-{
- if (m_appSink)
- return;
-
- m_appSink = (GstAppSink*)gst_element_factory_make("appsink", nullptr);
-
- GstAppSinkCallbacks callbacks;
- memset(&callbacks, 0, sizeof(callbacks));
- callbacks.new_sample = &new_sample;
- gst_app_sink_set_callbacks(m_appSink, &callbacks, this, nullptr);
- 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(m_outputBin.bin(), GST_ELEMENT(m_appSink));
- gst_element_link(m_audioConvert.element(), GST_ELEMENT(m_appSink));
-}
-
-void QGstreamerAudioDecoder::removeAppSink()
-{
- if (!m_appSink)
- return;
-
- gst_element_unlink(m_audioConvert.element(), GST_ELEMENT(m_appSink));
- gst_bin_remove(m_outputBin.bin(), GST_ELEMENT(m_appSink));
-
- m_appSink = nullptr;
-}
-
-void QGstreamerAudioDecoder::updateDuration()
-{
- int duration = -1;
-
- if (!m_playbin.isNull())
- duration = m_playbin.duration() / 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 QGstreamerAudioDecoder::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/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder_p.h b/src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder_p.h
deleted file mode 100644
index 693b00c3d..000000000
--- a/src/multimedia/platform/gstreamer/audio/qgstreameraudiodecoder_p.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 QGSTREAMERAUDIODECODERCONTROL_H
-#define QGSTREAMERAUDIODECODERCONTROL_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 <QtMultimedia/private/qtmultimediaglobal_p.h>
-#include <QObject>
-#include <QtCore/qmutex.h>
-#include <QtCore/qurl.h>
-
-#include "private/qplatformaudiodecoder_p.h"
-#include <private/qgstpipeline_p.h>
-#include "qaudiodecoder.h"
-
-#if QT_CONFIG(gstreamer_app)
-#include <private/qgstappsrc_p.h>
-#endif
-
-#include <private/qgst_p.h>
-#include <gst/app/gstappsink.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerMessage;
-
-class QGstreamerAudioDecoder
- : public QPlatformAudioDecoder,
- public QGstreamerBusMessageFilter
-{
- Q_OBJECT
-
-public:
- QGstreamerAudioDecoder(QAudioDecoder *parent);
- virtual ~QGstreamerAudioDecoder();
-
- QUrl source() const override;
- void setSource(const QUrl &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;
-
-#if QT_CONFIG(gstreamer_app)
- QGstAppSrc *appsrc() const { return m_appSrc; }
- static void configureAppSrcElement(GObject*, GObject*, GParamSpec*, QGstreamerAudioDecoder *_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);
-
- QGstPipeline m_playbin;
- QGstBin m_outputBin;
- QGstElement m_audioConvert;
- GstAppSink *m_appSink = nullptr;
- QGstAppSrc *m_appSrc = nullptr;
-
- QUrl mSource;
- QIODevice *mDevice = nullptr;
- QAudioFormat mFormat;
-
- mutable QMutex m_buffersMutex;
- int m_buffersAvailable = 0;
-
- qint64 m_position = -1;
- qint64 m_duration = -1;
-
- int m_durationQueries = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERPLAYERSESSION_H
diff --git a/src/multimedia/platform/gstreamer/audio/qgstreameraudiodevice.cpp b/src/multimedia/platform/gstreamer/audio/qgstreameraudiodevice.cpp
deleted file mode 100644
index 301283013..000000000
--- a/src/multimedia/platform/gstreamer/audio/qgstreameraudiodevice.cpp
+++ /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$
-**
-****************************************************************************/
-
-#include "qgstreameraudiodevice_p.h"
-
-#include <private/qgstutils_p.h>
-#include <private/qplatformmediaintegration_p.h>
-#include <private/qgstreamermediadevices_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QGStreamerAudioDeviceInfo::QGStreamerAudioDeviceInfo(GstDevice *d, const QByteArray &device, QAudioDevice::Mode mode)
- : QAudioDevicePrivate(device, mode),
- gstDevice(d)
-{
- Q_ASSERT(gstDevice);
- gst_object_ref(gstDevice);
-
- auto *n = gst_device_get_display_name(gstDevice);
- description = QString::fromUtf8(n);
- g_free(n);
-
- QGstCaps caps = gst_device_get_caps(gstDevice);
- int size = caps.size();
- for (int i = 0; i < size; ++i) {
- auto c = caps.at(i);
- if (c.name() == "audio/x-raw") {
- auto rate = c["rate"].toIntRange();
- if (rate) {
- minimumSampleRate = rate->min;
- maximumSampleRate = rate->max;
- }
- auto channels = c["channels"].toIntRange();
- if (channels) {
- minimumChannelCount = channels->min;
- maximumChannelCount = channels->max;
- }
- supportedSampleFormats = c["format"].getSampleFormats();
- }
- }
-
- preferredFormat.setChannelCount(qBound(minimumChannelCount, 2, maximumChannelCount));
- preferredFormat.setSampleRate(qBound(minimumSampleRate, 48000, maximumSampleRate));
- QAudioFormat::SampleFormat f = QAudioFormat::Int16;
- if (!supportedSampleFormats.contains(f))
- f = supportedSampleFormats.value(0, QAudioFormat::Unknown);
- preferredFormat.setSampleFormat(f);
-}
-
-QGStreamerAudioDeviceInfo::~QGStreamerAudioDeviceInfo()
-{
- if (gstDevice)
- gst_object_unref(gstDevice);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/audio/qgstreameraudiodevice_p.h b/src/multimedia/platform/gstreamer/audio/qgstreameraudiodevice_p.h
deleted file mode 100644
index 9da109e38..000000000
--- a/src/multimedia/platform/gstreamer/audio/qgstreameraudiodevice_p.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 QGSTREAMERAUDIODEVICEINFO_H
-#define QGSTREAMERAUDIODEVICEINFO_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 <QtCore/qbytearray.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qlist.h>
-
-#include "qaudio.h"
-#include "qaudiodevice.h"
-#include <private/qaudiodevice_p.h>
-
-#include <gst/gst.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGStreamerAudioDeviceInfo : public QAudioDevicePrivate
-{
-public:
- QGStreamerAudioDeviceInfo(GstDevice *gstDevice, const QByteArray &device, QAudioDevice::Mode mode);
- ~QGStreamerAudioDeviceInfo();
-
- GstDevice *gstDevice = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
-
diff --git a/src/multimedia/platform/gstreamer/audio/qgstreameraudiosink.cpp b/src/multimedia/platform/gstreamer/audio/qgstreameraudiosink.cpp
deleted file mode 100644
index 3bf5b597b..000000000
--- a/src/multimedia/platform/gstreamer/audio/qgstreameraudiosink.cpp
+++ /dev/null
@@ -1,395 +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/qcoreapplication.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qmath.h>
-#include <private/qaudiohelpers_p.h>
-
-#include "qgstreameraudiosink_p.h"
-#include "qgstreameraudiodevice_p.h"
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <private/qgstpipeline_p.h>
-#include <private/qgstappsrc_p.h>
-
-#include <private/qgstutils_p.h>
-#include <private/qgstreamermessage_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QGStreamerAudioSink::QGStreamerAudioSink(const QAudioDevice &device)
- : m_device(device.id()),
- gstPipeline("pipeline")
-{
- gstPipeline.installMessageFilter(this);
-
- m_appSrc = new QGstAppSrc;
- connect(m_appSrc, &QGstAppSrc::bytesProcessed, this, &QGStreamerAudioSink::bytesProcessedByAppSrc);
- connect(m_appSrc, &QGstAppSrc::noMoreData, this, &QGStreamerAudioSink::needData);
- gstAppSrc = m_appSrc->element();
-
- // gstDecodeBin = gst_element_factory_make ("decodebin", "dec");
- QGstElement queue("queue", "queue");
- QGstElement conv("audioconvert", "conv");
- gstVolume = QGstElement("volume", "volume");
- if (m_volume != 1.)
- gstVolume.set("volume", m_volume);
-
- // link decodeBin to audioconvert in a callback once we get a pad from the decoder
- // g_signal_connect (gstDecodeBin, "pad-added", (GCallback) padAdded, conv);
-
- const auto *audioInfo = static_cast<const QGStreamerAudioDeviceInfo *>(device.handle());
- gstOutput = gst_device_create_element(audioInfo->gstDevice, nullptr);
-
- gstPipeline.add(gstAppSrc, queue, /*gstDecodeBin, */ conv, gstVolume, gstOutput);
- gstAppSrc.link(queue, conv, gstVolume, gstOutput);
-}
-
-QGStreamerAudioSink::~QGStreamerAudioSink()
-{
- close();
- gstPipeline = {};
- gstVolume = {};
- gstAppSrc = {};
- delete m_appSrc;
- m_appSrc = nullptr;
-}
-
-void QGStreamerAudioSink::setError(QAudio::Error error)
-{
- if (m_errorState == error)
- return;
-
- m_errorState = error;
- emit errorChanged(error);
-}
-
-QAudio::Error QGStreamerAudioSink::error() const
-{
- return m_errorState;
-}
-
-void QGStreamerAudioSink::setState(QAudio::State state)
-{
- if (m_deviceState == state)
- return;
-
- m_deviceState = state;
- emit stateChanged(state);
-}
-
-QAudio::State QGStreamerAudioSink::state() const
-{
- return m_deviceState;
-}
-
-void QGStreamerAudioSink::start(QIODevice *device)
-{
- setState(QAudio::StoppedState);
- setError(QAudio::NoError);
-
- close();
-
- if (!m_format.isValid()) {
- setError(QAudio::OpenError);
- return;
- }
-
- m_pullMode = true;
- m_audioSource = device;
-
- if (!open()) {
- m_audioSource = nullptr;
- setError(QAudio::OpenError);
- return;
- }
-
- setState(QAudio::ActiveState);
-}
-
-QIODevice *QGStreamerAudioSink::start()
-{
- setState(QAudio::StoppedState);
- setError(QAudio::NoError);
-
- close();
-
- if (!m_format.isValid()) {
- setError(QAudio::OpenError);
- return nullptr;
- }
-
- m_pullMode = false;
-
- if (!open())
- return nullptr;
-
- m_audioSource = new GStreamerOutputPrivate(this);
- m_audioSource->open(QIODevice::WriteOnly|QIODevice::Unbuffered);
-
- setState(QAudio::IdleState);
-
- return m_audioSource;
-}
-
-#if 0
-static void padAdded(GstElement *element, GstPad *pad, gpointer data)
-{
- GstElement *other = static_cast<GstElement *>(data);
-
- gchar *name = gst_pad_get_name(pad);
- qDebug("A new pad %s was created for %s\n", name, gst_element_get_name(element));
- g_free(name);
-
- qDebug("element %s will be linked to %s\n",
- gst_element_get_name(element),
- gst_element_get_name(other));
- gst_element_link(element, other);
-}
-#endif
-
-bool QGStreamerAudioSink::processBusMessage(const QGstreamerMessage &message)
-{
- auto *msg = message.rawMessage();
- switch (GST_MESSAGE_TYPE (msg)) {
- case GST_MESSAGE_EOS:
- setState(QAudio::IdleState);
- break;
- case GST_MESSAGE_ERROR: {
- setError(QAudio::IOError);
- gchar *debug;
- GError *error;
-
- gst_message_parse_error (msg, &error, &debug);
- g_free (debug);
-
- qDebug("Error: %s\n", error->message);
- g_error_free (error);
-
- break;
- }
- default:
- break;
- }
-
- return true;
-}
-
-bool QGStreamerAudioSink::open()
-{
- if (m_opened)
- return true;
-
- if (gstOutput.isNull()) {
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- return false;
- }
-
-// qDebug() << "GST caps:" << gst_caps_to_string(caps);
- m_appSrc->setup(m_audioSource, m_audioSource ? m_audioSource->pos() : 0);
- m_appSrc->setAudioFormat(m_format);
-
- /* run */
- gstPipeline.setState(GST_STATE_PLAYING);
-
- m_opened = true;
-
- m_timeStamp.restart();
- m_bytesProcessed = 0;
-
- return true;
-}
-
-void QGStreamerAudioSink::close()
-{
- if (!m_opened)
- return;
-
- if (!gstPipeline.setStateSync(GST_STATE_NULL))
- qWarning() << "failed to close the audio output stream";
-
- if (!m_pullMode && m_audioSource)
- delete m_audioSource;
- m_audioSource = nullptr;
- m_opened = false;
-}
-
-qint64 QGStreamerAudioSink::write(const char *data, qint64 len)
-{
- if (!len)
- return 0;
- if (m_errorState == QAudio::UnderrunError)
- m_errorState = QAudio::NoError;
-
- m_appSrc->write(data, len);
- return len;
-}
-
-void QGStreamerAudioSink::stop()
-{
- if (m_deviceState == QAudio::StoppedState)
- return;
-
- close();
-
- setError(QAudio::NoError);
- setState(QAudio::StoppedState);
-}
-
-qsizetype QGStreamerAudioSink::bytesFree() const
-{
- if (m_deviceState != QAudio::ActiveState && m_deviceState != QAudio::IdleState)
- return 0;
-
- return m_appSrc->canAcceptMoreData() ? 4096*4 : 0;
-}
-
-void QGStreamerAudioSink::setBufferSize(qsizetype value)
-{
- m_bufferSize = value;
- if (!gstAppSrc.isNull())
- gst_app_src_set_max_bytes(GST_APP_SRC(gstAppSrc.element()), value);
-}
-
-qsizetype QGStreamerAudioSink::bufferSize() const
-{
- return m_bufferSize;
-}
-
-qint64 QGStreamerAudioSink::processedUSecs() const
-{
- qint64 result = qint64(1000000) * m_bytesProcessed /
- m_format.bytesPerFrame() /
- m_format.sampleRate();
-
- return result;
-}
-
-void QGStreamerAudioSink::resume()
-{
- if (m_deviceState == QAudio::SuspendedState) {
- m_appSrc->resume();
- gstPipeline.setState(GST_STATE_PLAYING);
-
- setState(m_pullMode ? QAudio::ActiveState : QAudio::IdleState);
- setError(QAudio::NoError);
- }
-}
-
-void QGStreamerAudioSink::setFormat(const QAudioFormat &format)
-{
- m_format = format;
-}
-
-QAudioFormat QGStreamerAudioSink::format() const
-{
- return m_format;
-}
-
-void QGStreamerAudioSink::suspend()
-{
- if (m_deviceState == QAudio::ActiveState || m_deviceState == QAudio::IdleState) {
- setError(QAudio::NoError);
- setState(QAudio::SuspendedState);
-
- gstPipeline.setState(GST_STATE_PAUSED);
- m_appSrc->suspend();
- // ### elapsed time
- }
-}
-
-void QGStreamerAudioSink::reset()
-{
- stop();
-}
-
-GStreamerOutputPrivate::GStreamerOutputPrivate(QGStreamerAudioSink *audio)
-{
- m_audioDevice = audio;
-}
-
-qint64 GStreamerOutputPrivate::readData(char *data, qint64 len)
-{
- Q_UNUSED(data);
- Q_UNUSED(len);
-
- return 0;
-}
-
-qint64 GStreamerOutputPrivate::writeData(const char *data, qint64 len)
-{
- if (m_audioDevice->state() == QAudio::IdleState)
- m_audioDevice->setState(QAudio::ActiveState);
- return m_audioDevice->write(data, len);
-}
-
-void QGStreamerAudioSink::setVolume(qreal vol)
-{
- if (m_volume == vol)
- return;
-
- m_volume = vol;
- if (!gstVolume.isNull())
- gstVolume.set("volume", vol);
-}
-
-qreal QGStreamerAudioSink::volume() const
-{
- return m_volume;
-}
-
-void QGStreamerAudioSink::bytesProcessedByAppSrc(int bytes)
-{
- m_bytesProcessed += bytes;
-}
-
-void QGStreamerAudioSink::needData()
-{
- if (state() != QAudio::StoppedState && state() != QAudio::IdleState) {
- setState(QAudio::IdleState);
- setError(QAudio::UnderrunError);
- }
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qgstreameraudiosink_p.cpp"
diff --git a/src/multimedia/platform/gstreamer/audio/qgstreameraudiosink_p.h b/src/multimedia/platform/gstreamer/audio/qgstreameraudiosink_p.h
deleted file mode 100644
index 872f0f241..000000000
--- a/src/multimedia/platform/gstreamer/audio/qgstreameraudiosink_p.h
+++ /dev/null
@@ -1,157 +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 QAUDIOOUTPUTPULSE_H
-#define QAUDIOOUTPUTPULSE_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 <QtCore/qfile.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qelapsedtimer.h>
-#include <QtCore/qiodevice.h>
-#include <QtCore/private/qringbuffer_p.h>
-
-#include "qaudio.h"
-#include "qaudiodevice.h"
-#include <private/qaudiosystem_p.h>
-
-#include <private/qgst_p.h>
-#include <private/qgstpipeline_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstAppSrc;
-
-class QGStreamerAudioSink
- : public QPlatformAudioSink,
- public QGstreamerBusMessageFilter
-{
- friend class GStreamerOutputPrivate;
- Q_OBJECT
-
-public:
- QGStreamerAudioSink(const QAudioDevice &device);
- ~QGStreamerAudioSink();
-
- void start(QIODevice *device) override;
- QIODevice *start() override;
- void stop() override;
- void reset() override;
- void suspend() override;
- void resume() override;
- qsizetype bytesFree() const override;
- void setBufferSize(qsizetype value) override;
- qsizetype bufferSize() const override;
- qint64 processedUSecs() const override;
- QAudio::Error error() const override;
- QAudio::State state() const override;
- void setFormat(const QAudioFormat &format) override;
- QAudioFormat format() const override;
-
- void setVolume(qreal volume) override;
- qreal volume() const override;
-
-private Q_SLOTS:
- void bytesProcessedByAppSrc(int bytes);
- void needData();
-
-private:
- void setState(QAudio::State state);
- void setError(QAudio::Error error);
-
- bool processBusMessage(const QGstreamerMessage &message) override;
-
- bool open();
- void close();
- qint64 write(const char *data, qint64 len);
-
-private:
- QByteArray m_device;
- QAudioFormat m_format;
- QAudio::Error m_errorState = QAudio::NoError;
- QAudio::State m_deviceState = QAudio::StoppedState;
- bool m_pullMode = true;
- bool m_opened = false;
- QIODevice *m_audioSource = nullptr;
- QTimer m_periodTimer;
- int m_bufferSize = 0;
- qint64 m_bytesProcessed = 0;
- QElapsedTimer m_timeStamp;
- qreal m_volume = 1.;
- QByteArray pushData;
-
- QGstPipeline gstPipeline;
- QGstElement gstOutput;
- QGstElement gstVolume;
- QGstElement gstAppSrc;
- QGstAppSrc *m_appSrc = nullptr;
-};
-
-class GStreamerOutputPrivate : public QIODevice
-{
- friend class QGStreamerAudioSink;
- Q_OBJECT
-
-public:
- GStreamerOutputPrivate(QGStreamerAudioSink *audio);
- virtual ~GStreamerOutputPrivate() {}
-
-protected:
- qint64 readData(char *data, qint64 len) override;
- qint64 writeData(const char *data, qint64 len) override;
-
-private:
- QGStreamerAudioSink *m_audioDevice;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/audio/qgstreameraudiosource.cpp b/src/multimedia/platform/gstreamer/audio/qgstreameraudiosource.cpp
deleted file mode 100644
index ffa402627..000000000
--- a/src/multimedia/platform/gstreamer/audio/qgstreameraudiosource.cpp
+++ /dev/null
@@ -1,407 +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/qcoreapplication.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qmath.h>
-#include <private/qaudiohelpers_p.h>
-
-#include "qgstreameraudiosource_p.h"
-#include "qgstreameraudiodevice_p.h"
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <gst/gst.h>
-Q_DECLARE_OPAQUE_POINTER(GstSample *);
-Q_DECLARE_METATYPE(GstSample *);
-
-QT_BEGIN_NAMESPACE
-
-
-QGStreamerAudioSource::QGStreamerAudioSource(const QAudioDevice &device)
- : m_info(device),
- m_device(device.id())
-{
- qRegisterMetaType<GstSample *>();
-}
-
-QGStreamerAudioSource::~QGStreamerAudioSource()
-{
- close();
-}
-
-void QGStreamerAudioSource::setError(QAudio::Error error)
-{
- if (m_errorState == error)
- return;
-
- m_errorState = error;
- emit errorChanged(error);
-}
-
-QAudio::Error QGStreamerAudioSource::error() const
-{
- return m_errorState;
-}
-
-void QGStreamerAudioSource::setState(QAudio::State state)
-{
- if (m_deviceState == state)
- return;
-
- m_deviceState = state;
- emit stateChanged(state);
-}
-
-QAudio::State QGStreamerAudioSource::state() const
-{
- return m_deviceState;
-}
-
-void QGStreamerAudioSource::setFormat(const QAudioFormat &format)
-{
- if (m_deviceState == QAudio::StoppedState)
- m_format = format;
-}
-
-QAudioFormat QGStreamerAudioSource::format() const
-{
- return m_format;
-}
-
-void QGStreamerAudioSource::start(QIODevice *device)
-{
- setState(QAudio::StoppedState);
- setError(QAudio::NoError);
-
- close();
-
- if (!open())
- return;
-
- m_pullMode = true;
- m_audioSink = device;
-
- setState(QAudio::ActiveState);
-}
-
-QIODevice *QGStreamerAudioSource::start()
-{
- setState(QAudio::StoppedState);
- setError(QAudio::NoError);
-
- close();
-
- if (!open())
- return nullptr;
-
- m_pullMode = false;
- m_audioSink = new GStreamerInputPrivate(this);
- m_audioSink->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
-
- setState(QAudio::IdleState);
-
- return m_audioSink;
-}
-
-void QGStreamerAudioSource::stop()
-{
- if (m_deviceState == QAudio::StoppedState)
- return;
-
- close();
-
- setError(QAudio::NoError);
- setState(QAudio::StoppedState);
-}
-
-bool QGStreamerAudioSource::open()
-{
- if (m_opened)
- return true;
-
- const auto *deviceInfo = static_cast<const QGStreamerAudioDeviceInfo *>(m_info.handle());
- if (!deviceInfo->gstDevice) {
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- return false;
- }
-
- gstInput = QGstElement(gst_device_create_element(deviceInfo->gstDevice, nullptr));
- if (gstInput.isNull()) {
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- return false;
- }
-
- auto gstCaps = QGstUtils::capsForAudioFormat(m_format);
-
- if (gstCaps.isNull()) {
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- return false;
- }
-
-
-#ifdef DEBUG_AUDIO
- qDebug() << "Opening input" << QTime::currentTime();
- qDebug() << "Caps: " << gst_caps_to_string(gstCaps);
-#endif
-
- gstPipeline = QGstPipeline("pipeline");
-
- auto *gstBus = gst_pipeline_get_bus(gstPipeline.pipeline());
- gst_bus_add_watch(gstBus, &QGStreamerAudioSource::busMessage, this);
- gst_object_unref (gstBus);
-
- gstAppSink = createAppSink();
- gstAppSink.set("caps", gstCaps);
-
- QGstElement conv("audioconvert", "conv");
- gstVolume = QGstElement("volume", "volume");
- if (m_volume != 1.)
- gstVolume.set("volume", m_volume);
-
- gstPipeline.add(gstInput, gstVolume, conv, gstAppSink);
- gstInput.link(gstVolume, conv, gstAppSink);
-
- gstPipeline.setState(GST_STATE_PLAYING);
-
- m_opened = true;
-
- m_timeStamp.restart();
- m_elapsedTimeOffset = 0;
- m_bytesWritten = 0;
-
- return true;
-}
-
-void QGStreamerAudioSource::close()
-{
- if (!m_opened)
- return;
-
- gstPipeline.setState(GST_STATE_NULL);
- gstPipeline = {};
- gstVolume = {};
- gstAppSink = {};
- gstInput = {};
-
- if (!m_pullMode && m_audioSink) {
- delete m_audioSink;
- }
- m_audioSink = nullptr;
- m_opened = false;
-}
-
-gboolean QGStreamerAudioSource::busMessage(GstBus *, GstMessage *msg, gpointer user_data)
-{
- QGStreamerAudioSource *input = static_cast<QGStreamerAudioSource *>(user_data);
- switch (GST_MESSAGE_TYPE (msg)) {
- case GST_MESSAGE_EOS:
- input->stop();
- break;
- case GST_MESSAGE_ERROR: {
- input->setError(QAudio::IOError);
- gchar *debug;
- GError *error;
-
- gst_message_parse_error (msg, &error, &debug);
- g_free (debug);
-
- qDebug("Error: %s\n", error->message);
- g_error_free (error);
-
- break;
- }
- default:
- break;
- }
- return false;
-}
-
-qsizetype QGStreamerAudioSource::bytesReady() const
-{
- return m_buffer.size();
-}
-
-void QGStreamerAudioSource::resume()
-{
- if (m_deviceState == QAudio::SuspendedState || m_deviceState == QAudio::IdleState) {
- gstPipeline.setState(GST_STATE_PLAYING);
- setState(QAudio::ActiveState);
- setError(QAudio::NoError);
- }
-}
-
-void QGStreamerAudioSource::setVolume(qreal vol)
-{
- if (m_volume == vol)
- return;
-
- m_volume = vol;
- if (!gstVolume.isNull())
- gstVolume.set("volume", vol);
-}
-
-qreal QGStreamerAudioSource::volume() const
-{
- return m_volume;
-}
-
-void QGStreamerAudioSource::setBufferSize(qsizetype value)
-{
- m_bufferSize = value;
-}
-
-qsizetype QGStreamerAudioSource::bufferSize() const
-{
- return m_bufferSize;
-}
-
-qint64 QGStreamerAudioSource::processedUSecs() const
-{
- return m_format.durationForBytes(m_bytesWritten);
-}
-
-void QGStreamerAudioSource::suspend()
-{
- if (m_deviceState == QAudio::ActiveState) {
- setError(QAudio::NoError);
- setState(QAudio::SuspendedState);
-
- gstPipeline.setState(GST_STATE_PAUSED);
- }
-}
-
-void QGStreamerAudioSource::reset()
-{
- stop();
- m_buffer.clear();
-}
-
-//#define MAX_BUFFERS_IN_QUEUE 4
-
-QGstElement QGStreamerAudioSource::createAppSink()
-{
- QGstElement sink("appsink", "appsink");
- GstAppSink *appSink = reinterpret_cast<GstAppSink *>(sink.element());
-
- GstAppSinkCallbacks callbacks;
- memset(&callbacks, 0, sizeof(callbacks));
- callbacks.eos = &eos;
- callbacks.new_sample = &new_sample;
- gst_app_sink_set_callbacks(appSink, &callbacks, this, nullptr);
-// gst_app_sink_set_max_buffers(appSink, MAX_BUFFERS_IN_QUEUE);
- gst_base_sink_set_sync(GST_BASE_SINK(appSink), FALSE);
-
- return sink;
-}
-
-void QGStreamerAudioSource::newDataAvailable(GstSample *sample)
-{
- if (m_audioSink) {
- GstBuffer *buffer = gst_sample_get_buffer(sample);
- GstMapInfo mapInfo;
- gst_buffer_map(buffer, &mapInfo, GST_MAP_READ);
- const char *bufferData = (const char*)mapInfo.data;
- gsize bufferSize = mapInfo.size;
-
- if (!m_pullMode) {
- // need to store that data in the QBuffer
- m_buffer.append(bufferData, bufferSize);
- m_audioSink->readyRead();
- } else {
- m_bytesWritten += bufferSize;
- m_audioSink->write(bufferData, bufferSize);
- }
-
- gst_buffer_unmap(buffer, &mapInfo);
- }
-
- gst_sample_unref(sample);
-}
-
-GstFlowReturn QGStreamerAudioSource::new_sample(GstAppSink *sink, gpointer user_data)
-{
- // "Note that the preroll buffer will also be returned as the first buffer when calling gst_app_sink_pull_buffer()."
- QGStreamerAudioSource *control = static_cast<QGStreamerAudioSource*>(user_data);
-
- GstSample *sample = gst_app_sink_pull_sample(sink);
- QMetaObject::invokeMethod(control, "newDataAvailable", Qt::AutoConnection, Q_ARG(GstSample *, sample));
-
- return GST_FLOW_OK;
-}
-
-void QGStreamerAudioSource::eos(GstAppSink *, gpointer user_data)
-{
- QGStreamerAudioSource *control = static_cast<QGStreamerAudioSource*>(user_data);
- control->setState(QAudio::StoppedState);
-}
-
-GStreamerInputPrivate::GStreamerInputPrivate(QGStreamerAudioSource *audio)
-{
- m_audioDevice = qobject_cast<QGStreamerAudioSource*>(audio);
-}
-
-qint64 GStreamerInputPrivate::readData(char *data, qint64 len)
-{
- if (m_audioDevice->state() == QAudio::IdleState)
- m_audioDevice->setState(QAudio::ActiveState);
- qint64 bytes = m_audioDevice->m_buffer.read(data, len);
- m_audioDevice->m_bytesWritten += bytes;
- return bytes;
-}
-
-qint64 GStreamerInputPrivate::writeData(const char *data, qint64 len)
-{
- Q_UNUSED(data);
- Q_UNUSED(len);
- return 0;
-}
-
-qint64 GStreamerInputPrivate::bytesAvailable() const
-{
- return m_audioDevice->m_buffer.size();
-}
-
-
-QT_END_NAMESPACE
-
-#include "moc_qgstreameraudiosource_p.cpp"
diff --git a/src/multimedia/platform/gstreamer/audio/qgstreameraudiosource_p.h b/src/multimedia/platform/gstreamer/audio/qgstreameraudiosource_p.h
deleted file mode 100644
index 67e11c1c5..000000000
--- a/src/multimedia/platform/gstreamer/audio/qgstreameraudiosource_p.h
+++ /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$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#ifndef QAUDIOINPUTPULSE_H
-#define QAUDIOINPUTPULSE_H
-
-#include <QtCore/qfile.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qelapsedtimer.h>
-#include <QtCore/qiodevice.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qatomic.h>
-#include <QtCore/private/qringbuffer_p.h>
-
-#include "qaudio.h"
-#include "qaudiodevice.h"
-#include <private/qaudiosystem_p.h>
-
-#include <private/qgstutils_p.h>
-#include <private/qgstpipeline_p.h>
-#include <gst/app/gstappsink.h>
-
-QT_BEGIN_NAMESPACE
-
-class GStreamerInputPrivate;
-
-class QGStreamerAudioSource
- : public QPlatformAudioSource
-{
- Q_OBJECT
- friend class GStreamerInputPrivate;
-public:
- QGStreamerAudioSource(const QAudioDevice &device);
- ~QGStreamerAudioSource();
-
- void start(QIODevice *device) override;
- QIODevice *start() override;
- void stop() override;
- void reset() override;
- void suspend() override;
- void resume() override;
- qsizetype bytesReady() const override;
- void setBufferSize(qsizetype value) override;
- qsizetype bufferSize() const override;
- qint64 processedUSecs() const override;
- QAudio::Error error() const override;
- QAudio::State state() const override;
- void setFormat(const QAudioFormat &format) override;
- QAudioFormat format() const override;
-
- void setVolume(qreal volume) override;
- qreal volume() const override;
-
-private Q_SLOTS:
- void newDataAvailable(GstSample *sample);
-
-private:
- void setState(QAudio::State state);
- void setError(QAudio::Error error);
-
- QGstElement createAppSink();
- static GstFlowReturn new_sample(GstAppSink *, gpointer user_data);
- static void eos(GstAppSink *, gpointer user_data);
-
- bool open();
- void close();
-
- static gboolean busMessage(GstBus *bus, GstMessage *msg, gpointer user_data);
-
- QAudioDevice m_info;
- qint64 m_bytesWritten = 0;
- QIODevice *m_audioSink = nullptr;
- QAudioFormat m_format;
- QAudio::Error m_errorState = QAudio::NoError;
- QAudio::State m_deviceState = QAudio::StoppedState;
- qreal m_volume = 1.;
-
- QRingBuffer m_buffer;
- QAtomicInteger<bool> m_pullMode = true;
- bool m_opened = false;
- int m_bufferSize = 0;
- qint64 m_elapsedTimeOffset = 0;
- QElapsedTimer m_timeStamp;
- QByteArray m_device;
- QByteArray m_tempBuffer;
-
- QGstElement gstInput;
- QGstPipeline gstPipeline;
- QGstElement gstVolume;
- QGstElement gstAppSink;
-};
-
-class GStreamerInputPrivate : public QIODevice
-{
- Q_OBJECT
-public:
- GStreamerInputPrivate(QGStreamerAudioSource *audio);
- ~GStreamerInputPrivate() {};
-
- qint64 readData(char *data, qint64 len) override;
- qint64 writeData(const char *data, qint64 len) override;
- qint64 bytesAvailable() const override;
- bool isSequential() const override { return true; }
-private:
- QGStreamerAudioSource *m_audioDevice;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/common/qgst_p.h b/src/multimedia/platform/gstreamer/common/qgst_p.h
deleted file mode 100644
index 0130ca00f..000000000
--- a/src/multimedia/platform/gstreamer/common/qgst_p.h
+++ /dev/null
@@ -1,620 +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 QGST_P_H
-#define QGST_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qtmultimediaglobal_p.h>
-
-#include <QSemaphore>
-#include <QtCore/qlist.h>
-
-#include <QtMultimedia/qaudioformat.h>
-#include <QtMultimedia/qvideoframe.h>
-
-#include <gst/gst.h>
-#include <gst/video/video-info.h>
-
-#include <functional>
-
-#if QT_CONFIG(gstreamer_photography)
-#define GST_USE_UNSTABLE_API
-#include <gst/interfaces/photography.h>
-#undef GST_USE_UNSTABLE_API
-#endif
-#ifndef QT_NO_DEBUG
-#include <qdebug.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QSize;
-class QGstStructure;
-class QGstCaps;
-class QGstPipelinePrivate;
-class QCameraFormat;
-
-template <typename T> struct QGRange
-{
- T min;
- T max;
-};
-
-class QGString
-{
- char *str;
-public:
- QGString(char *string) : str(string) {}
- ~QGString() { g_free(str); }
- operator QByteArray() { return QByteArray(str); }
- operator const char *() { return str; }
-};
-
-class QGValue
-{
-public:
- QGValue(const GValue *v) : value(v) {}
- const GValue *value;
-
- bool isNull() const { return !value; }
-
- std::optional<bool> toBool() const
- {
- if (!G_VALUE_HOLDS_BOOLEAN(value))
- return std::nullopt;
- return g_value_get_boolean(value);
- }
- std::optional<int> toInt() const
- {
- if (!G_VALUE_HOLDS_INT(value))
- return std::nullopt;
- return g_value_get_int(value);
- }
- std::optional<int> toInt64() const
- {
- if (!G_VALUE_HOLDS_INT64(value))
- return std::nullopt;
- return g_value_get_int64(value);
- }
- template<typename T>
- T *getPointer() const
- {
- return value ? static_cast<T *>(g_value_get_pointer(value)) : nullptr;
- }
-
- const char *toString() const
- {
- return value ? g_value_get_string(value) : nullptr;
- }
- std::optional<float> getFraction() const
- {
- if (!GST_VALUE_HOLDS_FRACTION(value))
- return std::nullopt;
- return (float)gst_value_get_fraction_numerator(value)/(float)gst_value_get_fraction_denominator(value);
- }
-
- std::optional<QGRange<float>> getFractionRange() const
- {
- if (!GST_VALUE_HOLDS_FRACTION_RANGE(value))
- return std::nullopt;
- QGValue min = gst_value_get_fraction_range_min(value);
- QGValue max = gst_value_get_fraction_range_max(value);
- return QGRange<float>{ *min.getFraction(), *max.getFraction() };
- }
-
- std::optional<QGRange<int>> toIntRange() const
- {
- if (!GST_VALUE_HOLDS_INT_RANGE(value))
- return std::nullopt;
- return QGRange<int>{ gst_value_get_int_range_min(value), gst_value_get_int_range_max(value) };
- }
-
- inline QGstStructure toStructure() const;
- inline QGstCaps toCaps() const;
-
- inline bool isList() const { return value && GST_VALUE_HOLDS_LIST(value); }
- inline int listSize() const { return gst_value_list_get_size(value); }
- inline QGValue at(int index) const { return gst_value_list_get_value(value, index); }
-
- Q_MULTIMEDIA_EXPORT QList<QAudioFormat::SampleFormat> getSampleFormats() const;
-};
-
-class QGstStructure {
-public:
- const GstStructure *structure = nullptr;
- QGstStructure() = default;
- QGstStructure(const GstStructure *s) : structure(s) {}
- void free() { if (structure) gst_structure_free(const_cast<GstStructure *>(structure)); structure = nullptr; }
-
- bool isNull() const { return !structure; }
-
- QByteArrayView name() const { return gst_structure_get_name(structure); }
-
- QGValue operator[](const char *name) const { return gst_structure_get_value(structure, name); }
-
- GstMessage *getMessage() const
- {
- GstMessage *msg;
- gst_structure_get(structure, "message", GST_TYPE_MESSAGE, &msg, nullptr);
- return msg;
- }
-
- Q_MULTIMEDIA_EXPORT QSize resolution() const;
- Q_MULTIMEDIA_EXPORT QVideoFrameFormat::PixelFormat pixelFormat() const;
- Q_MULTIMEDIA_EXPORT QGRange<float> frameRateRange() const;
-
- QByteArray toString() const
- {
- char *s = gst_structure_to_string(structure);
- QByteArray str(s);
- g_free(s);
- return str;
- }
- QGstStructure copy() const { return gst_structure_copy(structure); }
-};
-
-class QGstCaps {
- const GstCaps *caps = nullptr;
-public:
- enum MemoryFormat {
- CpuMemory,
- GLTexture,
- DMABuf
- };
-
- QGstCaps() = default;
- QGstCaps(const GstCaps *c) : caps(c) {}
-
- bool isNull() const { return !caps; }
-
- int size() const { return gst_caps_get_size(caps); }
- QGstStructure at(int index) { return gst_caps_get_structure(caps, index); }
- const GstCaps *get() const { return caps; }
- QByteArray toString() const
- {
- gchar *c = gst_caps_to_string(caps);
- QByteArray b(c);
- g_free(c);
- return b;
- }
- MemoryFormat memoryFormat() const {
- auto *features = gst_caps_get_features(caps, 0);
- if (gst_caps_features_contains(features, "memory:GLMemory"))
- return GLTexture;
- else if (gst_caps_features_contains(features, "memory:DMABuf"))
- return DMABuf;
- return CpuMemory;
- }
- QVideoFrameFormat formatForCaps(GstVideoInfo *info) const;
-};
-
-class QGstMutableCaps : public QGstCaps {
- GstCaps *caps = nullptr;
-public:
- enum RefMode { HasRef, NeedsRef };
- QGstMutableCaps() = default;
- QGstMutableCaps(GstCaps *c, RefMode mode = HasRef)
- : QGstCaps(c), caps(c)
- {
- Q_ASSERT(QGstCaps::get() == caps);
- if (mode == NeedsRef)
- gst_caps_ref(caps);
- }
- QGstMutableCaps(const QGstMutableCaps &other)
- : QGstCaps(other), caps(other.caps)
- {
- Q_ASSERT(QGstCaps::get() == caps);
- if (caps)
- gst_caps_ref(caps);
- }
- QGstMutableCaps &operator=(const QGstMutableCaps &other)
- {
- QGstCaps::operator=(other);
- if (other.caps)
- gst_caps_ref(other.caps);
- if (caps)
- gst_caps_unref(caps);
- caps = other.caps;
- Q_ASSERT(QGstCaps::get() == caps);
- return *this;
- }
- ~QGstMutableCaps() {
- Q_ASSERT(QGstCaps::get() == caps);
- if (caps)
- gst_caps_unref(caps);
- }
-
- void create() {
- caps = gst_caps_new_empty();
- QGstCaps::operator=(QGstCaps(caps));
- }
-
- void addPixelFormats(const QList<QVideoFrameFormat::PixelFormat> &formats, const char *modifier = nullptr);
- static QGstMutableCaps fromCameraFormat(const QCameraFormat &format);
-
- GstCaps *get() const { return caps; }
-};
-
-class QGstObject
-{
-protected:
- GstObject *m_object = nullptr;
-public:
- enum RefMode { HasRef, NeedsRef };
-
- QGstObject() = default;
- QGstObject(GstObject *o, RefMode mode = HasRef)
- : m_object(o)
- {
- if (o && mode == NeedsRef)
- // Use ref_sink to remove any floating references
- gst_object_ref_sink(m_object);
- }
- QGstObject(const QGstObject &other)
- : m_object(other.m_object)
- {
- if (m_object)
- gst_object_ref(m_object);
- }
- QGstObject &operator=(const QGstObject &other)
- {
- if (other.m_object)
- gst_object_ref(other.m_object);
- if (m_object)
- gst_object_unref(m_object);
- m_object = other.m_object;
- return *this;
- }
- ~QGstObject() {
- if (m_object)
- gst_object_unref(m_object);
- }
-
- friend bool operator==(const QGstObject &a, const QGstObject &b)
- { return a.m_object == b.m_object; }
- friend bool operator!=(const QGstObject &a, const QGstObject &b)
- { return a.m_object != b.m_object; }
-
- bool isNull() const { return !m_object; }
-
- void set(const char *property, const char *str) { g_object_set(m_object, property, str, nullptr); }
- void set(const char *property, bool b) { g_object_set(m_object, property, gboolean(b), nullptr); }
- void set(const char *property, uint i) { g_object_set(m_object, property, guint(i), nullptr); }
- void set(const char *property, int i) { g_object_set(m_object, property, gint(i), nullptr); }
- void set(const char *property, qint64 i) { g_object_set(m_object, property, gint64(i), nullptr); }
- void set(const char *property, quint64 i) { g_object_set(m_object, property, guint64(i), nullptr); }
- void set(const char *property, double d) { g_object_set(m_object, property, gdouble(d), nullptr); }
- void set(const char *property, const QGstObject &o) { g_object_set(m_object, property, o.object(), nullptr); }
- void set(const char *property, const QGstMutableCaps &c) { g_object_set(m_object, property, c.get(), nullptr); }
-
- QGString getString(const char *property) const
- { char *s = nullptr; g_object_get(m_object, property, &s, nullptr); return s; }
- QGstStructure getStructure(const char *property) const
- { GstStructure *s = nullptr; g_object_get(m_object, property, &s, nullptr); return QGstStructure(s); }
- bool getBool(const char *property) const { gboolean b = false; g_object_get(m_object, property, &b, nullptr); return b; }
- uint getUInt(const char *property) const { guint i = 0; g_object_get(m_object, property, &i, nullptr); return i; }
- int getInt(const char *property) const { gint i = 0; g_object_get(m_object, property, &i, nullptr); return i; }
- quint64 getUInt64(const char *property) const { guint64 i = 0; g_object_get(m_object, property, &i, nullptr); return i; }
- qint64 getInt64(const char *property) const { gint64 i = 0; g_object_get(m_object, property, &i, nullptr); return i; }
- float getFloat(const char *property) const { gfloat d = 0; g_object_get(m_object, property, &d, nullptr); return d; }
- double getDouble(const char *property) const { gdouble d = 0; g_object_get(m_object, property, &d, nullptr); return d; }
- QGstObject getObject(const char *property) const { GstObject *o = nullptr; g_object_get(m_object, property, &o, nullptr); return o; }
-
- void connect(const char *name, GCallback callback, gpointer userData) { g_signal_connect(m_object, name, callback, userData); }
-
- GstObject *object() const { return m_object; }
- const char *name() const { return m_object ? GST_OBJECT_NAME(m_object) : "(null)"; }
-};
-
-class QGstElement;
-
-class QGstPad : public QGstObject
-{
-public:
- QGstPad() = default;
- QGstPad(const QGstObject &o)
- : QGstPad(GST_PAD(o.object()), NeedsRef)
- {}
- QGstPad(GstPad *pad, RefMode mode = NeedsRef)
- : QGstObject(&pad->object, mode)
- {}
-
- QGstMutableCaps currentCaps() const
- { return QGstMutableCaps(gst_pad_get_current_caps(pad())); }
- QGstCaps queryCaps() const
- { return QGstCaps(gst_pad_query_caps(pad(), nullptr)); }
-
- bool isLinked() const { return gst_pad_is_linked(pad()); }
- bool link(const QGstPad &sink) const { return gst_pad_link(pad(), sink.pad()) == GST_PAD_LINK_OK; }
- bool unlink(const QGstPad &sink) const { return gst_pad_unlink(pad(), sink.pad()); }
- bool unlinkPeer() const { return unlink(peer()); }
- QGstPad peer() const { return QGstPad(gst_pad_get_peer(pad()), HasRef); }
- inline QGstElement parent() const;
-
- GstPad *pad() const { return GST_PAD_CAST(object()); }
-
- GstEvent *stickyEvent(GstEventType type) { return gst_pad_get_sticky_event(pad(), type, 0); }
- bool sendEvent(GstEvent *event) { return gst_pad_send_event (pad(), event); }
-
- template<auto Member, typename T>
- void addProbe(T *instance, GstPadProbeType type) {
- struct Impl {
- static GstPadProbeReturn callback(GstPad *pad, GstPadProbeInfo *info, gpointer userData) {
- return (static_cast<T *>(userData)->*Member)(QGstPad(pad, NeedsRef), info);
- };
- };
-
- gst_pad_add_probe (pad(), type, Impl::callback, instance, nullptr);
- }
-
- void doInIdleProbe(std::function<void()> work) {
- struct CallbackData {
- QSemaphore waitDone;
- std::function<void()> work;
- } cd;
- cd.work = work;
-
- auto callback= [](GstPad *, GstPadProbeInfo *, gpointer p) {
- auto cd = reinterpret_cast<CallbackData*>(p);
- cd->work();
- cd->waitDone.release();
- return GST_PAD_PROBE_REMOVE;
- };
-
- gst_pad_add_probe(pad(), GST_PAD_PROBE_TYPE_IDLE, callback, &cd, nullptr);
- cd.waitDone.acquire();
- }
-
- template<auto Member, typename T>
- void addEosProbe(T *instance) {
- struct Impl {
- static GstPadProbeReturn callback(GstPad */*pad*/, GstPadProbeInfo *info, gpointer userData) {
- if (GST_EVENT_TYPE(GST_PAD_PROBE_INFO_DATA(info)) != GST_EVENT_EOS)
- return GST_PAD_PROBE_PASS;
- (static_cast<T *>(userData)->*Member)();
- return GST_PAD_PROBE_REMOVE;
- };
- };
-
- gst_pad_add_probe (pad(), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, Impl::callback, instance, nullptr);
- }
-};
-
-class QGstClock : public QGstObject
-{
-public:
- QGstClock() = default;
- QGstClock(const QGstObject &o)
- : QGstClock(GST_CLOCK(o.object()))
- {}
- QGstClock(GstClock *clock, RefMode mode = NeedsRef)
- : QGstObject(&clock->object, mode)
- {}
-
- GstClock *clock() const { return GST_CLOCK_CAST(object()); }
-
- GstClockTime time() const { return gst_clock_get_time(clock()); }
-};
-
-class QGstElement : public QGstObject
-{
-public:
- QGstElement() = default;
- QGstElement(const QGstObject &o)
- : QGstElement(GST_ELEMENT(o.object()), NeedsRef)
- {}
- QGstElement(GstElement *element, RefMode mode = NeedsRef)
- : QGstObject(&element->object, mode)
- {}
-
- QGstElement(const char *factory, const char *name = nullptr)
- : QGstElement(gst_element_factory_make(factory, name), NeedsRef)
- {
- }
-
- bool linkFiltered(const QGstElement &next, const QGstMutableCaps &caps)
- { return gst_element_link_filtered(element(), next.element(), caps.get()); }
- bool link(const QGstElement &next)
- { return gst_element_link(element(), next.element()); }
- bool link(const QGstElement &n1, const QGstElement &n2)
- { return gst_element_link_many(element(), n1.element(), n2.element(), nullptr); }
- bool link(const QGstElement &n1, const QGstElement &n2, const QGstElement &n3)
- { return gst_element_link_many(element(), n1.element(), n2.element(), n3.element(), nullptr); }
- bool link(const QGstElement &n1, const QGstElement &n2, const QGstElement &n3, const QGstElement &n4)
- { return gst_element_link_many(element(), n1.element(), n2.element(), n3.element(), n4.element(), nullptr); }
- bool link(const QGstElement &n1, const QGstElement &n2, const QGstElement &n3, const QGstElement &n4, const QGstElement &n5)
- { return gst_element_link_many(element(), n1.element(), n2.element(), n3.element(), n4.element(), n5.element(), nullptr); }
-
- void unlink(const QGstElement &next)
- { gst_element_unlink(element(), next.element()); }
-
- QGstPad staticPad(const char *name) const { return QGstPad(gst_element_get_static_pad(element(), name), HasRef); }
- QGstPad src() const { return staticPad("src"); }
- QGstPad sink() const { return staticPad("sink"); }
- QGstPad getRequestPad(const char *name) const { return QGstPad(gst_element_get_request_pad(element(), name), HasRef); }
- void releaseRequestPad(const QGstPad &pad) const { return gst_element_release_request_pad(element(), pad.pad()); }
-
- GstState state() const
- {
- GstState state;
- gst_element_get_state(element(), &state, nullptr, 0);
- return state;
- }
- GstStateChangeReturn setState(GstState state) { return gst_element_set_state(element(), state); }
- bool setStateSync(GstState state)
- {
- auto change = gst_element_set_state(element(), state);
- if (change == GST_STATE_CHANGE_ASYNC) {
- change = gst_element_get_state(element(), nullptr, &state, 1000*1e6 /*nano seconds*/);
- }
-#ifndef QT_NO_DEBUG
- if (change != GST_STATE_CHANGE_SUCCESS && change != GST_STATE_CHANGE_NO_PREROLL)
- qWarning() << "Could not change state of" << name() << "to" << state << change;
-#endif
- return change == GST_STATE_CHANGE_SUCCESS;
- }
- bool syncStateWithParent() { return gst_element_sync_state_with_parent(element()) == TRUE; }
- bool finishStateChange()
- {
- auto change = gst_element_get_state(element(), nullptr, nullptr, 1000*1e6 /*nano seconds*/);
-#ifndef QT_NO_DEBUG
- if (change != GST_STATE_CHANGE_SUCCESS && change != GST_STATE_CHANGE_NO_PREROLL)
- qWarning() << "Could finish change state of" << name();
-#endif
- return change == GST_STATE_CHANGE_SUCCESS;
- }
-
- void lockState(bool locked) { gst_element_set_locked_state(element(), locked); }
- bool isStateLocked() const { return gst_element_is_locked_state(element()); }
-
- void sendEvent(GstEvent *event) const { gst_element_send_event(element(), event); }
- void sendEos() const { sendEvent(gst_event_new_eos()); }
-
- template<auto Member, typename T>
- void onPadAdded(T *instance) {
- struct Impl {
- static void callback(GstElement *e, GstPad *pad, gpointer userData) {
- (static_cast<T *>(userData)->*Member)(QGstElement(e), QGstPad(pad, NeedsRef));
- };
- };
-
- connect("pad-added", G_CALLBACK(Impl::callback), instance);
- }
- template<auto Member, typename T>
- void onPadRemoved(T *instance) {
- struct Impl {
- static void callback(GstElement *e, GstPad *pad, gpointer userData) {
- (static_cast<T *>(userData)->*Member)(QGstElement(e), QGstPad(pad, NeedsRef));
- };
- };
-
- connect("pad-removed", G_CALLBACK(Impl::callback), instance);
- }
- template<auto Member, typename T>
- void onNoMorePads(T *instance) {
- struct Impl {
- static void callback(GstElement *e, gpointer userData) {
- (static_cast<T *>(userData)->*Member)(QGstElement(e));
- };
- };
-
- connect("no-more-pads", G_CALLBACK(Impl::callback), instance);
- }
-
- GstClockTime baseTime() const { return gst_element_get_base_time(element()); }
- void setBaseTime(GstClockTime time) const { gst_element_set_base_time(element(), time); }
-
- GstElement *element() const { return GST_ELEMENT_CAST(m_object); }
-};
-
-inline QGstElement QGstPad::parent() const
-{
- return QGstElement(gst_pad_get_parent_element(pad()), HasRef);
-}
-
-class QGstBin : public QGstElement
-{
-public:
- QGstBin() = default;
- QGstBin(const QGstObject &o)
- : QGstBin(GST_BIN(o.object()), NeedsRef)
- {}
- QGstBin(const char *name)
- : QGstElement(gst_bin_new(name), NeedsRef)
- {
- }
- QGstBin(GstBin *bin, RefMode mode = NeedsRef)
- : QGstElement(&bin->element, mode)
- {}
-
- void add(const QGstElement &element)
- { gst_bin_add(bin(), element.element()); }
- void add(const QGstElement &e1, const QGstElement &e2)
- { gst_bin_add_many(bin(), e1.element(), e2.element(), nullptr); }
- void add(const QGstElement &e1, const QGstElement &e2, const QGstElement &e3)
- { gst_bin_add_many(bin(), e1.element(), e2.element(), e3.element(), nullptr); }
- void add(const QGstElement &e1, const QGstElement &e2, const QGstElement &e3, const QGstElement &e4)
- { gst_bin_add_many(bin(), e1.element(), e2.element(), e3.element(), e4.element(), nullptr); }
- void add(const QGstElement &e1, const QGstElement &e2, const QGstElement &e3, const QGstElement &e4, const QGstElement &e5)
- { gst_bin_add_many(bin(), e1.element(), e2.element(), e3.element(), e4.element(), e5.element(), nullptr); }
- void add(const QGstElement &e1, const QGstElement &e2, const QGstElement &e3, const QGstElement &e4, const QGstElement &e5, const QGstElement &e6)
- { gst_bin_add_many(bin(), e1.element(), e2.element(), e3.element(), e4.element(), e5.element(), e6.element(), nullptr); }
- void remove(const QGstElement &element)
- { gst_bin_remove(bin(), element.element()); }
-
- GstBin *bin() const { return GST_BIN_CAST(m_object); }
-
- void addGhostPad(const QGstElement &child, const char *name)
- {
- addGhostPad(name, child.staticPad(name));
- }
- void addGhostPad(const char *name, const QGstPad &pad)
- {
- gst_element_add_pad(element(), gst_ghost_pad_new(name, pad.pad()));
- }
-};
-
-inline QGstStructure QGValue::toStructure() const
-{
- if (!value || !GST_VALUE_HOLDS_STRUCTURE(value))
- return QGstStructure();
- return QGstStructure(gst_value_get_structure(value));
-}
-
-inline QGstCaps QGValue::toCaps() const
-{
- if (!value || !GST_VALUE_HOLDS_CAPS(value))
- return QGstCaps();
- return QGstCaps(gst_value_get_caps(value));
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/common/qgstappsrc.cpp b/src/multimedia/platform/gstreamer/common/qgstappsrc.cpp
deleted file mode 100644
index 992e3d5a9..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstappsrc.cpp
+++ /dev/null
@@ -1,308 +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 <QDebug>
-
-#include "qgstappsrc_p.h"
-#include "qgstutils_p.h"
-#include "qnetworkreply.h"
-#include "qloggingcategory.h"
-
-Q_LOGGING_CATEGORY(qLcAppSrc, "qt.multimedia.appsrc")
-
-QGstAppSrc::QGstAppSrc(QObject *parent)
- : QObject(parent)
-{
- m_appSrc = QGstElement("appsrc", "appsrc");
- if (m_appSrc.isNull())
- qWarning() << "Could not create GstAppSrc.";
-}
-
-QGstAppSrc::~QGstAppSrc()
-{
- m_appSrc.setStateSync(GST_STATE_NULL);
- streamDestroyed();
- qCDebug(qLcAppSrc) << "~QGstAppSrc";
-}
-
-bool QGstAppSrc::setup(QIODevice *stream, qint64 offset)
-{
- if (m_appSrc.isNull())
- return false;
-
- if (!setStream(stream, offset))
- return false;
-
- auto *appSrc = GST_APP_SRC(m_appSrc.element());
- GstAppSrcCallbacks m_callbacks;
- memset(&m_callbacks, 0, sizeof(GstAppSrcCallbacks));
- m_callbacks.need_data = &QGstAppSrc::on_need_data;
- m_callbacks.enough_data = &QGstAppSrc::on_enough_data;
- m_callbacks.seek_data = &QGstAppSrc::on_seek_data;
- gst_app_src_set_callbacks(appSrc, (GstAppSrcCallbacks*)&m_callbacks, this, nullptr);
-
- m_maxBytes = gst_app_src_get_max_bytes(appSrc);
- m_suspended = false;
-
- if (m_sequential)
- m_streamType = GST_APP_STREAM_TYPE_STREAM;
- else
- m_streamType = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
- gst_app_src_set_stream_type(appSrc, m_streamType);
- gst_app_src_set_size(appSrc, m_sequential ? -1 : m_stream->size() - m_offset);
-
- m_networkReply = qobject_cast<QNetworkReply *>(m_stream);
- m_noMoreData = true;
-
- return true;
-}
-
-void QGstAppSrc::setAudioFormat(const QAudioFormat &f)
-{
- m_format = f;
- if (!m_format.isValid())
- return;
-
- auto caps = QGstUtils::capsForAudioFormat(m_format);
- Q_ASSERT(!caps.isNull());
- m_appSrc.set("caps", caps);
- m_appSrc.set("format", GST_FORMAT_TIME);
-}
-
-void QGstAppSrc::setExternalAppSrc(const QGstElement &appsrc)
-{
- m_appSrc = appsrc;
-}
-
-bool QGstAppSrc::setStream(QIODevice *stream, qint64 offset)
-{
- if (m_stream) {
- disconnect(m_stream, SIGNAL(readyRead()), this, SLOT(onDataReady()));
- disconnect(m_stream, SIGNAL(destroyed()), this, SLOT(streamDestroyed()));
- m_stream = nullptr;
- }
-
- m_dataRequestSize = 0;
- m_sequential = true;
- m_maxBytes = 0;
- streamedSamples = 0;
-
- if (stream) {
- if (!stream->isOpen() && !stream->open(QIODevice::ReadOnly))
- return false;
- m_stream = stream;
- connect(m_stream, SIGNAL(destroyed()), SLOT(streamDestroyed()));
- connect(m_stream, SIGNAL(readyRead()), this, SLOT(onDataReady()));
- m_sequential = m_stream->isSequential();
- m_offset = offset;
- }
- return true;
-}
-
-QGstElement QGstAppSrc::element()
-{
- return m_appSrc;
-}
-
-void QGstAppSrc::write(const char *data, qsizetype size)
-{
- qCDebug(qLcAppSrc) << "write" << size << m_noMoreData << m_dataRequestSize;
- if (!size)
- return;
- Q_ASSERT(!m_stream);
- m_buffer.append(data, size);
- m_noMoreData = false;
- pushData();
-}
-
-void QGstAppSrc::onDataReady()
-{
- qCDebug(qLcAppSrc) << "onDataReady" << m_stream->bytesAvailable() << m_stream->size();
- pushData();
-}
-
-void QGstAppSrc::streamDestroyed()
-{
- qCDebug(qLcAppSrc) << "stream destroyed";
- m_stream = nullptr;
- m_dataRequestSize = 0;
- streamedSamples = 0;
- sendEOS();
-}
-
-void QGstAppSrc::pushData()
-{
- if (m_appSrc.isNull() || !m_dataRequestSize || m_suspended) {
- qCDebug(qLcAppSrc) << "push data: return immediately" << m_appSrc.isNull() << m_dataRequestSize << m_suspended;
- return;
- }
-
- qCDebug(qLcAppSrc) << "pushData" << (m_stream ? m_stream : nullptr) << m_buffer.size();
- if ((m_stream && m_stream->atEnd())) {
- eosOrIdle();
- qCDebug(qLcAppSrc) << "end pushData" << (m_stream ? m_stream : nullptr) << m_buffer.size();
- return;
- }
-
- qint64 size;
- if (m_stream)
- size = m_stream->bytesAvailable();
- else
- size = m_buffer.size();
-
- if (!m_dataRequestSize)
- m_dataRequestSize = m_maxBytes;
- size = qMin(size, (qint64)m_dataRequestSize);
- qCDebug(qLcAppSrc) << " reading" << size << "bytes" << size << m_dataRequestSize;
-
- GstBuffer* buffer = gst_buffer_new_and_alloc(size);
-
- if (m_sequential || !m_stream)
- buffer->offset = bytesReadSoFar;
- else
- buffer->offset = m_stream->pos();
-
- if (m_format.isValid()) {
- // timestamp raw audio data
- uint nSamples = size/m_format.bytesPerFrame();
-
- GST_BUFFER_TIMESTAMP(buffer) = gst_util_uint64_scale(streamedSamples, GST_SECOND, m_format.sampleRate());
- GST_BUFFER_DURATION(buffer) = gst_util_uint64_scale(nSamples, GST_SECOND, m_format.sampleRate());
- streamedSamples += nSamples;
- }
-
- GstMapInfo mapInfo;
- gst_buffer_map(buffer, &mapInfo, GST_MAP_WRITE);
- void* bufferData = mapInfo.data;
-
- qint64 bytesRead;
- if (m_stream)
- bytesRead = m_stream->read((char*)bufferData, size);
- else
- bytesRead = m_buffer.read((char*)bufferData, size);
- buffer->offset_end = buffer->offset + bytesRead - 1;
- bytesReadSoFar += bytesRead;
-
- gst_buffer_unmap(buffer, &mapInfo);
- qCDebug(qLcAppSrc) << "pushing bytes into gstreamer" << buffer->offset << bytesRead;
- if (bytesRead == 0) {
- gst_buffer_unref(buffer);
- eosOrIdle();
- qCDebug(qLcAppSrc) << "end pushData" << (m_stream ? m_stream : nullptr) << m_buffer.size();
- return;
- }
- m_noMoreData = false;
- emit bytesProcessed(bytesRead);
-
- GstFlowReturn ret = gst_app_src_push_buffer(GST_APP_SRC(m_appSrc.element()), buffer);
- if (ret == GST_FLOW_ERROR) {
- qWarning() << "QGstAppSrc: push buffer error";
- } else if (ret == GST_FLOW_FLUSHING) {
- qWarning() << "QGstAppSrc: push buffer wrong state";
- }
- qCDebug(qLcAppSrc) << "end pushData" << (m_stream ? m_stream : nullptr) << m_buffer.size();
-
-}
-
-bool QGstAppSrc::doSeek(qint64 value)
-{
- if (isStreamValid())
- return m_stream->seek(value + m_offset);
- return false;
-}
-
-
-gboolean QGstAppSrc::on_seek_data(GstAppSrc *, guint64 arg0, gpointer userdata)
-{
- // we do get some spurious seeks to INT_MAX, ignore those
- if (arg0 == std::numeric_limits<quint64>::max())
- return true;
-
- QGstAppSrc *self = reinterpret_cast<QGstAppSrc*>(userdata);
- Q_ASSERT(self);
- if (self->m_sequential)
- return false;
-
- QMetaObject::invokeMethod(self, "doSeek", Qt::AutoConnection, Q_ARG(qint64, arg0));
- return true;
-}
-
-void QGstAppSrc::on_enough_data(GstAppSrc *, gpointer userdata)
-{
- qCDebug(qLcAppSrc) << "on_enough_data";
- QGstAppSrc *self = static_cast<QGstAppSrc*>(userdata);
- Q_ASSERT(self);
- self->m_dataRequestSize = 0;
-}
-
-void QGstAppSrc::on_need_data(GstAppSrc *, guint arg0, gpointer userdata)
-{
- qCDebug(qLcAppSrc) << "on_need_data requesting bytes" << arg0;
- QGstAppSrc *self = static_cast<QGstAppSrc*>(userdata);
- Q_ASSERT(self);
- self->m_dataRequestSize = arg0;
- QMetaObject::invokeMethod(self, "pushData", Qt::AutoConnection);
- qCDebug(qLcAppSrc) << "done on_need_data";
-}
-
-void QGstAppSrc::sendEOS()
-{
- qCDebug(qLcAppSrc) << "sending EOS";
- if (m_appSrc.isNull())
- return;
-
- gst_app_src_end_of_stream(GST_APP_SRC(m_appSrc.element()));
-}
-
-void QGstAppSrc::eosOrIdle()
-{
- qCDebug(qLcAppSrc) << "eosOrIdle";
- if (m_appSrc.isNull())
- return;
-
- if (!m_sequential) {
- sendEOS();
- return;
- }
- if (m_noMoreData)
- return;
- qCDebug(qLcAppSrc) << " idle!";
- m_noMoreData = true;
- emit noMoreData();
-}
diff --git a/src/multimedia/platform/gstreamer/common/qgstappsrc_p.h b/src/multimedia/platform/gstreamer/common/qgstappsrc_p.h
deleted file mode 100644
index 3a978454c..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstappsrc_p.h
+++ /dev/null
@@ -1,132 +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 QGSTAPPSRC_H
-#define QGSTAPPSRC_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 <private/qtmultimediaglobal_p.h>
-#include <qaudioformat.h>
-
-#include <QtCore/qobject.h>
-#include <QtCore/qiodevice.h>
-#include <QtCore/private/qringbuffer_p.h>
-#include <QtCore/qatomic.h>
-
-#include <private/qgst_p.h>
-#include <gst/app/gstappsrc.h>
-
-QT_BEGIN_NAMESPACE
-
-class QNetworkReply;
-
-class Q_MULTIMEDIA_EXPORT QGstAppSrc : public QObject
-{
- Q_OBJECT
-public:
- QGstAppSrc(QObject *parent = 0);
- ~QGstAppSrc();
-
- bool setup(QIODevice *stream = nullptr, qint64 offset = 0);
- void setAudioFormat(const QAudioFormat &f);
-
- void setExternalAppSrc(const QGstElement &appsrc);
- QGstElement element();
-
- void write(const char *data, qsizetype size);
-
- bool canAcceptMoreData() { return m_noMoreData || m_dataRequestSize != 0; }
-
- void suspend() { m_suspended = true; }
- void resume() { m_suspended = false; m_noMoreData = true; }
-
-Q_SIGNALS:
- void bytesProcessed(int bytes);
- void noMoreData();
-
-private Q_SLOTS:
- void pushData();
- bool doSeek(qint64);
- void onDataReady();
-
- void streamDestroyed();
-private:
- bool setStream(QIODevice *, qint64 offset);
- bool isStreamValid() const
- {
- return m_stream != nullptr && m_stream->isOpen();
- }
-
- static gboolean on_seek_data(GstAppSrc *element, guint64 arg0, gpointer userdata);
- static void on_enough_data(GstAppSrc *element, gpointer userdata);
- static void on_need_data(GstAppSrc *element, uint arg0, gpointer userdata);
-
- void sendEOS();
- void eosOrIdle();
-
- QIODevice *m_stream = nullptr;
- QNetworkReply *m_networkReply = nullptr;
- QRingBuffer m_buffer;
- QAudioFormat m_format;
-
- QGstElement m_appSrc;
- bool m_sequential = true;
- bool m_suspended = false;
- bool m_noMoreData = false;
- GstAppStreamType m_streamType = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
- qint64 m_offset = 0;
- qint64 m_maxBytes = 0;
- qint64 bytesReadSoFar = 0;
- QAtomicInteger<unsigned int> m_dataRequestSize = 0;
- int streamedSamples = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/common/qgstpipeline.cpp b/src/multimedia/platform/gstreamer/common/qgstpipeline.cpp
deleted file mode 100644
index 0f98e7d21..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstpipeline.cpp
+++ /dev/null
@@ -1,375 +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/qmap.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qabstracteventdispatcher.h>
-#include <QtCore/qcoreapplication.h>
-#include <QtCore/qproperty.h>
-
-#include "qgstpipeline_p.h"
-#include "qgstreamermessage_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QGstPipelinePrivate : public QObject
-{
- Q_OBJECT
-public:
-
- int m_ref = 0;
- guint m_tag = 0;
- GstBus *m_bus = nullptr;
- QTimer *m_intervalTimer = nullptr;
- QMutex filterMutex;
- QList<QGstreamerSyncMessageFilter*> syncFilters;
- QList<QGstreamerBusMessageFilter*> busFilters;
- QProperty<bool> inStoppedState;
- mutable qint64 m_position = 0;
- double m_rate = 1.;
- bool m_flushOnConfigChanges = false;
- bool m_pendingFlush = false;
-
- int m_configCounter = 0;
- GstState m_savedState = GST_STATE_NULL;
-
- QGstPipelinePrivate(GstBus* bus, QObject* parent = 0);
- ~QGstPipelinePrivate();
-
- void ref() { ++ m_ref; }
- void deref() { if (!--m_ref) delete this; }
-
- void installMessageFilter(QGstreamerSyncMessageFilter *filter);
- void removeMessageFilter(QGstreamerSyncMessageFilter *filter);
- void installMessageFilter(QGstreamerBusMessageFilter *filter);
- void removeMessageFilter(QGstreamerBusMessageFilter *filter);
-
- static GstBusSyncReply syncGstBusFilter(GstBus* bus, GstMessage* message, QGstPipelinePrivate *d)
- {
- Q_UNUSED(bus);
- QMutexLocker lock(&d->filterMutex);
-
- for (QGstreamerSyncMessageFilter *filter : qAsConst(d->syncFilters)) {
- if (filter->processSyncMessage(QGstreamerMessage(message))) {
- gst_message_unref(message);
- return GST_BUS_DROP;
- }
- }
-
- return GST_BUS_PASS;
- }
-
-private Q_SLOTS:
- void interval()
- {
- GstMessage* message;
- while ((message = gst_bus_poll(m_bus, GST_MESSAGE_ANY, 0)) != nullptr) {
- processMessage(message);
- gst_message_unref(message);
- }
- }
- void doProcessMessage(const QGstreamerMessage& msg)
- {
- for (QGstreamerBusMessageFilter *filter : qAsConst(busFilters)) {
- if (filter->processBusMessage(msg))
- break;
- }
- }
-
-private:
- void processMessage(GstMessage* message)
- {
- QGstreamerMessage msg(message);
- doProcessMessage(msg);
- }
-
- void queueMessage(GstMessage* message)
- {
- QGstreamerMessage msg(message);
- QMetaObject::invokeMethod(this, "doProcessMessage", Qt::QueuedConnection,
- Q_ARG(QGstreamerMessage, msg));
- }
-
- static gboolean busCallback(GstBus *bus, GstMessage *message, gpointer data)
- {
- Q_UNUSED(bus);
- static_cast<QGstPipelinePrivate *>(data)->queueMessage(message);
- return TRUE;
- }
-};
-
-QGstPipelinePrivate::QGstPipelinePrivate(GstBus* bus, QObject* parent)
- : QObject(parent),
- m_bus(bus),
- inStoppedState(true)
-{
- gst_object_ref(GST_OBJECT(bus));
-
- // glib event loop can be disabled either by env variable or QT_NO_GLIB define, so check the dispacher
- QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher();
- const bool hasGlib = dispatcher && dispatcher->inherits("QEventDispatcherGlib");
- if (!hasGlib) {
- m_intervalTimer = new QTimer(this);
- m_intervalTimer->setInterval(250);
- connect(m_intervalTimer, SIGNAL(timeout()), SLOT(interval()));
- m_intervalTimer->start();
- } else {
- m_tag = gst_bus_add_watch_full(bus, G_PRIORITY_DEFAULT, busCallback, this, nullptr);
- }
-
- gst_bus_set_sync_handler(bus, (GstBusSyncHandler)syncGstBusFilter, this, nullptr);
-}
-
-QGstPipelinePrivate::~QGstPipelinePrivate()
-{
- delete m_intervalTimer;
-
- if (m_tag)
- gst_bus_remove_watch(m_bus);
-
- gst_bus_set_sync_handler(m_bus, nullptr, nullptr, nullptr);
- gst_object_unref(GST_OBJECT(m_bus));
-}
-
-void QGstPipelinePrivate::installMessageFilter(QGstreamerSyncMessageFilter *filter)
-{
- if (filter) {
- QMutexLocker lock(&filterMutex);
- if (!syncFilters.contains(filter))
- syncFilters.append(filter);
- }
-}
-
-void QGstPipelinePrivate::removeMessageFilter(QGstreamerSyncMessageFilter *filter)
-{
- if (filter) {
- QMutexLocker lock(&filterMutex);
- syncFilters.removeAll(filter);
- }
-}
-
-void QGstPipelinePrivate::installMessageFilter(QGstreamerBusMessageFilter *filter)
-{
- if (filter && !busFilters.contains(filter))
- busFilters.append(filter);
-}
-
-void QGstPipelinePrivate::removeMessageFilter(QGstreamerBusMessageFilter *filter)
-{
- if (filter)
- busFilters.removeAll(filter);
-}
-
-QGstPipeline::QGstPipeline(const QGstPipeline &o)
- : QGstBin(o.bin(), NeedsRef),
- d(o.d)
-{
- if (d)
- d->ref();
-}
-
-QGstPipeline &QGstPipeline::operator=(const QGstPipeline &o)
-{
- if (o.d)
- o.d->ref();
- if (d)
- d->deref();
- QGstBin::operator=(o);
- d = o.d;
- return *this;
-}
-
-QGstPipeline::QGstPipeline(const char *name)
- : QGstBin(GST_BIN(gst_pipeline_new(name)), NeedsRef)
-{
- d = new QGstPipelinePrivate(gst_pipeline_get_bus(pipeline()));
- d->ref();
-}
-
-QGstPipeline::QGstPipeline(GstPipeline *p)
- : QGstBin(&p->bin, NeedsRef)
-{
- d = new QGstPipelinePrivate(gst_pipeline_get_bus(pipeline()));
- d->ref();
-}
-
-QGstPipeline::~QGstPipeline()
-{
- if (d)
- d->deref();
-}
-
-QProperty<bool> *QGstPipeline::inStoppedState()
-{
- Q_ASSERT(d);
- return &d->inStoppedState;
-}
-
-void QGstPipeline::setFlushOnConfigChanges(bool flush)
-{
- d->m_flushOnConfigChanges = flush;
-}
-
-void QGstPipeline::installMessageFilter(QGstreamerSyncMessageFilter *filter)
-{
- Q_ASSERT(d);
- d->installMessageFilter(filter);
-}
-
-void QGstPipeline::removeMessageFilter(QGstreamerSyncMessageFilter *filter)
-{
- Q_ASSERT(d);
- d->removeMessageFilter(filter);
-}
-
-void QGstPipeline::installMessageFilter(QGstreamerBusMessageFilter *filter)
-{
- Q_ASSERT(d);
- d->installMessageFilter(filter);
-}
-
-void QGstPipeline::removeMessageFilter(QGstreamerBusMessageFilter *filter)
-{
- Q_ASSERT(d);
- d->removeMessageFilter(filter);
-}
-
-GstStateChangeReturn QGstPipeline::setState(GstState state)
-{
- auto retval = gst_element_set_state(element(), state);
- if (d->m_pendingFlush) {
- d->m_pendingFlush = false;
- flush();
- }
- return retval;
-}
-
-void QGstPipeline::beginConfig()
-{
- if (!d)
- return;
- Q_ASSERT(!isNull());
-
- ++d->m_configCounter;
- if (d->m_configCounter > 1)
- return;
-
- d->m_savedState = state();
- if (d->m_savedState == GST_STATE_PLAYING)
- setStateSync(GST_STATE_PAUSED);
-}
-
-void QGstPipeline::endConfig()
-{
- if (!d)
- return;
- Q_ASSERT(!isNull());
-
- --d->m_configCounter;
- if (d->m_configCounter)
- return;
-
- if (d->m_flushOnConfigChanges)
- d->m_pendingFlush = true;
- if (d->m_savedState == GST_STATE_PLAYING)
- setState(GST_STATE_PLAYING);
- d->m_savedState = GST_STATE_NULL;
-}
-
-void QGstPipeline::flush()
-{
- seek(position(), d->m_rate);
-}
-
-bool QGstPipeline::seek(qint64 pos, double rate)
-{
- // always adjust the rate, so it can be set before playback starts
- // setting position needs a loaded media file that's seekable
- d->m_rate = rate;
- bool success = gst_element_seek(element(), rate, GST_FORMAT_TIME,
- GstSeekFlags(GST_SEEK_FLAG_FLUSH),
- GST_SEEK_TYPE_SET, pos,
- GST_SEEK_TYPE_SET, -1);
- if (!success)
- return false;
-
- d->m_position = pos;
- return true;
-}
-
-bool QGstPipeline::setPlaybackRate(double rate)
-{
- if (rate == d->m_rate)
- return false;
- seek(position(), rate);
- return true;
-}
-
-double QGstPipeline::playbackRate() const
-{
- return d->m_rate;
-}
-
-bool QGstPipeline::setPosition(qint64 pos)
-{
- return seek(pos, d->m_rate);
-}
-
-qint64 QGstPipeline::position() const
-{
- gint64 pos;
- if (gst_element_query_position(element(), GST_FORMAT_TIME, &pos))
- d->m_position = pos;
- return d->m_position;
-}
-
-qint64 QGstPipeline::duration() const
-{
- gint64 d;
- if (!gst_element_query_duration(element(), GST_FORMAT_TIME, &d))
- return 0.;
- return d;
-}
-
-QT_END_NAMESPACE
-
-#include "qgstpipeline.moc"
-
diff --git a/src/multimedia/platform/gstreamer/common/qgstpipeline_p.h b/src/multimedia/platform/gstreamer/common/qgstpipeline_p.h
deleted file mode 100644
index 6ffaf33d6..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstpipeline_p.h
+++ /dev/null
@@ -1,139 +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 qgstpipeline_p_H
-#define qgstpipeline_p_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qtmultimediaglobal_p.h>
-#include <QObject>
-
-#include <private/qgst_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerMessage;
-
-class QGstreamerSyncMessageFilter {
-public:
- //returns true if message was processed and should be dropped, false otherwise
- virtual bool processSyncMessage(const QGstreamerMessage &message) = 0;
-};
-
-
-class QGstreamerBusMessageFilter {
-public:
- //returns true if message was processed and should be dropped, false otherwise
- virtual bool processBusMessage(const QGstreamerMessage &message) = 0;
-};
-
-class QGstPipelinePrivate;
-
-class QGstPipeline : public QGstBin
-{
- QGstPipelinePrivate *d = nullptr;
-public:
- constexpr QGstPipeline() = default;
- QGstPipeline(const QGstPipeline &o);
- QGstPipeline &operator=(const QGstPipeline &o);
- QGstPipeline(const char *name);
- QGstPipeline(GstPipeline *p);
- ~QGstPipeline();
-
- // This is needed to help us avoid sending QVideoFrames or audio buffers to the
- // application while we're prerolling the pipeline.
- // QMediaPlayer is still in a stopped state, while we put the gstreamer pipeline into a
- // Paused state so that we can get the required metadata of the stream and also have a fast
- // transition to play.
- QProperty<bool> *inStoppedState();
-
- void setFlushOnConfigChanges(bool flush);
-
- void installMessageFilter(QGstreamerSyncMessageFilter *filter);
- void removeMessageFilter(QGstreamerSyncMessageFilter *filter);
- void installMessageFilter(QGstreamerBusMessageFilter *filter);
- void removeMessageFilter(QGstreamerBusMessageFilter *filter);
-
- GstStateChangeReturn setState(GstState state);
-
- GstPipeline *pipeline() const { return GST_PIPELINE_CAST(m_object); }
-
- void dumpGraph(const char *fileName)
- {
- if (isNull())
- return;
-
-#if 1 //def QT_GST_CAPTURE_DEBUG
- GST_DEBUG_BIN_TO_DOT_FILE(bin(),
- 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);
-#else
- Q_UNUSED(fileName);
-#endif
- }
-
- void beginConfig();
- void endConfig();
-
- void flush();
-
- bool seek(qint64 pos, double rate);
- bool setPlaybackRate(double rate);
- double playbackRate() const;
-
- bool setPosition(qint64 pos);
- qint64 position() const;
-
- qint64 duration() const;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/common/qgstreameraudioinput.cpp b/src/multimedia/platform/gstreamer/common/qgstreameraudioinput.cpp
deleted file mode 100644
index cd1233c1d..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreameraudioinput.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 <private/qgstreameraudioinput_p.h>
-#include <private/qgstreameraudiodevice_p.h>
-#include <qaudiodevice.h>
-#include <qaudioinput.h>
-
-#include <QtCore/qloggingcategory.h>
-#include <QtNetwork/qnetworkaccessmanager.h>
-#include <QtNetwork/qnetworkreply.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-Q_LOGGING_CATEGORY(qLcMediaAudioInput, "qt.multimedia.audioInput")
-
-QT_BEGIN_NAMESPACE
-
-QGstreamerAudioInput::QGstreamerAudioInput(QAudioInput *parent)
- : QObject(parent),
- QPlatformAudioInput(parent),
- gstAudioInput("audioInput")
-{
- audioSrc = QGstElement("autoaudiosrc", "autoaudiosrc");
- audioVolume = QGstElement("volume", "volume");
- gstAudioInput.add(audioSrc, audioVolume);
- audioSrc.link(audioVolume);
-
- gstAudioInput.addGhostPad(audioVolume, "src");
-}
-
-QGstreamerAudioInput::~QGstreamerAudioInput()
-{
- gstAudioInput.setStateSync(GST_STATE_NULL);
-}
-
-int QGstreamerAudioInput::volume() const
-{
- return m_volume;
-}
-
-bool QGstreamerAudioInput::isMuted() const
-{
- return m_muted;
-}
-
-void QGstreamerAudioInput::setVolume(float vol)
-{
- if (vol == m_volume)
- return;
- m_volume = vol;
- audioVolume.set("volume", vol);
- emit volumeChanged(m_volume);
-}
-
-void QGstreamerAudioInput::setMuted(bool muted)
-{
- if (muted == m_muted)
- return;
- m_muted = muted;
- audioVolume.set("mute", muted);
- emit mutedChanged(muted);
-}
-
-void QGstreamerAudioInput::setAudioDevice(const QAudioDevice &device)
-{
- if (device == m_audioDevice)
- return;
- qCDebug(qLcMediaAudioInput) << "setAudioInput" << device.description() << device.isNull();
- m_audioDevice = device;
-
- QGstElement newSrc;
- auto *deviceInfo = static_cast<const QGStreamerAudioDeviceInfo *>(m_audioDevice.handle());
- if (deviceInfo && deviceInfo->gstDevice)
- newSrc = gst_device_create_element(deviceInfo->gstDevice, "audiosrc");
-
- if (newSrc.isNull())
- newSrc = QGstElement("autoaudiosrc", "audiosrc");
-
- // FIXME: most probably source can be disconnected outside of idle probe
- audioSrc.staticPad("src").doInIdleProbe([&](){
- audioSrc.unlink(audioVolume);
- });
- audioSrc.setStateSync(GST_STATE_NULL);
- gstAudioInput.remove(audioSrc);
- audioSrc = newSrc;
- gstAudioInput.add(audioSrc);
- audioSrc.link(audioVolume);
- audioSrc.syncStateWithParent();
-}
-
-QAudioDevice QGstreamerAudioInput::audioInput() const
-{
- return m_audioDevice;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/common/qgstreameraudioinput_p.h b/src/multimedia/platform/gstreamer/common/qgstreameraudioinput_p.h
deleted file mode 100644
index a0e7d96ab..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreameraudioinput_p.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QGSTREAMERAUDIOINPUT_P_H
-#define QGSTREAMERAUDIOINPUT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qtmultimediaglobal_p.h>
-#include <qaudiodevice.h>
-
-#include <QtCore/qobject.h>
-
-#include <private/qgst_p.h>
-#include <private/qgstpipeline_p.h>
-#include <private/qplatformaudioinput_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerMessage;
-class QAudioDevice;
-
-class Q_MULTIMEDIA_EXPORT QGstreamerAudioInput : public QObject, public QPlatformAudioInput
-{
- Q_OBJECT
-
-public:
- QGstreamerAudioInput(QAudioInput *parent);
- ~QGstreamerAudioInput();
-
- int volume() const;
- bool isMuted() const;
-
- bool setAudioInput(const QAudioDevice &);
- QAudioDevice audioInput() const;
-
- void setAudioDevice(const QAudioDevice &) override;
- void setVolume(float volume) override;
- void setMuted(bool muted) override;
-
- QGstElement gstElement() const { return gstAudioInput; }
-
-Q_SIGNALS:
- void mutedChanged(bool);
- void volumeChanged(int);
-
-private:
- float m_volume = 1.;
- bool m_muted = false;
-
- QAudioDevice m_audioDevice;
-
- // Gst elements
- QGstBin gstAudioInput;
-
- QGstElement audioSrc;
- QGstElement audioVolume;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/common/qgstreameraudiooutput.cpp b/src/multimedia/platform/gstreamer/common/qgstreameraudiooutput.cpp
deleted file mode 100644
index 6338c1ee0..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreameraudiooutput.cpp
+++ /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$
-**
-****************************************************************************/
-
-#include <private/qgstreameraudiooutput_p.h>
-#include <private/qgstreameraudiodevice_p.h>
-#include <qaudiodevice.h>
-#include <qaudiooutput.h>
-
-#include <QtCore/qloggingcategory.h>
-#include <QtNetwork/qnetworkaccessmanager.h>
-#include <QtNetwork/qnetworkreply.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-Q_LOGGING_CATEGORY(qLcMediaAudioOutput, "qt.multimedia.audiooutput")
-
-QT_BEGIN_NAMESPACE
-
-QGstreamerAudioOutput::QGstreamerAudioOutput(QAudioOutput *parent)
- : QObject(parent),
- QPlatformAudioOutput(parent),
- gstAudioOutput("audioOutput")
-{
- audioQueue = QGstElement("queue", "audioQueue");
- audioConvert = QGstElement("audioconvert", "audioConvert");
- audioResample = QGstElement("audioresample", "audioResample");
- audioVolume = QGstElement("volume", "volume");
- audioSink = QGstElement("autoaudiosink", "autoAudioSink");
- gstAudioOutput.add(audioQueue, audioConvert, audioResample, audioVolume, audioSink);
- audioQueue.link(audioConvert, audioResample, audioVolume, audioSink);
-
- gstAudioOutput.addGhostPad(audioQueue, "sink");
-}
-
-QGstreamerAudioOutput::~QGstreamerAudioOutput()
-{
- gstAudioOutput.setStateSync(GST_STATE_NULL);
-}
-
-void QGstreamerAudioOutput::setVolume(float vol)
-{
- audioVolume.set("volume", vol);
-}
-
-void QGstreamerAudioOutput::setMuted(bool muted)
-{
- audioVolume.set("mute", muted);
-}
-
-void QGstreamerAudioOutput::setPipeline(const QGstPipeline &pipeline)
-{
- gstPipeline = pipeline;
-}
-
-void QGstreamerAudioOutput::setAudioDevice(const QAudioDevice &info)
-{
- if (info == m_audioOutput)
- return;
- qCDebug(qLcMediaAudioOutput) << "setAudioOutput" << info.description() << info.isNull();
- m_audioOutput = info;
-
- QGstElement newSink;
- auto *deviceInfo = static_cast<const QGStreamerAudioDeviceInfo *>(m_audioOutput.handle());
- if (deviceInfo && deviceInfo->gstDevice)
- newSink = gst_device_create_element(deviceInfo->gstDevice , "audiosink");
-
- if (newSink.isNull())
- newSink = QGstElement("autoaudiosink", "audiosink");
-
- audioVolume.staticPad("src").doInIdleProbe([&](){
- audioVolume.unlink(audioSink);
- gstAudioOutput.remove(audioSink);
- gstAudioOutput.add(newSink);
- newSink.syncStateWithParent();
- audioVolume.link(newSink);
- });
-
- audioSink.setStateSync(GST_STATE_NULL);
- audioSink = newSink;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/common/qgstreameraudiooutput_p.h b/src/multimedia/platform/gstreamer/common/qgstreameraudiooutput_p.h
deleted file mode 100644
index c3b33c4f4..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreameraudiooutput_p.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QGSTREAMERAUDIOOUTPUT_P_H
-#define QGSTREAMERAUDIOOUTPUT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qtmultimediaglobal_p.h>
-#include <qaudiodevice.h>
-
-#include <QtCore/qobject.h>
-
-#include <private/qgst_p.h>
-#include <private/qgstpipeline_p.h>
-#include <private/qplatformaudiooutput_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerMessage;
-class QAudioDevice;
-
-class Q_MULTIMEDIA_EXPORT QGstreamerAudioOutput : public QObject, public QPlatformAudioOutput
-{
- Q_OBJECT
-
-public:
- QGstreamerAudioOutput(QAudioOutput *parent);
- ~QGstreamerAudioOutput();
-
- void setAudioDevice(const QAudioDevice &) override;
- void setVolume(float volume) override;
- void setMuted(bool muted) override;
-
- void setPipeline(const QGstPipeline &pipeline);
-
- QGstElement gstElement() const { return gstAudioOutput; }
-
-Q_SIGNALS:
- void mutedChanged(bool);
- void volumeChanged(int);
-
-private:
- QAudioDevice m_audioOutput;
-
- // Gst elements
- QGstPipeline gstPipeline;
- QGstBin gstAudioOutput;
-
- QGstElement audioQueue;
- QGstElement audioConvert;
- QGstElement audioResample;
- QGstElement audioVolume;
- QGstElement audioSink;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamerbufferprobe.cpp b/src/multimedia/platform/gstreamer/common/qgstreamerbufferprobe.cpp
deleted file mode 100644
index 3af8000bb..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreamerbufferprobe.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Jolla 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 "qgstreamerbufferprobe_p.h"
-#include "qgstutils_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QGstreamerBufferProbe::QGstreamerBufferProbe(Flags flags)
- : m_flags(flags)
-{
-}
-
-QGstreamerBufferProbe::~QGstreamerBufferProbe() = default;
-
-void QGstreamerBufferProbe::addProbeToPad(GstPad *pad, bool downstream)
-{
- if (GstCaps *caps = gst_pad_get_current_caps(pad)) {
- probeCaps(caps);
- gst_caps_unref(caps);
- }
- if (m_flags & ProbeCaps) {
- m_capsProbeId = gst_pad_add_probe(
- pad,
- downstream
- ? GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM
- : GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
- capsProbe,
- this,
- nullptr);
- }
- if (m_flags & ProbeBuffers) {
- m_bufferProbeId = gst_pad_add_probe(
- pad, GST_PAD_PROBE_TYPE_BUFFER, bufferProbe, this, nullptr);
- }
-}
-
-void QGstreamerBufferProbe::removeProbeFromPad(GstPad *pad)
-{
- if (m_capsProbeId != -1) {
- gst_pad_remove_probe(pad, m_capsProbeId);
- m_capsProbeId = -1;
- }
- if (m_bufferProbeId != -1) {
- gst_pad_remove_probe(pad, m_bufferProbeId);
- m_bufferProbeId = -1;
- }
-}
-
-void QGstreamerBufferProbe::probeCaps(GstCaps *)
-{
-}
-
-bool QGstreamerBufferProbe::probeBuffer(GstBuffer *)
-{
- return true;
-}
-
-GstPadProbeReturn QGstreamerBufferProbe::capsProbe(GstPad *, GstPadProbeInfo *info, gpointer user_data)
-{
- QGstreamerBufferProbe * const control = static_cast<QGstreamerBufferProbe *>(user_data);
-
- if (GstEvent * const event = gst_pad_probe_info_get_event(info)) {
- if (GST_EVENT_TYPE(event) == GST_EVENT_CAPS) {
- GstCaps *caps;
- gst_event_parse_caps(event, &caps);
-
- control->probeCaps(caps);
- }
- }
- return GST_PAD_PROBE_OK;
-}
-
-GstPadProbeReturn QGstreamerBufferProbe::bufferProbe(
- GstPad *, GstPadProbeInfo *info, gpointer user_data)
-{
- QGstreamerBufferProbe * const control = static_cast<QGstreamerBufferProbe *>(user_data);
- if (GstBuffer * const buffer = gst_pad_probe_info_get_buffer(info))
- return control->probeBuffer(buffer) ? GST_PAD_PROBE_OK : GST_PAD_PROBE_DROP;
- return GST_PAD_PROBE_OK;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamerbufferprobe_p.h b/src/multimedia/platform/gstreamer/common/qgstreamerbufferprobe_p.h
deleted file mode 100644
index d3ca9db2e..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreamerbufferprobe_p.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Jolla 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 QGSTREAMERBUFFERPROBE_H
-#define QGSTREAMERBUFFERPROBE_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 <private/qtmultimediaglobal_p.h>
-#include <gst/gst.h>
-
-#include <QtCore/qglobal.h>
-
-
-QT_BEGIN_NAMESPACE
-
-class Q_MULTIMEDIA_EXPORT QGstreamerBufferProbe
-{
-public:
- enum Flags
- {
- ProbeCaps = 0x01,
- ProbeBuffers = 0x02,
- ProbeAll = ProbeCaps | ProbeBuffers
- };
-
- explicit QGstreamerBufferProbe(Flags flags = ProbeAll);
- virtual ~QGstreamerBufferProbe();
-
- void addProbeToPad(GstPad *pad, bool downstream = true);
- void removeProbeFromPad(GstPad *pad);
-
-protected:
- virtual void probeCaps(GstCaps *caps);
- virtual bool probeBuffer(GstBuffer *buffer);
-
-private:
- static GstPadProbeReturn capsProbe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data);
- static GstPadProbeReturn bufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data);
- int m_capsProbeId = -1;
- int m_bufferProbeId = -1;
- const Flags m_flags;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERBUFFERPROBE_H
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamermediaplayer.cpp b/src/multimedia/platform/gstreamer/common/qgstreamermediaplayer.cpp
deleted file mode 100644
index 2c05c0cfe..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreamermediaplayer.cpp
+++ /dev/null
@@ -1,864 +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 <private/qgstreamermediaplayer_p.h>
-#include <private/qgstpipeline_p.h>
-#include <private/qgstreamermetadata_p.h>
-#include <private/qgstreamerformatinfo_p.h>
-#include <private/qgstreameraudiooutput_p.h>
-#include <private/qgstreamervideooutput_p.h>
-#include <private/qgstreamervideosink_p.h>
-#include "private/qgstreamermessage_p.h"
-#include <private/qgstreameraudiodevice_p.h>
-#include <private/qgstappsrc_p.h>
-#include <qaudiodevice.h>
-
-#include <QtCore/qdir.h>
-#include <QtCore/qsocketnotifier.h>
-#include <QtCore/qurl.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qloggingcategory.h>
-#include <QtNetwork/qnetworkaccessmanager.h>
-#include <QtNetwork/qnetworkreply.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-Q_LOGGING_CATEGORY(qLcMediaPlayer, "qt.multimedia.player")
-
-QT_BEGIN_NAMESPACE
-
-QGstreamerMediaPlayer::TrackSelector::TrackSelector(TrackType type, const char *name)
- : selector(QGstElement("input-selector", name)),
- type(type)
-{
- selector.set("sync-streams", true);
-
- if (type == SubtitleStream) {
- selector.set("sync-mode", 1 /*clock*/);
- selector.set("cache-buffers", true);
- }
-
- nullTrack = selector.getRequestPad("sink_%u");
-}
-
-QGstPad QGstreamerMediaPlayer::TrackSelector::createInputPad()
-{
- auto pad = selector.getRequestPad("sink_%u");
- tracks.append(pad);
- return pad;
-}
-
-void QGstreamerMediaPlayer::TrackSelector::removeAllInputPads()
-{
- for (auto &pad : tracks)
- selector.releaseRequestPad(pad);
- tracks.clear();
-}
-
-void QGstreamerMediaPlayer::TrackSelector::removeInputPad(QGstPad pad)
-{
- selector.releaseRequestPad(pad);
- tracks.removeOne(pad);
-}
-
-QGstPad QGstreamerMediaPlayer::TrackSelector::inputPad(int index)
-{
- if (index == -1)
- return nullTrack;
- if (index >= 0 && index < tracks.count())
- return tracks[index];
- return {};
-}
-
-QGstreamerMediaPlayer::TrackSelector &QGstreamerMediaPlayer::trackSelector(TrackType type)
-{
- auto &ts = trackSelectors[type];
- Q_ASSERT(ts.type == type);
- return ts;
-}
-
-QGstreamerMediaPlayer::QGstreamerMediaPlayer(QMediaPlayer *parent)
- : QObject(parent),
- QPlatformMediaPlayer(parent),
- trackSelectors{{{ VideoStream, "videoInputSelector" },
- { AudioStream, "audioInputSelector" },
- { SubtitleStream, "subTitleInputSelector" }}},
- playerPipeline("playerPipeline")
-{
- playerPipeline.setFlushOnConfigChanges(true);
-
- gstVideoOutput = new QGstreamerVideoOutput(this);
- gstVideoOutput->setPipeline(playerPipeline);
-
- for (auto &ts : trackSelectors)
- playerPipeline.add(ts.selector);
-
- playerPipeline.setState(GST_STATE_NULL);
- playerPipeline.installMessageFilter(static_cast<QGstreamerBusMessageFilter *>(this));
- playerPipeline.installMessageFilter(static_cast<QGstreamerSyncMessageFilter *>(this));
-
- /* Taken from gstdicoverer.c:
- * This is ugly. We get the GType of decodebin so we can quickly detect
- * when a decodebin is added to uridecodebin so we can set the
- * post-stream-topology setting to TRUE */
- auto decodebin = QGstElement("decodebin", nullptr);
- decodebinType = G_OBJECT_TYPE(decodebin.element());
- connect(&positionUpdateTimer, &QTimer::timeout, this, &QGstreamerMediaPlayer::updatePosition);
-}
-
-QGstreamerMediaPlayer::~QGstreamerMediaPlayer()
-{
- playerPipeline.removeMessageFilter(static_cast<QGstreamerBusMessageFilter *>(this));
- playerPipeline.removeMessageFilter(static_cast<QGstreamerSyncMessageFilter *>(this));
- playerPipeline.setStateSync(GST_STATE_NULL);
- topology.free();
-}
-
-qint64 QGstreamerMediaPlayer::position() const
-{
- if (playerPipeline.isNull() || m_url.isEmpty())
- return 0;
-
- return playerPipeline.position()/1e6;
-}
-
-qint64 QGstreamerMediaPlayer::duration() const
-{
- return m_duration;
-}
-
-float QGstreamerMediaPlayer::bufferProgress() const
-{
- return m_bufferProgress/100.;
-}
-
-QMediaTimeRange QGstreamerMediaPlayer::availablePlaybackRanges() const
-{
- return QMediaTimeRange();
-}
-
-qreal QGstreamerMediaPlayer::playbackRate() const
-{
- return playerPipeline.playbackRate();
-}
-
-void QGstreamerMediaPlayer::setPlaybackRate(qreal rate)
-{
- if (playerPipeline.setPlaybackRate(rate))
- playbackRateChanged(rate);
-}
-
-void QGstreamerMediaPlayer::setPosition(qint64 pos)
-{
- qint64 currentPos = playerPipeline.position()/1e6;
- if (pos == currentPos)
- return;
- playerPipeline.finishStateChange();
- playerPipeline.setPosition(pos*1e6);
- qCDebug(qLcMediaPlayer) << Q_FUNC_INFO << pos << playerPipeline.position()/1e6;
- if (mediaStatus() == QMediaPlayer::EndOfMedia)
- mediaStatusChanged(QMediaPlayer::LoadedMedia);
- positionChanged(pos);
-}
-
-void QGstreamerMediaPlayer::play()
-{
- if (state() == QMediaPlayer::PlayingState || m_url.isEmpty())
- return;
-
- *playerPipeline.inStoppedState() = false;
- if (mediaStatus() == QMediaPlayer::EndOfMedia) {
- playerPipeline.setPosition(0);
- updatePosition();
- }
-
- qCDebug(qLcMediaPlayer) << "play().";
- int ret = playerPipeline.setState(GST_STATE_PLAYING);
- if (m_requiresSeekOnPlay) {
- // Flushing the pipeline is required to get track changes
- // immediately, when they happen while paused.
- playerPipeline.flush();
- m_requiresSeekOnPlay = false;
- }
- if (ret == GST_STATE_CHANGE_FAILURE)
- qCDebug(qLcMediaPlayer) << "Unable to set the pipeline to the playing state.";
- if (mediaStatus() == QMediaPlayer::LoadedMedia)
- mediaStatusChanged(QMediaPlayer::BufferedMedia);
- emit stateChanged(QMediaPlayer::PlayingState);
- positionUpdateTimer.start(100);
-}
-
-void QGstreamerMediaPlayer::pause()
-{
- if (state() == QMediaPlayer::PausedState || m_url.isEmpty())
- return;
-
- positionUpdateTimer.stop();
- if (*playerPipeline.inStoppedState()) {
- *playerPipeline.inStoppedState() = false;
- playerPipeline.flush();
- }
- int ret = playerPipeline.setState(GST_STATE_PAUSED);
- if (ret == GST_STATE_CHANGE_FAILURE)
- qCDebug(qLcMediaPlayer) << "Unable to set the pipeline to the paused state.";
- if (mediaStatus() == QMediaPlayer::EndOfMedia) {
- playerPipeline.setPosition(0);
- mediaStatusChanged(QMediaPlayer::BufferedMedia);
- }
- updatePosition();
- emit stateChanged(QMediaPlayer::PausedState);
-}
-
-void QGstreamerMediaPlayer::stop()
-{
- if (state() == QMediaPlayer::StoppedState)
- return;
- stopOrEOS(false);
-}
-
-void QGstreamerMediaPlayer::stopOrEOS(bool eos)
-{
- positionUpdateTimer.stop();
- *playerPipeline.inStoppedState() = true;
- bool ret = playerPipeline.setStateSync(GST_STATE_PAUSED);
- if (!ret)
- qCDebug(qLcMediaPlayer) << "Unable to set the pipeline to the stopped state.";
- if (!eos)
- playerPipeline.setPosition(0);
- updatePosition();
- emit stateChanged(QMediaPlayer::StoppedState);
- mediaStatusChanged(eos ? QMediaPlayer::EndOfMedia : QMediaPlayer::LoadedMedia);
-}
-
-bool QGstreamerMediaPlayer::processBusMessage(const QGstreamerMessage &message)
-{
- if (message.isNull())
- return false;
-
-// qCDebug(qLcMediaPlayer) << "received bus message from" << message.source().name() << message.type() << (message.type() == GST_MESSAGE_TAG);
-
- GstMessage* gm = message.rawMessage();
- switch (message.type()) {
- case GST_MESSAGE_TAG: {
- // #### This isn't ideal. We shouldn't catch stream specific tags here, rather the global ones
- GstTagList *tag_list;
- gst_message_parse_tag(gm, &tag_list);
- //qCDebug(qLcMediaPlayer) << "Got tags: " << message.source().name() << gst_tag_list_to_string(tag_list);
- auto metaData = QGstreamerMetaData::fromGstTagList(tag_list);
- for (auto k : metaData.keys())
- m_metaData.insert(k, metaData.value(k));
- break;
- }
- case GST_MESSAGE_DURATION_CHANGED: {
- qint64 d = playerPipeline.duration()/1e6;
- qCDebug(qLcMediaPlayer) << " duration changed message" << d;
- if (d != m_duration) {
- m_duration = d;
- emit durationChanged(duration());
- }
- return false;
- }
- case GST_MESSAGE_EOS:
- stopOrEOS(true);
- break;
- case GST_MESSAGE_BUFFERING: {
- qCDebug(qLcMediaPlayer) << " buffering message";
- int progress = 0;
- gst_message_parse_buffering(gm, &progress);
- m_bufferProgress = progress;
- mediaStatusChanged(m_bufferProgress == 100 ? QMediaPlayer::BufferedMedia : QMediaPlayer::BufferingMedia);
- emit bufferProgressChanged(m_bufferProgress/100.);
- break;
- }
- case GST_MESSAGE_STATE_CHANGED: {
- if (message.source() != playerPipeline)
- return false;
-
- GstState oldState;
- GstState newState;
- GstState pending;
-
- gst_message_parse_state_changed(gm, &oldState, &newState, &pending);
- qCDebug(qLcMediaPlayer) << " state changed message" << oldState << newState << pending;
-
-#ifdef DEBUG_PLAYBIN
- static QStringList states = {
- QStringLiteral("GST_STATE_VOID_PENDING"), QStringLiteral("GST_STATE_NULL"),
- QStringLiteral("GST_STATE_READY"), QStringLiteral("GST_STATE_PAUSED"),
- QStringLiteral("GST_STATE_PLAYING") };
-
- qCDebug(qLcMediaPlayer) << QStringLiteral("state changed: old: %1 new: %2 pending: %3") \
- .arg(states[oldState]) \
- .arg(states[newState]) \
- .arg(states[pending]);
-#endif
-
- switch (newState) {
- case GST_STATE_VOID_PENDING:
- case GST_STATE_NULL:
- case GST_STATE_READY:
- seekableChanged(false);
- break;
- case GST_STATE_PAUSED:
- {
- if (prerolling) {
- qCDebug(qLcMediaPlayer) << "Preroll done, setting status to Loaded";
- prerolling = false;
- GST_DEBUG_BIN_TO_DOT_FILE(playerPipeline.bin(), GST_DEBUG_GRAPH_SHOW_ALL, "playerPipeline");
-
- parseStreamsAndMetadata();
-
- qint64 d = playerPipeline.duration()/1e6;
- if (d != m_duration) {
- m_duration = d;
- qCDebug(qLcMediaPlayer) << " duration changed" << d;
- emit durationChanged(duration());
- }
-
- emit tracksChanged();
- mediaStatusChanged(QMediaPlayer::LoadedMedia);
- }
-
- break;
- }
- case GST_STATE_PLAYING:
- mediaStatusChanged(QMediaPlayer::BufferedMedia);
- break;
- }
- 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)
- emit error(QMediaPlayer::FormatError, tr("Cannot play stream of type: <unknown>"));
- else
- emit error(QMediaPlayer::ResourceError, QString::fromUtf8(err->message));
- playerPipeline.dumpGraph("error");
- mediaStatusChanged(QMediaPlayer::InvalidMedia);
- g_error_free(err);
- g_free(debug);
- break;
- }
- case GST_MESSAGE_WARNING: {
- GError *err;
- gchar *debug;
- gst_message_parse_warning (gm, &err, &debug);
- qCWarning(qLcMediaPlayer) << "Warning:" << QString::fromUtf8(err->message);
- playerPipeline.dumpGraph("warning");
- g_error_free (err);
- g_free (debug);
- break;
- }
- case GST_MESSAGE_INFO: {
- if (qLcMediaPlayer().isDebugEnabled()) {
- GError *err;
- gchar *debug;
- gst_message_parse_info (gm, &err, &debug);
- qCDebug(qLcMediaPlayer) << "Info:" << QString::fromUtf8(err->message);
- g_error_free (err);
- g_free (debug);
- }
- break;
- }
- case GST_MESSAGE_SEGMENT_START: {
- qCDebug(qLcMediaPlayer) << " segment start message, updating position";
- QGstStructure structure(gst_message_get_structure(gm));
- auto p = structure["position"].toInt64();
- if (p) {
- qint64 position = (*p)/1000000;
- emit positionChanged(position);
- }
- break;
- }
- case GST_MESSAGE_ELEMENT: {
- QGstStructure structure(gst_message_get_structure(gm));
- auto type = structure.name();
- if (type == "stream-topology") {
- topology.free();
- topology = structure.copy();
- }
- break;
- }
-
- default:
-// qCDebug(qLcMediaPlayer) << " default message handler, doing nothing";
-
- break;
- }
-
- return false;
-}
-
-bool QGstreamerMediaPlayer::processSyncMessage(const QGstreamerMessage &message)
-{
-#if QT_CONFIG(gstreamer_gl)
- if (message.type() != GST_MESSAGE_NEED_CONTEXT)
- return false;
- const gchar *type = nullptr;
- gst_message_parse_context_type (message.rawMessage(), &type);
- if (strcmp(type, GST_GL_DISPLAY_CONTEXT_TYPE))
- return false;
- if (!gstVideoOutput || !gstVideoOutput->gstreamerVideoSink())
- return false;
- auto *context = gstVideoOutput->gstreamerVideoSink()->gstGlDisplayContext();
- if (!context)
- return false;
- gst_element_set_context(GST_ELEMENT(GST_MESSAGE_SRC(message.rawMessage())), context);
- playerPipeline.dumpGraph("need_context");
- return true;
-#else
- Q_UNUSED(message);
- return false;
-#endif
-}
-
-QUrl QGstreamerMediaPlayer::media() const
-{
- return m_url;
-}
-
-const QIODevice *QGstreamerMediaPlayer::mediaStream() const
-{
- return m_stream;
-}
-
-void QGstreamerMediaPlayer::decoderPadAdded(const QGstElement &src, const QGstPad &pad)
-{
- if (src != decoder)
- return;
-
- auto caps = pad.currentCaps();
- auto type = caps.at(0).name();
- qCDebug(qLcMediaPlayer) << "Received new pad" << pad.name() << "from" << src.name() << "type" << type;
- qCDebug(qLcMediaPlayer) << " " << caps.toString();
-
- TrackType streamType = NTrackTypes;
- if (type.startsWith("video/x-raw")) {
- streamType = VideoStream;
- } else if (type.startsWith("audio/x-raw")) {
- streamType = AudioStream;
- } else if (type.startsWith("text/")) {
- streamType = SubtitleStream;
- } else {
- qCWarning(qLcMediaPlayer) << "Ignoring unknown media stream:" << pad.name() << type;
- return;
- }
-
- auto &ts = trackSelector(streamType);
- connectOutput(ts);
-
- QGstPad sinkPad = ts.createInputPad();
- if (!pad.link(sinkPad)) {
- qCWarning(qLcMediaPlayer) << "Failed to add track, cannot link pads";
- return;
- }
- qCDebug(qLcMediaPlayer) << "Adding track";
-
- if (ts.trackCount() == 1) {
- if (streamType == VideoStream) {
- ts.setActiveInputPad(sinkPad);
- emit videoAvailableChanged(true);
- }
- else if (streamType == AudioStream) {
- ts.setActiveInputPad(sinkPad);
- emit audioAvailableChanged(true);
- }
- }
-
- if (!prerolling)
- emit tracksChanged();
-
- decoderOutputMap.insert(pad.name(), sinkPad);
-}
-
-void QGstreamerMediaPlayer::decoderPadRemoved(const QGstElement &src, const QGstPad &pad)
-{
- if (src != decoder)
- return;
-
- qCDebug(qLcMediaPlayer) << "Removed pad" << pad.name() << "from" << src.name();
- auto track = decoderOutputMap.value(pad.name());
- if (track.isNull())
- return;
-
- auto ts = std::find_if(std::begin(trackSelectors), std::end(trackSelectors),
- [&](TrackSelector &ts){ return ts.selector == track.parent(); });
- if (ts == std::end(trackSelectors))
- return;
-
- qCDebug(qLcMediaPlayer) << " was linked to pad" << track.name() << "from" << ts->selector.name();
- ts->removeInputPad(track);
-
- if (ts->trackCount() == 0) {
- removeOutput(*ts);
- if (ts->type == AudioStream)
- audioAvailableChanged(false);
- else if (ts->type == VideoStream)
- videoAvailableChanged(false);
- }
-
- if (!prerolling)
- tracksChanged();
-}
-
-void QGstreamerMediaPlayer::removeAllOutputs()
-{
- for (auto &ts : trackSelectors) {
- removeOutput(ts);
- ts.removeAllInputPads();
- }
- audioAvailableChanged(false);
- videoAvailableChanged(false);
-}
-
-void QGstreamerMediaPlayer::connectOutput(TrackSelector &ts)
-{
- if (ts.isConnected)
- return;
-
- QGstElement e;
- switch (ts.type) {
- case AudioStream:
- e = gstAudioOutput ? gstAudioOutput->gstElement() : QGstElement{};
- break;
- case VideoStream:
- e = gstVideoOutput ? gstVideoOutput->gstElement() : QGstElement{};
- break;
- case SubtitleStream:
- gstVideoOutput->linkSubtitleStream(ts.selector);
- break;
- default:
- return;
- }
-
- if (!e.isNull()) {
- qCDebug(qLcMediaPlayer) << "connecting output for track type" << ts.type;
- playerPipeline.add(e);
- ts.selector.link(e);
- e.setState(GST_STATE_PAUSED);
- }
-
- ts.isConnected = true;
-}
-
-void QGstreamerMediaPlayer::removeOutput(TrackSelector &ts)
-{
- if (!ts.isConnected)
- return;
-
- QGstElement e;
- switch (ts.type) {
- case AudioStream:
- e = gstAudioOutput ? gstAudioOutput->gstElement() : QGstElement{};
- break;
- case VideoStream:
- e = gstVideoOutput ? gstVideoOutput->gstElement() : QGstElement{};
- break;
- case SubtitleStream:
- // TODO: unlink subtitle stream
- break;
- default:
- break;
- }
-
- if (!e.isNull()) {
- qCDebug(qLcMediaPlayer) << "removing output for track type" << ts.type;
- e.setState(GST_STATE_NULL);
- playerPipeline.remove(e);
- }
-
- ts.isConnected = false;
-}
-
-void QGstreamerMediaPlayer::uridecodebinElementAddedCallback(GstElement */*uridecodebin*/, GstElement *child, QGstreamerMediaPlayer *that)
-{
- QGstElement c(child);
- qCDebug(qLcMediaPlayer) << "New element added to uridecodebin:" << c.name();
-
- if (G_OBJECT_TYPE(child) == that->decodebinType) {
- qCDebug(qLcMediaPlayer) << " -> setting post-stream-topology property";
- c.set("post-stream-topology", true);
- } else if (!qstrcmp(gst_element_get_name(child), "source")) {
- GstBaseSrc *src = GST_BASE_SRC(child);
- bool seekable = src && GST_BASE_SRC_GET_CLASS(src)->is_seekable(src);
- that->seekableChanged(seekable);
- }
-}
-
-void QGstreamerMediaPlayer::setMedia(const QUrl &content, QIODevice *stream)
-{
- qCDebug(qLcMediaPlayer) << Q_FUNC_INFO << "setting location to" << content;
-
- prerolling = true;
-
- bool ret = playerPipeline.setStateSync(GST_STATE_NULL);
- if (!ret)
- qCDebug(qLcMediaPlayer) << "Unable to set the pipeline to the stopped state.";
-
- m_url = content;
- m_stream = stream;
-
- if (!src.isNull())
- playerPipeline.remove(src);
- if (!decoder.isNull())
- playerPipeline.remove(decoder);
- src = QGstElement();
- decoder = QGstElement();
- removeAllOutputs();
- seekableChanged(false);
-
- if (m_duration != 0) {
- m_duration = 0;
- durationChanged(0);
- }
- stateChanged(QMediaPlayer::StoppedState);
- if (position() != 0)
- positionChanged(0);
- mediaStatusChanged(QMediaPlayer::NoMedia);
- if (!m_metaData.isEmpty()) {
- m_metaData.clear();
- metaDataChanged();
- }
-
- if (content.isEmpty())
- return;
-
- if (m_stream) {
- if (!m_appSrc)
- m_appSrc = new QGstAppSrc(this);
- src = m_appSrc->element();
- decoder = QGstElement("decodebin", "decoder");
- decoder.set("post-stream-topology", true);
- playerPipeline.add(src, decoder);
- src.link(decoder);
-
- m_appSrc->setup(m_stream);
- seekableChanged(!stream->isSequential());
- } else {
- // use uridecodebin
- decoder = QGstElement("uridecodebin", "uridecoder");
- playerPipeline.add(decoder);
- // can't set post-stream-topology to true, as uridecodebin doesn't have the property. Use a hack
- decoder.connect("element-added", GCallback(QGstreamerMediaPlayer::uridecodebinElementAddedCallback), this);
-
- decoder.set("uri", content.toEncoded().constData());
- if (m_bufferProgress != 0) {
- m_bufferProgress = 0;
- emit bufferProgressChanged(0.);
- }
- }
- decoder.onPadAdded<&QGstreamerMediaPlayer::decoderPadAdded>(this);
- decoder.onPadRemoved<&QGstreamerMediaPlayer::decoderPadRemoved>(this);
-
- mediaStatusChanged(QMediaPlayer::LoadingMedia);
-
- if (state() == QMediaPlayer::PlayingState) {
- int ret = playerPipeline.setState(GST_STATE_PLAYING);
- if (ret == GST_STATE_CHANGE_FAILURE)
- qCWarning(qLcMediaPlayer) << "Unable to set the pipeline to the playing state.";
- } else {
- int ret = playerPipeline.setState(GST_STATE_PAUSED);
- if (!ret)
- qCWarning(qLcMediaPlayer) << "Unable to set the pipeline to the paused state.";
- }
-
- playerPipeline.setPosition(0);
- positionChanged(0);
-}
-
-void QGstreamerMediaPlayer::setAudioOutput(QPlatformAudioOutput *output)
-{
- if (gstAudioOutput == output)
- return;
-
- auto &ts = trackSelector(AudioStream);
-
- playerPipeline.beginConfig();
- if (gstAudioOutput) {
- removeOutput(ts);
- gstAudioOutput->setPipeline({});
- }
- gstAudioOutput = static_cast<QGstreamerAudioOutput *>(output);
- if (gstAudioOutput) {
- gstAudioOutput->setPipeline(playerPipeline);
- connectOutput(ts);
- }
- playerPipeline.endConfig();
-}
-
-QMediaMetaData QGstreamerMediaPlayer::metaData() const
-{
- return m_metaData;
-}
-
-void QGstreamerMediaPlayer::setVideoSink(QVideoSink *sink)
-{
- gstVideoOutput->setVideoSink(sink);
-}
-
-static QGstStructure endOfChain(const QGstStructure &s)
-{
- QGstStructure e = s;
- while (1) {
- auto next = e["next"].toStructure();
- if (!next.isNull())
- e = next;
- else
- break;
- }
- return e;
-}
-
-void QGstreamerMediaPlayer::parseStreamsAndMetadata()
-{
- qCDebug(qLcMediaPlayer) << "============== parse topology ============";
- if (topology.isNull()) {
- qCDebug(qLcMediaPlayer) << " null topology";
- return;
- }
- auto caps = topology["caps"].toCaps();
- auto structure = caps.at(0);
- auto fileFormat = QGstreamerFormatInfo::fileFormatForCaps(structure);
- qCDebug(qLcMediaPlayer) << caps.toString() << fileFormat;
- m_metaData.insert(QMediaMetaData::FileFormat, QVariant::fromValue(fileFormat));
- m_metaData.insert(QMediaMetaData::Duration, duration());
- m_metaData.insert(QMediaMetaData::Url, m_url);
- QGValue tags = topology["tags"];
- if (!tags.isNull()) {
- GstTagList *tagList = nullptr;
- gst_structure_get(topology.structure, "tags", GST_TYPE_TAG_LIST, &tagList, nullptr);
- const auto metaData = QGstreamerMetaData::fromGstTagList(tagList);
- for (auto k : metaData.keys())
- m_metaData.insert(k, metaData.value(k));
- }
-
- auto demux = endOfChain(topology);
- auto next = demux["next"];
- if (!next.isList()) {
- qCDebug(qLcMediaPlayer) << " no additional streams";
- emit metaDataChanged();
- return;
- }
-
- // collect stream info
- int size = next.listSize();
- for (int i = 0; i < size; ++i) {
- auto val = next.at(i);
- caps = val.toStructure()["caps"].toCaps();
- structure = caps.at(0);
- if (structure.name().startsWith("audio/")) {
- auto codec = QGstreamerFormatInfo::audioCodecForCaps(structure);
- m_metaData.insert(QMediaMetaData::AudioCodec, QVariant::fromValue(codec));
- qCDebug(qLcMediaPlayer) << " audio" << caps.toString() << (int)codec;
- } else if (structure.name().startsWith("video/")) {
- auto codec = QGstreamerFormatInfo::videoCodecForCaps(structure);
- m_metaData.insert(QMediaMetaData::VideoCodec, QVariant::fromValue(codec));
- qCDebug(qLcMediaPlayer) << " video" << caps.toString() << (int)codec;
- auto framerate = structure["framerate"].getFraction();
- if (framerate)
- m_metaData.insert(QMediaMetaData::VideoFrameRate, *framerate);
- auto width = structure["width"].toInt();
- auto height = structure["height"].toInt();
- if (width && height)
- m_metaData.insert(QMediaMetaData::Resolution, QSize(*width, *height));
- }
- }
-
- auto sinkPad = trackSelector(VideoStream).activeInputPad();
- if (!sinkPad.isNull()) {
- bool hasTags = g_object_class_find_property (G_OBJECT_GET_CLASS (sinkPad.object()), "tags") != NULL;
-
- GstTagList *tl = nullptr;
- g_object_get(sinkPad.object(), "tags", &tl, nullptr);
- qCDebug(qLcMediaPlayer) << " tags=" << hasTags << (tl ? gst_tag_list_to_string(tl) : "(null)");
- }
-
-
- qCDebug(qLcMediaPlayer) << "============== end parse topology ============";
- emit metaDataChanged();
- playerPipeline.dumpGraph("playback");
-}
-
-int QGstreamerMediaPlayer::trackCount(QPlatformMediaPlayer::TrackType type)
-{
- return trackSelector(type).trackCount();
-}
-
-QMediaMetaData QGstreamerMediaPlayer::trackMetaData(QPlatformMediaPlayer::TrackType type, int index)
-{
- auto track = trackSelector(type).inputPad(index);
- if (track.isNull())
- return {};
-
- GstTagList *tagList = nullptr;
- g_object_get(track.object(), "tags", &tagList, nullptr);
-
- return tagList ? QGstreamerMetaData::fromGstTagList(tagList) : QMediaMetaData{};
-}
-
-int QGstreamerMediaPlayer::activeTrack(TrackType type)
-{
- return trackSelector(type).activeInputIndex();
-}
-
-void QGstreamerMediaPlayer::setActiveTrack(TrackType type, int index)
-{
- auto &ts = trackSelector(type);
- auto track = ts.inputPad(index);
- if (track.isNull())
- return;
-
- if (type == QPlatformMediaPlayer::SubtitleStream)
- gstVideoOutput->flushSubtitles();
-
- qCDebug(qLcMediaPlayer) << "Setting active track type" << type << "to" << index;
- ts.setActiveInputPad(track);
-
- // seek to force an immediate change of the stream
- if (playerPipeline.state() == GST_STATE_PLAYING)
- playerPipeline.flush();
- else
- m_requiresSeekOnPlay = true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamermediaplayer_p.h b/src/multimedia/platform/gstreamer/common/qgstreamermediaplayer_p.h
deleted file mode 100644
index a811e2832..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreamermediaplayer_p.h
+++ /dev/null
@@ -1,187 +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 QGSTREAMERMEDIAPLAYER_P_H
-#define QGSTREAMERMEDIAPLAYER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qstack.h>
-#include <private/qplatformmediaplayer_p.h>
-#include <private/qtmultimediaglobal_p.h>
-#include <qurl.h>
-#include <private/qgst_p.h>
-#include <private/qgstpipeline_p.h>
-
-#include <QtCore/qtimer.h>
-
-#include <array>
-
-QT_BEGIN_NAMESPACE
-
-class QNetworkAccessManager;
-class QGstreamerMessage;
-class QGstAppSrc;
-class QGstreamerAudioOutput;
-class QGstreamerVideoOutput;
-
-class Q_MULTIMEDIA_EXPORT QGstreamerMediaPlayer
- : public QObject,
- public QPlatformMediaPlayer,
- public QGstreamerBusMessageFilter,
- public QGstreamerSyncMessageFilter
-{
- Q_OBJECT
-
-public:
- QGstreamerMediaPlayer(QMediaPlayer *parent = 0);
- ~QGstreamerMediaPlayer();
-
- qint64 position() const override;
- qint64 duration() const override;
-
- float bufferProgress() 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&, QIODevice *) override;
-
- bool streamPlaybackSupported() const override { return true; }
-
- void setAudioOutput(QPlatformAudioOutput *output) override;
-
- QMediaMetaData metaData() const override;
-
- void setVideoSink(QVideoSink *sink) override;
-
- int trackCount(TrackType) override;
- QMediaMetaData trackMetaData(TrackType /*type*/, int /*streamNumber*/) override;
- int activeTrack(TrackType) override;
- void setActiveTrack(TrackType, int /*streamNumber*/) override;
-
- void setPosition(qint64 pos) override;
-
- void play() override;
- void pause() override;
- void stop() override;
-
- bool processBusMessage(const QGstreamerMessage& message) override;
- bool processSyncMessage(const QGstreamerMessage& message) override;
-
-public Q_SLOTS:
- void updatePosition() { positionChanged(position()); }
-
-private:
- struct TrackSelector {
- TrackSelector(TrackType, const char *name);
- QGstPad createInputPad();
- void removeInputPad(QGstPad pad);
- void removeAllInputPads();
- QGstPad inputPad(int index);
- int activeInputIndex() const { return tracks.indexOf(activeInputPad()); }
- QGstPad activeInputPad() const { return selector.getObject("active-pad"); }
- void setActiveInputPad(QGstPad input) { selector.set("active-pad", input); }
- int trackCount() const { return tracks.count(); }
-
- QGstElement selector;
- TrackType type;
- QList<QGstPad> tracks;
- QGstPad nullTrack;
- bool isConnected = false;
- };
-
- friend class QGstreamerStreamsControl;
- void decoderPadAdded(const QGstElement &src, const QGstPad &pad);
- void decoderPadRemoved(const QGstElement &src, const QGstPad &pad);
- static void uridecodebinElementAddedCallback(GstElement *uridecodebin, GstElement *child, QGstreamerMediaPlayer *that);
- void parseStreamsAndMetadata();
- void connectOutput(TrackSelector &ts);
- void removeOutput(TrackSelector &ts);
- void removeAllOutputs();
- void stopOrEOS(bool eos);
-
- std::array<TrackSelector, NTrackTypes> trackSelectors;
- TrackSelector &trackSelector(TrackType type);
-
- QMediaMetaData m_metaData;
-
- int m_bufferProgress = -1;
- QUrl m_url;
- QIODevice *m_stream = nullptr;
-
- bool prerolling = false;
- bool m_requiresSeekOnPlay = false;
- qint64 m_duration = 0;
- QTimer positionUpdateTimer;
-
- QGstAppSrc *m_appSrc = nullptr;
-
- GType decodebinType;
- QGstStructure topology;
-
- // Gst elements
- QGstPipeline playerPipeline;
- QGstElement src;
- QGstElement decoder;
-
- QGstreamerAudioOutput *gstAudioOutput = nullptr;
- QGstreamerVideoOutput *gstVideoOutput = nullptr;
-
- // QGstElement streamSynchronizer;
-
- QHash<QByteArray, QGstPad> decoderOutputMap;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamermessage.cpp b/src/multimedia/platform/gstreamer/common/qgstreamermessage.cpp
deleted file mode 100644
index 950cc46cb..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreamermessage.cpp
+++ /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$
-**
-****************************************************************************/
-
-#include <gst/gst.h>
-
-#include "qgstreamermessage_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QGstreamerMessage
- \internal
-*/
-
-QGstreamerMessage::QGstreamerMessage(GstMessage* message):
- m_message(message)
-{
- gst_message_ref(m_message);
-}
-
-QGstreamerMessage::QGstreamerMessage(QGstreamerMessage const& m):
- m_message(m.m_message)
-{
- gst_message_ref(m_message);
-}
-
-
-QGstreamerMessage::~QGstreamerMessage()
-{
- if (m_message != nullptr)
- gst_message_unref(m_message);
-}
-
-GstMessage* QGstreamerMessage::rawMessage() const
-{
- return m_message;
-}
-
-QGstreamerMessage& QGstreamerMessage::operator=(QGstreamerMessage const& rhs)
-{
- if (rhs.m_message != m_message) {
- if (rhs.m_message != nullptr)
- gst_message_ref(rhs.m_message);
-
- if (m_message != nullptr)
- gst_message_unref(m_message);
-
- m_message = rhs.m_message;
- }
-
- return *this;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamermessage_p.h b/src/multimedia/platform/gstreamer/common/qgstreamermessage_p.h
deleted file mode 100644
index 8d5ff440e..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreamermessage_p.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 QGSTREAMERMESSAGE_P_H
-#define QGSTREAMERMESSAGE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qtmultimediaglobal_p.h>
-#include <private/qgst_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// Required for QDoc workaround
-class QString;
-
-class Q_MULTIMEDIA_EXPORT QGstreamerMessage
-{
-public:
- QGstreamerMessage() = default;
- QGstreamerMessage(GstMessage* message);
- QGstreamerMessage(QGstreamerMessage const& m);
- ~QGstreamerMessage();
-
- bool isNull() const { return !m_message; }
- GstMessageType type() const { return GST_MESSAGE_TYPE(m_message); }
- QGstObject source() const { return QGstObject(GST_MESSAGE_SRC(m_message), QGstObject::NeedsRef); }
-
- GstMessage* rawMessage() const;
-
- QGstreamerMessage& operator=(QGstreamerMessage const& rhs);
-
-private:
- GstMessage* m_message = nullptr;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QGstreamerMessage);
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamermetadata.cpp b/src/multimedia/platform/gstreamer/common/qgstreamermetadata.cpp
deleted file mode 100644
index 3cf3146a3..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreamermetadata.cpp
+++ /dev/null
@@ -1,305 +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 "qgstreamermetadata_p.h"
-#include <QDebug>
-#include <QtMultimedia/qmediametadata.h>
-#include <QtCore/qdatetime.h>
-
-#include <gst/gstversion.h>
-#include <private/qgstutils_p.h>
-
-QT_BEGIN_NAMESPACE
-
-struct {
- const char *tag;
- QMediaMetaData::Key key;
-} gstTagToMetaDataKey[] = {
- { GST_TAG_TITLE, QMediaMetaData::Title },
- { GST_TAG_COMMENT, QMediaMetaData::Comment },
- { GST_TAG_DESCRIPTION, QMediaMetaData::Description },
- { GST_TAG_GENRE, QMediaMetaData::Genre },
- { GST_TAG_DATE_TIME, QMediaMetaData::Date },
- { GST_TAG_DATE, QMediaMetaData::Date },
-
- { GST_TAG_LANGUAGE_CODE, QMediaMetaData::Language },
-
- { GST_TAG_ORGANIZATION, QMediaMetaData::Publisher },
- { GST_TAG_COPYRIGHT, QMediaMetaData::Copyright },
-
- // Media
- { GST_TAG_DURATION, QMediaMetaData::Duration },
-
- // Audio
- { GST_TAG_BITRATE, QMediaMetaData::AudioBitRate },
- { GST_TAG_AUDIO_CODEC, QMediaMetaData::AudioCodec },
-
- // Music
- { GST_TAG_ALBUM, QMediaMetaData::AlbumTitle },
- { GST_TAG_ALBUM_ARTIST, QMediaMetaData::AlbumArtist },
- { GST_TAG_ARTIST, QMediaMetaData::ContributingArtist },
- { GST_TAG_TRACK_NUMBER, QMediaMetaData::TrackNumber },
-
- { GST_TAG_PREVIEW_IMAGE, QMediaMetaData::ThumbnailImage },
- { GST_TAG_IMAGE, QMediaMetaData::CoverArtImage },
-
- // Image/Video
- { "resolution", QMediaMetaData::Resolution },
- { GST_TAG_IMAGE_ORIENTATION, QMediaMetaData::Orientation },
-
- // Video
- { GST_TAG_VIDEO_CODEC, QMediaMetaData::VideoCodec },
-
- // Movie
- { GST_TAG_PERFORMER, QMediaMetaData::LeadPerformer },
-
- { nullptr, QMediaMetaData::Title }
-};
-
-static QMediaMetaData::Key tagToKey(const char *tag)
-{
- auto *map = gstTagToMetaDataKey;
- while (map->tag) {
- if (!strcmp(map->tag, tag))
- return map->key;
- ++map;
- }
- return QMediaMetaData::Key(-1);
-}
-
-static const char *keyToTag(QMediaMetaData::Key key)
-{
- auto *map = gstTagToMetaDataKey;
- while (map->tag) {
- if (map->key == key)
- return map->tag;
- ++map;
- }
- return nullptr;
-}
-
-//internal
-static void addTagToMap(const GstTagList *list,
- const gchar *tag,
- gpointer user_data)
-{
- QMediaMetaData::Key key = tagToKey(tag);
- if (key == QMediaMetaData::Key(-1))
- return;
-
- auto *map = reinterpret_cast<QHash<QMediaMetaData::Key, QVariant>* >(user_data);
-
- GValue val;
- val.g_type = 0;
- gst_tag_list_copy_value(&val, list, tag);
-
-
- switch( G_VALUE_TYPE(&val) ) {
- case G_TYPE_STRING:
- {
- const gchar *str_value = g_value_get_string(&val);
- if (key == QMediaMetaData::Language) {
- map->insert(key, QLocale::codeToLanguage(QString::fromUtf8(str_value)));
- break;
- }
- map->insert(key, QString::fromUtf8(str_value));
- break;
- }
- case G_TYPE_INT:
- map->insert(key, g_value_get_int(&val));
- break;
- case G_TYPE_UINT:
- map->insert(key, g_value_get_uint(&val));
- break;
- case G_TYPE_LONG:
- map->insert(key, qint64(g_value_get_long(&val)));
- break;
- case G_TYPE_BOOLEAN:
- map->insert(key, g_value_get_boolean(&val));
- break;
- case G_TYPE_CHAR:
- map->insert(key, g_value_get_schar(&val));
- break;
- case G_TYPE_DOUBLE:
- map->insert(key, g_value_get_double(&val));
- break;
- default:
- // GST_TYPE_DATE is a function, not a constant, so pull it out of the switch
- if (G_VALUE_TYPE(&val) == G_TYPE_DATE) {
- const GDate *date = (const GDate *)g_value_get_boxed(&val);
- if (g_date_valid(date)) {
- int year = g_date_get_year(date);
- int month = g_date_get_month(date);
- int day = g_date_get_day(date);
- // don't insert if we already have a datetime.
- if (!map->contains(key))
- map->insert(key, QDateTime(QDate(year, month, day), QTime()));
- }
- } else if (G_VALUE_TYPE(&val) == GST_TYPE_DATE_TIME) {
- const GstDateTime *dateTime = (const GstDateTime *)g_value_get_boxed(&val);
- int year = gst_date_time_has_year(dateTime) ? gst_date_time_get_year(dateTime) : 0;
- int month = gst_date_time_has_month(dateTime) ? gst_date_time_get_month(dateTime) : 0;
- int day = gst_date_time_has_day(dateTime) ? gst_date_time_get_day(dateTime) : 0;
- int hour = 0;
- int minute = 0;
- int second = 0;
- float tz = 0;
- if (gst_date_time_has_time(dateTime)) {
- hour = gst_date_time_get_hour(dateTime);
- minute = gst_date_time_get_minute(dateTime);
- second = gst_date_time_get_second(dateTime);
- tz = gst_date_time_get_time_zone_offset(dateTime);
- }
- QDateTime qDateTime(QDate(year, month, day), QTime(hour, minute, second),
- Qt::OffsetFromUTC, tz * 60 * 60);
- map->insert(key, qDateTime);
- } else if (G_VALUE_TYPE(&val) == GST_TYPE_SAMPLE) {
- GstSample *sample = (GstSample *)g_value_get_boxed(&val);
- GstCaps* caps = gst_sample_get_caps(sample);
- if (caps && !gst_caps_is_empty(caps)) {
- GstStructure *structure = gst_caps_get_structure(caps, 0);
- const gchar *name = gst_structure_get_name(structure);
- if (QByteArray(name).startsWith("image/")) {
- GstBuffer *buffer = gst_sample_get_buffer(sample);
- if (buffer) {
- GstMapInfo info;
- gst_buffer_map(buffer, &info, GST_MAP_READ);
- map->insert(key, QImage::fromData(info.data, info.size, name));
- gst_buffer_unmap(buffer, &info);
- }
- }
- }
- } else if (G_VALUE_TYPE(&val) == GST_TYPE_FRACTION) {
- int nom = gst_value_get_fraction_numerator(&val);
- int denom = gst_value_get_fraction_denominator(&val);
-
- if (denom > 0) {
- map->insert(key, double(nom)/denom);
- }
- }
- break;
- }
-
- g_value_unset(&val);
-}
-
-
-QGstreamerMetaData QGstreamerMetaData::fromGstTagList(const GstTagList *tags)
-{
- QGstreamerMetaData m;
- gst_tag_list_foreach(tags, addTagToMap, &m.data);
- return m;
-}
-
-
-void QGstreamerMetaData::setMetaData(GstElement *element) const
-{
- if (!GST_IS_TAG_SETTER(element))
- return;
-
- gst_tag_setter_reset_tags(GST_TAG_SETTER(element));
-
- for (auto it = data.cbegin(), end = data.cend(); it != end; ++it) {
- const char *tagName = keyToTag(it.key());
- if (!tagName)
- continue;
- const QVariant &tagValue = it.value();
-
- switch (tagValue.typeId()) {
- case QMetaType::QString:
- gst_tag_setter_add_tags(GST_TAG_SETTER(element),
- GST_TAG_MERGE_REPLACE,
- tagName,
- tagValue.toString().toUtf8().constData(),
- nullptr);
- break;
- case QMetaType::Int:
- case QMetaType::LongLong:
- gst_tag_setter_add_tags(GST_TAG_SETTER(element),
- GST_TAG_MERGE_REPLACE,
- tagName,
- tagValue.toInt(),
- nullptr);
- break;
- case QMetaType::Double:
- gst_tag_setter_add_tags(GST_TAG_SETTER(element),
- GST_TAG_MERGE_REPLACE,
- tagName,
- tagValue.toDouble(),
- nullptr);
- break;
- case QMetaType::QDateTime: {
- QDateTime date = tagValue.toDateTime();
- gst_tag_setter_add_tags(GST_TAG_SETTER(element),
- GST_TAG_MERGE_REPLACE,
- tagName,
- gst_date_time_new(date.offsetFromUtc() / 60. / 60.,
- date.date().year(), date.date().month(), date.date().day(),
- date.time().hour(), date.time().minute(), date.time().second()),
- nullptr);
- break;
- }
- case QMetaType::QLocale: {
- QString language = QLocale::languageToCode(tagValue.value<QLocale::Language>());
- gst_tag_setter_add_tags(GST_TAG_SETTER(element),
- GST_TAG_MERGE_REPLACE,
- tagName,
- language.toUtf8().constData(),
- nullptr);
- }
-
- default:
- break;
- }
- }
-}
-
-void QGstreamerMetaData::setMetaData(GstBin *bin) const
-{
- GstIterator *elements = gst_bin_iterate_all_by_interface(bin, GST_TYPE_TAG_SETTER);
- GValue item = G_VALUE_INIT;
- while (gst_iterator_next(elements, &item) == GST_ITERATOR_OK) {
- GstElement * const element = GST_ELEMENT(g_value_get_object(&item));
- setMetaData(element);
- }
- gst_iterator_free(elements);
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamermetadata_p.h b/src/multimedia/platform/gstreamer/common/qgstreamermetadata_p.h
deleted file mode 100644
index 53b29f548..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreamermetadata_p.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 QGSTREAMERMETADATA_H
-#define QGSTREAMERMETADATA_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 <qmediametadata.h>
-#include <qvariant.h>
-
-#include <gst/gst.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerMetaData : public QMediaMetaData
-{
-public:
- static QGstreamerMetaData fromGstTagList(const GstTagList *tags);
- GstTagList *toGstTagList() const;
-
- void setMetaData(GstBin *bin) const;
- void setMetaData(GstElement *element) const;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERMETADATA_H
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideooutput.cpp b/src/multimedia/platform/gstreamer/common/qgstreamervideooutput.cpp
deleted file mode 100644
index 36e0823d8..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreamervideooutput.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 <private/qgstreamervideooutput_p.h>
-#include <private/qgstreamervideosink_p.h>
-#include <private/qgstsubtitlesink_p.h>
-#include <qvideosink.h>
-
-#include <QtCore/qloggingcategory.h>
-#include <qthread.h>
-
-Q_LOGGING_CATEGORY(qLcMediaVideoOutput, "qt.multimedia.videooutput")
-
-QT_BEGIN_NAMESPACE
-
-QGstreamerVideoOutput::QGstreamerVideoOutput(QObject *parent)
- : QObject(parent),
- gstVideoOutput("videoOutput")
-{
- videoQueue = QGstElement("queue", "videoQueue");
- videoConvert = QGstElement("videoconvert", "videoConvert");
- videoSink = QGstElement("fakesink", "fakeVideoSink");
- gstVideoOutput.add(videoQueue, videoConvert, videoSink);
- if (!videoQueue.link(videoConvert, videoSink))
- qCDebug(qLcMediaVideoOutput) << ">>>>>> linking failed";
-
- gstVideoOutput.addGhostPad(videoQueue, "sink");
-}
-
-QGstreamerVideoOutput::~QGstreamerVideoOutput()
-{
- gstVideoOutput.setStateSync(GST_STATE_NULL);
-}
-
-void QGstreamerVideoOutput::setVideoSink(QVideoSink *sink)
-{
- auto *gstVideoSink = sink ? static_cast<QGstreamerVideoSink *>(sink->platformVideoSink()) : nullptr;
- if (gstVideoSink == m_videoSink)
- return;
-
- if (m_videoSink)
- m_videoSink->setPipeline({});
-
- m_videoSink = gstVideoSink;
- if (m_videoSink)
- m_videoSink->setPipeline(gstPipeline);
-
- QGstElement gstSink;
- if (m_videoSink) {
- gstSink = m_videoSink->gstSink();
- isFakeSink = false;
- } else {
- gstSink = QGstElement("fakesink", "fakevideosink");
- isFakeSink = true;
- }
-
- if (videoSink == gstSink)
- return;
-
- gstPipeline.beginConfig();
- if (!videoSink.isNull()) {
- videoSink.setStateSync(GST_STATE_NULL);
- gstVideoOutput.remove(videoSink);
- }
- videoSink = gstSink;
- gstVideoOutput.add(videoSink);
-
- videoConvert.link(videoSink);
- GstEvent *event = gst_event_new_reconfigure();
- gst_element_send_event(videoSink.element(), event);
- videoSink.setState(GST_STATE_PAUSED);
-
- doLinkSubtitleStream();
-
- gstPipeline.endConfig();
-
- qCDebug(qLcMediaVideoOutput) << "sinkChanged" << gstSink.name();
-
- GST_DEBUG_BIN_TO_DOT_FILE(gstPipeline.bin(),
- GstDebugGraphDetails(/*GST_DEBUG_GRAPH_SHOW_ALL |*/ GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE |
- GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES),
- videoSink.name());
-
-}
-
-void QGstreamerVideoOutput::setPipeline(const QGstPipeline &pipeline)
-{
- gstPipeline = pipeline;
- if (m_videoSink)
- m_videoSink->setPipeline(gstPipeline);
-}
-
-void QGstreamerVideoOutput::linkSubtitleStream(QGstElement src)
-{
- qCDebug(qLcMediaVideoOutput) << "link subtitle stream" << src.isNull();
- if (src == subtitleSrc)
- return;
-
- gstPipeline.beginConfig();
- subtitleSrc = src;
- doLinkSubtitleStream();
- gstPipeline.endConfig();
-}
-
-void QGstreamerVideoOutput::doLinkSubtitleStream()
-{
- if (!subtitleSink.isNull()) {
- subtitleSink.setStateSync(GST_STATE_NULL);
- gstPipeline.remove(subtitleSink);
- subtitleSink = {};
- }
- if (!m_videoSink || subtitleSrc.isNull())
- return;
- if (subtitleSink.isNull()) {
- subtitleSink = m_videoSink->subtitleSink();
- gstPipeline.add(subtitleSink);
- }
- if (!subtitleSrc.link(subtitleSink))
- qCDebug(qLcMediaVideoOutput) << "link subtitle stream failed";
-}
-
-void QGstreamerVideoOutput::setIsPreview()
-{
- // configures the queue to be fast and lightweight for camera preview
- // also avoids blocking the queue in case we have an encodebin attached to the tee as well
- videoQueue.set("leaky", 2 /*downstream*/);
- videoQueue.set("silent", true);
- videoQueue.set("max-size-buffers", 1);
- videoQueue.set("max-size-bytes", 0);
- videoQueue.set("max-size-time", 0);
-}
-
-void QGstreamerVideoOutput::flushSubtitles()
-{
- if (!subtitleSink.isNull()) {
- auto pad = subtitleSink.staticPad("sink");
- auto *event = gst_event_new_flush_start();
- pad.sendEvent(event);
- event = gst_event_new_flush_stop(false);
- pad.sendEvent(event);
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideooutput_p.h b/src/multimedia/platform/gstreamer/common/qgstreamervideooutput_p.h
deleted file mode 100644
index 41e8da413..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreamervideooutput_p.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QGSTREAMERVIDEOOUTPUT_P_H
-#define QGSTREAMERVIDEOOUTPUT_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qobject.h>
-#include <private/qtmultimediaglobal_p.h>
-#include <private/qgst_p.h>
-#include <private/qgstpipeline_p.h>
-#include <qwaitcondition.h>
-#include <qmutex.h>
-#include <qpointer.h>
-#include <private/qgstreamervideosink_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVideoSink;
-
-class Q_MULTIMEDIA_EXPORT QGstreamerVideoOutput : public QObject
-{
- Q_OBJECT
-
-public:
- QGstreamerVideoOutput(QObject *parent = 0);
- ~QGstreamerVideoOutput();
-
- void setVideoSink(QVideoSink *sink);
- QGstreamerVideoSink *gstreamerVideoSink() const { return m_videoSink; }
-
- void setPipeline(const QGstPipeline &pipeline);
-
- QGstElement gstElement() const { return gstVideoOutput; }
- void linkSubtitleStream(QGstElement subtitleSrc);
-
- void setIsPreview();
- void flushSubtitles();
-
-private:
- void doLinkSubtitleStream();
-
- QPointer<QGstreamerVideoSink> m_videoSink;
- bool isFakeSink = true;
-
- // Gst elements
- QGstPipeline gstPipeline;
-
- QGstBin gstVideoOutput;
- QGstElement videoQueue;
- QGstElement videoConvert;
- QGstElement videoSink;
-
- QGstElement subtitleSrc;
- QGstElement subtitleSink;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideooverlay.cpp b/src/multimedia/platform/gstreamer/common/qgstreamervideooverlay.cpp
deleted file mode 100644
index f682e8665..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreamervideooverlay.cpp
+++ /dev/null
@@ -1,253 +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 "qgstreamervideooverlay_p.h"
-
-#include <QtGui/qguiapplication.h>
-#include "qgstutils_p.h"
-#include "private/qgst_p.h"
-#include "private/qgstreamermessage_p.h"
-#include "private/qgstreamervideosink_p.h"
-
-#include <gst/video/videooverlay.h>
-
-#include <QtMultimedia/private/qtmultimediaglobal_p.h>
-
-QT_BEGIN_NAMESPACE
-
-struct ElementMap
-{
- const char *qtPlatform;
- const char *gstreamerElement;
-};
-
-// Ordered by descending priority
-static constexpr ElementMap elementMap[] =
-{
- { "xcb", "xvimagesink" },
- { "xcb", "ximagesink" },
-
- // wayland
- { "wayland", "waylandsink" }
-};
-
-static bool qt_gst_element_is_functioning(QGstElement element)
-{
- GstStateChangeReturn ret = element.setState(GST_STATE_READY);
- if (ret == GST_STATE_CHANGE_SUCCESS) {
- element.setState(GST_STATE_NULL);
- return true;
- }
-
- return false;
-}
-
-static QGstElement findBestVideoSink()
-{
- QString platform = QGuiApplication::platformName();
-
- // First, try some known video sinks, depending on the Qt platform plugin in use.
- for (auto i : elementMap) {
- if (platform != QLatin1String(i.qtPlatform))
- continue;
- QGstElement choice(i.gstreamerElement, i.gstreamerElement);
- if (choice.isNull())
- continue;
-
- if (qt_gst_element_is_functioning(choice))
- return choice;
- }
-
- // We need a native window ID to use the GstVideoOverlay interface.
- // Bail out if the Qt platform plugin in use cannot provide a sensible WId.
- if (platform != QLatin1String("xcb") && platform != QLatin1String("wayland"))
- return {};
-
- QGstElement choice;
- // If none of the known video sinks are available, try to find one that implements the
- // GstVideoOverlay interface and has autoplugging rank.
- GList *list = qt_gst_video_sinks();
- for (GList *item = list; item != nullptr; item = item->next) {
- GstElementFactory *f = GST_ELEMENT_FACTORY(item->data);
-
- if (!gst_element_factory_has_interface(f, "GstVideoOverlay"))
- continue;
-
- choice = QGstElement(gst_element_factory_create(f, nullptr));
- if (choice.isNull())
- continue;
-
- if (qt_gst_element_is_functioning(choice))
- break;
- choice = {};
- }
-
- gst_plugin_feature_list_free(list);
- if (choice.isNull())
- qWarning() << "Could not find a valid windowed video sink";
-
- return choice;
-}
-
-QGstreamerVideoOverlay::QGstreamerVideoOverlay(QGstreamerVideoSink *parent, const QByteArray &elementName)
- : QObject(parent)
- , QGstreamerBufferProbe(QGstreamerBufferProbe::ProbeCaps)
- , m_gstreamerVideoSink(parent)
-{
- QGstElement sink;
- if (!elementName.isEmpty())
- sink = QGstElement(elementName.constData(), nullptr);
- else
- sink = findBestVideoSink();
-
- setVideoSink(sink);
-}
-
-QGstreamerVideoOverlay::~QGstreamerVideoOverlay()
-{
- if (!m_videoSink.isNull()) {
- QGstPad pad = m_videoSink.staticPad("sink");
- removeProbeFromPad(pad.pad());
- }
-}
-
-QGstElement QGstreamerVideoOverlay::videoSink() const
-{
- return m_videoSink;
-}
-
-void QGstreamerVideoOverlay::setVideoSink(QGstElement sink)
-{
- if (sink.isNull())
- return;
-
- m_videoSink = sink;
-
- QGstPad pad = m_videoSink.staticPad("sink");
- addProbeToPad(pad.pad());
-
- auto *klass = G_OBJECT_GET_CLASS(m_videoSink.object());
- m_hasForceAspectRatio = g_object_class_find_property(klass, "force-aspect-ratio");
- m_hasFullscreen = g_object_class_find_property(klass, "fullscreen");
-}
-
-QSize QGstreamerVideoOverlay::nativeVideoSize() const
-{
- return m_nativeVideoSize;
-}
-
-void QGstreamerVideoOverlay::setWindowHandle(WId id)
-{
- m_windowId = id;
-
- if (!m_videoSink.isNull() && GST_IS_VIDEO_OVERLAY(m_videoSink.object())) {
- applyRenderRect();
-
- // Properties need to be reset when changing the winId.
- setAspectRatioMode(m_aspectRatioMode);
- setFullScreen(m_fullScreen);
- applyRenderRect();
- }
-}
-
-void QGstreamerVideoOverlay::setRenderRectangle(const QRect &rect)
-{
- renderRect = rect;
- applyRenderRect();
-}
-
-void QGstreamerVideoOverlay::applyRenderRect()
-{
- if (!m_windowId)
- return;
-
- int x = -1;
- int y = -1;
- int w = -1;
- int h = -1;
-
- if (!renderRect.isEmpty()) {
- x = renderRect.x();
- y = renderRect.y();
- w = renderRect.width();
- h = renderRect.height();
- QSize scaledVideo = m_nativeVideoSize.scaled(w, h, m_aspectRatioMode);
- x += (w - scaledVideo.width())/2;
- y += (h - scaledVideo.height())/2;
- w = scaledVideo.width();
- h = scaledVideo.height();
- }
-
- if (!m_videoSink.isNull() && GST_IS_VIDEO_OVERLAY(m_videoSink.object()))
- gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(m_videoSink.object()), x, y, w, h);
-}
-
-void QGstreamerVideoOverlay::probeCaps(GstCaps *caps)
-{
- QSize size = QGstCaps(caps).at(0).resolution();
- if (size != m_nativeVideoSize) {
- m_nativeVideoSize = size;
- m_gstreamerVideoSink->setNativeSize(m_nativeVideoSize);
- applyRenderRect();
- }
-}
-
-void QGstreamerVideoOverlay::setAspectRatioMode(Qt::AspectRatioMode mode)
-{
- m_aspectRatioMode = mode;
- if (m_hasForceAspectRatio)
- m_videoSink.set("force-aspect-ratio", (mode == Qt::KeepAspectRatio));
-}
-
-void QGstreamerVideoOverlay::setFullScreen(bool fullscreen)
-{
- m_fullScreen = fullscreen;
- if (m_hasFullscreen)
- m_videoSink.set("fullscreen", fullscreen);
-}
-
-bool QGstreamerVideoOverlay::processSyncMessage(const QGstreamerMessage &message)
-{
- if (!gst_is_video_overlay_prepare_window_handle_message(message.rawMessage()))
- return false;
- gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videoSink.object()), m_windowId);
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideooverlay_p.h b/src/multimedia/platform/gstreamer/common/qgstreamervideooverlay_p.h
deleted file mode 100644
index 234fc56ff..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreamervideooverlay_p.h
+++ /dev/null
@@ -1,110 +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 QGSTREAMERVIDEOOVERLAY_P_H
-#define QGSTREAMERVIDEOOVERLAY_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qgstpipeline_p.h>
-#include <private/qgstreamerbufferprobe_p.h>
-#include <private/qgst_p.h>
-#include <QtGui/qwindowdefs.h>
-
-QT_BEGIN_NAMESPACE
-class QGstreamerVideoSink;
-
-class Q_MULTIMEDIA_EXPORT QGstreamerVideoOverlay
- : public QObject
- , public QGstreamerSyncMessageFilter
- , private QGstreamerBufferProbe
-{
- Q_OBJECT
-public:
- explicit QGstreamerVideoOverlay(QGstreamerVideoSink *parent = 0, const QByteArray &elementName = QByteArray());
- virtual ~QGstreamerVideoOverlay();
-
- QGstElement videoSink() const;
- void setVideoSink(QGstElement);
- QSize nativeVideoSize() const;
-
- void setWindowHandle(WId id);
- void setRenderRectangle(const QRect &rect);
-
- void setAspectRatioMode(Qt::AspectRatioMode mode);
- void setFullScreen(bool fullscreen);
-
- bool processSyncMessage(const QGstreamerMessage &message) override;
-
- bool isNull() const { return m_videoSink.isNull(); }
-
-Q_SIGNALS:
- void nativeVideoSizeChanged();
- void activeChanged();
-
-private:
- void probeCaps(GstCaps *caps) override;
- void applyRenderRect();
-
- QGstreamerVideoSink *m_gstreamerVideoSink = nullptr;
- QGstElement m_videoSink;
- QSize m_nativeVideoSize;
-
- bool m_hasForceAspectRatio = false;
- bool m_hasFullscreen = false;
- Qt::AspectRatioMode m_aspectRatioMode = Qt::KeepAspectRatio;
- bool m_fullScreen = false;
-
- WId m_windowId = 0;
- QRect renderRect;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERVIDEOOVERLAY_P_H
-
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp b/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp
deleted file mode 100644
index ca7daf6eb..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp
+++ /dev/null
@@ -1,261 +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 "qgstreamervideosink_p.h"
-#include "private/qgstvideorenderersink_p.h"
-#include "private/qgstsubtitlesink_p.h"
-#include <private/qgstutils_p.h>
-#include <QtGui/private/qrhi_p.h>
-
-#if QT_CONFIG(gstreamer_gl)
-#include <QtGui/private/qrhigles2_p.h>
-#include <QGuiApplication>
-#include <QtGui/qopenglcontext.h>
-#include <QWindow>
-#include <qpa/qplatformnativeinterface.h>
-#include <gst/gl/gstglconfig.h>
-
-#if GST_GL_HAVE_WINDOW_X11
-# include <gst/gl/x11/gstgldisplay_x11.h>
-#endif
-#if GST_GL_HAVE_PLATFORM_EGL
-# include <gst/gl/egl/gstgldisplay_egl.h>
-# include <EGL/egl.h>
-# include <EGL/eglext.h>
-#endif
-#if GST_GL_HAVE_WINDOW_WAYLAND
-# include <gst/gl/wayland/gstgldisplay_wayland.h>
-#endif
-#endif // #if QT_CONFIG(gstreamer_gl)
-
-#include <QtCore/qdebug.h>
-
-#include <QtCore/qloggingcategory.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(qLcMediaVideoSink, "qt.multimedia.videosink")
-
-QGstreamerVideoSink::QGstreamerVideoSink(QVideoSink *parent)
- : QPlatformVideoSink(parent)
-{
- sinkBin = QGstBin("videoSinkBin");
- // This is a hack for some iMX platforms. Thos require the use of a special video
- // conversion element in the pipeline before the video sink, as they unfortunately
- // output some proprietary format from the decoder even though it's marked as
- // a regular supported video/x-raw format.
- //
- // To fix this, simply insert the element into the pipeline if it's available. Otherwise
- // we simply use an identity element.
- gstQueue = QGstElement("queue");
- auto imxVideoConvert = QGstElement("imxvideoconvert_g2d");
- if (!imxVideoConvert.isNull())
- gstPreprocess = imxVideoConvert;
- else
- gstPreprocess = QGstElement("identity");
- sinkBin.add(gstQueue, gstPreprocess);
- gstQueue.link(gstPreprocess);
- sinkBin.addGhostPad(gstQueue, "sink");
-
- gstSubtitleSink = GST_ELEMENT(QGstSubtitleSink::createSink(this));
-}
-
-QGstreamerVideoSink::~QGstreamerVideoSink()
-{
- unrefGstContexts();
-
- setPipeline(QGstPipeline());
-}
-
-QGstElement QGstreamerVideoSink::gstSink()
-{
- updateSinkElement();
- return sinkBin;
-}
-
-void QGstreamerVideoSink::setPipeline(QGstPipeline pipeline)
-{
- gstPipeline = pipeline;
-}
-
-void QGstreamerVideoSink::setRhi(QRhi *rhi)
-{
- if (rhi && rhi->backend() != QRhi::OpenGLES2)
- rhi = nullptr;
- if (m_rhi == rhi)
- return;
-
- m_rhi = rhi;
- updateGstContexts();
- if (!gstQtSink.isNull()) {
- // force creation of a new sink with proper caps
- createQtSink();
- updateSinkElement();
- }
-}
-
-void QGstreamerVideoSink::createQtSink()
-{
- gstQtSink = QGstElement(reinterpret_cast<GstElement *>(QGstVideoRendererSink::createSink(this)));
-}
-
-void QGstreamerVideoSink::updateSinkElement()
-{
- QGstElement newSink;
- if (gstQtSink.isNull())
- createQtSink();
- newSink = gstQtSink;
-
- if (newSink == gstVideoSink)
- return;
-
- gstPipeline.beginConfig();
-
- if (!gstVideoSink.isNull()) {
- gstVideoSink.setStateSync(GST_STATE_NULL);
- sinkBin.remove(gstVideoSink);
- }
-
- gstVideoSink = newSink;
- sinkBin.add(gstVideoSink);
- if (!gstPreprocess.link(gstVideoSink))
- qCDebug(qLcMediaVideoSink) << "couldn't link preprocess and sink";
- gstVideoSink.setState(GST_STATE_PAUSED);
-
- gstPipeline.endConfig();
- gstPipeline.dumpGraph("updateVideoSink");
-}
-
-void QGstreamerVideoSink::unrefGstContexts()
-{
- if (m_gstGlDisplayContext)
- gst_context_unref(m_gstGlDisplayContext);
- m_gstGlDisplayContext = nullptr;
- if (m_gstGlLocalContext)
- gst_context_unref(m_gstGlLocalContext);
- m_gstGlLocalContext = nullptr;
- m_eglDisplay = nullptr;
- m_eglImageTargetTexture2D = nullptr;
-}
-
-void QGstreamerVideoSink::updateGstContexts()
-{
- unrefGstContexts();
-
-#if QT_CONFIG(gstreamer_gl)
- if (!m_rhi || m_rhi->backend() != QRhi::OpenGLES2)
- return;
-
- auto *nativeHandles = static_cast<const QRhiGles2NativeHandles *>(m_rhi->nativeHandles());
- auto glContext = nativeHandles->context;
- Q_ASSERT(glContext);
-
- const QString platform = QGuiApplication::platformName();
- QPlatformNativeInterface *pni = QGuiApplication::platformNativeInterface();
- m_eglDisplay = pni->nativeResourceForIntegration("egldisplay");
- qDebug() << "platform is" << platform << m_eglDisplay;
-
- GstGLDisplay *gstGlDisplay = nullptr;
- const char *contextName = "eglcontext";
- GstGLPlatform glPlatform = GST_GL_PLATFORM_EGL;
- // use the egl display if we have one
- if (m_eglDisplay) {
-#if GST_GL_HAVE_PLATFORM_EGL
- gstGlDisplay = (GstGLDisplay *)gst_gl_display_egl_new_with_egl_display(m_eglDisplay);
- m_eglImageTargetTexture2D = eglGetProcAddress("glEGLImageTargetTexture2DOES");
-#endif
- } else {
- auto display = pni->nativeResourceForIntegration("display");
-
- if (display) {
-#if GST_GL_HAVE_WINDOW_X11
- if (platform == QLatin1String("xcb")) {
- contextName = "glxcontext";
- glPlatform = GST_GL_PLATFORM_GLX;
-
- gstGlDisplay = (GstGLDisplay *)gst_gl_display_x11_new_with_display((Display *)display);
- }
-#endif
-#if GST_GL_HAVE_WINDOW_WAYLAND
- if (platform.startsWith(QLatin1String("wayland"))) {
- Q_ASSERT(!gstGlDisplay);
- gstGlDisplay = (GstGLDisplay *)gst_gl_display_wayland_new_with_display((struct wl_display *)display);
- }
-#endif
- }
- }
-
- if (!gstGlDisplay) {
- qWarning() << "Could not create GstGLDisplay";
- return;
- }
-
- void *nativeContext = pni->nativeResourceForContext(contextName, glContext);
- if (!nativeContext)
- qWarning() << "Could not find resource for" << contextName;
-
- GstGLAPI glApi = QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL ? GST_GL_API_OPENGL : GST_GL_API_GLES2;
- GstGLContext *appContext = gst_gl_context_new_wrapped(gstGlDisplay, (guintptr)nativeContext, glPlatform, glApi);
- if (!appContext)
- qWarning() << "Could not create wrappped context for platform:" << glPlatform;
-
- GstGLContext *displayContext = nullptr;
- GError *error = nullptr;
- gst_gl_display_create_context(gstGlDisplay, appContext, &displayContext, &error);
- if (error) {
- qWarning() << "Could not create display context:" << error->message;
- g_clear_error(&error);
- }
-
- if (appContext)
- gst_object_unref(appContext);
-
- m_gstGlDisplayContext = gst_context_new(GST_GL_DISPLAY_CONTEXT_TYPE, false);
- gst_context_set_gl_display(m_gstGlDisplayContext, gstGlDisplay);
-
- m_gstGlLocalContext = gst_context_new("gst.gl.local_context", false);
- GstStructure *structure = gst_context_writable_structure(m_gstGlLocalContext);
- gst_structure_set(structure, "context", GST_TYPE_GL_CONTEXT, displayContext, nullptr);
-
- if (!gstPipeline.isNull())
- gst_element_set_context(gstPipeline.element(), m_gstGlLocalContext);
-#endif // #if QT_CONFIG(gstreamer_gl)
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideosink_p.h b/src/multimedia/platform/gstreamer/common/qgstreamervideosink_p.h
deleted file mode 100644
index a049bc465..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstreamervideosink_p.h
+++ /dev/null
@@ -1,116 +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 QGSTREAMERVIDEOWINDOW_H
-#define QGSTREAMERVIDEOWINDOW_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 <private/qtmultimediaglobal_p.h>
-#include <private/qplatformvideosink_p.h>
-
-#include <private/qgstpipeline_p.h>
-#include <private/qgstreamervideooverlay_p.h>
-#include <QtGui/qcolor.h>
-#include <qvideosink.h>
-
-#if QT_CONFIG(gstreamer_gl)
-#include <gst/gl/gl.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-class QGstreamerVideoRenderer;
-class QVideoWindow;
-
-class Q_MULTIMEDIA_EXPORT QGstreamerVideoSink
- : public QPlatformVideoSink
-{
- Q_OBJECT
-public:
- explicit QGstreamerVideoSink(QVideoSink *parent = 0);
- ~QGstreamerVideoSink();
-
- void setRhi(QRhi *rhi) override;
- QRhi *rhi() const { return m_rhi; }
-
- QGstElement gstSink();
- QGstElement subtitleSink() const { return gstSubtitleSink; }
-
- void setPipeline(QGstPipeline pipeline);
-
- GstContext *gstGlDisplayContext() const { return m_gstGlDisplayContext; }
- GstContext *gstGlLocalContext() const { return m_gstGlLocalContext; }
- Qt::HANDLE eglDisplay() const { return m_eglDisplay; }
- QFunctionPointer eglImageTargetTexture2D() const { return m_eglImageTargetTexture2D; }
-
-private:
- void createQtSink();
- void updateSinkElement();
-
- void unrefGstContexts();
- void updateGstContexts();
-
- QGstPipeline gstPipeline;
- QGstBin sinkBin;
- QGstElement gstQueue;
- QGstElement gstPreprocess;
- QGstElement gstVideoSink;
- QGstElement gstQtSink;
- QGstElement gstSubtitleSink;
-
- QRhi *m_rhi = nullptr;
-
- Qt::HANDLE m_eglDisplay = nullptr;
- QFunctionPointer m_eglImageTargetTexture2D = nullptr;
- GstContext *m_gstGlLocalContext = nullptr;
- GstContext *m_gstGlDisplayContext = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/common/qgstsubtitlesink.cpp b/src/multimedia/platform/gstreamer/common/qgstsubtitlesink.cpp
deleted file mode 100644
index d9b76d57f..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstsubtitlesink.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** 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 <QDebug>
-#include <QThread>
-#include <QEvent>
-
-#include "qgstreamervideosink_p.h"
-#include "qgstsubtitlesink_p.h"
-#include "qgstutils_p.h"
-
-QT_BEGIN_NAMESPACE
-
-static GstBaseSinkClass *sink_parent_class;
-static thread_local QGstreamerVideoSink *current_sink;
-
-#define ST_SINK(s) QGstSubtitleSink *sink(reinterpret_cast<QGstSubtitleSink *>(s))
-
-QGstSubtitleSink *QGstSubtitleSink::createSink(QGstreamerVideoSink *sink)
-{
- current_sink = sink;
-
- QGstSubtitleSink *gstSink = reinterpret_cast<QGstSubtitleSink *>(
- g_object_new(QGstSubtitleSink::get_type(), nullptr));
- g_object_set(gstSink, "async", false, nullptr);
-
- return gstSink;
-}
-
-GType QGstSubtitleSink::get_type()
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info =
- {
- sizeof(QGstSubtitleSinkClass), // class_size
- base_init, // base_init
- nullptr, // base_finalize
- class_init, // class_init
- nullptr, // class_finalize
- nullptr, // class_data
- sizeof(QGstSubtitleSink), // instance_size
- 0, // n_preallocs
- instance_init, // instance_init
- nullptr // value_table
- };
-
- type = g_type_register_static(
- GST_TYPE_BASE_SINK, "QGstSubtitleSink", &info, GTypeFlags(0));
-
- // Register the sink type to be used in custom piplines.
- // When surface is ready the sink can be used.
- gst_element_register(nullptr, "qtsubtitlesink", GST_RANK_PRIMARY, type);
- }
-
- return type;
-}
-
-void QGstSubtitleSink::class_init(gpointer g_class, gpointer class_data)
-{
- Q_UNUSED(class_data);
-
- sink_parent_class = reinterpret_cast<GstBaseSinkClass *>(g_type_class_peek_parent(g_class));
-
- GstBaseSinkClass *base_sink_class = reinterpret_cast<GstBaseSinkClass *>(g_class);
- base_sink_class->render = QGstSubtitleSink::render;
- base_sink_class->get_caps = QGstSubtitleSink::get_caps;
- base_sink_class->set_caps = QGstSubtitleSink::set_caps;
- base_sink_class->propose_allocation = QGstSubtitleSink::propose_allocation;
- base_sink_class->wait_event = QGstSubtitleSink::wait_event;
-
- GstElementClass *element_class = reinterpret_cast<GstElementClass *>(g_class);
- element_class->change_state = QGstSubtitleSink::change_state;
- gst_element_class_set_metadata(element_class,
- "Qt built-in subtitle sink",
- "Sink/Subtitle",
- "Qt default built-in subtitle sink",
- "The Qt Company");
-
- GObjectClass *object_class = reinterpret_cast<GObjectClass *>(g_class);
- object_class->finalize = QGstSubtitleSink::finalize;
-}
-
-void QGstSubtitleSink::base_init(gpointer g_class)
-{
- static GstStaticPadTemplate sink_pad_template = GST_STATIC_PAD_TEMPLATE(
- "sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS("ANY"));
-
- gst_element_class_add_pad_template(
- GST_ELEMENT_CLASS(g_class), gst_static_pad_template_get(&sink_pad_template));
-}
-
-void QGstSubtitleSink::instance_init(GTypeInstance *instance, gpointer g_class)
-{
- Q_UNUSED(g_class);
- ST_SINK(instance);
-
- Q_ASSERT(current_sink);
- sink->sink = current_sink;
- current_sink = nullptr;
-}
-
-void QGstSubtitleSink::finalize(GObject *object)
-{
- // Chain up
- G_OBJECT_CLASS(sink_parent_class)->finalize(object);
-}
-
-GstStateChangeReturn QGstSubtitleSink::change_state(GstElement *element, GstStateChange transition)
-{
- return GST_ELEMENT_CLASS(sink_parent_class)->change_state(element, transition);
-}
-
-GstCaps *QGstSubtitleSink::get_caps(GstBaseSink *base, GstCaps *filter)
-{
- return sink_parent_class->get_caps(base, filter);
-}
-
-gboolean QGstSubtitleSink::set_caps(GstBaseSink *base, GstCaps *caps)
-{
- qDebug() << "set_caps:" << QGstCaps(caps).toString();
- return sink_parent_class->set_caps(base, caps);
-}
-
-gboolean QGstSubtitleSink::propose_allocation(GstBaseSink *base, GstQuery *query)
-{
- return sink_parent_class->propose_allocation(base, query);
-}
-
-GstFlowReturn QGstSubtitleSink::wait_event(GstBaseSink *base, GstEvent *event)
-{
- GstFlowReturn retval = sink_parent_class->wait_event(base, event);
- ST_SINK(base);
- if (event->type == GST_EVENT_GAP) {
-// qDebug() << "gap, clearing subtitle";
- sink->sink->setSubtitleText(QString());
- }
- return retval;
-}
-
-GstFlowReturn QGstSubtitleSink::render(GstBaseSink *base, GstBuffer *buffer)
-{
- ST_SINK(base);
- GstMemory *mem = gst_buffer_get_memory(buffer, 0);
- GstMapInfo info;
- QString subtitle;
- if (gst_memory_map(mem, &info, GST_MAP_READ))
- subtitle = QString::fromUtf8(info.data);
- gst_memory_unmap(mem, &info);
-// qDebug() << "render" << buffer << subtitle;
- sink->sink->setSubtitleText(subtitle);
- return GST_FLOW_OK;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/common/qgstsubtitlesink_p.h b/src/multimedia/platform/gstreamer/common/qgstsubtitlesink_p.h
deleted file mode 100644
index aa9127c7d..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstsubtitlesink_p.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** 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 QGSTSUBTITLESINK_P_H
-#define QGSTSUBTITLESINK_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtMultimedia/private/qtmultimediaglobal_p.h>
-
-#include <QtCore/qlist.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qqueue.h>
-#include <QtCore/qpointer.h>
-#include <QtCore/qwaitcondition.h>
-#include <private/qgst_p.h>
-#include <gst/base/gstbasesink.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerVideoSink;
-
-class Q_MULTIMEDIA_EXPORT QGstSubtitleSink
-{
-public:
- GstBaseSink parent;
-
- static QGstSubtitleSink *createSink(QGstreamerVideoSink *sink);
-
-private:
- static GType get_type();
- static void class_init(gpointer g_class, gpointer class_data);
- static void base_init(gpointer g_class);
- static void instance_init(GTypeInstance *instance, gpointer g_class);
-
- static void finalize(GObject *object);
-
- static GstStateChangeReturn change_state(GstElement *element, GstStateChange transition);
-
- static GstCaps *get_caps(GstBaseSink *sink, GstCaps *filter);
- static gboolean set_caps(GstBaseSink *sink, GstCaps *caps);
-
- static gboolean propose_allocation(GstBaseSink *sink, GstQuery *query);
-
- static GstFlowReturn wait_event(GstBaseSink * sink, GstEvent * event);
- static GstFlowReturn render(GstBaseSink *sink, GstBuffer *buffer);
-
-private:
- QGstreamerVideoSink *sink = nullptr;
-};
-
-
-class QGstSubtitleSinkClass
-{
-public:
- GstBaseSinkClass parent_class;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/common/qgstutils.cpp b/src/multimedia/platform/gstreamer/common/qgstutils.cpp
deleted file mode 100644
index 3a0215e35..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstutils.cpp
+++ /dev/null
@@ -1,423 +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 "qgstutils_p.h"
-
-#include <QtCore/qdatetime.h>
-#include <QtCore/qdir.h>
-#include <QtCore/qbytearray.h>
-#include <QtCore/qvariant.h>
-#include <QtCore/qregularexpression.h>
-#include <QtCore/qsize.h>
-#include <QtCore/qset.h>
-#include <QtCore/qstringlist.h>
-#include <QtGui/qimage.h>
-#include <qaudioformat.h>
-#include <QtCore/qelapsedtimer.h>
-#include <QtMultimedia/qvideoframeformat.h>
-#include <private/qmultimediautils_p.h>
-
-#include <gst/audio/audio.h>
-#include <gst/video/video.h>
-
-template<typename T, int N> constexpr int lengthOf(const T (&)[N]) { return N; }
-
-QT_BEGIN_NAMESPACE
-
-
-namespace {
-
-static const char *audioSampleFormatNames[QAudioFormat::NSampleFormats] = {
- nullptr,
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- "U8",
- "S16LE",
- "S32LE",
- "F32LE"
-#else
- "U8",
- "S16BE",
- "S32BE",
- "F32BE"
-#endif
-};
-
-static QAudioFormat::SampleFormat gstSampleFormatToSampleFormat(const char *fmt)
-{
- if (fmt) {
- for (int i = 1; i < QAudioFormat::NSampleFormats; ++i) {
- if (strcmp(fmt, audioSampleFormatNames[i]))
- continue;
- return QAudioFormat::SampleFormat(i);
- }
- }
- return QAudioFormat::Unknown;
-}
-
-}
-
-/*
- Returns audio format for a sample \a sample.
- If the buffer doesn't have a valid audio format, an empty QAudioFormat is returned.
-*/
-QAudioFormat QGstUtils::audioFormatForSample(GstSample *sample)
-{
- QGstCaps caps = gst_sample_get_caps(sample);
- if (caps.isNull())
- return QAudioFormat();
- return audioFormatForCaps(caps);
-}
-
-QAudioFormat QGstUtils::audioFormatForCaps(QGstCaps caps)
-{
- QAudioFormat format;
- QGstStructure s = caps.at(0);
- if (s.name() != "audio/x-raw")
- return format;
-
- auto rate = s["rate"].toInt();
- auto channels = s["channels"].toInt();
- QAudioFormat::SampleFormat fmt = gstSampleFormatToSampleFormat(s["format"].toString());
- if (!rate || !channels || fmt == QAudioFormat::Unknown)
- return format;
-
- format.setSampleRate(*rate);
- format.setChannelCount(*channels);
- format.setSampleFormat(fmt);
-
- return format;
-}
-
-/*
- Builds GstCaps for an audio format \a format.
- Returns 0 if the audio format is not valid.
-
- \note Caller must unreference GstCaps.
-*/
-
-QGstMutableCaps QGstUtils::capsForAudioFormat(const QAudioFormat &format)
-{
- if (!format.isValid())
- return {};
-
- auto sampleFormat = format.sampleFormat();
- return gst_caps_new_simple(
- "audio/x-raw",
- "format" , G_TYPE_STRING, audioSampleFormatNames[sampleFormat],
- "rate" , G_TYPE_INT , format.sampleRate(),
- "channels", G_TYPE_INT , format.channelCount(),
- "layout" , G_TYPE_STRING, "interleaved",
- nullptr);
-}
-
-QList<QAudioFormat::SampleFormat> QGValue::getSampleFormats() const
-{
- if (!GST_VALUE_HOLDS_LIST(value))
- return {};
-
- QList<QAudioFormat::SampleFormat> formats;
- guint nFormats = gst_value_list_get_size(value);
- for (guint f = 0; f < nFormats; ++f) {
- QGValue v = gst_value_list_get_value(value, f);
- auto *name = v.toString();
- QAudioFormat::SampleFormat fmt = gstSampleFormatToSampleFormat(name);
- if (fmt == QAudioFormat::Unknown)
- continue;;
- formats.append(fmt);
- }
- return formats;
-}
-
-namespace {
-
-struct VideoFormat
-{
- QVideoFrameFormat::PixelFormat pixelFormat;
- GstVideoFormat gstFormat;
-};
-
-static const VideoFormat qt_videoFormatLookup[] =
-{
- { QVideoFrameFormat::Format_YUV420P, GST_VIDEO_FORMAT_I420 },
- { QVideoFrameFormat::Format_YUV422P, GST_VIDEO_FORMAT_Y42B },
- { QVideoFrameFormat::Format_YV12 , GST_VIDEO_FORMAT_YV12 },
- { QVideoFrameFormat::Format_UYVY , GST_VIDEO_FORMAT_UYVY },
- { QVideoFrameFormat::Format_YUYV , GST_VIDEO_FORMAT_YUY2 },
- { QVideoFrameFormat::Format_NV12 , GST_VIDEO_FORMAT_NV12 },
- { QVideoFrameFormat::Format_NV21 , GST_VIDEO_FORMAT_NV21 },
- { QVideoFrameFormat::Format_AYUV , GST_VIDEO_FORMAT_AYUV },
- { QVideoFrameFormat::Format_Y8 , GST_VIDEO_FORMAT_GRAY8 },
- { QVideoFrameFormat::Format_XRGB8888 , GST_VIDEO_FORMAT_xRGB },
- { QVideoFrameFormat::Format_XBGR8888 , GST_VIDEO_FORMAT_xBGR },
- { QVideoFrameFormat::Format_RGBX8888 , GST_VIDEO_FORMAT_RGBx },
- { QVideoFrameFormat::Format_BGRX8888 , GST_VIDEO_FORMAT_BGRx },
- { QVideoFrameFormat::Format_ARGB8888, GST_VIDEO_FORMAT_ARGB },
- { QVideoFrameFormat::Format_ABGR8888, GST_VIDEO_FORMAT_ABGR },
- { QVideoFrameFormat::Format_RGBA8888, GST_VIDEO_FORMAT_RGBA },
- { QVideoFrameFormat::Format_BGRA8888, GST_VIDEO_FORMAT_BGRA },
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- { QVideoFrameFormat::Format_Y16 , GST_VIDEO_FORMAT_GRAY16_LE },
- { QVideoFrameFormat::Format_P010 , GST_VIDEO_FORMAT_P010_10LE },
-#else
- { QVideoFrameFormat::Format_Y16 , GST_VIDEO_FORMAT_GRAY16_BE },
- { QVideoFrameFormat::Format_P010 , GST_VIDEO_FORMAT_P010_10BE },
-#endif
-};
-
-static int indexOfVideoFormat(QVideoFrameFormat::PixelFormat format)
-{
- for (int i = 0; i < lengthOf(qt_videoFormatLookup); ++i)
- if (qt_videoFormatLookup[i].pixelFormat == format)
- return i;
-
- return -1;
-}
-
-static int indexOfVideoFormat(GstVideoFormat format)
-{
- for (int i = 0; i < lengthOf(qt_videoFormatLookup); ++i)
- if (qt_videoFormatLookup[i].gstFormat == format)
- return i;
-
- return -1;
-}
-
-}
-
-QVideoFrameFormat QGstCaps::formatForCaps(GstVideoInfo *info) const
-{
- GstVideoInfo vidInfo;
- GstVideoInfo *infoPtr = info ? info : &vidInfo;
-
- if (gst_video_info_from_caps(infoPtr, caps)) {
- int index = indexOfVideoFormat(infoPtr->finfo->format);
-
- if (index != -1) {
- QVideoFrameFormat format(
- QSize(infoPtr->width, infoPtr->height),
- qt_videoFormatLookup[index].pixelFormat);
-
- if (infoPtr->fps_d > 0)
- format.setFrameRate(qreal(infoPtr->fps_n) / infoPtr->fps_d);
-
- return format;
- }
- }
- return QVideoFrameFormat();
-}
-
-void QGstMutableCaps::addPixelFormats(const QList<QVideoFrameFormat::PixelFormat> &formats, const char *modifier)
-{
- GValue list = {};
- g_value_init(&list, GST_TYPE_LIST);
-
- for (QVideoFrameFormat::PixelFormat format : formats) {
- int index = indexOfVideoFormat(format);
- if (index == -1)
- continue;
- GValue item = {};
-
- g_value_init(&item, G_TYPE_STRING);
- g_value_set_string(&item, gst_video_format_to_string(qt_videoFormatLookup[index].gstFormat));
- gst_value_list_append_value(&list, &item);
- g_value_unset(&item);
- }
- QGValue v(&list);
- auto *structure = gst_structure_new("video/x-raw",
- "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1,
- "width" , GST_TYPE_INT_RANGE, 1, INT_MAX,
- "height" , GST_TYPE_INT_RANGE, 1, INT_MAX,
- nullptr);
- gst_structure_set_value(structure, "format", &list);
- gst_caps_append_structure(caps, structure);
- g_value_unset(&list);
-
- if (modifier)
- gst_caps_set_features(caps, size() - 1, gst_caps_features_from_string(modifier));
-}
-
-QGstMutableCaps QGstMutableCaps::fromCameraFormat(const QCameraFormat &format)
-{
- QGstMutableCaps caps;
- caps.create();
-
- QSize size = format.resolution();
- GstStructure *structure = nullptr;
-// int num = 0;
-// int den = 1;
-// if (format.maxFrameRate() > 0)
-// qt_real_to_fraction(1. / format.maxFrameRate(), &num, &den);
-// qDebug() << "fromCameraFormat" << format.maxFrameRate() << num << den;
-
- if (format.pixelFormat() == QVideoFrameFormat::Format_Jpeg) {
- structure = gst_structure_new("image/jpeg",
- "width" , G_TYPE_INT, size.width(),
- "height" , G_TYPE_INT, size.height(),
-// "framerate", GST_TYPE_FRACTION, den, num,
- nullptr);
- } else {
- int index = indexOfVideoFormat(format.pixelFormat());
- if (index < 0)
- return QGstMutableCaps();
- auto gstFormat = qt_videoFormatLookup[index].gstFormat;
- structure = gst_structure_new("video/x-raw",
- "format" , G_TYPE_STRING, gst_video_format_to_string(gstFormat),
- "width" , G_TYPE_INT, size.width(),
- "height" , G_TYPE_INT, size.height(),
-// "framerate", GST_TYPE_FRACTION, den, num,
- nullptr);
- }
- gst_caps_append_structure(caps.caps, structure);
- return caps;
-}
-
-void QGstUtils::setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buffer)
-{
- // GStreamer uses nanoseconds, Qt uses microseconds
- qint64 startTime = GST_BUFFER_TIMESTAMP(buffer);
- if (startTime >= 0) {
- frame->setStartTime(startTime/G_GINT64_CONSTANT (1000));
-
- qint64 duration = GST_BUFFER_DURATION(buffer);
- if (duration >= 0)
- frame->setEndTime((startTime + duration)/G_GINT64_CONSTANT (1000));
- }
-}
-
-QSize QGstStructure::resolution() const
-{
- QSize size;
-
- int w, h;
- if (structure &&
- gst_structure_get_int(structure, "width", &w) &&
- gst_structure_get_int(structure, "height", &h)) {
- size.rwidth() = w;
- size.rheight() = h;
- }
-
- return size;
-}
-
-QVideoFrameFormat::PixelFormat QGstStructure::pixelFormat() const
-{
- QVideoFrameFormat::PixelFormat pixelFormat = QVideoFrameFormat::Format_Invalid;
-
- if (!structure)
- return pixelFormat;
-
- if (gst_structure_has_name(structure, "video/x-raw")) {
- const gchar *s = gst_structure_get_string(structure, "format");
- if (s) {
- GstVideoFormat format = gst_video_format_from_string(s);
- int index = indexOfVideoFormat(format);
-
- if (index != -1)
- pixelFormat = qt_videoFormatLookup[index].pixelFormat;
- }
- } else if (gst_structure_has_name(structure, "image/jpeg")) {
- pixelFormat = QVideoFrameFormat::Format_Jpeg;
- }
-
- return pixelFormat;
-}
-
-QGRange<float> QGstStructure::frameRateRange() const
-{
- float minRate = 0.;
- float maxRate = 0.;
-
- if (!structure)
- return {0.f, 0.f};
-
- auto extractFraction = [] (const GValue *v) -> float {
- return (float)gst_value_get_fraction_numerator(v)/(float)gst_value_get_fraction_denominator(v);
- };
- auto extractFrameRate = [&] (const GValue *v) {
- auto insert = [&] (float min, float max) {
- if (max > maxRate)
- maxRate = max;
- if (min < minRate)
- minRate = min;
- };
-
- if (GST_VALUE_HOLDS_FRACTION(v)) {
- float rate = extractFraction(v);
- insert(rate, rate);
- } else if (GST_VALUE_HOLDS_FRACTION_RANGE(v)) {
- auto *min = gst_value_get_fraction_range_max(v);
- auto *max = gst_value_get_fraction_range_max(v);
- insert(extractFraction(min), extractFraction(max));
- }
- };
-
- const GValue *gstFrameRates = gst_structure_get_value(structure, "framerate");
- if (gstFrameRates) {
- if (GST_VALUE_HOLDS_LIST(gstFrameRates)) {
- guint nFrameRates = gst_value_list_get_size(gstFrameRates);
- for (guint f = 0; f < nFrameRates; ++f) {
- extractFrameRate(gst_value_list_get_value(gstFrameRates, f));
- }
- } else {
- extractFrameRate(gstFrameRates);
- }
- } else {
- const GValue *min = gst_structure_get_value(structure, "min-framerate");
- const GValue *max = gst_structure_get_value(structure, "max-framerate");
- if (min && max) {
- minRate = extractFraction(min);
- maxRate = extractFraction(max);
- }
- }
-
- return {minRate, maxRate};
-}
-
-GList *qt_gst_video_sinks()
-{
- GList *list = nullptr;
-
- list = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_SINK | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO,
- GST_RANK_MARGINAL);
-
- return list;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/common/qgstutils_p.h b/src/multimedia/platform/gstreamer/common/qgstutils_p.h
deleted file mode 100644
index a0dc51a56..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstutils_p.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 QGSTUTILS_P_H
-#define QGSTUTILS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qtmultimediaglobal_p.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qmap.h>
-#include <QtCore/qset.h>
-#include <private/qgst_p.h>
-#include <gst/video/video.h>
-#include <qaudioformat.h>
-#include <qcamera.h>
-#include <qvideoframe.h>
-#include <QDebug>
-
-QT_BEGIN_NAMESPACE
-
-class QSize;
-class QVariant;
-class QByteArray;
-class QImage;
-class QVideoFrameFormat;
-
-namespace QGstUtils {
- Q_MULTIMEDIA_EXPORT QAudioFormat audioFormatForSample(GstSample *sample);
- QAudioFormat audioFormatForCaps(QGstCaps caps);
- Q_MULTIMEDIA_EXPORT QGstMutableCaps capsForAudioFormat(const QAudioFormat &format);
-
- void setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buffer);
-}
-
-Q_MULTIMEDIA_EXPORT GList *qt_gst_video_sinks();
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/common/qgstvideobuffer.cpp b/src/multimedia/platform/gstreamer/common/qgstvideobuffer.cpp
deleted file mode 100644
index 878b4d410..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstvideobuffer.cpp
+++ /dev/null
@@ -1,373 +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 "qgstvideobuffer_p.h"
-#include "qgstreamervideosink_p.h"
-#include "qvideotexturehelper_p.h"
-#include <qpa/qplatformnativeinterface.h>
-#include <qguiapplication.h>
-
-#include <gst/video/video.h>
-#include <gst/video/video-frame.h>
-#include <gst/video/gstvideometa.h>
-#include <gst/pbutils/gstpluginsbaseversion.h>
-
-#include "qgstutils_p.h"
-
-#if QT_CONFIG(gstreamer_gl)
-#include <QtGui/private/qrhi_p.h>
-#include <QtGui/private/qrhigles2_p.h>
-#include <QtGui/qopenglcontext.h>
-#include <QtGui/qopenglfunctions.h>
-#include <QtGui/qopengl.h>
-
-#include <gst/gl/gstglconfig.h>
-#include <gst/gl/gstglmemory.h>
-#include <gst/gl/gstglsyncmeta.h>
-#include <gst/allocators/gstdmabuf.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-// keep things building without drm_fourcc.h
-#define fourcc_code(a, b, c, d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
- ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
-
-#define DRM_FORMAT_RGBA8888 fourcc_code('R', 'A', '2', '4') /* [31:0] R:G:B:A 8:8:8:8 little endian */
-#define DRM_FORMAT_RGB888 fourcc_code('R', 'G', '2', '4') /* [23:0] R:G:B little endian */
-#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8') /* [15:0] R:G 8:8 little endian */
-#define DRM_FORMAT_ABGR8888 fourcc_code('A', 'B', '2', '4') /* [31:0] A:B:G:R 8:8:8:8 little endian */
-#define DRM_FORMAT_BGR888 fourcc_code('B', 'G', '2', '4') /* [23:0] B:G:R little endian */
-#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8') /* [15:0] G:R 8:8 little endian */
-#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ') /* [7:0] R */
-#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ') /* [15:0] R little endian */
-#define DRM_FORMAT_RGB565 fourcc_code('R', 'G', '1', '6') /* [15:0] R:G:B 5:6:5 little endian */
-#define DRM_FORMAT_RG1616 fourcc_code('R', 'G', '3', '2') /* [31:0] R:G 16:16 little endian */
-#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2') /* [31:0] G:R 16:16 little endian */
-#define DRM_FORMAT_BGRA1010102 fourcc_code('B', 'A', '3', '0') /* [31:0] B:G:R:A 10:10:10:2 little endian */
-
-QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, const GstVideoInfo &info, QGstreamerVideoSink *sink,
- const QVideoFrameFormat &frameFormat,
- QGstCaps::MemoryFormat format)
- : QAbstractVideoBuffer((sink && sink->rhi() && format != QGstCaps::CpuMemory) ?
- QVideoFrame::RhiTextureHandle : QVideoFrame::NoHandle, sink ? sink->rhi() : nullptr)
- , memoryFormat(format)
- , m_frameFormat(frameFormat)
- , m_videoInfo(info)
- , m_buffer(buffer)
-{
- gst_buffer_ref(m_buffer);
- if (sink) {
- eglDisplay = sink->eglDisplay();
- eglImageTargetTexture2D = sink->eglImageTargetTexture2D();
- }
-}
-
-QGstVideoBuffer::~QGstVideoBuffer()
-{
- unmap();
-
- gst_buffer_unref(m_buffer);
- if (m_syncBuffer)
- gst_buffer_unref(m_syncBuffer);
-
- if (m_ownTextures && glContext) {
- int planes = 0;
- for (planes = 0; planes < 3; ++planes) {
- if (m_textures[planes] == 0)
- break;
- }
-#if QT_CONFIG(gstreamer_gl)
- if (rhi) {
- rhi->makeThreadLocalNativeContextCurrent();
- QOpenGLFunctions functions(glContext);
- functions.glDeleteTextures(planes, m_textures);
- }
-#endif
- }
-}
-
-
-QVideoFrame::MapMode QGstVideoBuffer::mapMode() const
-{
- return m_mode;
-}
-
-QAbstractVideoBuffer::MapData QGstVideoBuffer::map(QVideoFrame::MapMode mode)
-{
- const GstMapFlags flags = GstMapFlags(((mode & QVideoFrame::ReadOnly) ? GST_MAP_READ : 0)
- | ((mode & QVideoFrame::WriteOnly) ? GST_MAP_WRITE : 0));
-
- MapData mapData;
- if (mode == QVideoFrame::NotMapped || m_mode != QVideoFrame::NotMapped)
- return mapData;
-
- if (m_videoInfo.finfo->n_planes == 0) { // Encoded
- if (gst_buffer_map(m_buffer, &m_frame.map[0], flags)) {
- mapData.nPlanes = 1;
- mapData.bytesPerLine[0] = -1;
- mapData.size[0] = m_frame.map[0].size;
- mapData.data[0] = static_cast<uchar *>(m_frame.map[0].data);
-
- m_mode = mode;
- }
- } else if (gst_video_frame_map(&m_frame, &m_videoInfo, m_buffer, flags)) {
- mapData.nPlanes = GST_VIDEO_FRAME_N_PLANES(&m_frame);
-
- for (guint i = 0; i < GST_VIDEO_FRAME_N_PLANES(&m_frame); ++i) {
- mapData.bytesPerLine[i] = GST_VIDEO_FRAME_PLANE_STRIDE(&m_frame, i);
- mapData.data[i] = static_cast<uchar *>(GST_VIDEO_FRAME_PLANE_DATA(&m_frame, i));
- mapData.size[i] = mapData.bytesPerLine[i]*GST_VIDEO_FRAME_COMP_HEIGHT(&m_frame, i);
- }
-
- m_mode = mode;
- }
- return mapData;
-}
-
-void QGstVideoBuffer::unmap()
-{
- if (m_mode != QVideoFrame::NotMapped) {
- if (m_videoInfo.finfo->n_planes == 0)
- gst_buffer_unmap(m_buffer, &m_frame.map[0]);
- else
- gst_video_frame_unmap(&m_frame);
- }
- m_mode = QVideoFrame::NotMapped;
-}
-
-#if QT_CONFIG(gstreamer_gl)
-static int
-fourccFromVideoInfo(const GstVideoInfo * info, int plane)
-{
- GstVideoFormat format = GST_VIDEO_INFO_FORMAT (info);
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- const gint rgba_fourcc = DRM_FORMAT_ABGR8888;
- const gint rgb_fourcc = DRM_FORMAT_BGR888;
- const gint rg_fourcc = DRM_FORMAT_GR88;
-#else
- const gint rgba_fourcc = DRM_FORMAT_RGBA8888;
- const gint rgb_fourcc = DRM_FORMAT_RGB888;
- const gint rg_fourcc = DRM_FORMAT_RG88;
-#endif
-
- GST_DEBUG ("Getting DRM fourcc for %s plane %i",
- gst_video_format_to_string (format), plane);
-
- switch (format) {
- case GST_VIDEO_FORMAT_RGB16:
- case GST_VIDEO_FORMAT_BGR16:
- return DRM_FORMAT_RGB565;
-
- case GST_VIDEO_FORMAT_RGB:
- case GST_VIDEO_FORMAT_BGR:
- return rgb_fourcc;
-
- case GST_VIDEO_FORMAT_RGBA:
- case GST_VIDEO_FORMAT_RGBx:
- case GST_VIDEO_FORMAT_BGRA:
- case GST_VIDEO_FORMAT_BGRx:
- case GST_VIDEO_FORMAT_ARGB:
- case GST_VIDEO_FORMAT_xRGB:
- case GST_VIDEO_FORMAT_ABGR:
- case GST_VIDEO_FORMAT_xBGR:
- case GST_VIDEO_FORMAT_AYUV:
-#if GST_CHECK_PLUGINS_BASE_VERSION(1,16,0)
- case GST_VIDEO_FORMAT_VUYA:
-#endif
- return rgba_fourcc;
-
- case GST_VIDEO_FORMAT_GRAY8:
- return DRM_FORMAT_R8;
-
- case GST_VIDEO_FORMAT_YUY2:
- case GST_VIDEO_FORMAT_UYVY:
- case GST_VIDEO_FORMAT_GRAY16_LE:
- case GST_VIDEO_FORMAT_GRAY16_BE:
- return rg_fourcc;
-
- case GST_VIDEO_FORMAT_NV12:
- case GST_VIDEO_FORMAT_NV21:
- return plane == 0 ? DRM_FORMAT_R8 : rg_fourcc;
-
- case GST_VIDEO_FORMAT_I420:
- case GST_VIDEO_FORMAT_YV12:
- case GST_VIDEO_FORMAT_Y41B:
- case GST_VIDEO_FORMAT_Y42B:
- case GST_VIDEO_FORMAT_Y444:
- return DRM_FORMAT_R8;
-
-#if GST_CHECK_PLUGINS_BASE_VERSION(1,16,0)
- case GST_VIDEO_FORMAT_BGR10A2_LE:
- return DRM_FORMAT_BGRA1010102;
-#endif
-
-// case GST_VIDEO_FORMAT_RGB10A2_LE:
-// return DRM_FORMAT_RGBA1010102;
-
- case GST_VIDEO_FORMAT_P010_10LE:
-// case GST_VIDEO_FORMAT_P012_LE:
-// case GST_VIDEO_FORMAT_P016_LE:
- return plane == 0 ? DRM_FORMAT_R16 : DRM_FORMAT_GR1616;
-
- case GST_VIDEO_FORMAT_P010_10BE:
-// case GST_VIDEO_FORMAT_P012_BE:
-// case GST_VIDEO_FORMAT_P016_BE:
- return plane == 0 ? DRM_FORMAT_R16 : DRM_FORMAT_RG1616;
-
- default:
- GST_ERROR ("Unsupported format for DMABuf.");
- return -1;
- }
-}
-#endif
-
-void QGstVideoBuffer::mapTextures()
-{
- if (!rhi)
- return;
-
-#if QT_CONFIG(gstreamer_gl)
- if (memoryFormat == QGstCaps::GLTexture) {
- auto *mem = GST_GL_BASE_MEMORY_CAST(gst_buffer_peek_memory(m_buffer, 0));
- Q_ASSERT(mem);
- if (!gst_video_frame_map(&m_frame, &m_videoInfo, m_buffer, GstMapFlags(GST_MAP_READ|GST_MAP_GL))) {
- qWarning() << "Could not map GL textures";
- } else {
- auto *sync_meta = gst_buffer_get_gl_sync_meta(m_buffer);
-
- if (!sync_meta) {
- m_syncBuffer = gst_buffer_new();
- sync_meta = gst_buffer_add_gl_sync_meta(mem->context, m_syncBuffer);
- }
- gst_gl_sync_meta_set_sync_point (sync_meta, mem->context);
- gst_gl_sync_meta_wait (sync_meta, mem->context);
-
- int nPlanes = m_frame.info.finfo->n_planes;
- for (int i = 0; i < nPlanes; ++i) {
- m_textures[i] = *(guint32 *)m_frame.data[i];
- }
- gst_video_frame_unmap(&m_frame);
- }
- }
-#if GST_GL_HAVE_PLATFORM_EGL
- else if (memoryFormat == QGstCaps::DMABuf) {
- if (m_textures[0])
- return;
- Q_ASSERT(gst_is_dmabuf_memory(gst_buffer_peek_memory(m_buffer, 0)));
- Q_ASSERT(eglDisplay);
- Q_ASSERT(eglImageTargetTexture2D);
-
- auto *nativeHandles = static_cast<const QRhiGles2NativeHandles *>(rhi->nativeHandles());
- glContext = nativeHandles->context;
- if (!glContext) {
- qWarning() << "no GL context";
- return;
- }
-
- if (!gst_video_frame_map(&m_frame, &m_videoInfo, m_buffer, GstMapFlags(GST_MAP_READ))) {
- qDebug() << "Couldn't map DMA video frame";
- return;
- }
-
- int nPlanes = GST_VIDEO_FRAME_N_PLANES(&m_frame);
-// int width = GST_VIDEO_FRAME_WIDTH(&m_frame);
-// int height = GST_VIDEO_FRAME_HEIGHT(&m_frame);
- Q_ASSERT(GST_VIDEO_FRAME_N_PLANES(&m_frame) == gst_buffer_n_memory(m_buffer));
-
- QOpenGLFunctions functions(glContext);
- functions.glGenTextures(nPlanes, m_textures);
- m_ownTextures = true;
-
-// qDebug() << Qt::hex << "glGenTextures: glerror" << glGetError() << "egl error" << eglGetError();
-// qDebug() << "converting DMA buffer nPlanes=" << nPlanes << m_textures[0] << m_textures[1] << m_textures[2];
-
- for (int i = 0; i < nPlanes; ++i) {
- auto offset = GST_VIDEO_FRAME_PLANE_OFFSET(&m_frame, i);
- auto stride = GST_VIDEO_FRAME_PLANE_STRIDE(&m_frame, i);
- int planeWidth = GST_VIDEO_FRAME_COMP_WIDTH(&m_frame, i);
- int planeHeight = GST_VIDEO_FRAME_COMP_HEIGHT(&m_frame, i);
- auto mem = gst_buffer_peek_memory(m_buffer, i);
- int fd = gst_dmabuf_memory_get_fd(mem);
-
-// qDebug() << " plane" << i << "size" << width << height << "stride" << stride << "offset" << offset << "fd=" << fd;
- // ### do we need to open/close the fd?
- // ### can we convert several planes at once?
- // Get the correct DRM_FORMATs from the texture format in the description
- EGLAttrib const attribute_list[] = {
- EGL_WIDTH, planeWidth,
- EGL_HEIGHT, planeHeight,
- EGL_LINUX_DRM_FOURCC_EXT, fourccFromVideoInfo(&m_videoInfo, i),
- EGL_DMA_BUF_PLANE0_FD_EXT, fd,
- EGL_DMA_BUF_PLANE0_OFFSET_EXT, (EGLAttrib)offset,
- EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
- EGL_NONE
- };
- EGLImage image = eglCreateImage(eglDisplay,
- EGL_NO_CONTEXT,
- EGL_LINUX_DMA_BUF_EXT,
- nullptr,
- attribute_list);
- if (image == EGL_NO_IMAGE_KHR) {
- qWarning() << "could not create EGL image for plane" << i << Qt::hex << eglGetError();
- }
-// qDebug() << Qt::hex << "eglCreateImage: glerror" << glGetError() << "egl error" << eglGetError();
- functions.glBindTexture(GL_TEXTURE_2D, m_textures[i]);
-// qDebug() << Qt::hex << "bind texture: glerror" << glGetError() << "egl error" << eglGetError();
- auto EGLImageTargetTexture2D = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglImageTargetTexture2D;
- EGLImageTargetTexture2D(GL_TEXTURE_2D, image);
-// qDebug() << Qt::hex << "glerror" << glGetError() << "egl error" << eglGetError();
- eglDestroyImage(eglDisplay, image);
- }
- gst_video_frame_unmap(&m_frame);
- }
-#endif
-#endif
- m_texturesUploaded = true;
-}
-
-quint64 QGstVideoBuffer::textureHandle(int plane) const
-{
- return m_textures[plane];
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/common/qgstvideobuffer_p.h b/src/multimedia/platform/gstreamer/common/qgstvideobuffer_p.h
deleted file mode 100644
index bcd60539b..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstvideobuffer_p.h
+++ /dev/null
@@ -1,103 +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 QGSTVIDEOBUFFER_P_H
-#define QGSTVIDEOBUFFER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qtmultimediaglobal_p.h>
-#include <private/qabstractvideobuffer_p.h>
-#include <QtCore/qvariant.h>
-
-#include <private/qgst_p.h>
-#include <gst/video/video.h>
-
-QT_BEGIN_NAMESPACE
-class QVideoFrameFormat;
-class QGstreamerVideoSink;
-class QOpenGLContext;
-
-class Q_MULTIMEDIA_EXPORT QGstVideoBuffer : public QAbstractVideoBuffer
-{
-public:
-
- QGstVideoBuffer(GstBuffer *buffer, const GstVideoInfo &info, QGstreamerVideoSink *sink,
- const QVideoFrameFormat &frameFormat, QGstCaps::MemoryFormat format);
- QGstVideoBuffer(GstBuffer *buffer, const QVideoFrameFormat &format, const GstVideoInfo &info)
- : QGstVideoBuffer(buffer, info, nullptr, format, QGstCaps::CpuMemory)
- {}
- ~QGstVideoBuffer();
-
- GstBuffer *buffer() const { return m_buffer; }
- QVideoFrame::MapMode mapMode() const override;
-
- MapData map(QVideoFrame::MapMode mode) override;
- void unmap() override;
-
- void mapTextures() override;
- quint64 textureHandle(int plane) const override;
-private:
- QGstCaps::MemoryFormat memoryFormat = QGstCaps::CpuMemory;
- QVideoFrameFormat m_frameFormat;
- mutable GstVideoInfo m_videoInfo;
- mutable GstVideoFrame m_frame;
- GstBuffer *m_buffer = nullptr;
- GstBuffer *m_syncBuffer = nullptr;
- QVideoFrame::MapMode m_mode = QVideoFrame::NotMapped;
- QOpenGLContext *glContext = nullptr;
- Qt::HANDLE eglDisplay = nullptr;
- QFunctionPointer eglImageTargetTexture2D = nullptr;
- uint m_textures[3] = {};
- bool m_texturesUploaded = false;
- bool m_ownTextures = false;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/common/qgstvideorenderersink.cpp b/src/multimedia/platform/gstreamer/common/qgstvideorenderersink.cpp
deleted file mode 100644
index a74fa1b4b..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstvideorenderersink.cpp
+++ /dev/null
@@ -1,601 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Jolla 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 <qvideoframe.h>
-#include <qvideosink.h>
-#include <QDebug>
-#include <QMap>
-#include <QThread>
-#include <QEvent>
-#include <QCoreApplication>
-
-#include <private/qfactoryloader_p.h>
-#include "qgstvideobuffer_p.h"
-#include "qgstreamervideosink_p.h"
-
-#include "qgstvideorenderersink_p.h"
-
-#include <gst/video/video.h>
-#include <gst/video/gstvideometa.h>
-
-#include "qgstutils_p.h"
-
-#include <QtGui/private/qrhi_p.h>
-#if QT_CONFIG(gstreamer_gl)
-#include <gst/gl/gl.h>
-#endif // #if QT_CONFIG(gstreamer_gl)
-
-// DMA support
-#include <gst/allocators/gstdmabuf.h>
-
-//#define DEBUG_VIDEO_SURFACE_SINK
-
-QT_BEGIN_NAMESPACE
-
-QGstVideoRenderer::QGstVideoRenderer(QGstreamerVideoSink *sink)
- : m_sink(sink)
-{
- createSurfaceCaps();
-}
-
-QGstVideoRenderer::~QGstVideoRenderer()
-{
-}
-
-void QGstVideoRenderer::createSurfaceCaps()
-{
- QRhi *rhi = m_sink->rhi();
- Q_UNUSED(rhi);
-
- QGstMutableCaps caps;
- caps.create();
-
- // All the formats that both we and gstreamer support
- auto formats = QList<QVideoFrameFormat::PixelFormat>()
- << QVideoFrameFormat::Format_YUV420P
- << QVideoFrameFormat::Format_YUV422P
- << QVideoFrameFormat::Format_YV12
- << QVideoFrameFormat::Format_UYVY
- << QVideoFrameFormat::Format_YUYV
- << QVideoFrameFormat::Format_NV12
- << QVideoFrameFormat::Format_NV21
- << QVideoFrameFormat::Format_AYUV
- << QVideoFrameFormat::Format_P010
- << QVideoFrameFormat::Format_XRGB8888
- << QVideoFrameFormat::Format_XBGR8888
- << QVideoFrameFormat::Format_RGBX8888
- << QVideoFrameFormat::Format_BGRX8888
- << QVideoFrameFormat::Format_ARGB8888
- << QVideoFrameFormat::Format_ABGR8888
- << QVideoFrameFormat::Format_RGBA8888
- << QVideoFrameFormat::Format_BGRA8888
- << QVideoFrameFormat::Format_Y8
- << QVideoFrameFormat::Format_Y16
- ;
-#if QT_CONFIG(gstreamer_gl)
- if (rhi && rhi->backend() == QRhi::OpenGLES2) {
- caps.addPixelFormats(formats, GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
- if (m_sink->eglDisplay() && m_sink->eglImageTargetTexture2D()) {
- // We currently do not handle planar DMA buffers, as it's somewhat unclear how to
- // convert the planar EGLImage into something we can use from OpenGL
- auto singlePlaneFormats = QList<QVideoFrameFormat::PixelFormat>()
- << QVideoFrameFormat::Format_UYVY
- << QVideoFrameFormat::Format_YUYV
- << QVideoFrameFormat::Format_AYUV
- << QVideoFrameFormat::Format_XRGB8888
- << QVideoFrameFormat::Format_XBGR8888
- << QVideoFrameFormat::Format_RGBX8888
- << QVideoFrameFormat::Format_BGRX8888
- << QVideoFrameFormat::Format_ARGB8888
- << QVideoFrameFormat::Format_ABGR8888
- << QVideoFrameFormat::Format_RGBA8888
- << QVideoFrameFormat::Format_BGRA8888
- << QVideoFrameFormat::Format_Y8
- << QVideoFrameFormat::Format_Y16
- ;
- caps.addPixelFormats(singlePlaneFormats, GST_CAPS_FEATURE_MEMORY_DMABUF);
- }
- }
-#endif
- caps.addPixelFormats(formats);
-
- m_surfaceCaps = caps;
-}
-
-QGstMutableCaps QGstVideoRenderer::caps()
-{
- QMutexLocker locker(&m_mutex);
-
- return m_surfaceCaps;
-}
-
-bool QGstVideoRenderer::start(GstCaps *caps)
-{
-// qDebug() << "QGstVideoRenderer::start" << QGstCaps(caps).toString();
- QMutexLocker locker(&m_mutex);
-
- if (m_active) {
- m_flush = true;
- m_stop = true;
- }
-
- m_startCaps = QGstMutableCaps(caps, QGstMutableCaps::NeedsRef);
-
- /*
- Waiting for start() to be invoked in the main thread may block
- if gstreamer blocks the main thread until this call is finished.
- This situation is rare and usually caused by setState(Null)
- while pipeline is being prerolled.
-
- The proper solution to this involves controlling gstreamer pipeline from
- other thread than video surface.
-
- Currently start() fails if wait() timed out.
- */
- if (!waitForAsyncEvent(&locker, &m_setupCondition, 1000) && !m_startCaps.isNull()) {
- qWarning() << "Failed to start video surface due to main thread blocked.";
- m_startCaps = {};
- }
-
- return m_active;
-}
-
-void QGstVideoRenderer::stop()
-{
- QMutexLocker locker(&m_mutex);
-
- if (!m_active)
- return;
-
- m_flush = true;
- m_stop = true;
-
- m_startCaps = {};
-
- waitForAsyncEvent(&locker, &m_setupCondition, 500);
-}
-
-void QGstVideoRenderer::unlock()
-{
- QMutexLocker locker(&m_mutex);
-
- m_setupCondition.wakeAll();
- m_renderCondition.wakeAll();
-}
-
-bool QGstVideoRenderer::proposeAllocation(GstQuery *query)
-{
- Q_UNUSED(query);
- QMutexLocker locker(&m_mutex);
- return m_active;
-}
-
-void QGstVideoRenderer::flush()
-{
- QMutexLocker locker(&m_mutex);
-
- m_flush = true;
- m_renderBuffer = nullptr;
- m_renderCondition.wakeAll();
-
- notify();
-}
-
-GstFlowReturn QGstVideoRenderer::render(GstBuffer *buffer)
-{
- QMutexLocker locker(&m_mutex);
-
- m_renderReturn = GST_FLOW_OK;
- m_renderBuffer = buffer;
-
- waitForAsyncEvent(&locker, &m_renderCondition, 300);
-
- m_renderBuffer = nullptr;
-
- return m_renderReturn;
-}
-
-bool QGstVideoRenderer::query(GstQuery *query)
-{
-#if QT_CONFIG(gstreamer_gl)
- if (GST_QUERY_TYPE(query) == GST_QUERY_CONTEXT) {
- const gchar *type;
- gst_query_parse_context_type(query, &type);
-
- if (strcmp(type, "gst.gl.local_context") != 0)
- return false;
-
- auto *gstGlContext = m_sink->gstGlLocalContext();
- if (!gstGlContext)
- return false;
-
- gst_query_set_context(query, gstGlContext);
-
- return true;
- }
-#else
- Q_UNUSED(query);
-#endif
- return false;
-}
-
-bool QGstVideoRenderer::event(QEvent *event)
-{
- if (event->type() == QEvent::UpdateRequest) {
- QMutexLocker locker(&m_mutex);
-
- if (m_notified) {
- while (handleEvent(&locker)) {}
- m_notified = false;
- }
- return true;
- }
-
- return QObject::event(event);
-}
-
-bool QGstVideoRenderer::handleEvent(QMutexLocker<QMutex> *locker)
-{
- if (m_flush) {
- m_flush = false;
- if (m_active) {
- locker->unlock();
-
- if (m_sink && !m_flushed)
- m_sink->setVideoFrame(QVideoFrame());
- m_flushed = true;
- }
- } else if (m_stop) {
- m_stop = false;
-
- if (m_active) {
- m_active = false;
- m_flushed = true;
- }
- } else if (!m_startCaps.isNull()) {
- Q_ASSERT(!m_active);
-
- auto startCaps = m_startCaps;
- m_startCaps = nullptr;
-
- if (m_sink) {
- locker->unlock();
-
- m_flushed = true;
- m_format = startCaps.formatForCaps(&m_videoInfo);
- memoryFormat = startCaps.memoryFormat();
-
- locker->relock();
- m_active = m_format.isValid();
- } else if (m_active) {
- m_active = false;
- m_flushed = true;
- }
-
- } else if (m_renderBuffer) {
- GstBuffer *buffer = m_renderBuffer;
- m_renderBuffer = nullptr;
- m_renderReturn = GST_FLOW_ERROR;
-
- if (m_active && m_sink) {
- gst_buffer_ref(buffer);
-
- locker->unlock();
-
- m_flushed = false;
-
- auto meta = gst_buffer_get_video_crop_meta (buffer);
- if (meta) {
- QRect vp(meta->x, meta->y, meta->width, meta->height);
- if (m_format.viewport() != vp) {
-#ifdef DEBUG_VIDEO_SURFACE_SINK
- qDebug() << Q_FUNC_INFO << " Update viewport on Metadata: [" << meta->height << "x" << meta->width << " | " << meta->x << "x" << meta->y << "]";
-#endif \
- //Update viewport if data is not the same
- m_format.setViewport(vp);
- }
- }
-
- QGstVideoBuffer *videoBuffer = new QGstVideoBuffer(buffer, m_videoInfo, m_sink, m_format, memoryFormat);
- QVideoFrame frame(videoBuffer, m_format);
- QGstUtils::setFrameTimeStamps(&frame, buffer);
-
- m_sink->setVideoFrame(frame);
-
- gst_buffer_unref(buffer);
-
- locker->relock();
-
- m_renderReturn = GST_FLOW_OK;
- }
-
- m_renderCondition.wakeAll();
- } else {
- m_setupCondition.wakeAll();
-
- return false;
- }
- return true;
-}
-
-void QGstVideoRenderer::notify()
-{
- if (!m_notified) {
- m_notified = true;
- QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
- }
-}
-
-bool QGstVideoRenderer::waitForAsyncEvent(
- QMutexLocker<QMutex> *locker, QWaitCondition *condition, unsigned long time)
-{
- if (QThread::currentThread() == thread()) {
- while (handleEvent(locker)) {}
- m_notified = false;
-
- return true;
- }
-
- notify();
-
- return condition->wait(&m_mutex, time);
-}
-
-static GstVideoSinkClass *sink_parent_class;
-static thread_local QGstreamerVideoSink *current_sink;
-
-#define VO_SINK(s) QGstVideoRendererSink *sink(reinterpret_cast<QGstVideoRendererSink *>(s))
-
-QGstVideoRendererSink *QGstVideoRendererSink::createSink(QGstreamerVideoSink *sink)
-{
- setSink(sink);
- QGstVideoRendererSink *gstSink = reinterpret_cast<QGstVideoRendererSink *>(
- g_object_new(QGstVideoRendererSink::get_type(), nullptr));
-
- g_signal_connect(G_OBJECT(gstSink), "notify::show-preroll-frame", G_CALLBACK(handleShowPrerollChange), gstSink);
-
- return gstSink;
-}
-
-void QGstVideoRendererSink::setSink(QGstreamerVideoSink *sink)
-{
- current_sink = sink;
- get_type();
-}
-
-GType QGstVideoRendererSink::get_type()
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info =
- {
- sizeof(QGstVideoRendererSinkClass), // class_size
- base_init, // base_init
- nullptr, // base_finalize
- class_init, // class_init
- nullptr, // class_finalize
- nullptr, // class_data
- sizeof(QGstVideoRendererSink), // instance_size
- 0, // n_preallocs
- instance_init, // instance_init
- nullptr // value_table
- };
-
- type = g_type_register_static(
- GST_TYPE_VIDEO_SINK, "QGstVideoRendererSink", &info, GTypeFlags(0));
-
- // Register the sink type to be used in custom piplines.
- // When surface is ready the sink can be used.
- gst_element_register(nullptr, "qtvideosink", GST_RANK_PRIMARY, type);
- }
-
- return type;
-}
-
-void QGstVideoRendererSink::class_init(gpointer g_class, gpointer class_data)
-{
- Q_UNUSED(class_data);
-
- sink_parent_class = reinterpret_cast<GstVideoSinkClass *>(g_type_class_peek_parent(g_class));
-
- GstVideoSinkClass *video_sink_class = reinterpret_cast<GstVideoSinkClass *>(g_class);
- video_sink_class->show_frame = QGstVideoRendererSink::show_frame;
-
- GstBaseSinkClass *base_sink_class = reinterpret_cast<GstBaseSinkClass *>(g_class);
- base_sink_class->get_caps = QGstVideoRendererSink::get_caps;
- base_sink_class->set_caps = QGstVideoRendererSink::set_caps;
- base_sink_class->propose_allocation = QGstVideoRendererSink::propose_allocation;
- base_sink_class->stop = QGstVideoRendererSink::stop;
- base_sink_class->unlock = QGstVideoRendererSink::unlock;
- base_sink_class->query = QGstVideoRendererSink::query;
-
- GstElementClass *element_class = reinterpret_cast<GstElementClass *>(g_class);
- element_class->change_state = QGstVideoRendererSink::change_state;
- gst_element_class_set_metadata(element_class,
- "Qt built-in video renderer sink",
- "Sink/Video",
- "Qt default built-in video renderer sink",
- "The Qt Company");
-
- GObjectClass *object_class = reinterpret_cast<GObjectClass *>(g_class);
- object_class->finalize = QGstVideoRendererSink::finalize;
-}
-
-void QGstVideoRendererSink::base_init(gpointer g_class)
-{
- static GstStaticPadTemplate sink_pad_template = GST_STATIC_PAD_TEMPLATE(
- "sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS(
- "video/x-raw, "
- "framerate = (fraction) [ 0, MAX ], "
- "width = (int) [ 1, MAX ], "
- "height = (int) [ 1, MAX ]"));
-
- gst_element_class_add_pad_template(
- GST_ELEMENT_CLASS(g_class), gst_static_pad_template_get(&sink_pad_template));
-}
-
-void QGstVideoRendererSink::instance_init(GTypeInstance *instance, gpointer g_class)
-{
- Q_UNUSED(g_class);
- VO_SINK(instance);
-
- Q_ASSERT(current_sink);
-
- sink->renderer = new QGstVideoRenderer(current_sink);
- sink->renderer->moveToThread(current_sink->thread());
- current_sink = nullptr;
-}
-
-void QGstVideoRendererSink::finalize(GObject *object)
-{
- VO_SINK(object);
-
- delete sink->renderer;
-
- // Chain up
- G_OBJECT_CLASS(sink_parent_class)->finalize(object);
-}
-
-void QGstVideoRendererSink::handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d)
-{
- Q_UNUSED(o);
- Q_UNUSED(p);
- QGstVideoRendererSink *sink = reinterpret_cast<QGstVideoRendererSink *>(d);
-
- gboolean showPrerollFrame = true; // "show-preroll-frame" property is true by default
- g_object_get(G_OBJECT(sink), "show-preroll-frame", &showPrerollFrame, nullptr);
-
- if (!showPrerollFrame) {
- GstState state = GST_STATE_VOID_PENDING;
- GstClockTime timeout = 10000000; // 10 ms
- gst_element_get_state(GST_ELEMENT(sink), &state, nullptr, timeout);
- // show-preroll-frame being set to 'false' while in GST_STATE_PAUSED means
- // the QMediaPlayer was stopped from the paused state.
- // We need to flush the current frame.
- if (state == GST_STATE_PAUSED)
- sink->renderer->flush();
- }
-}
-
-GstStateChangeReturn QGstVideoRendererSink::change_state(
- GstElement *element, GstStateChange transition)
-{
- QGstVideoRendererSink *sink = reinterpret_cast<QGstVideoRendererSink *>(element);
-
- gboolean showPrerollFrame = true; // "show-preroll-frame" property is true by default
- g_object_get(G_OBJECT(element), "show-preroll-frame", &showPrerollFrame, nullptr);
-
- // If show-preroll-frame is 'false' when transitioning from GST_STATE_PLAYING to
- // GST_STATE_PAUSED, it means the QMediaPlayer was stopped.
- // We need to flush the current frame.
- if (transition == GST_STATE_CHANGE_PLAYING_TO_PAUSED && !showPrerollFrame)
- sink->renderer->flush();
-
- return GST_ELEMENT_CLASS(sink_parent_class)->change_state(element, transition);
-}
-
-GstCaps *QGstVideoRendererSink::get_caps(GstBaseSink *base, GstCaps *filter)
-{
- VO_SINK(base);
-
- QGstMutableCaps caps = sink->renderer->caps();
- if (filter)
- caps = gst_caps_intersect(caps.get(), filter);
-
- gst_caps_ref(caps.get());
- return caps.get();
-}
-
-gboolean QGstVideoRendererSink::set_caps(GstBaseSink *base, GstCaps *caps)
-{
- VO_SINK(base);
-
-#ifdef DEBUG_VIDEO_SURFACE_SINK
- qDebug() << "set_caps:";
- qDebug() << caps;
-#endif
-
- if (!caps) {
- sink->renderer->stop();
-
- return TRUE;
- } else if (sink->renderer->start(caps)) {
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-gboolean QGstVideoRendererSink::propose_allocation(GstBaseSink *base, GstQuery *query)
-{
- VO_SINK(base);
- return sink->renderer->proposeAllocation(query);
-}
-
-gboolean QGstVideoRendererSink::stop(GstBaseSink *base)
-{
- VO_SINK(base);
- sink->renderer->stop();
- return TRUE;
-}
-
-gboolean QGstVideoRendererSink::unlock(GstBaseSink *base)
-{
- VO_SINK(base);
- sink->renderer->unlock();
- return TRUE;
-}
-
-GstFlowReturn QGstVideoRendererSink::show_frame(GstVideoSink *base, GstBuffer *buffer)
-{
- VO_SINK(base);
- return sink->renderer->render(buffer);
-}
-
-gboolean QGstVideoRendererSink::query(GstBaseSink *base, GstQuery *query)
-{
- VO_SINK(base);
- if (sink->renderer->query(query))
- return TRUE;
-
- return GST_BASE_SINK_CLASS(sink_parent_class)->query(base, query);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/common/qgstvideorenderersink_p.h b/src/multimedia/platform/gstreamer/common/qgstvideorenderersink_p.h
deleted file mode 100644
index 9cbd6b5b2..000000000
--- a/src/multimedia/platform/gstreamer/common/qgstvideorenderersink_p.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Jolla 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 QGSTVIDEORENDERERSINK_P_H
-#define QGSTVIDEORENDERERSINK_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtMultimedia/private/qtmultimediaglobal_p.h>
-#include <gst/video/gstvideosink.h>
-#include <gst/video/video.h>
-
-#include <QtCore/qlist.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qqueue.h>
-#include <QtCore/qpointer.h>
-#include <QtCore/qwaitcondition.h>
-#include <qvideoframeformat.h>
-#include <qvideoframe.h>
-#include <private/qgstvideobuffer_p.h>
-#include <private/qgst_p.h>
-
-QT_BEGIN_NAMESPACE
-class QVideoSink;
-
-class QGstVideoRenderer : public QObject
-{
- Q_OBJECT
-public:
- QGstVideoRenderer(QGstreamerVideoSink *sink);
- ~QGstVideoRenderer();
-
- QGstMutableCaps caps();
-
- bool start(GstCaps *caps);
- void stop();
- void unlock();
- bool proposeAllocation(GstQuery *query);
-
- void flush();
-
- GstFlowReturn render(GstBuffer *buffer);
-
- bool event(QEvent *event) override;
- bool query(GstQuery *query);
-
-private slots:
- bool handleEvent(QMutexLocker<QMutex> *locker);
-
-private:
- void notify();
- bool waitForAsyncEvent(QMutexLocker<QMutex> *locker, QWaitCondition *condition, unsigned long time);
- void createSurfaceCaps();
-
- QPointer<QGstreamerVideoSink> m_sink;
-
- QMutex m_mutex;
- QWaitCondition m_setupCondition;
- QWaitCondition m_renderCondition;
-
- // --- accessed from multiple threads, need to hold mutex to access
- GstFlowReturn m_renderReturn = GST_FLOW_OK;
- bool m_active = false;
-
- QGstMutableCaps m_surfaceCaps;
-
- QGstMutableCaps m_startCaps;
- GstBuffer *m_renderBuffer = nullptr;
-
- bool m_notified = false;
- bool m_stop = false;
- bool m_flush = false;
-
- // --- only accessed from one thread
- QVideoFrameFormat m_format;
- GstVideoInfo m_videoInfo;
- bool m_flushed = true;
- QGstCaps::MemoryFormat memoryFormat = QGstCaps::CpuMemory;
-};
-
-class Q_MULTIMEDIA_EXPORT QGstVideoRendererSink
-{
-public:
- GstVideoSink parent;
-
- static QGstVideoRendererSink *createSink(QGstreamerVideoSink *surface);
- static void setSink(QGstreamerVideoSink *surface);
-
-private:
- static GType get_type();
- static void class_init(gpointer g_class, gpointer class_data);
- static void base_init(gpointer g_class);
- static void instance_init(GTypeInstance *instance, gpointer g_class);
-
- static void finalize(GObject *object);
-
- static void handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d);
-
- static GstStateChangeReturn change_state(GstElement *element, GstStateChange transition);
-
- static GstCaps *get_caps(GstBaseSink *sink, GstCaps *filter);
- static gboolean set_caps(GstBaseSink *sink, GstCaps *caps);
-
- static gboolean propose_allocation(GstBaseSink *sink, GstQuery *query);
-
- static gboolean stop(GstBaseSink *sink);
-
- static gboolean unlock(GstBaseSink *sink);
-
- static GstFlowReturn show_frame(GstVideoSink *sink, GstBuffer *buffer);
- static gboolean query(GstBaseSink *element, GstQuery *query);
-
-private:
- QGstVideoRenderer *renderer = nullptr;
-};
-
-
-class QGstVideoRendererSinkClass
-{
-public:
- GstVideoSinkClass parent_class;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp
deleted file mode 100644
index 1ee0244ef..000000000
--- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera.cpp
+++ /dev/null
@@ -1,738 +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 <qcameradevice.h>
-
-#include "qgstreamercamera_p.h"
-#include "qgstreamerimagecapture_p.h"
-#include <private/qgstreamermediadevices_p.h>
-#include <private/qgstreamerintegration_p.h>
-#include <qmediacapturesession.h>
-
-#if QT_CONFIG(linux_v4l)
-#include <linux/videodev2.h>
-#include <private/qcore_unix_p.h>
-#endif
-
-#include <QtCore/qdebug.h>
-
-QGstreamerCamera::QGstreamerCamera(QCamera *camera)
- : QPlatformCamera(camera)
-{
- gstCamera = QGstElement("videotestsrc");
- gstCapsFilter = QGstElement("capsfilter", "videoCapsFilter");
- gstDecode = QGstElement("identity");
- gstVideoConvert = QGstElement("videoconvert", "videoConvert");
- gstVideoScale = QGstElement("videoscale", "videoScale");
- gstCameraBin = QGstBin("camerabin");
- gstCameraBin.add(gstCamera, gstCapsFilter, gstDecode, gstVideoConvert, gstVideoScale);
- gstCamera.link(gstCapsFilter, gstDecode, gstVideoConvert, gstVideoScale);
- gstCameraBin.addGhostPad(gstVideoScale, "src");
-}
-
-QGstreamerCamera::~QGstreamerCamera()
-{
-#if QT_CONFIG(linux_v4l)
- if (v4l2FileDescriptor >= 0)
- qt_safe_close(v4l2FileDescriptor);
- v4l2FileDescriptor = -1;
-#endif
- gstCameraBin.setStateSync(GST_STATE_NULL);
-}
-
-bool QGstreamerCamera::isActive() const
-{
- return m_active;
-}
-
-void QGstreamerCamera::setActive(bool active)
-{
- if (m_active == active)
- return;
- if (m_cameraDevice.isNull() && active)
- return;
-
- m_active = active;
-
- emit activeChanged(active);
-}
-
-void QGstreamerCamera::setCamera(const QCameraDevice &camera)
-{
- if (m_cameraDevice == camera)
- return;
- qDebug() << "setCamera" << camera;
-
- m_cameraDevice = camera;
-
- QGstElement gstNewCamera;
- if (camera.isNull()) {
- gstNewCamera = QGstElement("videotestsrc");
- } else {
- auto *devices = static_cast<QGstreamerMediaDevices *>(QGstreamerIntegration::instance()->devices());
- auto *device = devices->videoDevice(camera.id());
- gstNewCamera = gst_device_create_element(device, "camerasrc");
- QGstStructure properties = gst_device_get_properties(device);
- if (properties.name() == "v4l2deviceprovider")
- m_v4l2Device = QString::fromUtf8(properties["device.path"].toString());
- }
-
- QCameraFormat f = findBestCameraFormat(camera);
- auto caps = QGstMutableCaps::fromCameraFormat(f);
- auto gstNewDecode = QGstElement(f.pixelFormat() == QVideoFrameFormat::Format_Jpeg ? "jpegdec" : "identity");
-
- gstCamera.setStateSync(GST_STATE_NULL);
- gstDecode.setStateSync(GST_STATE_NULL);
-
- gstCamera.unlink(gstCapsFilter);
- gstCapsFilter.unlink(gstDecode);
- gstDecode.unlink(gstVideoConvert);
-
- gstCameraBin.remove(gstCamera);
- gstCameraBin.remove(gstDecode);
-
- gstCapsFilter.set("caps", caps);
-
- gstCameraBin.add(gstNewCamera, gstNewDecode);
-
- gstNewDecode.link(gstVideoConvert);
- gstCapsFilter.link(gstNewDecode);
-
- if (!gstNewCamera.link(gstCapsFilter))
- qWarning() << "linking camera failed" << gstCamera.name() << caps.toString();
-
- // Start sending frames once pipeline is linked
- // FIXME: put camera to READY state before linking to decoder as in the NULL state it does not know its true caps
- gstCapsFilter.syncStateWithParent();
- gstNewDecode.syncStateWithParent();
- gstNewCamera.syncStateWithParent();
-
- gstCamera = gstNewCamera;
- gstDecode = gstNewDecode;
-
- updateCameraProperties();
-}
-
-bool QGstreamerCamera::setCameraFormat(const QCameraFormat &format)
-{
- if (!format.isNull() && !m_cameraDevice.videoFormats().contains(format))
- return false;
-
- qDebug() << "Set camera format";
-
- QCameraFormat f = format;
- if (f.isNull())
- f = findBestCameraFormat(m_cameraDevice);
-
- auto caps = QGstMutableCaps::fromCameraFormat(f);
-
- auto newGstDecode = QGstElement(f.pixelFormat() == QVideoFrameFormat::Format_Jpeg ? "jpegdec" : "identity");
- gstCameraBin.add(newGstDecode);
- newGstDecode.syncStateWithParent();
-
- gstCamera.staticPad("src").doInIdleProbe([&](){
- gstCamera.unlink(gstCapsFilter);
- gstCapsFilter.unlink(gstDecode);
- gstDecode.unlink(gstVideoConvert);
-
- gstCapsFilter.set("caps", caps);
-
- newGstDecode.link(gstVideoConvert);
- gstCapsFilter.link(newGstDecode);
- if (!gstCamera.link(gstCapsFilter))
- qWarning() << "linking filtered camera to decoder failed" << gstCamera.name() << caps.toString();
- });
-
- gstDecode.setStateSync(GST_STATE_NULL);
- gstCameraBin.remove(gstDecode);
-
- gstDecode = newGstDecode;
-
- return true;
-}
-
-void QGstreamerCamera::updateCameraProperties()
-{
-#if QT_CONFIG(linux_v4l)
- if (isV4L2Camera()) {
- initV4L2Controls();
- return;
- }
-#endif
-#if QT_CONFIG(gstreamer_photography)
- if (auto *p = photography())
- gst_photography_set_white_balance_mode(p, GST_PHOTOGRAPHY_WB_MODE_AUTO);
- QCamera::Features f = QCamera::Feature::ColorTemperature | QCamera::Feature::ExposureCompensation |
- QCamera::Feature::IsoSensitivity | QCamera::Feature::ManualExposureTime;
- supportedFeaturesChanged(f);
-#endif
-
-}
-
-#if QT_CONFIG(gstreamer_photography)
-GstPhotography *QGstreamerCamera::photography() const
-{
- if (!gstCamera.isNull() && GST_IS_PHOTOGRAPHY(gstCamera.element()))
- return GST_PHOTOGRAPHY(gstCamera.element());
- return nullptr;
-}
-#endif
-
-void QGstreamerCamera::setFocusMode(QCamera::FocusMode mode)
-{
- if (mode == focusMode())
- return;
-
-#if QT_CONFIG(gstreamer_photography)
- auto p = photography();
- if (p) {
- GstPhotographyFocusMode photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_CONTINUOUS_NORMAL;
-
- switch (mode) {
- case QCamera::FocusModeAutoNear:
- photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_MACRO;
- break;
- case QCamera::FocusModeAutoFar:
- // not quite, but hey :)
- Q_FALLTHROUGH();
- case QCamera::FocusModeHyperfocal:
- photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_HYPERFOCAL;
- break;
- case QCamera::FocusModeInfinity:
- photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_INFINITY;
- break;
- case QCamera::FocusModeManual:
- photographyMode = GST_PHOTOGRAPHY_FOCUS_MODE_MANUAL;
- break;
- default: // QCamera::FocusModeAuto:
- break;
- }
-
- if (gst_photography_set_focus_mode(p, photographyMode))
- focusModeChanged(mode);
- }
-#endif
-}
-
-bool QGstreamerCamera::isFocusModeSupported(QCamera::FocusMode mode) const
-{
-#if QT_CONFIG(gstreamer_photography)
- if (photography())
- return true;
-#endif
- return mode == QCamera::FocusModeAuto;
-}
-
-void QGstreamerCamera::setFlashMode(QCamera::FlashMode mode)
-{
- Q_UNUSED(mode);
-
-#if QT_CONFIG(gstreamer_photography)
- if (auto *p = photography()) {
- GstPhotographyFlashMode flashMode;
- gst_photography_get_flash_mode(p, &flashMode);
-
- switch (mode) {
- case QCamera::FlashAuto:
- flashMode = GST_PHOTOGRAPHY_FLASH_MODE_AUTO;
- break;
- case QCamera::FlashOff:
- flashMode = GST_PHOTOGRAPHY_FLASH_MODE_OFF;
- break;
- case QCamera::FlashOn:
- flashMode = GST_PHOTOGRAPHY_FLASH_MODE_ON;
- break;
- }
-
- if (gst_photography_set_flash_mode(p, flashMode))
- flashModeChanged(mode);
- }
-#endif
-}
-
-bool QGstreamerCamera::isFlashModeSupported(QCamera::FlashMode mode) const
-{
-#if QT_CONFIG(gstreamer_photography)
- if (photography())
- return true;
-#endif
-
- return mode == QCamera::FlashAuto;
-}
-
-bool QGstreamerCamera::isFlashReady() const
-{
-#if QT_CONFIG(gstreamer_photography)
- if (photography())
- return true;
-#endif
-
- return false;
-}
-
-void QGstreamerCamera::setExposureMode(QCamera::ExposureMode mode)
-{
- Q_UNUSED(mode);
-#if QT_CONFIG(linux_v4l)
- if (isV4L2Camera() && v4l2AutoExposureSupported && v4l2ManualExposureSupported) {
- if (mode != QCamera::ExposureAuto && mode != QCamera::ExposureManual)
- return;
- int value = QCamera::ExposureAuto ? V4L2_EXPOSURE_AUTO : V4L2_EXPOSURE_MANUAL;
- setV4L2Parameter(V4L2_CID_EXPOSURE_AUTO, value);
- exposureModeChanged(mode);
- return;
- }
-#endif
-
-#if QT_CONFIG(gstreamer_photography)
- auto *p = photography();
- if (!p)
- return;
-
- GstPhotographySceneMode sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_AUTO;
-
- switch (mode) {
- case QCamera::ExposureManual:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_MANUAL;
- break;
- case QCamera::ExposurePortrait:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_PORTRAIT;
- break;
- case QCamera::ExposureSports:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_SPORT;
- break;
- case QCamera::ExposureNight:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_NIGHT;
- break;
- case QCamera::ExposureAuto:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_AUTO;
- break;
- case QCamera::ExposureLandscape:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_LANDSCAPE;
- break;
- case QCamera::ExposureSnow:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_SNOW;
- break;
- case QCamera::ExposureBeach:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_BEACH;
- break;
- case QCamera::ExposureAction:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_ACTION;
- break;
- case QCamera::ExposureNightPortrait:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_NIGHT_PORTRAIT;
- break;
- case QCamera::ExposureTheatre:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_THEATRE;
- break;
- case QCamera::ExposureSunset:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_SUNSET;
- break;
- case QCamera::ExposureSteadyPhoto:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_STEADY_PHOTO;
- break;
- case QCamera::ExposureFireworks:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_FIREWORKS;
- break;
- case QCamera::ExposureParty:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_PARTY;
- break;
- case QCamera::ExposureCandlelight:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_CANDLELIGHT;
- break;
- case QCamera::ExposureBarcode:
- sceneMode = GST_PHOTOGRAPHY_SCENE_MODE_BARCODE;
- break;
- default:
- return;
- }
-
- if (gst_photography_set_scene_mode(p, sceneMode))
- exposureModeChanged(mode);
-#endif
-}
-
-bool QGstreamerCamera::isExposureModeSupported(QCamera::ExposureMode mode) const
-{
- if (mode == QCamera::ExposureAuto)
- return true;
-#if QT_CONFIG(linux_v4l)
- if (isV4L2Camera() && v4l2ManualExposureSupported && v4l2AutoExposureSupported)
- return mode == QCamera::ExposureManual;
-#endif
-#if QT_CONFIG(gstreamer_photography)
- if (photography())
- return true;
-#endif
-
- return false;
-}
-
-void QGstreamerCamera::setExposureCompensation(float compensation)
-{
- Q_UNUSED(compensation);
-#if QT_CONFIG(linux_v4l)
- if (isV4L2Camera() && (v4l2MinExposureAdjustment != 0 || v4l2MaxExposureAdjustment != 0)) {
- int value = qBound(v4l2MinExposureAdjustment, (int)(compensation*1000), v4l2MaxExposureAdjustment);
- setV4L2Parameter(V4L2_CID_AUTO_EXPOSURE_BIAS, value);
- exposureCompensationChanged(value/1000.);
- return;
- }
-#endif
-
-#if QT_CONFIG(gstreamer_photography)
- if (auto *p = photography()) {
- if (gst_photography_set_ev_compensation(p, compensation))
- exposureCompensationChanged(compensation);
- }
-#endif
-}
-
-void QGstreamerCamera::setManualIsoSensitivity(int iso)
-{
- Q_UNUSED(iso);
-#if QT_CONFIG(linux_v4l)
- if (isV4L2Camera()) {
- if (!(supportedFeatures() & QCamera::Feature::IsoSensitivity))
- return;
- setV4L2Parameter(V4L2_CID_ISO_SENSITIVITY_AUTO, iso <= 0 ? V4L2_ISO_SENSITIVITY_AUTO : V4L2_ISO_SENSITIVITY_MANUAL);
- if (iso > 0) {
- iso = qBound(minIso(), iso, maxIso());
- setV4L2Parameter(V4L2_CID_ISO_SENSITIVITY, iso);
- }
- return;
- }
-#endif
-#if QT_CONFIG(gstreamer_photography)
- if (auto *p = photography()) {
- if (gst_photography_set_iso_speed(p, iso))
- isoSensitivityChanged(iso);
- }
-#endif
-}
-
-int QGstreamerCamera::isoSensitivity() const
-{
-#if QT_CONFIG(linux_v4l)
- if (isV4L2Camera()) {
- if (!(supportedFeatures() & QCamera::Feature::IsoSensitivity))
- return -1;
- return getV4L2Parameter(V4L2_CID_ISO_SENSITIVITY);
- }
-#endif
-#if QT_CONFIG(gstreamer_photography)
- if (auto *p = photography()) {
- guint speed = 0;
- if (gst_photography_get_iso_speed(p, &speed))
- return speed;
- }
-#endif
- return 100;
-}
-
-void QGstreamerCamera::setManualExposureTime(float secs)
-{
- Q_UNUSED(secs);
-#if QT_CONFIG(linux_v4l)
- if (isV4L2Camera() && v4l2ManualExposureSupported && v4l2AutoExposureSupported) {
- int exposure = qBound(v4l2MinExposure, qRound(secs*10000.), v4l2MaxExposure);
- setV4L2Parameter(V4L2_CID_EXPOSURE_ABSOLUTE, exposure);
- exposureTimeChanged(exposure/10000.);
- return;
- }
-#endif
-
-#if QT_CONFIG(gstreamer_photography)
- if (auto *p = photography()) {
- if (gst_photography_set_exposure(p, guint(secs*1000000)))
- exposureTimeChanged(secs);
- }
-#endif
-}
-
-float QGstreamerCamera::exposureTime() const
-{
-#if QT_CONFIG(linux_v4l)
- if (isV4L2Camera()) {
- return getV4L2Parameter(V4L2_CID_EXPOSURE_ABSOLUTE)/10000.;
- }
-#endif
-#if QT_CONFIG(gstreamer_photography)
- if (auto *p = photography()) {
- guint32 exposure = 0;
- if (gst_photography_get_exposure(p, &exposure))
- return exposure/1000000.;
- }
-#endif
- return -1;
-}
-
-bool QGstreamerCamera::isWhiteBalanceModeSupported(QCamera::WhiteBalanceMode mode) const
-{
- if (mode == QCamera::WhiteBalanceAuto)
- return true;
-
-#if QT_CONFIG(linux_v4l)
- if (isV4L2Camera()) {
- if (v4l2AutoWhiteBalanceSupported && v4l2ColorTemperatureSupported)
- return true;
- }
-#endif
-#if QT_CONFIG(gstreamer_photography)
- if (auto *p = photography()) {
- Q_UNUSED(p);
- switch (mode) {
- case QCamera::WhiteBalanceAuto:
- case QCamera::WhiteBalanceSunlight:
- case QCamera::WhiteBalanceCloudy:
- case QCamera::WhiteBalanceShade:
- case QCamera::WhiteBalanceSunset:
- case QCamera::WhiteBalanceTungsten:
- case QCamera::WhiteBalanceFluorescent:
- return true;
- case QCamera::WhiteBalanceManual: {
-#if GST_CHECK_VERSION(1, 18, 0)
- GstPhotographyInterface *iface = GST_PHOTOGRAPHY_GET_INTERFACE(p);
- if (iface->set_color_temperature && iface->get_color_temperature)
- return true;
-#endif
- break;
- }
- default:
- break;
- }
- }
-#endif
-
- return mode == QCamera::WhiteBalanceAuto;
-}
-
-void QGstreamerCamera::setWhiteBalanceMode(QCamera::WhiteBalanceMode mode)
-{
- Q_ASSERT(isWhiteBalanceModeSupported(mode));
-
-#if QT_CONFIG(linux_v4l)
- if (isV4L2Camera()) {
- int temperature = colorTemperatureForWhiteBalance(mode);
- int t = setV4L2ColorTemperature(temperature);
- if (t == 0)
- mode = QCamera::WhiteBalanceAuto;
- whiteBalanceModeChanged(mode);
- return;
- }
-#endif
-
-#if QT_CONFIG(gstreamer_photography)
- if (auto *p = photography()) {
- GstPhotographyWhiteBalanceMode gstMode = GST_PHOTOGRAPHY_WB_MODE_AUTO;
- switch (mode) {
- case QCamera::WhiteBalanceSunlight:
- gstMode = GST_PHOTOGRAPHY_WB_MODE_DAYLIGHT;
- break;
- case QCamera::WhiteBalanceCloudy:
- gstMode = GST_PHOTOGRAPHY_WB_MODE_CLOUDY;
- break;
- case QCamera::WhiteBalanceShade:
- gstMode = GST_PHOTOGRAPHY_WB_MODE_SHADE;
- break;
- case QCamera::WhiteBalanceSunset:
- gstMode = GST_PHOTOGRAPHY_WB_MODE_SUNSET;
- break;
- case QCamera::WhiteBalanceTungsten:
- gstMode = GST_PHOTOGRAPHY_WB_MODE_TUNGSTEN;
- break;
- case QCamera::WhiteBalanceFluorescent:
- gstMode = GST_PHOTOGRAPHY_WB_MODE_FLUORESCENT;
- break;
- case QCamera::WhiteBalanceAuto:
- default:
- break;
- }
- if (gst_photography_set_white_balance_mode(p, gstMode)) {
- whiteBalanceModeChanged(mode);
- return;
- }
- }
-#endif
-}
-
-void QGstreamerCamera::setColorTemperature(int temperature)
-{
- if (temperature == 0) {
- setWhiteBalanceMode(QCamera::WhiteBalanceAuto);
- return;
- }
-
- Q_ASSERT(isWhiteBalanceModeSupported(QCamera::WhiteBalanceManual));
-
-#if QT_CONFIG(linux_v4l)
- if (isV4L2Camera()) {
- int t = setV4L2ColorTemperature(temperature);
- if (t)
- colorTemperatureChanged(t);
- return;
- }
-#endif
-
-#if QT_CONFIG(gstreamer_photography) && GST_CHECK_VERSION(1, 18, 0)
- if (auto *p = photography()) {
- GstPhotographyInterface *iface = GST_PHOTOGRAPHY_GET_INTERFACE(p);
- Q_ASSERT(iface->set_color_temperature);
- iface->set_color_temperature(p, temperature);
- return;
- }
-#endif
-}
-
-#if QT_CONFIG(linux_v4l)
-void QGstreamerCamera::initV4L2Controls()
-{
- v4l2AutoWhiteBalanceSupported = false;
- v4l2ColorTemperatureSupported = false;
- QCamera::Features features;
-
-
- const QString deviceName = v4l2Device();
- Q_ASSERT(!deviceName.isEmpty());
-
- v4l2FileDescriptor = qt_safe_open(deviceName.toLocal8Bit().constData(), O_RDONLY);
- if (v4l2FileDescriptor == -1) {
- qWarning() << "Unable to open the camera" << deviceName
- << "for read to query the parameter info:" << qt_error_string(errno);
- return;
- }
-
- struct v4l2_queryctrl queryControl;
- ::memset(&queryControl, 0, sizeof(queryControl));
- queryControl.id = V4L2_CID_AUTO_WHITE_BALANCE;
-
- if (::ioctl(v4l2FileDescriptor, VIDIOC_QUERYCTRL, &queryControl) == 0) {
- v4l2AutoWhiteBalanceSupported = true;
- setV4L2Parameter(V4L2_CID_AUTO_WHITE_BALANCE, true);
- }
-
- ::memset(&queryControl, 0, sizeof(queryControl));
- queryControl.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
- if (::ioctl(v4l2FileDescriptor, VIDIOC_QUERYCTRL, &queryControl) == 0) {
- v4l2MinColorTemp = queryControl.minimum;
- v4l2MaxColorTemp = queryControl.maximum;
- v4l2ColorTemperatureSupported = true;
- features |= QCamera::Feature::ColorTemperature;
- }
-
- ::memset(&queryControl, 0, sizeof(queryControl));
- queryControl.id = V4L2_CID_EXPOSURE_AUTO;
- if (::ioctl(v4l2FileDescriptor, VIDIOC_QUERYCTRL, &queryControl) == 0) {
- v4l2AutoExposureSupported = true;
- }
-
- ::memset(&queryControl, 0, sizeof(queryControl));
- queryControl.id = V4L2_CID_EXPOSURE_ABSOLUTE;
- if (::ioctl(v4l2FileDescriptor, VIDIOC_QUERYCTRL, &queryControl) == 0) {
- v4l2ManualExposureSupported = true;
- v4l2MinExposure = queryControl.minimum;
- v4l2MaxExposure = queryControl.maximum;
- features |= QCamera::Feature::ManualExposureTime;
- }
-
- ::memset(&queryControl, 0, sizeof(queryControl));
- queryControl.id = V4L2_CID_AUTO_EXPOSURE_BIAS;
- if (::ioctl(v4l2FileDescriptor, VIDIOC_QUERYCTRL, &queryControl) == 0) {
- v4l2MinExposureAdjustment = queryControl.minimum;
- v4l2MaxExposureAdjustment = queryControl.maximum;
- features |= QCamera::Feature::ExposureCompensation;
- }
-
- ::memset(&queryControl, 0, sizeof(queryControl));
- queryControl.id = V4L2_CID_ISO_SENSITIVITY_AUTO;
- if (::ioctl(v4l2FileDescriptor, VIDIOC_QUERYCTRL, &queryControl) == 0) {
- queryControl.id = V4L2_CID_ISO_SENSITIVITY;
- if (::ioctl(v4l2FileDescriptor, VIDIOC_QUERYCTRL, &queryControl) == 0) {
- features |= QCamera::Feature::IsoSensitivity;
- minIsoChanged(queryControl.minimum);
- maxIsoChanged(queryControl.minimum);
- }
- }
-
- supportedFeaturesChanged(features);
-}
-
-int QGstreamerCamera::setV4L2ColorTemperature(int temperature)
-{
- struct v4l2_control control;
- ::memset(&control, 0, sizeof(control));
-
- if (v4l2AutoWhiteBalanceSupported) {
- setV4L2Parameter(V4L2_CID_AUTO_WHITE_BALANCE, temperature == 0 ? true : false);
- } else if (temperature == 0) {
- temperature = 5600;
- }
-
- if (temperature != 0 && v4l2ColorTemperatureSupported) {
- temperature = qBound(v4l2MinColorTemp, temperature, v4l2MaxColorTemp);
- if (!setV4L2Parameter(V4L2_CID_WHITE_BALANCE_TEMPERATURE, qBound(v4l2MinColorTemp, temperature, v4l2MaxColorTemp)))
- temperature = 0;
- } else {
- temperature = 0;
- }
-
- return temperature;
-}
-
-bool QGstreamerCamera::setV4L2Parameter(quint32 id, qint32 value)
-{
- struct v4l2_control control{id, value};
- if (::ioctl(v4l2FileDescriptor, VIDIOC_S_CTRL, &control) != 0) {
- qWarning() << "Unable to set the V4L2 Parameter" << Qt::hex << id << "to" << value << qt_error_string(errno);
- return false;
- }
- return true;
-}
-
-int QGstreamerCamera::getV4L2Parameter(quint32 id) const
-{
- struct v4l2_control control{id, 0};
- if (::ioctl(v4l2FileDescriptor, VIDIOC_G_CTRL, &control) != 0) {
- qWarning() << "Unable to get the V4L2 Parameter" << Qt::hex << id << qt_error_string(errno);
- return 0;
- }
- return control.value;
-}
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera_p.h b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera_p.h
deleted file mode 100644
index 94f2f8678..000000000
--- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercamera_p.h
+++ /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 Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** 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
-
-//
-// 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 <QHash>
-#include <private/qplatformcamera_p.h>
-#include "qgstreamermediacapture_p.h"
-#include <private/qgst_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerCamera : public QPlatformCamera
-{
- Q_OBJECT
-public:
- QGstreamerCamera(QCamera *camera);
- virtual ~QGstreamerCamera();
-
- bool isActive() const override;
- void setActive(bool active) override;
-
- void setCamera(const QCameraDevice &camera) override;
- bool setCameraFormat(const QCameraFormat &format) override;
-
- QGstElement gstElement() const { return gstCameraBin.element(); }
-#if QT_CONFIG(gstreamer_photography)
- GstPhotography *photography() const;
-#endif
-
- void setFocusMode(QCamera::FocusMode mode) override;
- bool isFocusModeSupported(QCamera::FocusMode mode) const override;
-
- void setFlashMode(QCamera::FlashMode mode) override;
- bool isFlashModeSupported(QCamera::FlashMode mode) const override;
- bool isFlashReady() const override;
-
- void setExposureMode(QCamera::ExposureMode) override;
- bool isExposureModeSupported(QCamera::ExposureMode mode) const override;
- void setExposureCompensation(float) override;
- void setManualIsoSensitivity(int) override;
- int isoSensitivity() const override;
- void setManualExposureTime(float) override;
- float exposureTime() const override;
-
- bool isWhiteBalanceModeSupported(QCamera::WhiteBalanceMode mode) const override;
- void setWhiteBalanceMode(QCamera::WhiteBalanceMode mode) override;
- void setColorTemperature(int temperature) override;
-
- QString v4l2Device() const { return m_v4l2Device; }
- bool isV4L2Camera() const { return !m_v4l2Device.isEmpty(); }
-
-private:
- void updateCameraProperties();
-#if QT_CONFIG(linux_v4l)
- void initV4L2Controls();
- int setV4L2ColorTemperature(int temperature);
- bool setV4L2Parameter(quint32 id, qint32 value);
- int getV4L2Parameter(quint32 id) const;
-
- bool v4l2AutoWhiteBalanceSupported = false;
- bool v4l2ColorTemperatureSupported = false;
- bool v4l2AutoExposureSupported = false;
- bool v4l2ManualExposureSupported = false;
- qint32 v4l2MinColorTemp = 5600; // Daylight...
- qint32 v4l2MaxColorTemp = 5600;
- qint32 v4l2MinExposure = 0;
- qint32 v4l2MaxExposure = 0;
- qint32 v4l2MinExposureAdjustment = 0;
- qint32 v4l2MaxExposureAdjustment = 0;
- int v4l2FileDescriptor = -1;
-#endif
-
- QCameraDevice m_cameraDevice;
-
- QGstBin gstCameraBin;
- QGstElement gstCamera;
- QGstElement gstCapsFilter;
- QGstElement gstDecode;
- QGstElement gstVideoConvert;
- QGstElement gstVideoScale;
-
- bool m_active = false;
- QString m_v4l2Device;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERCAMERACONTROL_H
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamerimagecapture.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamerimagecapture.cpp
deleted file mode 100644
index 2d943def2..000000000
--- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamerimagecapture.cpp
+++ /dev/null
@@ -1,301 +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 "qgstreamerimagecapture_p.h"
-#include "qplatformcamera_p.h"
-#include <private/qplatformimagecapture_p.h>
-#include <private/qgstvideobuffer_p.h>
-#include <private/qgstutils_p.h>
-#include <private/qgstreamermetadata_p.h>
-#include <qvideoframeformat.h>
-#include "qmediastoragelocation_p.h"
-
-#include <QtCore/QDebug>
-#include <QtCore/QDir>
-#include <qstandardpaths.h>
-
-#include <qloggingcategory.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(qLcImageCapture, "qt.multimedia.imageCapture")
-
-QGstreamerImageCapture::QGstreamerImageCapture(QImageCapture *parent)
- : QPlatformImageCapture(parent),
- QGstreamerBufferProbe(ProbeBuffers)
-{
- bin = QGstBin("imageCaptureBin");
-
- queue = QGstElement("queue", "imageCaptureQueue");
- // configures the queue to be fast, lightweight and non blocking
- queue.set("leaky", 2 /*downstream*/);
- queue.set("silent", true);
- queue.set("max-size-buffers", 1);
- queue.set("max-size-bytes", 0);
- queue.set("max-size-time", 0);
-
- videoConvert = QGstElement("videoconvert", "imageCaptureConvert");
- encoder = QGstElement("jpegenc", "jpegEncoder");
- muxer = QGstElement("jifmux", "jpegMuxer");
- sink = QGstElement("fakesink","imageCaptureSink");
- // imageCaptureSink do not wait for a preroll buffer when going READY -> PAUSED
- // as no buffer will arrive until capture() is called
- sink.set("async", false);
-
- bin.add(queue, videoConvert, encoder, muxer, sink);
- queue.link(videoConvert, encoder, muxer, sink);
- bin.addGhostPad(queue, "sink");
-
- addProbeToPad(queue.staticPad("src").pad(), false);
-
- sink.set("signal-handoffs", true);
- g_signal_connect(sink.object(), "handoff", G_CALLBACK(&QGstreamerImageCapture::saveImageFilter), this);
-}
-
-QGstreamerImageCapture::~QGstreamerImageCapture()
-{
- bin.setStateSync(GST_STATE_NULL);
-}
-
-bool QGstreamerImageCapture::isReadyForCapture() const
-{
- return m_session && !passImage && cameraActive;
-}
-
-int QGstreamerImageCapture::capture(const QString &fileName)
-{
- QString path = QMediaStorageLocation::generateFileName(fileName, QStandardPaths::PicturesLocation, QLatin1String("jpg"));
- return doCapture(path);
-}
-
-int QGstreamerImageCapture::captureToBuffer()
-{
- return doCapture(QString());
-}
-
-int QGstreamerImageCapture::doCapture(const QString &fileName)
-{
- qCDebug(qLcImageCapture) << "do capture";
- if (!m_session) {
- //emit error in the next event loop,
- //so application can associate it with returned request id.
- QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
- Q_ARG(int, -1),
- Q_ARG(int, QImageCapture::ResourceError),
- Q_ARG(QString, QPlatformImageCapture::msgImageCaptureNotSet()));
-
- qCDebug(qLcImageCapture) << "error 1";
- return -1;
- }
- if (!m_session->camera()) {
- //emit error in the next event loop,
- //so application can associate it with returned request id.
- QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
- Q_ARG(int, -1),
- Q_ARG(int, QImageCapture::ResourceError),
- Q_ARG(QString,tr("No camera available.")));
-
- qCDebug(qLcImageCapture) << "error 2";
- return -1;
- }
- if (passImage) {
- //emit error in the next event loop,
- //so application can associate it with returned request id.
- QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection,
- Q_ARG(int, -1),
- Q_ARG(int, QImageCapture::NotReadyError),
- Q_ARG(QString, QPlatformImageCapture::msgCameraNotReady()));
-
- qCDebug(qLcImageCapture) << "error 3";
- return -1;
- }
- m_lastId++;
-
- pendingImages.enqueue({m_lastId, fileName, QMediaMetaData{}});
- // let one image pass the pipeline
- passImage = true;
-
- emit readyForCaptureChanged(false);
- return m_lastId;
-}
-
-bool QGstreamerImageCapture::probeBuffer(GstBuffer *buffer)
-{
- if (!passImage)
- return false;
- qCDebug(qLcImageCapture) << "probe buffer";
-
- passImage = false;
-
- emit readyForCaptureChanged(isReadyForCapture());
-
- QGstCaps caps = gst_pad_get_current_caps(bin.staticPad("sink").pad());
- GstVideoInfo previewInfo;
- gst_video_info_from_caps(&previewInfo, caps.get());
-
- auto memoryFormat = caps.memoryFormat();
- auto fmt = QGstCaps(caps).formatForCaps(&previewInfo);
- auto *sink = m_session->gstreamerVideoSink();
- auto *gstBuffer = new QGstVideoBuffer(buffer, previewInfo, sink, fmt, memoryFormat);
- QVideoFrame frame(gstBuffer, fmt);
- QImage img = frame.toImage();
- if (img.isNull()) {
- qDebug() << "received a null image";
- return true;
- }
-
- auto &imageData = pendingImages.head();
-
- emit imageExposed(imageData.id);
-
- qCDebug(qLcImageCapture) << "Image available!";
- emit imageAvailable(imageData.id, frame);
-
- emit imageCaptured(imageData.id, img);
-
- QMediaMetaData metaData = this->metaData();
- metaData.insert(QMediaMetaData::Date, QDateTime::currentDateTime());
- metaData.insert(QMediaMetaData::Resolution, frame.size());
- imageData.metaData = metaData;
-
- // ensure taginject injects this metaData
- const auto &md = static_cast<const QGstreamerMetaData &>(metaData);
- md.setMetaData(muxer.element());
-
- emit imageMetadataAvailable(imageData.id, metaData);
-
- return true;
-}
-
-void QGstreamerImageCapture::setCaptureSession(QPlatformMediaCaptureSession *session)
-{
- QGstreamerMediaCapture *captureSession = static_cast<QGstreamerMediaCapture *>(session);
- if (m_session == captureSession)
- return;
-
- if (m_session) {
- disconnect(m_session, nullptr, this, nullptr);
- m_lastId = 0;
- pendingImages.clear();
- passImage = false;
- cameraActive = false;
- }
-
- m_session = captureSession;
- if (!m_session)
- return;
-
- connect(m_session, &QPlatformMediaCaptureSession::cameraChanged, this, &QGstreamerImageCapture::onCameraChanged);
- onCameraChanged();
-}
-
-void QGstreamerImageCapture::cameraActiveChanged(bool active)
-{
- qCDebug(qLcImageCapture) << "cameraActiveChanged" << cameraActive << active;
- if (cameraActive == active)
- return;
- cameraActive = active;
- qCDebug(qLcImageCapture) << "isReady" << isReadyForCapture();
- emit readyForCaptureChanged(isReadyForCapture());
-}
-
-void QGstreamerImageCapture::onCameraChanged()
-{
- if (m_session->camera()) {
- cameraActiveChanged(m_session->camera()->isActive());
- connect(m_session->camera(), &QPlatformCamera::activeChanged, this, &QGstreamerImageCapture::cameraActiveChanged);
- }
-
-}
-
-gboolean QGstreamerImageCapture::saveImageFilter(GstElement *element,
- GstBuffer *buffer,
- GstPad *pad,
- void *appdata)
-{
- Q_UNUSED(element);
- Q_UNUSED(pad);
- QGstreamerImageCapture *capture = static_cast<QGstreamerImageCapture *>(appdata);
-
- capture->passImage = false;
-
- if (capture->pendingImages.isEmpty()) {
- return true;
- }
-
- auto imageData = capture->pendingImages.dequeue();
- if (imageData.filename.isEmpty()) {
- return true;
- }
-
- qCDebug(qLcImageCapture) << "saving image as" << imageData.filename;
-
- QFile f(imageData.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(&QGstreamerImageCapture::imageSaved);
- savedSignal.invoke(capture,
- Qt::QueuedConnection,
- Q_ARG(int, imageData.id),
- Q_ARG(QString, imageData.filename));
- }
-
- return TRUE;
-}
-
-QImageEncoderSettings QGstreamerImageCapture::imageSettings() const
-{
- return m_settings;
-}
-
-void QGstreamerImageCapture::setImageSettings(const QImageEncoderSettings &settings)
-{
- if (m_settings != settings) {
- m_settings = settings;
- // ###
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamerimagecapture_p.h b/src/multimedia/platform/gstreamer/mediacapture/qgstreamerimagecapture_p.h
deleted file mode 100644
index a0f5d1a0b..000000000
--- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamerimagecapture_p.h
+++ /dev/null
@@ -1,121 +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
-
-//
-// 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 <private/qplatformimagecapture_p.h>
-#include "qgstreamermediacapture_p.h"
-#include "private/qgstreamerbufferprobe_p.h"
-
-#include <qqueue.h>
-
-#include <private/qgst_p.h>
-#include <gst/video/video.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerImageCapture : public QPlatformImageCapture, private QGstreamerBufferProbe
-
-{
- Q_OBJECT
-public:
- QGstreamerImageCapture(QImageCapture *parent);
- virtual ~QGstreamerImageCapture();
-
- bool isReadyForCapture() const override;
- int capture(const QString &fileName) override;
- int captureToBuffer() override;
-
- QImageEncoderSettings imageSettings() const override;
- void setImageSettings(const QImageEncoderSettings &settings) override;
-
- bool probeBuffer(GstBuffer *buffer) override;
-
- void setCaptureSession(QPlatformMediaCaptureSession *session);
-
- QGstElement gstElement() const { return bin.element(); }
-
-public Q_SLOTS:
- void cameraActiveChanged(bool active);
- void onCameraChanged();
-
-private:
- int doCapture(const QString &fileName);
- static gboolean saveImageFilter(GstElement *element, GstBuffer *buffer, GstPad *pad, void *appdata);
-
- QGstreamerMediaCapture *m_session = nullptr;
- int m_lastId = 0;
- QImageEncoderSettings m_settings;
-
- struct PendingImage {
- int id;
- QString filename;
- QMediaMetaData metaData;
- };
-
- QQueue<PendingImage> pendingImages;
-
- QGstBin bin;
- QGstElement queue;
- QGstElement videoConvert;
- QGstElement encoder;
- QGstElement muxer;
- QGstElement sink;
- QGstPad videoSrcPad;
-
- bool passImage = false;
- bool cameraActive = false;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERCAPTURECORNTROL_H
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture.cpp
deleted file mode 100644
index 478eb1c0a..000000000
--- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture.cpp
+++ /dev/null
@@ -1,370 +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 "qgstreamermediacapture_p.h"
-#include "qgstreamermediaencoder_p.h"
-#include "qgstreamerimagecapture_p.h"
-#include "qgstreamercamera_p.h"
-#include <private/qgstpipeline_p.h>
-
-#include "private/qgstreameraudioinput_p.h"
-#include "private/qgstreameraudiooutput_p.h"
-#include "private/qgstreamervideooutput_p.h"
-
-#include <qloggingcategory.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(qLcMediaCapture, "qt.multimedia.capture")
-
-
-static void linkTeeToPad(QGstElement tee, QGstPad sink)
-{
- if (tee.isNull() || sink.isNull())
- return;
-
- auto source = tee.getRequestPad("src_%u");
- source.link(sink);
-}
-
-static void unlinkTeeFromPad(QGstElement tee, QGstPad sink)
-{
- if (tee.isNull() || sink.isNull())
- return;
-
- auto source = sink.peer();
- source.unlink(sink);
-
- tee.releaseRequestPad(source);
-}
-
-
-QGstreamerMediaCapture::QGstreamerMediaCapture()
- : gstPipeline("pipeline")
-{
- gstVideoOutput = new QGstreamerVideoOutput(this);
- gstVideoOutput->setIsPreview();
- gstVideoOutput->setPipeline(gstPipeline);
-
- // Use system clock to drive all elements in the pipeline. Otherwise,
- // the clock is sourced from the elements (e.g. from an audio source).
- // Since the elements are added and removed dynamically the clock would
- // also change causing lost of synchronization in the pipeline.
- gst_pipeline_use_clock(gstPipeline.pipeline(), gst_system_clock_obtain());
-
- // This is the recording pipeline with only live sources, thus the pipeline
- // will be always in the playing state.
- gstPipeline.setState(GST_STATE_PLAYING);
-
- // TODO: remove this debug before final commit
- // Four basic elements of the capture session showing the current position and state
- // All presented position should show similar progress.
- heartbeat.setInterval(1000);
- heartbeat.start();
- QObject::connect(&heartbeat, &QTimer::timeout, [this]() {
- if (!gstPipeline.isNull()) {
- gint64 current = -1;
- gst_element_query_position(gstPipeline.element(),GST_FORMAT_TIME, &current);
- qDebug() << "Pipeline " << current / 1000000 << gstPipeline.state();
-// auto name = QString::number(current).toLocal8Bit().data();
-// gstPipeline.dumpGraph(name);
- }
- if (gstAudioInput && !gstAudioInput->gstElement().isNull()) {
- gint64 current = -1;
- auto element = gstAudioInput->gstElement().element();
- gst_element_query_position(element,GST_FORMAT_TIME, &current);
- qDebug() << "Audio " << current / 1000000 << gstAudioInput->gstElement().state();
- }
- if (gstCamera && !gstCamera->gstElement().isNull()) {
- gint64 current = -1;
- gst_element_query_position(gstCamera->gstElement().element(),GST_FORMAT_TIME, &current);
- qDebug() << "Camera " << current / 1000000 << gstCamera->gstElement().state();
- }
- auto encoder = !m_mediaEncoder ? QGstElement{} : m_mediaEncoder->getEncoder();
- if (!encoder.isNull()) {
- gint64 current = -1;
- gst_element_query_position(encoder.element(),GST_FORMAT_TIME, &current);
- qDebug() << "Encoder " << current / 1000000 << encoder.state();
- }
- });
-
- gstPipeline.dumpGraph("initial");
-}
-
-QGstreamerMediaCapture::~QGstreamerMediaCapture()
-{
- setMediaEncoder(nullptr);
- setImageCapture(nullptr);
- setCamera(nullptr);
- gstPipeline.setStateSync(GST_STATE_NULL);
-}
-
-QPlatformCamera *QGstreamerMediaCapture::camera()
-{
- return gstCamera;
-}
-
-void QGstreamerMediaCapture::setCamera(QPlatformCamera *camera)
-{
- QGstreamerCamera *control = static_cast<QGstreamerCamera *>(camera);
- if (gstCamera == control)
- return;
-
- if (gstCamera) {
- unlinkTeeFromPad(gstVideoTee, encoderVideoSink);
- unlinkTeeFromPad(gstVideoTee, imageCaptureSink);
-
- auto camera = gstCamera->gstElement();
- camera.setStateSync(GST_STATE_NULL);
- gstVideoTee.setStateSync(GST_STATE_NULL);
- gstVideoOutput->gstElement().setStateSync(GST_STATE_NULL);
-
- gstPipeline.remove(camera);
- gstPipeline.remove(gstVideoTee);
- gstPipeline.remove(gstVideoOutput->gstElement());
-
- gstVideoTee = {};
- gstCamera->setCaptureSession(nullptr);
- }
-
- gstCamera = control;
- if (gstCamera) {
- QGstElement camera = gstCamera->gstElement();
- gstVideoTee = QGstElement("tee", "videotee");
- gstVideoTee.set("allow-not-linked", true);
-
- gstPipeline.add(gstVideoOutput->gstElement(), camera, gstVideoTee);
-
- linkTeeToPad(gstVideoTee, encoderVideoSink);
- linkTeeToPad(gstVideoTee, gstVideoOutput->gstElement().staticPad("sink"));
- linkTeeToPad(gstVideoTee, imageCaptureSink);
-
- camera.link(gstVideoTee);
-
- gstVideoOutput->gstElement().setState(GST_STATE_PLAYING);
- gstVideoTee.setState(GST_STATE_PLAYING);
- camera.setState(GST_STATE_PLAYING);
- }
-
- gstPipeline.dumpGraph("camera");
-
- emit cameraChanged();
-}
-
-QPlatformImageCapture *QGstreamerMediaCapture::imageCapture()
-{
- return m_imageCapture;
-}
-
-void QGstreamerMediaCapture::setImageCapture(QPlatformImageCapture *imageCapture)
-{
- QGstreamerImageCapture *control = static_cast<QGstreamerImageCapture *>(imageCapture);
- if (m_imageCapture == control)
- return;
-
- if (m_imageCapture) {
- unlinkTeeFromPad(gstVideoTee, imageCaptureSink);
- m_imageCapture->gstElement().setStateSync(GST_STATE_NULL);
- gstPipeline.remove(m_imageCapture->gstElement());
- imageCaptureSink = {};
- m_imageCapture->setCaptureSession(nullptr);
- }
-
- m_imageCapture = control;
- if (m_imageCapture) {
- imageCaptureSink = m_imageCapture->gstElement().staticPad("sink");
- m_imageCapture->gstElement().setState(GST_STATE_PLAYING);
- gstPipeline.add(m_imageCapture->gstElement());
- linkTeeToPad(gstVideoTee, imageCaptureSink);
- m_imageCapture->setCaptureSession(this);
- }
-
- gstPipeline.dumpGraph("imageCapture");
-
- emit imageCaptureChanged();
-}
-
-void QGstreamerMediaCapture::setMediaEncoder(QPlatformMediaEncoder *encoder)
-{
- QGstreamerMediaEncoder *control = static_cast<QGstreamerMediaEncoder *>(encoder);
- if (m_mediaEncoder == control)
- return;
-
- if (m_mediaEncoder)
- m_mediaEncoder->setCaptureSession(nullptr);
- m_mediaEncoder = control;
- if (m_mediaEncoder)
- m_mediaEncoder->setCaptureSession(this);
-
- emit encoderChanged();
- gstPipeline.dumpGraph("encoder");
-}
-
-QPlatformMediaEncoder *QGstreamerMediaCapture::mediaEncoder()
-{
- return m_mediaEncoder;
-}
-
-void QGstreamerMediaCapture::linkEncoder(QGstPad audioSink, QGstPad videoSink)
-{
- if (!gstVideoTee.isNull() && !videoSink.isNull()) {
- auto caps = gst_pad_get_current_caps(gstVideoTee.sink().pad());
-
- encoderVideoCapsFilter = QGstElement("capsfilter", "encoderVideoCapsFilter");
- encoderVideoCapsFilter.set("caps", QGstMutableCaps(caps));
-
- gstPipeline.add(encoderVideoCapsFilter);
-
- encoderVideoCapsFilter.src().link(videoSink);
- linkTeeToPad(gstVideoTee, encoderVideoCapsFilter.sink());
- encoderVideoCapsFilter.setState(GST_STATE_PLAYING);
- encoderVideoSink = encoderVideoCapsFilter.sink();
- }
-
- if (!gstAudioTee.isNull() && !audioSink.isNull()) {
- auto caps = gst_pad_get_current_caps(gstAudioTee.sink().pad());
-
- encoderAudioCapsFilter = QGstElement("capsfilter", "encoderAudioCapsFilter");
- encoderAudioCapsFilter.set("caps", QGstMutableCaps(caps));
-
- gstPipeline.add(encoderAudioCapsFilter);
-
- encoderAudioCapsFilter.src().link(audioSink);
- linkTeeToPad(gstAudioTee, encoderAudioCapsFilter.sink());
- encoderAudioCapsFilter.setState(GST_STATE_PLAYING);
- encoderAudioSink = encoderAudioCapsFilter.sink();
- }
-}
-
-void QGstreamerMediaCapture::unlinkEncoder()
-{
- if (!encoderVideoCapsFilter.isNull()) {
- encoderVideoCapsFilter.src().unlinkPeer();
- unlinkTeeFromPad(gstVideoTee, encoderVideoCapsFilter.sink());
- encoderVideoCapsFilter.setStateSync(GST_STATE_NULL);
- gstPipeline.remove(encoderVideoCapsFilter);
- encoderVideoCapsFilter = {};
- }
-
- if (!encoderAudioCapsFilter.isNull()) {
- encoderAudioCapsFilter.src().unlinkPeer();
- unlinkTeeFromPad(gstAudioTee, encoderAudioCapsFilter.sink());
- encoderAudioCapsFilter.setStateSync(GST_STATE_NULL);
- gstPipeline.remove(encoderAudioCapsFilter);
- encoderAudioCapsFilter = {};
- }
-
- encoderAudioSink = {};
- encoderVideoSink = {};
-}
-
-void QGstreamerMediaCapture::setAudioInput(QPlatformAudioInput *input)
-{
- if (gstAudioInput == input)
- return;
-
- if (gstAudioInput) {
- unlinkTeeFromPad(gstAudioTee, encoderAudioSink);
-
- if (gstAudioOutput) {
- unlinkTeeFromPad(gstAudioTee, gstAudioOutput->gstElement().staticPad("sink"));
- gstAudioOutput->gstElement().setStateSync(GST_STATE_NULL);
- gstPipeline.remove(gstAudioOutput->gstElement());
- }
-
- gstAudioInput->gstElement().setStateSync(GST_STATE_NULL);
- gstPipeline.remove(gstAudioInput->gstElement());
- gstAudioTee.setStateSync(GST_STATE_NULL);
- gstPipeline.remove(gstAudioTee);
- gstAudioTee = {};
- }
-
- gstAudioInput = static_cast<QGstreamerAudioInput *>(input);
- if (gstAudioInput) {
- Q_ASSERT(gstAudioTee.isNull());
- gstAudioTee = QGstElement("tee", "audiotee");
- gstAudioTee.set("allow-not-linked", true);
- gstPipeline.add(gstAudioInput->gstElement(), gstAudioTee);
- gstAudioInput->gstElement().link(gstAudioTee);
-
- if (gstAudioOutput) {
- gstPipeline.add(gstAudioOutput->gstElement());
- gstAudioOutput->gstElement().setState(GST_STATE_PLAYING);
- linkTeeToPad(gstAudioTee, gstAudioOutput->gstElement().staticPad("sink"));
- }
-
- gstAudioTee.setState(GST_STATE_PLAYING);
- gstAudioInput->gstElement().setStateSync(GST_STATE_PLAYING);
-
- linkTeeToPad(gstAudioTee, encoderAudioSink);
- }
-}
-
-void QGstreamerMediaCapture::setVideoPreview(QVideoSink *sink)
-{
- gstVideoOutput->setVideoSink(sink);
-}
-
-void QGstreamerMediaCapture::setAudioOutput(QPlatformAudioOutput *output)
-{
- if (gstAudioOutput == output)
- return;
-
- if (gstAudioOutput && gstAudioInput) {
- // If audio input is set, the output is in the pipeline
- unlinkTeeFromPad(gstAudioTee, gstAudioOutput->gstElement().staticPad("sink"));
- gstAudioOutput->gstElement().setStateSync(GST_STATE_NULL);
- gstPipeline.remove(gstAudioOutput->gstElement());
- }
-
- gstAudioOutput = static_cast<QGstreamerAudioOutput *>(output);
- if (gstAudioOutput && gstAudioInput) {
- gstPipeline.add(gstAudioOutput->gstElement());
- gstAudioOutput->gstElement().setState(GST_STATE_PLAYING);
- linkTeeToPad(gstAudioTee, gstAudioOutput->gstElement().staticPad("sink"));
- }
-}
-
-QGstreamerVideoSink *QGstreamerMediaCapture::gstreamerVideoSink() const
-{
- return gstVideoOutput ? gstVideoOutput->gstreamerVideoSink() : nullptr;
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture_p.h b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture_p.h
deleted file mode 100644
index ed75a27d1..000000000
--- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediacapture_p.h
+++ /dev/null
@@ -1,129 +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
-
-//
-// 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 <private/qplatformmediacapture_p.h>
-#include <private/qplatformmediaintegration_p.h>
-
-#include <private/qgst_p.h>
-#include <private/qgstpipeline_p.h>
-
-#include <qtimer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerCamera;
-class QGstreamerImageCapture;
-class QGstreamerMediaEncoder;
-class QGstreamerAudioInput;
-class QGstreamerAudioOutput;
-class QGstreamerVideoOutput;
-class QGstreamerVideoSink;
-
-class QGstreamerMediaCapture : public QPlatformMediaCaptureSession
-{
- Q_OBJECT
-
-public:
- QGstreamerMediaCapture();
- virtual ~QGstreamerMediaCapture();
-
- QPlatformCamera *camera() override;
- void setCamera(QPlatformCamera *camera) override;
-
- QPlatformImageCapture *imageCapture() override;
- void setImageCapture(QPlatformImageCapture *imageCapture) override;
-
- QPlatformMediaEncoder *mediaEncoder() override;
- void setMediaEncoder(QPlatformMediaEncoder *encoder) override;
-
- void setAudioInput(QPlatformAudioInput *input) override;
- QGstreamerAudioInput *audioInput() { return gstAudioInput; }
-
- void setVideoPreview(QVideoSink *sink) override;
- void setAudioOutput(QPlatformAudioOutput *output) override;
-
- void linkEncoder(QGstPad audioSink, QGstPad videoSink);
- void unlinkEncoder();
-
- QGstPipeline pipeline() const { return gstPipeline; }
-
- QGstreamerVideoSink *gstreamerVideoSink() const;
-
-private:
- friend QGstreamerMediaEncoder;
- // Gst elements
- QGstPipeline gstPipeline;
- QTimer heartbeat;
-
- QGstreamerAudioInput *gstAudioInput = nullptr;
- QGstreamerCamera *gstCamera = nullptr;
-
- QGstElement gstAudioTee;
- QGstElement gstVideoTee;
- QGstElement encoderVideoCapsFilter;
- QGstElement encoderAudioCapsFilter;
-
- QGstPad encoderAudioSink;
- QGstPad encoderVideoSink;
- QGstPad imageCaptureSink;
-
- QGstreamerAudioOutput *gstAudioOutput = nullptr;
- QGstreamerVideoOutput *gstVideoOutput = nullptr;
-
- QGstreamerMediaEncoder *m_mediaEncoder = nullptr;
- QGstreamerImageCapture *m_imageCapture = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERCAPTURESERVICE_H
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp
deleted file mode 100644
index 434a6ca67..000000000
--- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder.cpp
+++ /dev/null
@@ -1,439 +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 "qgstreamermediaencoder_p.h"
-#include "private/qgstreamerintegration_p.h"
-#include "private/qgstreamerformatinfo_p.h"
-#include "private/qgstpipeline_p.h"
-#include "private/qgstreamermessage_p.h"
-#include "private/qplatformcamera_p.h"
-#include "qaudiodevice.h"
-#include "qmediastoragelocation_p.h"
-
-#include <qdebug.h>
-#include <qstandardpaths.h>
-#include <qmimetype.h>
-#include <qloggingcategory.h>
-
-#include <gst/gsttagsetter.h>
-#include <gst/gstversion.h>
-#include <gst/video/video.h>
-#include <gst/pbutils/encoding-profile.h>
-
-Q_LOGGING_CATEGORY(qLcMediaEncoder, "qt.multimedia.encoder")
-
-QGstreamerMediaEncoder::QGstreamerMediaEncoder(QMediaRecorder *parent)
- : QPlatformMediaEncoder(parent),
- audioPauseControl(*this),
- videoPauseControl(*this)
-{
- signalDurationChangedTimer.setInterval(100);
- signalDurationChangedTimer.callOnTimeout([this](){ durationChanged(duration()); });
-}
-
-QGstreamerMediaEncoder::~QGstreamerMediaEncoder()
-{
- if (!gstPipeline.isNull()) {
- finalize();
- gstPipeline.removeMessageFilter(this);
- gstPipeline.setStateSync(GST_STATE_NULL);
- }
-}
-
-bool QGstreamerMediaEncoder::isLocationWritable(const QUrl &) const
-{
- return true;
-}
-
-void QGstreamerMediaEncoder::handleSessionError(QMediaRecorder::Error code, const QString &description)
-{
- error(code, description);
- stop();
-}
-
-bool QGstreamerMediaEncoder::processBusMessage(const QGstreamerMessage &message)
-{
- GstMessage *gm = message.rawMessage();
- if (!gm)
- return false;
-
-// qCDebug(qLcMediaEncoder) << "received event from" << message.source().name() << Qt::hex << message.type();
-// if (message.type() == GST_MESSAGE_STATE_CHANGED) {
-// GstState oldState;
-// GstState newState;
-// GstState pending;
-// gst_message_parse_state_changed(gm, &oldState, &newState, &pending);
-// qCDebug(qLcMediaEncoder) << "received state change from" << message.source().name() << oldState << newState << pending;
-// }
- if (message.type() == GST_MESSAGE_ELEMENT) {
- QGstStructure s = gst_message_get_structure(gm);
- qCDebug(qLcMediaEncoder) << "received element message from" << message.source().name() << s.name();
- if (s.name() == "GstBinForwarded")
- gm = s.getMessage();
- if (!gm)
- return false;
- }
-
- if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_EOS) {
- qCDebug(qLcMediaEncoder) << "received EOS from" << QGstObject(GST_MESSAGE_SRC(gm)).name();
- finalize();
- return false;
- }
-
- if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ERROR) {
- GError *err;
- gchar *debug;
- gst_message_parse_error(gm, &err, &debug);
- error(QMediaRecorder::ResourceError, QString::fromUtf8(err->message));
- g_error_free(err);
- g_free(debug);
- finalize();
- }
-
- if (GST_MESSAGE_SRC(gm) == gstEncoder.object()) {
- 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);
-
- if (newState == GST_STATE_PAUSED && !m_metaData.isEmpty())
- setMetaData(m_metaData);
- break;
- }
- default:
- break;
- }
- }
- return false;
-}
-
-qint64 QGstreamerMediaEncoder::duration() const
-{
- return std::max(audioPauseControl.duration, videoPauseControl.duration);
-}
-
-
-static GstEncodingContainerProfile *createContainerProfile(const QMediaEncoderSettings &settings)
-{
- auto *formatInfo = QGstreamerIntegration::instance()->m_formatsInfo;
-
- QGstMutableCaps caps = formatInfo->formatCaps(settings.fileFormat());
-
- GstEncodingContainerProfile *profile = (GstEncodingContainerProfile *)gst_encoding_container_profile_new(
- "container_profile",
- (gchar *)"custom container profile",
- const_cast<GstCaps *>(caps.get()),
- nullptr); //preset
- return profile;
-}
-
-static GstEncodingProfile *createVideoProfile(const QMediaEncoderSettings &settings)
-{
- auto *formatInfo = QGstreamerIntegration::instance()->m_formatsInfo;
-
- QGstMutableCaps caps = formatInfo->videoCaps(settings.mediaFormat());
- if (caps.isNull())
- return nullptr;
-
- GstEncodingVideoProfile *profile = gst_encoding_video_profile_new(
- const_cast<GstCaps *>(caps.get()),
- nullptr,
- nullptr, //restriction
- 0); //presence
-
- gst_encoding_video_profile_set_pass(profile, 0);
- gst_encoding_video_profile_set_variableframerate(profile, TRUE);
-
- return (GstEncodingProfile *)profile;
-}
-
-static GstEncodingProfile *createAudioProfile(const QMediaEncoderSettings &settings)
-{
- auto *formatInfo = QGstreamerIntegration::instance()->m_formatsInfo;
-
- auto caps = formatInfo->audioCaps(settings.mediaFormat());
- if (caps.isNull())
- return nullptr;
-
- GstEncodingProfile *profile = (GstEncodingProfile *)gst_encoding_audio_profile_new(
- const_cast<GstCaps *>(caps.get()),
- nullptr, //preset
- nullptr, //restriction
- 0); //presence
-
- return profile;
-}
-
-
-static GstEncodingContainerProfile *createEncodingProfile(const QMediaEncoderSettings &settings)
-{
- auto *containerProfile = createContainerProfile(settings);
- if (!containerProfile) {
- qWarning() << "QGstreamerMediaEncoder: failed to create container profile!";
- return nullptr;
- }
-
- GstEncodingProfile *audioProfile = createAudioProfile(settings);
- GstEncodingProfile *videoProfile = nullptr;
- if (settings.videoCodec() != QMediaFormat::VideoCodec::Unspecified)
- videoProfile = createVideoProfile(settings);
-// qDebug() << "audio profile" << (audioProfile ? gst_caps_to_string(gst_encoding_profile_get_format(audioProfile)) : "(null)");
-// qDebug() << "video profile" << (videoProfile ? gst_caps_to_string(gst_encoding_profile_get_format(videoProfile)) : "(null)");
-// qDebug() << "conta profile" << gst_caps_to_string(gst_encoding_profile_get_format((GstEncodingProfile *)containerProfile));
-
- if (videoProfile) {
- if (!gst_encoding_container_profile_add_profile(containerProfile, videoProfile)) {
- qWarning() << "QGstreamerMediaEncoder: failed to add video profile!";
- gst_encoding_profile_unref(videoProfile);
- }
- }
- if (audioProfile) {
- if (!gst_encoding_container_profile_add_profile(containerProfile, audioProfile)) {
- qWarning() << "QGstreamerMediaEncoder: failed to add audio profile!";
- gst_encoding_profile_unref(audioProfile);
- }
- }
-
- return containerProfile;
-}
-
-void QGstreamerMediaEncoder::PauseControl::reset()
-{
- pauseOffsetPts = 0;
- pauseStartPts.reset();
- duration = 0;
- firstBufferPts.reset();
-}
-
-void QGstreamerMediaEncoder::PauseControl::installOn(QGstPad pad)
-{
- pad.addProbe<&QGstreamerMediaEncoder::PauseControl::processBuffer>(this, GST_PAD_PROBE_TYPE_BUFFER);
-}
-
-GstPadProbeReturn QGstreamerMediaEncoder::PauseControl::processBuffer(QGstPad, GstPadProbeInfo *info)
-{
- auto buffer = GST_PAD_PROBE_INFO_BUFFER(info);
- if (!buffer)
- return GST_PAD_PROBE_OK;
-
- buffer = gst_buffer_make_writable(buffer);
-
- if (!buffer)
- return GST_PAD_PROBE_OK;
-
- GST_PAD_PROBE_INFO_DATA(info) = buffer;
-
- if (!GST_BUFFER_PTS_IS_VALID(buffer))
- return GST_PAD_PROBE_OK;
-
- if (!firstBufferPts)
- firstBufferPts = GST_BUFFER_PTS(buffer);
-
- if (encoder.state() == QMediaRecorder::PausedState) {
- if (!pauseStartPts)
- pauseStartPts = GST_BUFFER_PTS(buffer);
-
- return GST_PAD_PROBE_DROP;
- }
-
- if (pauseStartPts) {
- pauseOffsetPts += GST_BUFFER_PTS(buffer) - *pauseStartPts;
- pauseStartPts.reset();
- }
- GST_BUFFER_PTS(buffer) -= pauseOffsetPts;
-
- duration = (GST_BUFFER_PTS(buffer) - *firstBufferPts) / GST_MSECOND;
-
- return GST_PAD_PROBE_OK;
-}
-
-void QGstreamerMediaEncoder::record(QMediaEncoderSettings &settings)
-{
- if (!m_session || state() != QMediaRecorder::StoppedState)
- return;
-
- const auto hasVideo = m_session->camera() && m_session->camera()->isActive();
- const auto hasAudio = m_session->audioInput() != nullptr;
-
- if (!hasVideo && !hasAudio) {
- error(QMediaRecorder::ResourceError, QMediaRecorder::tr("No camera or audio input"));
- return;
- }
-
- const auto audioOnly = settings.videoCodec() == QMediaFormat::VideoCodec::Unspecified;
-
- auto primaryLocation = audioOnly ? QStandardPaths::MusicLocation : QStandardPaths::MoviesLocation;
- auto container = settings.mimeType().preferredSuffix();
- auto location = QMediaStorageLocation::generateFileName(outputLocation().toLocalFile(), primaryLocation, container);
-
- QUrl actualSink = QUrl::fromLocalFile(QDir::currentPath()).resolved(location);
- qCDebug(qLcMediaEncoder) << "recording new video to" << actualSink;
-
- Q_ASSERT(!actualSink.isEmpty());
-
- gstEncoder = QGstElement("encodebin", "encodebin");
- auto *encodingProfile = createEncodingProfile(settings);
- g_object_set (gstEncoder.object(), "profile", encodingProfile, nullptr);
- gst_encoding_profile_unref(encodingProfile);
-
- gstFileSink = QGstElement("filesink", "filesink");
- gstFileSink.set("location", QFile::encodeName(actualSink.toLocalFile()).constData());
- gstFileSink.set("async", false);
-
- QGstPad audioSink = {};
- QGstPad videoSink = {};
-
- audioPauseControl.reset();
- videoPauseControl.reset();
-
- if (hasAudio) {
- audioSink = gstEncoder.getRequestPad("audio_%u");
- if (audioSink.isNull())
- qWarning() << "Unsupported audio codec";
- else
- audioPauseControl.installOn(audioSink);
- }
-
- if (hasVideo) {
- videoSink = gstEncoder.getRequestPad("video_%u");
- if (videoSink.isNull())
- qWarning() << "Unsupported video codec";
- else
- videoPauseControl.installOn(videoSink);
- }
-
- gstPipeline.add(gstEncoder, gstFileSink);
- gstEncoder.link(gstFileSink);
- m_session->linkEncoder(audioSink, videoSink);
-
- gstEncoder.syncStateWithParent();
- gstFileSink.syncStateWithParent();
-
- signalDurationChangedTimer.start();
- gstPipeline.dumpGraph("recording");
-
- stateChanged(QMediaRecorder::RecordingState);
- actualLocationChanged(QUrl::fromLocalFile(location));
-}
-
-void QGstreamerMediaEncoder::pause()
-{
- if (!m_session || state() != QMediaRecorder::RecordingState)
- return;
- signalDurationChangedTimer.stop();
- gstPipeline.dumpGraph("before-pause");
- stateChanged(QMediaRecorder::PausedState);
-}
-
-void QGstreamerMediaEncoder::resume()
-{
- gstPipeline.dumpGraph("before-resume");
- if (!m_session || state() != QMediaRecorder::PausedState)
- return;
- signalDurationChangedTimer.start();
- stateChanged(QMediaRecorder::RecordingState);
-}
-
-void QGstreamerMediaEncoder::stop()
-{
- if (!m_session || state() == QMediaRecorder::StoppedState)
- return;
- qCDebug(qLcMediaEncoder) << "stop";
-
- m_session->unlinkEncoder();
- signalDurationChangedTimer.stop();
-
- //with live sources it's necessary to send EOS even to pipeline
- //before going to STOPPED state
- qCDebug(qLcMediaEncoder) << ">>>>>>>>>>>>> sending EOS";
- gstEncoder.sendEos();
-}
-
-void QGstreamerMediaEncoder::finalize()
-{
- if (!m_session || gstEncoder.isNull())
- return;
-
- qCDebug(qLcMediaEncoder) << "finalize";
-
- gstEncoder.setState(GST_STATE_NULL);
- gstFileSink.setState(GST_STATE_NULL);
- gstPipeline.remove(gstEncoder);
- gstPipeline.remove(gstFileSink);
- gstFileSink = {};
- gstEncoder = {};
- stateChanged(QMediaRecorder::StoppedState);
-}
-
-void QGstreamerMediaEncoder::setMetaData(const QMediaMetaData &metaData)
-{
- if (!m_session)
- return;
- m_metaData = static_cast<const QGstreamerMetaData &>(metaData);
- m_metaData.setMetaData(gstEncoder.bin());
-
-}
-
-QMediaMetaData QGstreamerMediaEncoder::metaData() const
-{
- return m_metaData;
-}
-
-void QGstreamerMediaEncoder::setCaptureSession(QPlatformMediaCaptureSession *session)
-{
- QGstreamerMediaCapture *captureSession = static_cast<QGstreamerMediaCapture *>(session);
- if (m_session == captureSession)
- return;
-
- if (m_session) {
- finalize();
- gstPipeline.removeMessageFilter(this);
- gstPipeline = {};
- }
-
- m_session = captureSession;
- if (!m_session)
- return;
-
- gstPipeline = captureSession->gstPipeline;
- gstPipeline.set("message-forward", true);
- gstPipeline.installMessageFilter(this);
-}
diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder_p.h b/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder_p.h
deleted file mode 100644
index 649edbfd9..000000000
--- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamermediaencoder_p.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 QGSTREAMERENCODERCONTROL_H
-#define QGSTREAMERENCODERCONTROL_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 <private/qplatformmediaencoder_p.h>
-#include "qgstreamermediacapture_p.h"
-#include "private/qgstreamermetadata_p.h"
-
-#include <QtCore/qurl.h>
-#include <QtCore/qdir.h>
-#include <qelapsedtimer.h>
-#include <qtimer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QMediaMetaData;
-class QGstreamerMessage;
-
-class QGstreamerMediaEncoder : public QPlatformMediaEncoder, QGstreamerBusMessageFilter
-{
-public:
- QGstreamerMediaEncoder(QMediaRecorder *parent);
- virtual ~QGstreamerMediaEncoder();
-
- bool isLocationWritable(const QUrl &sink) const override;
-
- qint64 duration() const override;
-
- void record(QMediaEncoderSettings &settings) override;
- void pause() override;
- void resume() override;
- void stop() override;
-
- void setMetaData(const QMediaMetaData &) override;
- QMediaMetaData metaData() const override;
-
- void setCaptureSession(QPlatformMediaCaptureSession *session);
-
- QGstElement getEncoder() { return gstEncoder; }
-private:
- bool processBusMessage(const QGstreamerMessage& message) override;
-
-private:
- struct PauseControl {
- PauseControl(QPlatformMediaEncoder &encoder) : encoder(encoder) {}
-
- GstPadProbeReturn processBuffer(QGstPad pad, GstPadProbeInfo *info);
- void installOn(QGstPad pad);
- void reset();
-
- QPlatformMediaEncoder &encoder;
- GstClockTime pauseOffsetPts = 0;
- std::optional<GstClockTime> pauseStartPts;
- std::optional<GstClockTime> firstBufferPts;
- qint64 duration = 0;
- };
-
- PauseControl audioPauseControl;
- PauseControl videoPauseControl;
-
- void handleSessionError(QMediaRecorder::Error code, const QString &description);
- void finalize();
-
- QGstreamerMediaCapture *m_session = nullptr;
- QGstreamerMetaData m_metaData;
- QTimer signalDurationChangedTimer;
-
- QGstPipeline gstPipeline;
- QGstBin gstEncoder;
- QGstElement gstFileSink;
-};
-
-QT_END_NAMESPACE
-
-#endif // QGSTREAMERENCODERCONTROL_H
diff --git a/src/multimedia/platform/gstreamer/qgstreamerformatinfo.cpp b/src/multimedia/platform/gstreamer/qgstreamerformatinfo.cpp
deleted file mode 100644
index 1bf17ac89..000000000
--- a/src/multimedia/platform/gstreamer/qgstreamerformatinfo.cpp
+++ /dev/null
@@ -1,459 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qgstreamerformatinfo_p.h"
-
-#include "private/qgstutils_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QMediaFormat::AudioCodec QGstreamerFormatInfo::audioCodecForCaps(QGstStructure structure)
-{
- const char *name = structure.name().data();
-
- if (!name || strncmp(name, "audio/", 6))
- return QMediaFormat::AudioCodec::Unspecified;
- name += 6;
- if (!strcmp(name, "mpeg")) {
- auto version = structure["mpegversion"].toInt();
- if (version == 1) {
- auto layer = structure["layer"];
- if (!layer.isNull())
- return QMediaFormat::AudioCodec::MP3;
- }
- if (version == 4)
- return QMediaFormat::AudioCodec::AAC;
- } else if (!strcmp(name, "x-ac3")) {
- return QMediaFormat::AudioCodec::AC3;
- } else if (!strcmp(name, "x-eac3")) {
- return QMediaFormat::AudioCodec::EAC3;
- } else if (!strcmp(name, "x-flac")) {
- return QMediaFormat::AudioCodec::FLAC;
- } else if (!strcmp(name, "x-alac")) {
- return QMediaFormat::AudioCodec::ALAC;
- } else if (!strcmp(name, "x-true-hd")) {
- return QMediaFormat::AudioCodec::DolbyTrueHD;
- } else if (!strcmp(name, "x-vorbis")) {
- return QMediaFormat::AudioCodec::Vorbis;
- } else if (!strcmp(name, "x-opus")) {
- return QMediaFormat::AudioCodec::Opus;
- } else if (!strcmp(name, "x-wav")) {
- return QMediaFormat::AudioCodec::Wave;
- } else if (!strcmp(name, "x-wma")) {
- return QMediaFormat::AudioCodec::WMA;
- }
- return QMediaFormat::AudioCodec::Unspecified;
-}
-
-QMediaFormat::VideoCodec QGstreamerFormatInfo::videoCodecForCaps(QGstStructure structure)
-{
- const char *name = structure.name().data();
-
- if (!name || strncmp(name, "video/", 6))
- return QMediaFormat::VideoCodec::Unspecified;
- name += 6;
-
- if (!strcmp(name, "mpeg")) {
- auto version = structure["mpegversion"].toInt();
- if (version == 1)
- return QMediaFormat::VideoCodec::MPEG1;
- else if (version == 2)
- return QMediaFormat::VideoCodec::MPEG2;
- else if (version == 4)
- return QMediaFormat::VideoCodec::MPEG4;
- } else if (!strcmp(name, "x-h264")) {
- return QMediaFormat::VideoCodec::H264;
-#if GST_CHECK_VERSION(1, 17, 0) // x265enc seems to be broken on 1.16 at least
- } else if (!strcmp(name, "x-h265")) {
- return QMediaFormat::VideoCodec::H265;
-#endif
- } else if (!strcmp(name, "x-vp8")) {
- return QMediaFormat::VideoCodec::VP8;
- } else if (!strcmp(name, "x-vp9")) {
- return QMediaFormat::VideoCodec::VP9;
- } else if (!strcmp(name, "x-av1")) {
- return QMediaFormat::VideoCodec::AV1;
- } else if (!strcmp(name, "x-theora")) {
- return QMediaFormat::VideoCodec::Theora;
- } else if (!strcmp(name, "x-jpeg")) {
- return QMediaFormat::VideoCodec::MotionJPEG;
- } else if (!strcmp(name, "x-wmv")) {
- return QMediaFormat::VideoCodec::WMV;
- }
- return QMediaFormat::VideoCodec::Unspecified;
-}
-
-QMediaFormat::FileFormat QGstreamerFormatInfo::fileFormatForCaps(QGstStructure structure)
-{
- const char *name = structure.name().data();
-
- if (!strcmp(name, "video/x-ms-asf")) {
- return QMediaFormat::FileFormat::WMV;
- } else if (!strcmp(name, "video/x-msvideo")) {
- return QMediaFormat::FileFormat::AVI;
- } else if (!strcmp(name, "video/x-matroska")) {
- return QMediaFormat::FileFormat::Matroska;
- } else if (!strcmp(name, "video/quicktime")) {
- auto variant = structure["variant"].toString();
- if (!variant)
- return QMediaFormat::FileFormat::QuickTime;
- else if (!strcmp(variant, "iso"))
- return QMediaFormat::FileFormat::MPEG4;
- } else if (!strcmp(name, "video/ogg")) {
- return QMediaFormat::FileFormat::Ogg;
- } else if (!strcmp(name, "video/webm")) {
- return QMediaFormat::FileFormat::WebM;
- } else if (!strcmp(name, "audio/x-m4a")) {
- return QMediaFormat::FileFormat::Mpeg4Audio;
- } else if (!strcmp(name, "audio/x-wav")) {
- return QMediaFormat::FileFormat::Wave;
- } else if (!strcmp(name, "audio/mpeg")) {
- auto mpegversion = structure["mpegversion"].toInt();
- if (mpegversion == 1) {
- auto layer = structure["layer"];
- if (!layer.isNull())
- return QMediaFormat::FileFormat::MP3;
- }
- }
- return QMediaFormat::UnspecifiedFormat;
-}
-
-
-QImageCapture::FileFormat QGstreamerFormatInfo::imageFormatForCaps(QGstStructure structure)
-{
- const char *name = structure.name().data();
-
- if (!strcmp(name, "image/jpeg")) {
- return QImageCapture::JPEG;
- } else if (!strcmp(name, "image/png")) {
- return QImageCapture::PNG;
- } else if (!strcmp(name, "image/webp")) {
- return QImageCapture::WebP;
- } else if (!strcmp(name, "image/webp")) {
- return QImageCapture::WebP;
- } else if (!strcmp(name, "image/tiff")) {
- return QImageCapture::Tiff;
- }
- return QImageCapture::UnspecifiedFormat;
-}
-
-static QPair<QList<QMediaFormat::AudioCodec>, QList<QMediaFormat::VideoCodec>> getCodecsList(bool decode)
-{
- QList<QMediaFormat::AudioCodec> audio;
- QList<QMediaFormat::VideoCodec> video;
-
- GstPadDirection padDirection = decode ? GST_PAD_SINK : GST_PAD_SRC;
-
- GList *elementList = gst_element_factory_list_get_elements(decode ? GST_ELEMENT_FACTORY_TYPE_DECODER : GST_ELEMENT_FACTORY_TYPE_ENCODER,
- GST_RANK_MARGINAL);
-
- GList *element = elementList;
- while (element) {
- GstElementFactory *factory = (GstElementFactory *)element->data;
- element = element->next;
-
- const GList *padTemplates = gst_element_factory_get_static_pad_templates(factory);
- while (padTemplates) {
- GstStaticPadTemplate *padTemplate = (GstStaticPadTemplate *)padTemplates->data;
- padTemplates = padTemplates->next;
-
- if (padTemplate->direction == padDirection) {
- QGstMutableCaps caps = gst_static_caps_get(&padTemplate->static_caps);
-
- for (int i = 0; i < caps.size(); i++) {
- QGstStructure structure = caps.at(i);
- auto a = QGstreamerFormatInfo::audioCodecForCaps(structure);
- if (a != QMediaFormat::AudioCodec::Unspecified && !audio.contains(a))
- audio.append(a);
- auto v = QGstreamerFormatInfo::videoCodecForCaps(structure);
- if (v != QMediaFormat::VideoCodec::Unspecified && !video.contains(v))
- video.append(v);
- }
- }
- }
- }
- gst_plugin_feature_list_free(elementList);
- return {audio, video};
-}
-
-
-QList<QGstreamerFormatInfo::CodecMap> QGstreamerFormatInfo::getMuxerList(bool demuxer,
- QList<QMediaFormat::AudioCodec> supportedAudioCodecs,
- QList<QMediaFormat::VideoCodec> supportedVideoCodecs)
-{
- QList<QGstreamerFormatInfo::CodecMap> muxers;
-
- GstPadDirection padDirection = demuxer ? GST_PAD_SINK : GST_PAD_SRC;
-
- GList *elementList = gst_element_factory_list_get_elements(demuxer ? GST_ELEMENT_FACTORY_TYPE_DEMUXER : GST_ELEMENT_FACTORY_TYPE_MUXER,
- GST_RANK_MARGINAL);
- GList *element = elementList;
- while (element) {
- GstElementFactory *factory = (GstElementFactory *)element->data;
- element = element->next;
-
- QList<QMediaFormat::FileFormat> fileFormats;
-
- const GList *padTemplates = gst_element_factory_get_static_pad_templates(factory);
- while (padTemplates) {
- GstStaticPadTemplate *padTemplate = (GstStaticPadTemplate *)padTemplates->data;
- padTemplates = padTemplates->next;
-
- if (padTemplate->direction == padDirection) {
- QGstMutableCaps caps = gst_static_caps_get(&padTemplate->static_caps);
-
- for (int i = 0; i < caps.size(); i++) {
- QGstStructure structure = caps.at(i);
- auto fmt = fileFormatForCaps(structure);
- if (fmt != QMediaFormat::UnspecifiedFormat)
- fileFormats.append(fmt);
- }
- }
- }
- if (fileFormats.isEmpty())
- continue;
-
- QList<QMediaFormat::AudioCodec> audioCodecs;
- QList<QMediaFormat::VideoCodec> videoCodecs;
-
- padTemplates = gst_element_factory_get_static_pad_templates(factory);
- while (padTemplates) {
- GstStaticPadTemplate *padTemplate = (GstStaticPadTemplate *)padTemplates->data;
- padTemplates = padTemplates->next;
-
- // check the other side for supported inputs/outputs
- if (padTemplate->direction != padDirection) {
- QGstMutableCaps caps = gst_static_caps_get(&padTemplate->static_caps);
-
- bool acceptsRawAudio = false;
- for (int i = 0; i < caps.size(); i++) {
- QGstStructure structure = caps.at(i);
- if (structure.name() == "audio/x-raw")
- acceptsRawAudio = true;
- auto audio = audioCodecForCaps(structure);
- if (audio != QMediaFormat::AudioCodec::Unspecified && supportedAudioCodecs.contains(audio))
- audioCodecs.append(audio);
- auto video = videoCodecForCaps(structure);
- if (video != QMediaFormat::VideoCodec::Unspecified && supportedVideoCodecs.contains(video))
- videoCodecs.append(video);
- }
- if (acceptsRawAudio && fileFormats.size() == 1) {
- switch (fileFormats.at(0)) {
- case QMediaFormat::Mpeg4Audio:
- default:
- break;
- case QMediaFormat::MP3:
- audioCodecs.append(QMediaFormat::AudioCodec::MP3);
- break;
- case QMediaFormat::FLAC:
- audioCodecs.append(QMediaFormat::AudioCodec::FLAC);
- break;
- case QMediaFormat::Wave:
- audioCodecs.append(QMediaFormat::AudioCodec::Wave);
- break;
- }
- }
- }
- }
- if (!audioCodecs.isEmpty() || !videoCodecs.isEmpty()) {
- for (auto f : qAsConst(fileFormats)) {
- muxers.append({f, audioCodecs, videoCodecs});
- if (f == QMediaFormat::MPEG4 && !fileFormats.contains(QMediaFormat::Mpeg4Audio)) {
- muxers.append({QMediaFormat::Mpeg4Audio, audioCodecs, {}});
- if (audioCodecs.contains(QMediaFormat::AudioCodec::AAC))
- muxers.append({QMediaFormat::AAC, { QMediaFormat::AudioCodec::AAC }, {}});
- } else if (f == QMediaFormat::WMV && !fileFormats.contains(QMediaFormat::WMA)) {
- muxers.append({QMediaFormat::WMA, audioCodecs, {}});
- }
- }
- }
- }
- gst_plugin_feature_list_free(elementList);
- return muxers;
-}
-
-static QList<QImageCapture::FileFormat> getImageFormatList()
-{
- QSet<QImageCapture::FileFormat> formats;
-
- GList *elementList = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_ENCODER,
- GST_RANK_MARGINAL);
-
- GList *element = elementList;
- while (element) {
- GstElementFactory *factory = (GstElementFactory *)element->data;
- element = element->next;
-
- const GList *padTemplates = gst_element_factory_get_static_pad_templates(factory);
- while (padTemplates) {
- GstStaticPadTemplate *padTemplate = (GstStaticPadTemplate *)padTemplates->data;
- padTemplates = padTemplates->next;
-
- if (padTemplate->direction == GST_PAD_SRC) {
- QGstMutableCaps caps = gst_static_caps_get(&padTemplate->static_caps);
-
- for (int i = 0; i < caps.size(); i++) {
- QGstStructure structure = caps.at(i);
- auto f = QGstreamerFormatInfo::imageFormatForCaps(structure);
- if (f != QImageCapture::UnspecifiedFormat) {
-// qDebug() << structure.toString() << f;
- formats.insert(f);
- }
- }
- }
- }
- }
- gst_plugin_feature_list_free(elementList);
- return formats.values();
-}
-
-#if 0
-static void dumpAudioCodecs(const QList<QMediaFormat::AudioCodec> &codecList)
-{
- qDebug() << "Audio codecs:";
- for (const auto &c : codecList)
- qDebug() << " " << QMediaFormat::audioCodecName(c);
-}
-
-static void dumpVideoCodecs(const QList<QMediaFormat::VideoCodec> &codecList)
-{
- qDebug() << "Video codecs:";
- for (const auto &c : codecList)
- qDebug() << " " << QMediaFormat::videoCodecName(c);
-}
-
-static void dumpMuxers(const QList<QPlatformMediaFormatInfo::CodecMap> &muxerList)
-{
- for (const auto &m : muxerList) {
- qDebug() << " " << QMediaFormat::fileFormatName(m.format);
- qDebug() << " Audio";
- for (const auto &a : m.audio)
- qDebug() << " " << QMediaFormat::audioCodecName(a);
- qDebug() << " Video";
- for (const auto &v : m.video)
- qDebug() << " " << QMediaFormat::videoCodecName(v);
- }
-
-}
-#endif
-
-QGstreamerFormatInfo::QGstreamerFormatInfo()
-{
- auto codecs = getCodecsList(/*decode = */ true);
- decoders = getMuxerList(true, codecs.first, codecs.second);
-
- codecs = getCodecsList(/*decode = */ false);
- encoders = getMuxerList(/* demuxer = */false, codecs.first, codecs.second);
-// dumpAudioCodecs(codecs.first);
-// dumpVideoCodecs(codecs.second);
-// dumpMuxers(encoders);
-
- imageFormats = getImageFormatList();
-}
-
-QGstreamerFormatInfo::~QGstreamerFormatInfo() = default;
-
-QGstMutableCaps QGstreamerFormatInfo::formatCaps(const QMediaFormat &f) const
-{
- auto format = f.fileFormat();
- Q_ASSERT(format != QMediaFormat::UnspecifiedFormat);
-
- const char *capsForFormat[QMediaFormat::LastFileFormat + 1] = {
- "video/x-ms-asf", // WMV
- "video/x-msvideo", // AVI
- "video/x-matroska", // Matroska
- "video/quicktime, variant=(string)iso", // MPEG4
- "video/ogg", // Ogg
- "video/quicktime", // QuickTime
- "video/webm", // WebM
- "video/quicktime, variant=(string)iso", // Mpeg4Audio is the same is mp4...
- "video/quicktime, variant=(string)iso", // AAC is also an MP4 container
- "video/x-ms-asf", // WMA, same as WMV
- "audio/mpeg, mpegversion=(int)1, layer=(int)3", // MP3
- "audio/x-flac", // FLAC
- "audio/x-wav" // Wave
- };
- return gst_caps_from_string(capsForFormat[format]);
-}
-
-QGstMutableCaps QGstreamerFormatInfo::audioCaps(const QMediaFormat &f) const
-{
- auto codec = f.audioCodec();
- if (codec == QMediaFormat::AudioCodec::Unspecified)
- return nullptr;
-
- const char *capsForCodec[(int)QMediaFormat::AudioCodec::LastAudioCodec + 1] = {
- "audio/mpeg, mpegversion=(int)1, layer=(int)3", // MP3
- "audio/mpeg, mpegversion=(int)4", // AAC
- "audio/x-ac3", // AC3
- "audio/x-eac3", // EAC3
- "audio/x-flac", // FLAC
- "audio/x-true-hd", // DolbyTrueHD
- "audio/x-opus", // Opus
- "audio/x-vorbis", // Vorbis
- "audio/x-raw", // WAVE
- "audio/x-wma", // WMA
- "audio/x-alac", // ALAC
- };
- return gst_caps_from_string(capsForCodec[(int)codec]);
-}
-
-QGstMutableCaps QGstreamerFormatInfo::videoCaps(const QMediaFormat &f) const
-{
- auto codec = f.videoCodec();
- if (codec == QMediaFormat::VideoCodec::Unspecified)
- return nullptr;
-
- const char *capsForCodec[(int)QMediaFormat::VideoCodec::LastVideoCodec + 1] = {
- "video/mpeg, mpegversion=(int)1", // MPEG1,
- "video/mpeg, mpegversion=(int)2", // MPEG2,
- "video/mpeg, mpegversion=(int)4", // MPEG4,
- "video/x-h264", // H264,
- "video/x-h265", // H265,
- "video/x-vp8", // VP8,
- "video/x-vp9", // VP9,
- "video/x-av1", // AV1,
- "video/x-theora", // Theora,
- "audio/x-wmv", // WMV
- "video/x-jpeg", // MotionJPEG,
- };
- return gst_caps_from_string(capsForCodec[(int)codec]);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/qgstreamerformatinfo_p.h b/src/multimedia/platform/gstreamer/qgstreamerformatinfo_p.h
deleted file mode 100644
index f8de964e4..000000000
--- a/src/multimedia/platform/gstreamer/qgstreamerformatinfo_p.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QGSTREAMERFORMATINFO_H
-#define QGSTREAMERFORMATINFO_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 <private/qplatformmediaformatinfo_p.h>
-#include <qhash.h>
-#include <qlist.h>
-#include <private/qgstutils_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerFormatInfo : public QPlatformMediaFormatInfo
-{
-public:
- QGstreamerFormatInfo();
- ~QGstreamerFormatInfo();
-
- QGstMutableCaps formatCaps(const QMediaFormat &f) const;
- QGstMutableCaps audioCaps(const QMediaFormat &f) const;
- QGstMutableCaps videoCaps(const QMediaFormat &f) const;
-
- static QMediaFormat::AudioCodec audioCodecForCaps(QGstStructure structure);
- static QMediaFormat::VideoCodec videoCodecForCaps(QGstStructure structure);
- static QMediaFormat::FileFormat fileFormatForCaps(QGstStructure structure);
- static QImageCapture::FileFormat imageFormatForCaps(QGstStructure structure);
-
- QList<CodecMap> getMuxerList(bool demuxer, QList<QMediaFormat::AudioCodec> audioCodecs, QList<QMediaFormat::VideoCodec> videoCodecs);
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/qgstreamerintegration.cpp b/src/multimedia/platform/gstreamer/qgstreamerintegration.cpp
deleted file mode 100644
index 6f28fe42d..000000000
--- a/src/multimedia/platform/gstreamer/qgstreamerintegration.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qgstreamerintegration_p.h"
-#include "qgstreamermediadevices_p.h"
-#include "private/qgstreamermediaplayer_p.h"
-#include "private/qgstreamermediacapture_p.h"
-#include "private/qgstreameraudiodecoder_p.h"
-#include "private/qgstreamercamera_p.h"
-#include "private/qgstreamermediaencoder_p.h"
-#include "private/qgstreamerimagecapture_p.h"
-#include "private/qgstreamerformatinfo_p.h"
-#include "private/qgstreamervideosink_p.h"
-#include "private/qgstreameraudioinput_p.h"
-#include "private/qgstreameraudiooutput_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QGstreamerIntegration::QGstreamerIntegration()
-{
- gst_init(nullptr, nullptr);
- m_devices = new QGstreamerMediaDevices();
- m_formatsInfo = new QGstreamerFormatInfo();
-}
-
-QGstreamerIntegration::~QGstreamerIntegration()
-{
- delete m_devices;
- delete m_formatsInfo;
-}
-
-QPlatformMediaDevices *QGstreamerIntegration::devices()
-{
- return m_devices;
-}
-
-QPlatformMediaFormatInfo *QGstreamerIntegration::formatInfo()
-{
- return m_formatsInfo;
-}
-
-QPlatformAudioDecoder *QGstreamerIntegration::createAudioDecoder(QAudioDecoder *decoder)
-{
- return new QGstreamerAudioDecoder(decoder);
-}
-
-QPlatformMediaCaptureSession *QGstreamerIntegration::createCaptureSession()
-{
- return new QGstreamerMediaCapture();
-}
-
-QPlatformMediaPlayer *QGstreamerIntegration::createPlayer(QMediaPlayer *player)
-{
- return new QGstreamerMediaPlayer(player);
-}
-
-QPlatformCamera *QGstreamerIntegration::createCamera(QCamera *camera)
-{
- return new QGstreamerCamera(camera);
-}
-
-QPlatformMediaEncoder *QGstreamerIntegration::createEncoder(QMediaRecorder *encoder)
-{
- return new QGstreamerMediaEncoder(encoder);
-}
-
-QPlatformImageCapture *QGstreamerIntegration::createImageCapture(QImageCapture *imageCapture)
-{
- return new QGstreamerImageCapture(imageCapture);
-}
-
-QPlatformVideoSink *QGstreamerIntegration::createVideoSink(QVideoSink *sink)
-{
- return new QGstreamerVideoSink(sink);
-}
-
-QPlatformAudioInput *QGstreamerIntegration::createAudioInput(QAudioInput *q)
-{
- return new QGstreamerAudioInput(q);
-}
-
-QPlatformAudioOutput *QGstreamerIntegration::createAudioOutput(QAudioOutput *q)
-{
- return new QGstreamerAudioOutput(q);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/qgstreamerintegration_p.h b/src/multimedia/platform/gstreamer/qgstreamerintegration_p.h
deleted file mode 100644
index 14167e750..000000000
--- a/src/multimedia/platform/gstreamer/qgstreamerintegration_p.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QGSTREAMERINTEGRATION_H
-#define QGSTREAMERINTEGRATION_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 <private/qplatformmediaintegration_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerMediaDevices;
-class QGstreamerPlayerInterface;
-class QGstreamerFormatInfo;
-
-class QGstreamerIntegration : public QPlatformMediaIntegration
-{
-public:
- QGstreamerIntegration();
- ~QGstreamerIntegration();
-
- static QGstreamerIntegration *instance() { return static_cast<QGstreamerIntegration *>(QPlatformMediaIntegration::instance()); }
- QPlatformMediaDevices *devices() override;
- QPlatformMediaFormatInfo *formatInfo() override;
-
- QPlatformAudioDecoder *createAudioDecoder(QAudioDecoder *decoder) override;
- QPlatformMediaCaptureSession *createCaptureSession() override;
- QPlatformMediaPlayer *createPlayer(QMediaPlayer *player) override;
- QPlatformCamera *createCamera(QCamera *) override;
- QPlatformMediaEncoder *createEncoder(QMediaRecorder *) override;
- QPlatformImageCapture *createImageCapture(QImageCapture *) override;
-
- QPlatformVideoSink *createVideoSink(QVideoSink *sink) override;
-
- QPlatformAudioInput *createAudioInput(QAudioInput *) override;
- QPlatformAudioOutput *createAudioOutput(QAudioOutput *) override;
-
- QGstreamerMediaDevices *m_devices = nullptr;
- QGstreamerFormatInfo *m_formatsInfo = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/gstreamer/qgstreamermediadevices.cpp b/src/multimedia/platform/gstreamer/qgstreamermediadevices.cpp
deleted file mode 100644
index f66329f5e..000000000
--- a/src/multimedia/platform/gstreamer/qgstreamermediadevices.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qgstreamermediadevices_p.h"
-#include "qmediadevices.h"
-#include "qcameradevice_p.h"
-
-#include "private/qgstreameraudiosource_p.h"
-#include "private/qgstreameraudiosink_p.h"
-#include "private/qgstreameraudiodevice_p.h"
-#include "private/qgstutils_p.h"
-
-QT_BEGIN_NAMESPACE
-
-static gboolean deviceMonitor(GstBus *, GstMessage *message, gpointer m)
-{
- QGstreamerMediaDevices *manager = static_cast<QGstreamerMediaDevices *>(m);
- GstDevice *device = nullptr;
-
- switch (GST_MESSAGE_TYPE (message)) {
- case GST_MESSAGE_DEVICE_ADDED:
- gst_message_parse_device_added(message, &device);
- manager->addDevice(device);
- break;
- case GST_MESSAGE_DEVICE_REMOVED:
- gst_message_parse_device_removed(message, &device);
- manager->removeDevice(device);
- break;
- default:
- break;
- }
- if (device)
- gst_object_unref (device);
-
- return G_SOURCE_CONTINUE;
-}
-
-QGstreamerMediaDevices::QGstreamerMediaDevices()
- : QPlatformMediaDevices()
-{
- GstDeviceMonitor *monitor;
- GstBus *bus;
-
- monitor = gst_device_monitor_new();
-
- gst_device_monitor_add_filter (monitor, "Video/Source", nullptr);
- gst_device_monitor_add_filter (monitor, "Audio/Source", nullptr);
- gst_device_monitor_add_filter (monitor, "Audio/Sink", nullptr);
-
- bus = gst_device_monitor_get_bus(monitor);
- gst_bus_add_watch(bus, deviceMonitor, this);
- gst_object_unref(bus);
-
- gst_device_monitor_start(monitor);
-
- auto devices = gst_device_monitor_get_devices(monitor);
-
- while (devices) {
- GstDevice *device = static_cast<GstDevice *>(devices->data);
- addDevice(device);
- gst_object_unref(device);
- devices = g_list_delete_link(devices, devices);
- }
-}
-
-static QList<QAudioDevice> devicesFromSet(const QSet<GstDevice *> &deviceSet, QAudioDevice::Mode mode)
-{
- QList<QAudioDevice> devices;
- for (auto *d : deviceSet) {
- auto *properties = gst_device_get_properties(d);
- if (properties) {
- auto *klass = gst_structure_get_string(properties, "device.class");
- if (qstrcmp(klass, "monitor")) {
- auto *name = gst_structure_get_string(properties, "sysfs.path");
- gboolean def;
- auto *info = new QGStreamerAudioDeviceInfo(d, name, mode);
- if (gst_structure_get_boolean(properties, "is-default", &def) && def)
- devices.prepend(info->create());
- else
- devices.append(info->create());
- }
-
- gst_structure_free(properties);
- }
- }
- return devices;
-};
-
-QList<QAudioDevice> QGstreamerMediaDevices::audioInputs() const
-{
- return devicesFromSet(m_audioSources, QAudioDevice::Input);
-}
-
-QList<QAudioDevice> QGstreamerMediaDevices::audioOutputs() const
-{
- return devicesFromSet(m_audioSinks, QAudioDevice::Output);
-}
-
-QList<QCameraDevice> QGstreamerMediaDevices::videoInputs() const
-{
- QList<QCameraDevice> devices;
-
- for (auto *d : qAsConst(m_videoSources)) {
- QGstStructure properties = gst_device_get_properties(d);
- if (!properties.isNull()) {
- QCameraDevicePrivate *info = new QCameraDevicePrivate;
- auto *desc = gst_device_get_display_name(d);
- info->description = QString::fromUtf8(desc);
- g_free(desc);
-
- info->id = properties["device.path"].toString();
- auto def = properties["is-default"].toBool();
- info->isDefault = def && *def;
- if (def)
- devices.prepend(info->create());
- else
- devices.append(info->create());
- properties.free();
- QGstCaps caps = gst_device_get_caps(d);
- if (!caps.isNull()) {
- QList<QCameraFormat> formats;
- QSet<QSize> photoResolutions;
-
- int size = caps.size();
- for (int i = 0; i < size; ++i) {
- auto cap = caps.at(i);
-
- QSize resolution = cap.resolution();
- if (!resolution.isValid())
- continue;
-
- auto pixelFormat = cap.pixelFormat();
- auto frameRate = cap.frameRateRange();
-
- auto *f = new QCameraFormatPrivate{
- QSharedData(),
- pixelFormat,
- resolution,
- frameRate.min,
- frameRate.max
- };
- formats << f->create();
- photoResolutions.insert(resolution);
- }
- info->videoFormats = formats;
- // ### sort resolutions?
- info->photoResolutions = photoResolutions.values();
- }
- }
- }
- return devices;
-}
-
-QPlatformAudioSource *QGstreamerMediaDevices::createAudioSource(const QAudioDevice &deviceInfo)
-{
- return new QGStreamerAudioSource(deviceInfo);
-}
-
-QPlatformAudioSink *QGstreamerMediaDevices::createAudioSink(const QAudioDevice &deviceInfo)
-{
- return new QGStreamerAudioSink(deviceInfo);
-}
-
-void QGstreamerMediaDevices::addDevice(GstDevice *device)
-{
- gchar *type = gst_device_get_device_class(device);
-// qDebug() << "adding device:" << device << type << gst_device_get_display_name(device) << gst_structure_to_string(gst_device_get_properties(device));
- gst_object_ref(device);
- if (!strcmp(type, "Video/Source")) {
- m_videoSources.insert(device);
- videoInputsChanged();
- } else if (!strcmp(type, "Audio/Source")) {
- m_audioSources.insert(device);
- audioInputsChanged();
- } else if (!strcmp(type, "Audio/Sink")) {
- m_audioSinks.insert(device);
- audioOutputsChanged();
- } else {
- gst_object_unref(device);
- }
- g_free(type);
-}
-
-void QGstreamerMediaDevices::removeDevice(GstDevice *device)
-{
-// qDebug() << "removing device:" << device << gst_device_get_display_name(device);
- if (m_videoSources.remove(device)) {
- videoInputsChanged();
- } else if (m_audioSources.remove(device)) {
- audioInputsChanged();
- } else if (m_audioSinks.remove(device)) {
- audioOutputsChanged();
- }
-
- gst_object_unref(device);
-}
-
-static GstDevice *getDevice(const QSet<GstDevice *> &devices, const char *key, const QByteArray &id)
-{
- GstDevice *gstDevice = nullptr;
- for (auto *d : devices) {
- QGstStructure properties = gst_device_get_properties(d);
- if (!properties.isNull()) {
- auto *name = properties[key].toString();
- if (id == name) {
- gstDevice = d;
- }
- }
- properties.free();
- if (gstDevice)
- break;
- }
- return gstDevice;
-
-}
-
-GstDevice *QGstreamerMediaDevices::audioDevice(const QByteArray &id, QAudioDevice::Mode mode) const
-{
- const auto devices = (mode == QAudioDevice::Output) ? m_audioSinks : m_audioSources;
-
- return getDevice(devices, "sysfs.path", id);
-}
-
-GstDevice *QGstreamerMediaDevices::videoDevice(const QByteArray &id) const
-{
- return getDevice(m_videoSources, "device.path", id);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/gstreamer/qgstreamermediadevices_p.h b/src/multimedia/platform/gstreamer/qgstreamermediadevices_p.h
deleted file mode 100644
index e3f34433f..000000000
--- a/src/multimedia/platform/gstreamer/qgstreamermediadevices_p.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QGSTREAMERMEDIADEVICES_H
-#define QGSTREAMERMEDIADEVICES_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 <private/qplatformmediadevices_p.h>
-#include <gst/gst.h>
-#include <qset.h>
-#include <qaudiodevice.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGstreamerMediaDevices : public QPlatformMediaDevices
-{
-public:
- QGstreamerMediaDevices();
-
- QList<QAudioDevice> audioInputs() const override;
- QList<QAudioDevice> audioOutputs() const override;
- QList<QCameraDevice> videoInputs() const override;
- QPlatformAudioSource *createAudioSource(const QAudioDevice &deviceInfo) override;
- QPlatformAudioSink *createAudioSink(const QAudioDevice &deviceInfo) override;
-
- void addDevice(GstDevice *);
- void removeDevice(GstDevice *);
-
- GstDevice *audioDevice(const QByteArray &id, QAudioDevice::Mode mode) const;
- GstDevice *videoDevice(const QByteArray &id) const;
-
-private:
- QSet<GstDevice *> m_videoSources;
- QSet<GstDevice *> m_audioSources;
- QSet<GstDevice *> m_audioSinks;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/pulseaudio/qaudioengine_pulse.cpp b/src/multimedia/platform/pulseaudio/qaudioengine_pulse.cpp
deleted file mode 100644
index 53ffffe53..000000000
--- a/src/multimedia/platform/pulseaudio/qaudioengine_pulse.cpp
+++ /dev/null
@@ -1,479 +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/qdebug.h>
-
-#include <qaudiodevice.h>
-#include <QTimer>
-#include "qaudioengine_pulse_p.h"
-#include "qpulseaudiodevice_p.h"
-#include "qpulsehelpers_p.h"
-#include <sys/types.h>
-#include <unistd.h>
-
-QT_BEGIN_NAMESPACE
-
-static void serverInfoCallback(pa_context *context, const pa_server_info *info, void *userdata)
-{
- if (!info) {
- qWarning() << QString::fromLatin1("Failed to get server information: %s").arg(QString::fromUtf8(pa_strerror(pa_context_errno(context))));
- return;
- }
-
-#ifdef DEBUG_PULSE
- char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
-
- pa_sample_spec_snprint(ss, sizeof(ss), &info->sample_spec);
- pa_channel_map_snprint(cm, sizeof(cm), &info->channel_map);
-
- qDebug() << QString("User name: %1\n"
- "Host Name: %2\n"
- "Server Name: %3\n"
- "Server Version: %4\n"
- "Default Sample Specification: %5\n"
- "Default Channel Map: %6\n"
- "Default Sink: %7\n"
- "Default Source: %8\n").arg(
- info->user_name,
- info->host_name,
- info->server_name,
- info->server_version,
- ss,
- cm,
- info->default_sink_name,
- info->default_source_name);
-#endif
-
- QPulseAudioEngine *pulseEngine = static_cast<QPulseAudioEngine*>(userdata);
- pulseEngine->m_serverLock.lockForWrite();
- pulseEngine->m_defaultSink = info->default_sink_name;
- pulseEngine->m_defaultSource = info->default_source_name;
- // ### ensure the QAudioDevices are updated if default changes and emit changed signal in the device manager
- pulseEngine->m_serverLock.unlock();
-
- pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
-}
-
-static void sinkInfoCallback(pa_context *context, const pa_sink_info *info, int isLast, void *userdata)
-{
- QPulseAudioEngine *pulseEngine = static_cast<QPulseAudioEngine*>(userdata);
-
- if (isLast < 0) {
- qWarning() << QString::fromLatin1("Failed to get sink information: %s").arg(QString::fromUtf8(pa_strerror(pa_context_errno(context))));
- return;
- }
-
- if (isLast) {
- pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
- return;
- }
-
- Q_ASSERT(info);
-
-#ifdef DEBUG_PULSE
- QMap<pa_sink_state, QString> stateMap;
- stateMap[PA_SINK_INVALID_STATE] = "n/a";
- stateMap[PA_SINK_RUNNING] = "RUNNING";
- stateMap[PA_SINK_IDLE] = "IDLE";
- stateMap[PA_SINK_SUSPENDED] = "SUSPENDED";
-
- qDebug() << QString("Sink #%1\n"
- "\tState: %2\n"
- "\tName: %3\n"
- "\tDescription: %4\n"
- ).arg(QString::number(info->index),
- stateMap.value(info->state),
- info->name,
- info->description);
-#endif
-
- QWriteLocker locker(&pulseEngine->m_sinkLock);
- bool isDefault = pulseEngine->m_defaultSink == info->name;
- auto *dinfo = new QPulseAudioDeviceInfo(info->name, info->description, isDefault, QAudioDevice::Output);
- pulseEngine->m_sinks.insert(info->index, dinfo->create());
-}
-
-static void sourceInfoCallback(pa_context *context, const pa_source_info *info, int isLast, void *userdata)
-{
- Q_UNUSED(context);
- QPulseAudioEngine *pulseEngine = static_cast<QPulseAudioEngine*>(userdata);
-
- if (isLast) {
- pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
- return;
- }
-
- Q_ASSERT(info);
-
-#ifdef DEBUG_PULSE
- QMap<pa_source_state, QString> stateMap;
- stateMap[PA_SOURCE_INVALID_STATE] = "n/a";
- stateMap[PA_SOURCE_RUNNING] = "RUNNING";
- stateMap[PA_SOURCE_IDLE] = "IDLE";
- stateMap[PA_SOURCE_SUSPENDED] = "SUSPENDED";
-
- qDebug() << QString("Source #%1\n"
- "\tState: %2\n"
- "\tName: %3\n"
- "\tDescription: %4\n"
- ).arg(QString::number(info->index),
- stateMap.value(info->state),
- info->name,
- info->description);
-#endif
-
- QWriteLocker locker(&pulseEngine->m_sourceLock);
- // skip monitor channels
- if (info->monitor_of_sink != PA_INVALID_INDEX)
- return;
- bool isDefault = pulseEngine->m_defaultSink == info->name;
- auto *dinfo = new QPulseAudioDeviceInfo(info->name, info->description, isDefault, QAudioDevice::Input);
- pulseEngine->m_sources.insert(info->index, dinfo->create());
-}
-
-static void event_cb(pa_context* context, pa_subscription_event_type_t t, uint32_t index, void* userdata)
-{
- QPulseAudioEngine *pulseEngine = static_cast<QPulseAudioEngine*>(userdata);
-
- int type = t & PA_SUBSCRIPTION_EVENT_TYPE_MASK;
- int facility = t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK;
-
- switch (type) {
- case PA_SUBSCRIPTION_EVENT_NEW:
- case PA_SUBSCRIPTION_EVENT_CHANGE:
- switch (facility) {
- case PA_SUBSCRIPTION_EVENT_SERVER: {
- pa_operation *op = pa_context_get_server_info(context, serverInfoCallback, userdata);
- if (op)
- pa_operation_unref(op);
- else
- qWarning("PulseAudioService: failed to get server info");
- break;
- }
- case PA_SUBSCRIPTION_EVENT_SINK: {
- pa_operation *op = pa_context_get_sink_info_by_index(context, index, sinkInfoCallback, userdata);
- if (op)
- pa_operation_unref(op);
- else
- qWarning("PulseAudioService: failed to get sink info");
- break;
- }
- case PA_SUBSCRIPTION_EVENT_SOURCE: {
- pa_operation *op = pa_context_get_source_info_by_index(context, index, sourceInfoCallback, userdata);
- if (op)
- pa_operation_unref(op);
- else
- qWarning("PulseAudioService: failed to get source info");
- break;
- }
- default:
- break;
- }
- break;
- case PA_SUBSCRIPTION_EVENT_REMOVE:
- switch (facility) {
- case PA_SUBSCRIPTION_EVENT_SINK:
- pulseEngine->m_sinkLock.lockForWrite();
- pulseEngine->m_sinks.remove(index);
- pulseEngine->m_sinkLock.unlock();
- break;
- case PA_SUBSCRIPTION_EVENT_SOURCE:
- pulseEngine->m_sourceLock.lockForWrite();
- pulseEngine->m_sources.remove(index);
- pulseEngine->m_sourceLock.unlock();
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
-}
-
-static void contextStateCallbackInit(pa_context *context, void *userdata)
-{
- Q_UNUSED(context);
-#ifdef DEBUG_PULSE
- qDebug() << QPulseAudioInternal::stateToQString(pa_context_get_state(context));
-#endif
- QPulseAudioEngine *pulseEngine = reinterpret_cast<QPulseAudioEngine*>(userdata);
- pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
-}
-
-static void contextStateCallback(pa_context *c, void *userdata)
-{
- QPulseAudioEngine *self = reinterpret_cast<QPulseAudioEngine*>(userdata);
- pa_context_state_t state = pa_context_get_state(c);
-
-#ifdef DEBUG_PULSE
- qDebug() << QPulseAudioInternal::stateToQString(state);
-#endif
-
- if (state == PA_CONTEXT_FAILED)
- QMetaObject::invokeMethod(self, "onContextFailed", Qt::QueuedConnection);
-}
-
-Q_GLOBAL_STATIC(QPulseAudioEngine, pulseEngine);
-
-QPulseAudioEngine::QPulseAudioEngine(QObject *parent)
- : QObject(parent)
- , m_mainLoopApi(nullptr)
- , m_context(nullptr)
- , m_prepared(false)
-{
- prepare();
-}
-
-QPulseAudioEngine::~QPulseAudioEngine()
-{
- if (m_prepared)
- release();
-}
-
-void QPulseAudioEngine::prepare()
-{
- bool keepGoing = true;
- bool ok = true;
-
- m_mainLoop = pa_threaded_mainloop_new();
- if (m_mainLoop == nullptr) {
- qWarning("PulseAudioService: unable to create pulseaudio mainloop");
- return;
- }
-
- if (pa_threaded_mainloop_start(m_mainLoop) != 0) {
- qWarning("PulseAudioService: unable to start pulseaudio mainloop");
- pa_threaded_mainloop_free(m_mainLoop);
- m_mainLoop = nullptr;
- return;
- }
-
- m_mainLoopApi = pa_threaded_mainloop_get_api(m_mainLoop);
-
- lock();
-
- m_context = pa_context_new(m_mainLoopApi, QString(QLatin1String("QtPulseAudio:%1")).arg(::getpid()).toLatin1().constData());
-
- if (m_context == nullptr) {
- qWarning("PulseAudioService: Unable to create new pulseaudio context");
- pa_threaded_mainloop_unlock(m_mainLoop);
- pa_threaded_mainloop_free(m_mainLoop);
- m_mainLoop = nullptr;
- onContextFailed();
- return;
- }
-
- pa_context_set_state_callback(m_context, contextStateCallbackInit, this);
-
- if (pa_context_connect(m_context, nullptr, (pa_context_flags_t)0, nullptr) < 0) {
- qWarning("PulseAudioService: pa_context_connect() failed");
- pa_context_unref(m_context);
- pa_threaded_mainloop_unlock(m_mainLoop);
- pa_threaded_mainloop_free(m_mainLoop);
- m_mainLoop = nullptr;
- m_context = nullptr;
- return;
- }
-
- pa_threaded_mainloop_wait(m_mainLoop);
-
- while (keepGoing) {
- switch (pa_context_get_state(m_context)) {
- case PA_CONTEXT_CONNECTING:
- case PA_CONTEXT_AUTHORIZING:
- case PA_CONTEXT_SETTING_NAME:
- break;
-
- case PA_CONTEXT_READY:
-#ifdef DEBUG_PULSE
- qDebug("Connection established.");
-#endif
- keepGoing = false;
- break;
-
- case PA_CONTEXT_TERMINATED:
- qCritical("PulseAudioService: Context terminated.");
- keepGoing = false;
- ok = false;
- break;
-
- case PA_CONTEXT_FAILED:
- default:
- qCritical() << QString::fromLatin1("PulseAudioService: Connection failure: %1")
- .arg(QString::fromUtf8(pa_strerror(pa_context_errno(m_context))));
- keepGoing = false;
- ok = false;
- }
-
- if (keepGoing)
- pa_threaded_mainloop_wait(m_mainLoop);
- }
-
- if (ok) {
- pa_context_set_state_callback(m_context, contextStateCallback, this);
-
- pa_context_set_subscribe_callback(m_context, event_cb, this);
- pa_operation *op = pa_context_subscribe(m_context,
- pa_subscription_mask_t(PA_SUBSCRIPTION_MASK_SINK |
- PA_SUBSCRIPTION_MASK_SOURCE |
- PA_SUBSCRIPTION_MASK_SERVER),
- nullptr, nullptr);
- if (op)
- pa_operation_unref(op);
- else
- qWarning("PulseAudioService: failed to subscribe to context notifications");
- } else {
- pa_context_unref(m_context);
- m_context = nullptr;
- }
-
- unlock();
-
- if (ok) {
- updateDevices();
- m_prepared = true;
- } else {
- pa_threaded_mainloop_free(m_mainLoop);
- m_mainLoop = nullptr;
- onContextFailed();
- }
-}
-
-void QPulseAudioEngine::release()
-{
- if (!m_prepared)
- return;
-
- if (m_context) {
- pa_context_disconnect(m_context);
- pa_context_unref(m_context);
- m_context = nullptr;
- }
-
- if (m_mainLoop) {
- pa_threaded_mainloop_stop(m_mainLoop);
- pa_threaded_mainloop_free(m_mainLoop);
- m_mainLoop = nullptr;
- }
-
- m_prepared = false;
-}
-
-void QPulseAudioEngine::updateDevices()
-{
- lock();
-
- // Get default input and output devices
- pa_operation *operation = pa_context_get_server_info(m_context, serverInfoCallback, this);
- if (operation) {
- while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING)
- pa_threaded_mainloop_wait(m_mainLoop);
- pa_operation_unref(operation);
- } else {
- qWarning("PulseAudioService: failed to get server info");
- }
-
- // Get output devices
- operation = pa_context_get_sink_info_list(m_context, sinkInfoCallback, this);
- if (operation) {
- while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING)
- pa_threaded_mainloop_wait(m_mainLoop);
- pa_operation_unref(operation);
- } else {
- qWarning("PulseAudioService: failed to get sink info");
- }
-
- // Get input devices
- operation = pa_context_get_source_info_list(m_context, sourceInfoCallback, this);
- if (operation) {
- while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING)
- pa_threaded_mainloop_wait(m_mainLoop);
- pa_operation_unref(operation);
- } else {
- qWarning("PulseAudioService: failed to get source info");
- }
-
- unlock();
-}
-
-void QPulseAudioEngine::onContextFailed()
-{
- // Give a chance to the connected slots to still use the Pulse main loop before releasing it.
- emit contextFailed();
-
- release();
-
- // Try to reconnect later
- QTimer::singleShot(3000, this, SLOT(prepare()));
-}
-
-QPulseAudioEngine *QPulseAudioEngine::instance()
-{
- return pulseEngine();
-}
-
-QList<QAudioDevice> QPulseAudioEngine::availableDevices(QAudioDevice::Mode mode) const
-{
- QList<QAudioDevice> devices;
- QByteArray defaultDevice;
-
- m_serverLock.lockForRead();
-
- if (mode == QAudioDevice::Output) {
- QReadLocker locker(&m_sinkLock);
- devices = m_sinks.values();
- defaultDevice = m_defaultSink;
- } else {
- QReadLocker locker(&m_sourceLock);
- devices = m_sources.values();
- defaultDevice = m_defaultSource;
- }
-
- m_serverLock.unlock();
-
- return devices;
-}
-
-QByteArray QPulseAudioEngine::defaultDevice(QAudioDevice::Mode mode) const
-{
- return (mode == QAudioDevice::Output) ? m_defaultSink : m_defaultSource;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/pulseaudio/qaudioengine_pulse_p.h b/src/multimedia/platform/pulseaudio/qaudioengine_pulse_p.h
deleted file mode 100644
index c384d274b..000000000
--- a/src/multimedia/platform/pulseaudio/qaudioengine_pulse_p.h
+++ /dev/null
@@ -1,127 +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 QPULSEAUDIOENGINE_H
-#define QPULSEAUDIOENGINE_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 <QtCore/qmap.h>
-#include <QtCore/qbytearray.h>
-#include <QtCore/qreadwritelock.h>
-#include <pulse/pulseaudio.h>
-#include "qpulsehelpers_p.h"
-#include <qaudioformat.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPulseAudioEngine : public QObject
-{
- Q_OBJECT
-
-public:
- QPulseAudioEngine(QObject *parent = 0);
- ~QPulseAudioEngine();
-
- static QPulseAudioEngine *instance();
- pa_threaded_mainloop *mainloop() { return m_mainLoop; }
- pa_context *context() { return m_context; }
-
- inline void lock()
- {
- if (m_mainLoop)
- pa_threaded_mainloop_lock(m_mainLoop);
- }
-
- inline void unlock()
- {
- if (m_mainLoop)
- pa_threaded_mainloop_unlock(m_mainLoop);
- }
-
- inline void wait(pa_operation *op)
- {
- while (m_mainLoop && pa_operation_get_state(op) == PA_OPERATION_RUNNING)
- pa_threaded_mainloop_wait(m_mainLoop);
- }
-
- QList<QAudioDevice> availableDevices(QAudioDevice::Mode mode) const;
- QByteArray defaultDevice(QAudioDevice::Mode mode) const;
-
-Q_SIGNALS:
- void contextFailed();
-
-private Q_SLOTS:
- void prepare();
- void onContextFailed();
-
-private:
- void updateDevices();
- void release();
-
-public:
- QMap<int, QAudioDevice> m_sinks;
- QMap<int, QAudioDevice> m_sources;
-
- QByteArray m_defaultSink;
- QByteArray m_defaultSource;
-
- mutable QReadWriteLock m_sinkLock;
- mutable QReadWriteLock m_sourceLock;
- mutable QReadWriteLock m_serverLock;
-
-private:
- pa_mainloop_api *m_mainLoopApi;
- pa_threaded_mainloop *m_mainLoop;
- pa_context *m_context;
- bool m_prepared;
- };
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/pulseaudio/qpulseaudiodevice.cpp b/src/multimedia/platform/pulseaudio/qpulseaudiodevice.cpp
deleted file mode 100644
index df161ab18..000000000
--- a/src/multimedia/platform/pulseaudio/qpulseaudiodevice.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 "qpulseaudiodevice_p.h"
-#include "qaudioengine_pulse_p.h"
-#include "qpulsehelpers_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QPulseAudioDeviceInfo::QPulseAudioDeviceInfo(const char *device, const char *desc, bool isDef, QAudioDevice::Mode mode)
- : QAudioDevicePrivate(device, mode)
-{
- description = QString::fromUtf8(desc);
- isDefault = isDef;
-
- minimumChannelCount = 1;
- maximumChannelCount = PA_CHANNELS_MAX;
- minimumSampleRate = 1;
- maximumSampleRate = PA_RATE_MAX;
-
- constexpr bool isBigEndian = QSysInfo::ByteOrder == QSysInfo::BigEndian;
-
- const struct {
- pa_sample_format pa_fmt;
- QAudioFormat::SampleFormat qt_fmt;
- } formatMap[] = {
- { PA_SAMPLE_U8, QAudioFormat::UInt8 },
- { isBigEndian ? PA_SAMPLE_S16BE : PA_SAMPLE_S16LE, QAudioFormat::Int16 },
- { isBigEndian ? PA_SAMPLE_S32BE : PA_SAMPLE_S32LE, QAudioFormat::Int32 },
- { isBigEndian ? PA_SAMPLE_FLOAT32BE : PA_SAMPLE_FLOAT32LE, QAudioFormat::Float },
- };
-
- pa_sample_spec spec;
- spec.channels = 1;
- spec.rate = 48000;
-
- for (const auto &f : formatMap) {
- spec.format = f.pa_fmt;
- if (pa_sample_spec_valid(&spec) != 0)
- supportedSampleFormats.append(f.qt_fmt);
- }
-
- preferredFormat.setChannelCount(2);
- preferredFormat.setSampleRate(48000);
- QAudioFormat::SampleFormat f = QAudioFormat::Int16;
- if (!supportedSampleFormats.contains(f))
- f = supportedSampleFormats.value(0, QAudioFormat::Unknown);
- preferredFormat.setSampleFormat(f);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/pulseaudio/qpulseaudiodevice_p.h b/src/multimedia/platform/pulseaudio/qpulseaudiodevice_p.h
deleted file mode 100644
index 111134614..000000000
--- a/src/multimedia/platform/pulseaudio/qpulseaudiodevice_p.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 QAUDIODEVICEINFOPULSE_H
-#define QAUDIODEVICEINFOPULSE_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 <QtCore/qbytearray.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qlist.h>
-
-#include "qaudio.h"
-#include "qaudiodevice.h"
-#include <private/qaudiosystem_p.h>
-#include <private/qaudiodevice_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPulseAudioDeviceInfo : public QAudioDevicePrivate
-{
-public:
- QPulseAudioDeviceInfo(const char *device, const char *description, bool isDefault, QAudioDevice::Mode mode);
- ~QPulseAudioDeviceInfo() {}
-};
-
-QT_END_NAMESPACE
-
-#endif
-
diff --git a/src/multimedia/platform/pulseaudio/qpulseaudiointegration.cpp b/src/multimedia/platform/pulseaudio/qpulseaudiointegration.cpp
deleted file mode 100644
index f68f2934a..000000000
--- a/src/multimedia/platform/pulseaudio/qpulseaudiointegration.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qpulseaudiointegration_p.h"
-#include "qpulseaudiomediadevices_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QPulseAudioIntegration::QPulseAudioIntegration()
-{
- pulseEngine = new QPulseAudioEngine;
-}
-
-QPulseAudioIntegration::~QPulseAudioIntegration()
-{
- delete m_devices;
-}
-
-QPlatformMediaDevices *QPulseAudioIntegration::devices()
-{
- if (!m_devices)
- m_devices = new QPulseAudioMediaDevices(pulseEngine);
- return m_devices;
-}
-
-QPlatformMediaFormatInfo *QPulseAudioIntegration::formatInfo()
-{
- Q_ASSERT(!"In need of implementation"); // TODO
- return nullptr;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/pulseaudio/qpulseaudiointegration_p.h b/src/multimedia/platform/pulseaudio/qpulseaudiointegration_p.h
deleted file mode 100644
index eb83e6856..000000000
--- a/src/multimedia/platform/pulseaudio/qpulseaudiointegration_p.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QPULSEAUDIOINTEGRATION_H
-#define QPULSEAUDIOINTEGRATION_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 <private/qplatformmediaintegration_p.h>
-#include <private/qaudioengine_pulse_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPulseAudioMediaDevices;
-
-class QPulseAudioIntegration : public QPlatformMediaIntegration
-{
-public:
- QPulseAudioIntegration();
- ~QPulseAudioIntegration();
-
- QPlatformMediaDevices *devices() override;
- QPlatformMediaFormatInfo *formatInfo() override;
-
- QPulseAudioMediaDevices *m_devices = nullptr;
- QPulseAudioEngine *pulseEngine = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/pulseaudio/qpulseaudiomediadevices.cpp b/src/multimedia/platform/pulseaudio/qpulseaudiomediadevices.cpp
deleted file mode 100644
index 4c3c561b4..000000000
--- a/src/multimedia/platform/pulseaudio/qpulseaudiomediadevices.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qpulseaudiomediadevices_p.h"
-#include "qmediadevices.h"
-#include "qcameradevice_p.h"
-
-#include "private/qpulseaudiosource_p.h"
-#include "private/qpulseaudiosink_p.h"
-#include "private/qpulseaudiodevice_p.h"
-#include "private/qaudioengine_pulse_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QPulseAudioMediaDevices::QPulseAudioMediaDevices(QPulseAudioEngine *engine)
- : QPlatformMediaDevices(),
- pulseEngine(engine)
-{
-}
-
-QList<QAudioDevice> QPulseAudioMediaDevices::audioInputs() const
-{
- return pulseEngine->availableDevices(QAudioDevice::Input);
-}
-
-QList<QAudioDevice> QPulseAudioMediaDevices::audioOutputs() const
-{
- return pulseEngine->availableDevices(QAudioDevice::Output);
-}
-
-QList<QCameraDevice> QPulseAudioMediaDevices::videoInputs() const
-{
- return {};
-}
-
-QPlatformAudioSource *QPulseAudioMediaDevices::createAudioSource(const QAudioDevice &deviceInfo)
-{
- return new QPulseAudioSource(deviceInfo.id());
-}
-
-QPlatformAudioSink *QPulseAudioMediaDevices::createAudioSink(const QAudioDevice &deviceInfo)
-{
- return new QPulseAudioSink(deviceInfo.id());
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/pulseaudio/qpulseaudiomediadevices_p.h b/src/multimedia/platform/pulseaudio/qpulseaudiomediadevices_p.h
deleted file mode 100644
index 4cb28056f..000000000
--- a/src/multimedia/platform/pulseaudio/qpulseaudiomediadevices_p.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QPULSEAUDIOMEDIADEVICES_H
-#define QPULSEAUDIOMEDIADEVICES_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 <private/qplatformmediadevices_p.h>
-#include <qset.h>
-#include <qaudio.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPulseAudioEngine;
-
-class QPulseAudioMediaDevices : public QPlatformMediaDevices
-{
-public:
- QPulseAudioMediaDevices(QPulseAudioEngine *engine);
-
- QList<QAudioDevice> audioInputs() const override;
- QList<QAudioDevice> audioOutputs() const override;
- QList<QCameraDevice> videoInputs() const override;
- QPlatformAudioSource *createAudioSource(const QAudioDevice &deviceInfo) override;
- QPlatformAudioSink *createAudioSink(const QAudioDevice &deviceInfo) override;
-
-private:
- QPulseAudioEngine *pulseEngine;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/pulseaudio/qpulseaudiosink.cpp b/src/multimedia/platform/pulseaudio/qpulseaudiosink.cpp
deleted file mode 100644
index 87779e5a7..000000000
--- a/src/multimedia/platform/pulseaudio/qpulseaudiosink.cpp
+++ /dev/null
@@ -1,709 +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/qcoreapplication.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qmath.h>
-#include <private/qaudiohelpers_p.h>
-
-#include "qpulseaudiosink_p.h"
-#include "qpulseaudiodevice_p.h"
-#include "qaudioengine_pulse_p.h"
-#include "qpulsehelpers_p.h"
-#include <sys/types.h>
-#include <unistd.h>
-
-QT_BEGIN_NAMESPACE
-
-const int PeriodTimeMs = 20;
-const int LowLatencyPeriodTimeMs = 10;
-const int LowLatencyBufferSizeMs = 40;
-
-#define LOW_LATENCY_CATEGORY_NAME "game"
-
-static void outputStreamWriteCallback(pa_stream *stream, size_t length, void *userdata)
-{
- Q_UNUSED(stream);
- Q_UNUSED(length);
- Q_UNUSED(userdata);
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
- pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
-}
-
-static void outputStreamStateCallback(pa_stream *stream, void *userdata)
-{
- Q_UNUSED(userdata);
- pa_stream_state_t state = pa_stream_get_state(stream);
-#ifdef DEBUG_PULSE
- qDebug() << "Stream state: " << QPulseAudioInternal::stateToQString(state);
-#endif
- switch (state) {
- case PA_STREAM_CREATING:
- case PA_STREAM_READY:
- case PA_STREAM_TERMINATED:
- break;
-
- case PA_STREAM_FAILED:
- default:
- qWarning() << QString::fromLatin1("Stream error: %1").arg(QString::fromUtf8(pa_strerror(pa_context_errno(pa_stream_get_context(stream)))));
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
- pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
- break;
- }
-}
-
-static void outputStreamUnderflowCallback(pa_stream *stream, void *userdata)
-{
- Q_UNUSED(stream);
- ((QPulseAudioSink*)userdata)->streamUnderflowCallback();
-}
-
-static void outputStreamOverflowCallback(pa_stream *stream, void *userdata)
-{
- Q_UNUSED(stream);
- Q_UNUSED(userdata);
- qWarning() << "Got a buffer overflow!";
-}
-
-static void outputStreamLatencyCallback(pa_stream *stream, void *userdata)
-{
- Q_UNUSED(stream);
- Q_UNUSED(userdata);
-
-#ifdef DEBUG_PULSE
- const pa_timing_info *info = pa_stream_get_timing_info(stream);
-
- qDebug() << "Write index corrupt: " << info->write_index_corrupt;
- qDebug() << "Write index: " << info->write_index;
- qDebug() << "Read index corrupt: " << info->read_index_corrupt;
- qDebug() << "Read index: " << info->read_index;
- qDebug() << "Sink usec: " << info->sink_usec;
- qDebug() << "Configured sink usec: " << info->configured_sink_usec;
-#endif
-}
-
-static void outputStreamSuccessCallback(pa_stream *stream, int success, void *userdata)
-{
- Q_UNUSED(stream);
- Q_UNUSED(success);
- Q_UNUSED(userdata);
-
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
- pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
-}
-
-static void outputStreamDrainComplete(pa_stream *stream, int success, void *userdata)
-{
- Q_UNUSED(stream);
- Q_UNUSED(success);
- Q_UNUSED(userdata);
-
-#ifdef DEBUG_PULSE
- qDebug() << "Draining completed successfully: " << (bool)success;
-#endif
-}
-
-static void streamAdjustPrebufferCallback(pa_stream *stream, int success, void *userdata)
-{
- Q_UNUSED(stream);
- Q_UNUSED(success);
- Q_UNUSED(userdata);
-
-#ifdef DEBUG_PULSE
- qDebug() << "Adjust prebuffer completed successfully: " << (bool)success;
-#endif
-}
-
-
-QPulseAudioSink::QPulseAudioSink(const QByteArray &device)
- : m_device(device)
- , m_errorState(QAudio::NoError)
- , m_deviceState(QAudio::StoppedState)
- , m_pullMode(true)
- , m_opened(false)
- , m_audioSource(nullptr)
- , m_periodTime(0)
- , m_stream(nullptr)
- , m_periodSize(0)
- , m_bufferSize(0)
- , m_maxBufferSize(0)
- , m_totalTimeValue(0)
- , m_tickTimer(new QTimer(this))
- , m_audioBuffer(nullptr)
- , m_resuming(false)
- , m_volume(1.0)
-{
- connect(m_tickTimer, SIGNAL(timeout()), SLOT(userFeed()));
-}
-
-QPulseAudioSink::~QPulseAudioSink()
-{
- close();
- disconnect(m_tickTimer, SIGNAL(timeout()));
- QCoreApplication::processEvents();
-}
-
-void QPulseAudioSink::setError(QAudio::Error error)
-{
- if (m_errorState == error)
- return;
-
- m_errorState = error;
- emit errorChanged(error);
-}
-
-QAudio::Error QPulseAudioSink::error() const
-{
- return m_errorState;
-}
-
-void QPulseAudioSink::setState(QAudio::State state)
-{
- if (m_deviceState == state)
- return;
-
- m_deviceState = state;
- emit stateChanged(state);
-}
-
-QAudio::State QPulseAudioSink::state() const
-{
- return m_deviceState;
-}
-
-void QPulseAudioSink::streamUnderflowCallback()
-{
- if (m_deviceState != QAudio::IdleState && !m_resuming) {
- setError(QAudio::UnderrunError);
- setState(QAudio::IdleState);
- }
-}
-
-void QPulseAudioSink::start(QIODevice *device)
-{
- setState(QAudio::StoppedState);
- setError(QAudio::NoError);
-
- // Handle change of mode
- if (m_audioSource && !m_pullMode) {
- delete m_audioSource;
- }
- m_audioSource = nullptr;
-
- close();
-
- m_pullMode = true;
- m_audioSource = device;
-
- if (!open()) {
- m_audioSource = nullptr;
- return;
- }
-
- setState(QAudio::ActiveState);
-}
-
-QIODevice *QPulseAudioSink::start()
-{
- setState(QAudio::StoppedState);
- setError(QAudio::NoError);
-
- // Handle change of mode
- if (m_audioSource && !m_pullMode) {
- delete m_audioSource;
- }
- m_audioSource = nullptr;
-
- close();
-
- m_pullMode = false;
-
- if (!open())
- return nullptr;
-
- m_audioSource = new PulseOutputPrivate(this);
- m_audioSource->open(QIODevice::WriteOnly|QIODevice::Unbuffered);
-
- setState(QAudio::IdleState);
-
- return m_audioSource;
-}
-
-bool QPulseAudioSink::open()
-{
- if (m_opened)
- return true;
-
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
-
- if (!pulseEngine->context() || pa_context_get_state(pulseEngine->context()) != PA_CONTEXT_READY) {
- setError(QAudio::FatalError);
- setState(QAudio::StoppedState);
- emit stateChanged(m_deviceState);
- return false;
- }
-
- pa_sample_spec spec = QPulseAudioInternal::audioFormatToSampleSpec(m_format);
-
- if (!pa_sample_spec_valid(&spec)) {
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- emit stateChanged(m_deviceState);
- return false;
- }
-
- m_spec = spec;
- m_totalTimeValue = 0;
-
- if (m_streamName.isNull())
- m_streamName = QString(QLatin1String("QtmPulseStream-%1-%2")).arg(::getpid()).arg(quintptr(this)).toUtf8();
-
-#ifdef DEBUG_PULSE
- qDebug() << "Format: " << QPulseAudioInternal::sampleFormatToQString(spec.format);
- qDebug() << "Rate: " << spec.rate;
- qDebug() << "Channels: " << spec.channels;
- qDebug() << "Frame size: " << pa_frame_size(&spec);
-#endif
-
- pulseEngine->lock();
-
-
- pa_proplist *propList = pa_proplist_new();
-#if 0
- qint64 bytesPerSecond = m_format.sampleRate() * m_format.bytesPerFrame();
- static const char *mediaRoleFromAudioRole[] = {
- nullptr, // UnknownRole
- "music", // MusicRole
- "video", // VideoRole
- "phone", // VoiceCommunicationRole
- "event", // AlarmRole
- "event", // NotificationRole
- "phone", // RingtoneRole
- "a11y", // AccessibilityRole
- nullptr, // SonificationRole
- "game" // GameRole
- };
-
- const char *r = mediaRoleFromAudioRole[m_role];
- if (r)
- pa_proplist_sets(propList, PA_PROP_MEDIA_ROLE, r);
-#endif
-
- static const auto mapName = qEnvironmentVariable("QT_PA_CHANNEL_MAP");
- pa_channel_map_def_t mapDef = PA_CHANNEL_MAP_DEFAULT;
- if (mapName == QLatin1String("ALSA"))
- mapDef = PA_CHANNEL_MAP_ALSA;
- else if (mapName == QLatin1String("AUX"))
- mapDef = PA_CHANNEL_MAP_AUX;
- else if (mapName == QLatin1String("WAVEEX"))
- mapDef = PA_CHANNEL_MAP_WAVEEX;
- else if (mapName == QLatin1String("OSS"))
- mapDef = PA_CHANNEL_MAP_OSS;
- else if (!mapName.isEmpty())
- qWarning() << "Unknown pulse audio channel mapping definition:" << mapName;
-
- pa_channel_map m;
- auto channelMap = pa_channel_map_init_extend(&m, m_spec.channels, mapDef);
- if (!channelMap)
- qWarning() << "QAudioSink: pa_channel_map_init_extend() Could not initialize channel map";
-
- m_stream = pa_stream_new_with_proplist(pulseEngine->context(), m_streamName.constData(), &m_spec, channelMap, propList);
- if (!m_stream) {
- qWarning() << "QAudioSink: pa_stream_new_with_proplist() failed!";
- pulseEngine->unlock();
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- emit stateChanged(m_deviceState);
- return false;
- }
-
- pa_proplist_free(propList);
-
- pa_stream_set_state_callback(m_stream, outputStreamStateCallback, this);
- pa_stream_set_write_callback(m_stream, outputStreamWriteCallback, this);
-
- pa_stream_set_underflow_callback(m_stream, outputStreamUnderflowCallback, this);
- pa_stream_set_overflow_callback(m_stream, outputStreamOverflowCallback, this);
- pa_stream_set_latency_update_callback(m_stream, outputStreamLatencyCallback, this);
-
-// if (m_bufferSize <= 0 && m_role == QAudio::GameRoleRole)
-// m_bufferSize = bytesPerSecond * LowLatencyBufferSizeMs / qint64(1000);
-
- pa_buffer_attr requestedBuffer;
- requestedBuffer.fragsize = (uint32_t)-1;
- requestedBuffer.maxlength = (uint32_t)-1;
- requestedBuffer.minreq = (uint32_t)-1;
- requestedBuffer.prebuf = (uint32_t)-1;
- requestedBuffer.tlength = m_bufferSize;
-
- if (pa_stream_connect_playback(m_stream, m_device.data(), (m_bufferSize > 0) ? &requestedBuffer : nullptr, (pa_stream_flags_t)0, nullptr, nullptr) < 0) {
- qWarning() << "pa_stream_connect_playback() failed!";
- pa_stream_unref(m_stream);
- m_stream = nullptr;
- pulseEngine->unlock();
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- emit stateChanged(m_deviceState);
- return false;
- }
-
- while (pa_stream_get_state(m_stream) != PA_STREAM_READY)
- pa_threaded_mainloop_wait(pulseEngine->mainloop());
-
- const pa_buffer_attr *buffer = pa_stream_get_buffer_attr(m_stream);
- m_periodTime = /*(m_role == QAudio::GameRole) ? LowLatencyPeriodTimeMs :*/ PeriodTimeMs;
- m_periodSize = pa_usec_to_bytes(m_periodTime*1000, &m_spec);
- m_bufferSize = buffer->tlength;
- m_maxBufferSize = buffer->maxlength;
- m_audioBuffer = new char[m_maxBufferSize];
-
- const qint64 streamSize = m_audioSource ? m_audioSource->size() : 0;
- if (m_pullMode && streamSize > 0 && static_cast<qint64>(buffer->prebuf) > streamSize) {
- pa_buffer_attr newBufferAttr;
- newBufferAttr = *buffer;
- newBufferAttr.prebuf = streamSize;
- pa_operation *o = pa_stream_set_buffer_attr(m_stream, &newBufferAttr, streamAdjustPrebufferCallback, nullptr);
- if (o)
- pa_operation_unref(o);
- }
-
-#ifdef DEBUG_PULSE
- qDebug() << "Buffering info:";
- qDebug() << "\tMax length: " << buffer->maxlength;
- qDebug() << "\tTarget length: " << buffer->tlength;
- qDebug() << "\tPre-buffering: " << buffer->prebuf;
- qDebug() << "\tMinimum request: " << buffer->minreq;
- qDebug() << "\tFragment size: " << buffer->fragsize;
-#endif
-
- pulseEngine->unlock();
-
- connect(pulseEngine, &QPulseAudioEngine::contextFailed, this, &QPulseAudioSink::onPulseContextFailed);
-
- m_opened = true;
-
- m_tickTimer->start(m_periodTime);
-
- m_elapsedTimeOffset = 0;
-
- return true;
-}
-
-void QPulseAudioSink::close()
-{
- if (!m_opened)
- return;
-
- m_tickTimer->stop();
-
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
-
- if (m_stream) {
- pulseEngine->lock();
-
- pa_stream_set_state_callback(m_stream, nullptr, nullptr);
- pa_stream_set_write_callback(m_stream, nullptr, nullptr);
- pa_stream_set_underflow_callback(m_stream, nullptr, nullptr);
- pa_stream_set_overflow_callback(m_stream, nullptr, nullptr);
- pa_stream_set_latency_update_callback(m_stream, nullptr, nullptr);
-
- pa_operation *o = pa_stream_drain(m_stream, outputStreamDrainComplete, nullptr);
- if (o)
- pa_operation_unref(o);
-
- pa_stream_disconnect(m_stream);
- pa_stream_unref(m_stream);
- m_stream = nullptr;
-
- pulseEngine->unlock();
- }
-
- disconnect(pulseEngine, &QPulseAudioEngine::contextFailed, this, &QPulseAudioSink::onPulseContextFailed);
-
- if (!m_pullMode && m_audioSource) {
- delete m_audioSource;
- m_audioSource = nullptr;
- }
- m_opened = false;
- if (m_audioBuffer) {
- delete[] m_audioBuffer;
- m_audioBuffer = nullptr;
- }
-}
-
-void QPulseAudioSink::userFeed()
-{
- if (m_deviceState == QAudio::StoppedState || m_deviceState == QAudio::SuspendedState)
- return;
-
- m_resuming = false;
-
- if (m_pullMode) {
- int writableSize = bytesFree();
- int chunks = writableSize / m_periodSize;
- if (chunks == 0)
- return;
-
- int input = m_periodSize; // always request 1 chunk of data from user
- if (input > m_maxBufferSize)
- input = m_maxBufferSize;
-
- int audioBytesPulled = m_audioSource->read(m_audioBuffer, input);
- Q_ASSERT(audioBytesPulled <= input);
- if (m_audioBuffer && audioBytesPulled > 0) {
- if (audioBytesPulled > input) {
- qWarning() << "QPulseAudioSink::userFeed() - Invalid audio data size provided from user:"
- << audioBytesPulled << "should be less than" << input;
- audioBytesPulled = input;
- }
- qint64 bytesWritten = write(m_audioBuffer, audioBytesPulled);
- Q_ASSERT(bytesWritten == audioBytesPulled); //unfinished write should not happen since the data provided is less than writableSize
- Q_UNUSED(bytesWritten);
-
- if (chunks > 1) {
- // PulseAudio needs more data. Ask for it immediately.
- QMetaObject::invokeMethod(this, "userFeed", Qt::QueuedConnection);
- }
- }
- }
-
- if (m_deviceState != QAudio::ActiveState)
- return;
-}
-
-qint64 QPulseAudioSink::write(const char *data, qint64 len)
-{
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
-
- pulseEngine->lock();
-
- len = qMin(len, static_cast<qint64>(pa_stream_writable_size(m_stream)));
-
- if (m_volume < 1.0f) {
- // Don't use PulseAudio volume, as it might affect all other streams of the same category
- // or even affect the system volume if flat volumes are enabled
- void *dest = nullptr;
- size_t nbytes = len;
- if (pa_stream_begin_write(m_stream, &dest, &nbytes) < 0) {
- qWarning("QAudioSink(pulseaudio): pa_stream_begin_write, error = %s",
- pa_strerror(pa_context_errno(pulseEngine->context())));
- setError(QAudio::IOError);
- return 0;
- }
-
- len = int(nbytes);
- QAudioHelperInternal::qMultiplySamples(m_volume, m_format, data, dest, len);
- data = reinterpret_cast<char *>(dest);
- }
-
- if (pa_stream_write(m_stream, data, len, nullptr, 0, PA_SEEK_RELATIVE) < 0) {
- qWarning("QAudioSink(pulseaudio): pa_stream_write, error = %s",
- pa_strerror(pa_context_errno(pulseEngine->context())));
- setError(QAudio::IOError);
- return 0;
- }
-
- pulseEngine->unlock();
- m_totalTimeValue += len;
-
- setError(QAudio::NoError);
- setState(QAudio::ActiveState);
-
- return len;
-}
-
-void QPulseAudioSink::stop()
-{
- if (m_deviceState == QAudio::StoppedState)
- return;
-
- close();
-
- setError(QAudio::NoError);
- setState(QAudio::StoppedState);
-}
-
-qsizetype QPulseAudioSink::bytesFree() const
-{
- if (m_deviceState != QAudio::ActiveState && m_deviceState != QAudio::IdleState)
- return 0;
-
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
- pulseEngine->lock();
- int writableSize = pa_stream_writable_size(m_stream);
- pulseEngine->unlock();
- return writableSize;
-}
-
-void QPulseAudioSink::setBufferSize(qsizetype value)
-{
- m_bufferSize = value;
-}
-
-qsizetype QPulseAudioSink::bufferSize() const
-{
- return m_bufferSize;
-}
-
-qint64 QPulseAudioSink::processedUSecs() const
-{
- qint64 result = qint64(1000000) * m_totalTimeValue / m_format.bytesPerFrame() / m_format.sampleRate();
-
- return result;
-}
-
-void QPulseAudioSink::resume()
-{
- if (m_deviceState == QAudio::SuspendedState) {
- m_resuming = true;
-
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
-
- pulseEngine->lock();
-
- pa_operation *operation = pa_stream_cork(m_stream, 0, outputStreamSuccessCallback, nullptr);
- pulseEngine->wait(operation);
- pa_operation_unref(operation);
-
- operation = pa_stream_trigger(m_stream, outputStreamSuccessCallback, nullptr);
- pulseEngine->wait(operation);
- pa_operation_unref(operation);
-
- pulseEngine->unlock();
-
- m_tickTimer->start(m_periodTime);
-
- setState(m_pullMode ? QAudio::ActiveState : QAudio::IdleState);
- setError(QAudio::NoError);
- }
-}
-
-void QPulseAudioSink::setFormat(const QAudioFormat &format)
-{
- m_format = format;
-}
-
-QAudioFormat QPulseAudioSink::format() const
-{
- return m_format;
-}
-
-void QPulseAudioSink::suspend()
-{
- if (m_deviceState == QAudio::ActiveState || m_deviceState == QAudio::IdleState) {
- setError(QAudio::NoError);
- setState(QAudio::SuspendedState);
-
- m_tickTimer->stop();
-
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
- pa_operation *operation;
-
- pulseEngine->lock();
-
- operation = pa_stream_cork(m_stream, 1, outputStreamSuccessCallback, nullptr);
- pulseEngine->wait(operation);
- pa_operation_unref(operation);
-
- pulseEngine->unlock();
- }
-}
-
-void QPulseAudioSink::reset()
-{
- stop();
-}
-
-PulseOutputPrivate::PulseOutputPrivate(QPulseAudioSink *audio)
-{
- m_audioDevice = qobject_cast<QPulseAudioSink*>(audio);
-}
-
-qint64 PulseOutputPrivate::readData(char *data, qint64 len)
-{
- Q_UNUSED(data);
- Q_UNUSED(len);
-
- return 0;
-}
-
-qint64 PulseOutputPrivate::writeData(const char *data, qint64 len)
-{
- int retry = 0;
- qint64 written = 0;
-
- if ((m_audioDevice->m_deviceState == QAudio::ActiveState
- || m_audioDevice->m_deviceState == QAudio::IdleState)) {
- while(written < len) {
- int chunk = m_audioDevice->write(data+written, (len-written));
- if (chunk <= 0)
- retry++;
- written+=chunk;
- if (retry > 10)
- return written;
- }
- }
-
- return written;
-}
-
-void QPulseAudioSink::setVolume(qreal vol)
-{
- if (qFuzzyCompare(m_volume, vol))
- return;
-
- m_volume = qBound(qreal(0), vol, qreal(1));
-}
-
-qreal QPulseAudioSink::volume() const
-{
- return m_volume;
-}
-
-void QPulseAudioSink::onPulseContextFailed()
-{
- close();
-
- setError(QAudio::FatalError);
- setState(QAudio::StoppedState);
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qpulseaudiosink_p.cpp"
diff --git a/src/multimedia/platform/pulseaudio/qpulseaudiosink_p.h b/src/multimedia/platform/pulseaudio/qpulseaudiosink_p.h
deleted file mode 100644
index 9397c507a..000000000
--- a/src/multimedia/platform/pulseaudio/qpulseaudiosink_p.h
+++ /dev/null
@@ -1,155 +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 QAUDIOOUTPUTPULSE_H
-#define QAUDIOOUTPUTPULSE_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 <QtCore/qfile.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qelapsedtimer.h>
-#include <QtCore/qiodevice.h>
-
-#include "qaudio.h"
-#include "qaudiodevice.h"
-#include <private/qaudiosystem_p.h>
-
-#include <pulse/pulseaudio.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPulseAudioSink : public QPlatformAudioSink
-{
- friend class PulseOutputPrivate;
- Q_OBJECT
-
-public:
- QPulseAudioSink(const QByteArray &device);
- ~QPulseAudioSink();
-
- void start(QIODevice *device) override;
- QIODevice *start() override;
- void stop() override;
- void reset() override;
- void suspend() override;
- void resume() override;
- qsizetype bytesFree() const override;
- void setBufferSize(qsizetype value) override;
- qsizetype bufferSize() const override;
- qint64 processedUSecs() const override;
- QAudio::Error error() const override;
- QAudio::State state() const override;
- void setFormat(const QAudioFormat &format) override;
- QAudioFormat format() const override;
-
- void setVolume(qreal volume) override;
- qreal volume() const override;
-
-public:
- void streamUnderflowCallback();
-
-private:
- void setState(QAudio::State state);
- void setError(QAudio::Error error);
-
- bool open();
- void close();
- qint64 write(const char *data, qint64 len);
-
-private Q_SLOTS:
- void userFeed();
- void onPulseContextFailed();
-
-private:
- QByteArray m_device;
- QByteArray m_streamName;
- QAudioFormat m_format;
- QAudio::Error m_errorState;
- QAudio::State m_deviceState;
- bool m_pullMode;
- bool m_opened;
- QIODevice *m_audioSource;
- QTimer m_periodTimer;
- int m_periodTime;
- pa_stream *m_stream;
- int m_periodSize;
- int m_bufferSize;
- int m_maxBufferSize;
- qint64 m_totalTimeValue;
- QTimer *m_tickTimer;
- char *m_audioBuffer;
- qint64 m_elapsedTimeOffset;
- bool m_resuming;
-
- qreal m_volume;
- pa_sample_spec m_spec;
-};
-
-class PulseOutputPrivate : public QIODevice
-{
- friend class QPulseAudioSink;
- Q_OBJECT
-
-public:
- PulseOutputPrivate(QPulseAudioSink *audio);
- virtual ~PulseOutputPrivate() {}
-
-protected:
- qint64 readData(char *data, qint64 len) override;
- qint64 writeData(const char *data, qint64 len) override;
-
-private:
- QPulseAudioSink *m_audioDevice;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/pulseaudio/qpulseaudiosource.cpp b/src/multimedia/platform/pulseaudio/qpulseaudiosource.cpp
deleted file mode 100644
index a7a0d4702..000000000
--- a/src/multimedia/platform/pulseaudio/qpulseaudiosource.cpp
+++ /dev/null
@@ -1,645 +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/qcoreapplication.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qmath.h>
-#include <private/qaudiohelpers_p.h>
-
-#include "qpulseaudiosource_p.h"
-#include "qaudioengine_pulse_p.h"
-#include "qpulseaudiodevice_p.h"
-#include "qpulsehelpers_p.h"
-#include <sys/types.h>
-#include <unistd.h>
-
-QT_BEGIN_NAMESPACE
-
-const int PeriodTimeMs = 50;
-
-static void inputStreamReadCallback(pa_stream *stream, size_t length, void *userdata)
-{
- Q_UNUSED(userdata);
- Q_UNUSED(length);
- Q_UNUSED(stream);
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
- pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
-}
-
-static void inputStreamStateCallback(pa_stream *stream, void *userdata)
-{
- Q_UNUSED(userdata);
- pa_stream_state_t state = pa_stream_get_state(stream);
-#ifdef DEBUG_PULSE
- qDebug() << "Stream state: " << QPulseAudioInternal::stateToQString(state);
-#endif
- switch (state) {
- case PA_STREAM_CREATING:
- break;
- case PA_STREAM_READY: {
-#ifdef DEBUG_PULSE
- QPulseAudioSource *audioInput = static_cast<QPulseAudioSource*>(userdata);
- const pa_buffer_attr *buffer_attr = pa_stream_get_buffer_attr(stream);
- qDebug() << "*** maxlength: " << buffer_attr->maxlength;
- qDebug() << "*** prebuf: " << buffer_attr->prebuf;
- qDebug() << "*** fragsize: " << buffer_attr->fragsize;
- qDebug() << "*** minreq: " << buffer_attr->minreq;
- qDebug() << "*** tlength: " << buffer_attr->tlength;
-
- pa_sample_spec spec = QPulseAudioInternal::audioFormatToSampleSpec(audioInput->format());
- qDebug() << "*** bytes_to_usec: " << pa_bytes_to_usec(buffer_attr->fragsize, &spec);
-#endif
- }
- break;
- case PA_STREAM_TERMINATED:
- break;
- case PA_STREAM_FAILED:
- default:
- qWarning() << QString::fromLatin1("Stream error: %1").arg(QString::fromUtf8(pa_strerror(pa_context_errno(pa_stream_get_context(stream)))));
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
- pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
- break;
- }
-}
-
-static void inputStreamUnderflowCallback(pa_stream *stream, void *userdata)
-{
- Q_UNUSED(userdata);
- Q_UNUSED(stream);
- qWarning() << "Got a buffer underflow!";
-}
-
-static void inputStreamOverflowCallback(pa_stream *stream, void *userdata)
-{
- Q_UNUSED(stream);
- Q_UNUSED(userdata);
- qWarning() << "Got a buffer overflow!";
-}
-
-static void inputStreamSuccessCallback(pa_stream *stream, int success, void *userdata)
-{
- Q_UNUSED(stream);
- Q_UNUSED(userdata);
- Q_UNUSED(success);
-
- //if (!success)
- //TODO: Is cork success? i->operation_success = success;
-
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
- pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
-}
-
-QPulseAudioSource::QPulseAudioSource(const QByteArray &device)
- : m_totalTimeValue(0)
- , m_audioSource(nullptr)
- , m_errorState(QAudio::NoError)
- , m_deviceState(QAudio::StoppedState)
- , m_volume(qreal(1.0f))
- , m_pullMode(true)
- , m_opened(false)
- , m_bytesAvailable(0)
- , m_bufferSize(0)
- , m_periodSize(0)
- , m_periodTime(PeriodTimeMs)
- , m_stream(nullptr)
- , m_device(device)
-{
- m_timer = new QTimer(this);
- connect(m_timer, SIGNAL(timeout()), SLOT(userFeed()));
-}
-
-QPulseAudioSource::~QPulseAudioSource()
-{
- close();
- disconnect(m_timer, SIGNAL(timeout()));
- QCoreApplication::processEvents();
- delete m_timer;
-}
-
-void QPulseAudioSource::setError(QAudio::Error error)
-{
- if (m_errorState == error)
- return;
-
- m_errorState = error;
- emit errorChanged(error);
-}
-
-QAudio::Error QPulseAudioSource::error() const
-{
- return m_errorState;
-}
-
-void QPulseAudioSource::setState(QAudio::State state)
-{
- if (m_deviceState == state)
- return;
-
- m_deviceState = state;
- emit stateChanged(state);
-}
-
-QAudio::State QPulseAudioSource::state() const
-{
- return m_deviceState;
-}
-
-void QPulseAudioSource::setFormat(const QAudioFormat &format)
-{
- if (m_deviceState == QAudio::StoppedState)
- m_format = format;
-}
-
-QAudioFormat QPulseAudioSource::format() const
-{
- return m_format;
-}
-
-void QPulseAudioSource::start(QIODevice *device)
-{
- setState(QAudio::StoppedState);
- setError(QAudio::NoError);
-
- if (!m_pullMode && m_audioSource) {
- delete m_audioSource;
- m_audioSource = nullptr;
- }
-
- close();
-
- if (!open())
- return;
-
- m_pullMode = true;
- m_audioSource = device;
-
- setState(QAudio::ActiveState);
-}
-
-QIODevice *QPulseAudioSource::start()
-{
- setState(QAudio::StoppedState);
- setError(QAudio::NoError);
-
- if (!m_pullMode && m_audioSource) {
- delete m_audioSource;
- m_audioSource = nullptr;
- }
-
- close();
-
- if (!open())
- return nullptr;
-
- m_pullMode = false;
- m_audioSource = new PulseInputPrivate(this);
- m_audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
-
- setState(QAudio::IdleState);
-
- return m_audioSource;
-}
-
-void QPulseAudioSource::stop()
-{
- if (m_deviceState == QAudio::StoppedState)
- return;
-
- close();
-
- setError(QAudio::NoError);
- setState(QAudio::StoppedState);
-}
-
-bool QPulseAudioSource::open()
-{
- if (m_opened)
- return true;
-
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
-
- if (!pulseEngine->context() || pa_context_get_state(pulseEngine->context()) != PA_CONTEXT_READY) {
- setError(QAudio::FatalError);
- setState(QAudio::StoppedState);
- return false;
- }
-
- pa_sample_spec spec = QPulseAudioInternal::audioFormatToSampleSpec(m_format);
-
- if (!pa_sample_spec_valid(&spec)) {
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- return false;
- }
-
- m_spec = spec;
-
-#ifdef DEBUG_PULSE
-// QTime now(QTime::currentTime());
-// qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
-#endif
-
- if (m_streamName.isNull())
- m_streamName = QString(QLatin1String("QtmPulseStream-%1-%2")).arg(::getpid()).arg(quintptr(this)).toUtf8();
-
-#ifdef DEBUG_PULSE
- qDebug() << "Format: " << QPulseAudioInternal::sampleFormatToQString(spec.format);
- qDebug() << "Rate: " << spec.rate;
- qDebug() << "Channels: " << spec.channels;
- qDebug() << "Frame size: " << pa_frame_size(&spec);
-#endif
-
- pulseEngine->lock();
- pa_channel_map channel_map;
-
- pa_channel_map_init_extend(&channel_map, spec.channels, PA_CHANNEL_MAP_DEFAULT);
-
- if (!pa_channel_map_compatible(&channel_map, &spec))
- qWarning() << "Channel map doesn't match sample specification!";
-
- m_stream = pa_stream_new(pulseEngine->context(), m_streamName.constData(), &spec, &channel_map);
-
- pa_stream_set_state_callback(m_stream, inputStreamStateCallback, this);
- pa_stream_set_read_callback(m_stream, inputStreamReadCallback, this);
-
- pa_stream_set_underflow_callback(m_stream, inputStreamUnderflowCallback, this);
- pa_stream_set_overflow_callback(m_stream, inputStreamOverflowCallback, this);
-
- m_periodSize = pa_usec_to_bytes(PeriodTimeMs*1000, &spec);
-
- int flags = 0;
- pa_buffer_attr buffer_attr;
- buffer_attr.maxlength = (uint32_t) -1;
- buffer_attr.prebuf = (uint32_t) -1;
- buffer_attr.tlength = (uint32_t) -1;
- buffer_attr.minreq = (uint32_t) -1;
- flags |= PA_STREAM_ADJUST_LATENCY;
-
- if (m_bufferSize > 0)
- buffer_attr.fragsize = (uint32_t) m_bufferSize;
- else
- buffer_attr.fragsize = (uint32_t) m_periodSize;
-
- if (pa_stream_connect_record(m_stream, m_device.data(), &buffer_attr, (pa_stream_flags_t)flags) < 0) {
- qWarning() << "pa_stream_connect_record() failed!";
- pa_stream_unref(m_stream);
- m_stream = nullptr;
- pulseEngine->unlock();
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- return false;
- }
-
- while (pa_stream_get_state(m_stream) != PA_STREAM_READY)
- pa_threaded_mainloop_wait(pulseEngine->mainloop());
-
- const pa_buffer_attr *actualBufferAttr = pa_stream_get_buffer_attr(m_stream);
- m_periodSize = actualBufferAttr->fragsize;
- m_periodTime = pa_bytes_to_usec(m_periodSize, &spec) / 1000;
- if (actualBufferAttr->tlength != (uint32_t)-1)
- m_bufferSize = actualBufferAttr->tlength;
-
- pulseEngine->unlock();
-
- connect(pulseEngine, &QPulseAudioEngine::contextFailed, this, &QPulseAudioSource::onPulseContextFailed);
-
- m_opened = true;
- m_timer->start(m_periodTime);
-
- m_elapsedTimeOffset = 0;
- m_totalTimeValue = 0;
-
- return true;
-}
-
-void QPulseAudioSource::close()
-{
- if (!m_opened)
- return;
-
- m_timer->stop();
-
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
-
- if (m_stream) {
- pulseEngine->lock();
-
- pa_stream_set_state_callback(m_stream, nullptr, nullptr);
- pa_stream_set_read_callback(m_stream, nullptr, nullptr);
- pa_stream_set_underflow_callback(m_stream, nullptr, nullptr);
- pa_stream_set_overflow_callback(m_stream, nullptr, nullptr);
-
- pa_stream_disconnect(m_stream);
- pa_stream_unref(m_stream);
- m_stream = nullptr;
-
- pulseEngine->unlock();
- }
-
- disconnect(pulseEngine, &QPulseAudioEngine::contextFailed, this, &QPulseAudioSource::onPulseContextFailed);
-
- if (!m_pullMode && m_audioSource) {
- delete m_audioSource;
- m_audioSource = nullptr;
- }
- m_opened = false;
-}
-
-int QPulseAudioSource::checkBytesReady()
-{
- if (m_deviceState != QAudio::ActiveState && m_deviceState != QAudio::IdleState) {
- m_bytesAvailable = 0;
- } else {
- m_bytesAvailable = pa_stream_readable_size(m_stream);
- }
-
- return m_bytesAvailable;
-}
-
-qsizetype QPulseAudioSource::bytesReady() const
-{
- return qMax(m_bytesAvailable, 0);
-}
-
-qint64 QPulseAudioSource::read(char *data, qint64 len)
-{
- m_bytesAvailable = checkBytesReady();
-
- setError(QAudio::NoError);
- setState(QAudio::ActiveState);
-
- int readBytes = 0;
-
- if (!m_pullMode && !m_tempBuffer.isEmpty()) {
- readBytes = qMin(static_cast<int>(len), m_tempBuffer.size());
- memcpy(data, m_tempBuffer.constData(), readBytes);
- m_totalTimeValue += readBytes;
-
- if (readBytes < m_tempBuffer.size()) {
- m_tempBuffer.remove(0, readBytes);
- return readBytes;
- }
-
- m_tempBuffer.clear();
- }
-
- while (pa_stream_readable_size(m_stream) > 0) {
- size_t readLength = 0;
-
-#ifdef DEBUG_PULSE
- qDebug() << "QPulseAudioSource::read -- " << pa_stream_readable_size(m_stream) << " bytes available from pulse audio";
-#endif
-
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
- pulseEngine->lock();
-
- const void *audioBuffer;
-
- // Second and third parameters (audioBuffer and length) to pa_stream_peek are output parameters,
- // the audioBuffer pointer is set to point to the actual pulse audio data,
- // and the length is set to the length of this data.
- if (pa_stream_peek(m_stream, &audioBuffer, &readLength) < 0) {
- qWarning() << QString::fromLatin1("pa_stream_peek() failed: %1")
- .arg(QString::fromUtf8(pa_strerror(pa_context_errno(pa_stream_get_context(m_stream)))));
- pulseEngine->unlock();
- return 0;
- }
-
- qint64 actualLength = 0;
- if (m_pullMode) {
- QByteArray adjusted(readLength, Qt::Uninitialized);
- applyVolume(audioBuffer, adjusted.data(), readLength);
- actualLength = m_audioSource->write(adjusted);
-
- if (actualLength < qint64(readLength)) {
- pulseEngine->unlock();
-
- setError(QAudio::UnderrunError);
- setState(QAudio::IdleState);
-
- return actualLength;
- }
- } else {
- actualLength = qMin(static_cast<int>(len - readBytes), static_cast<int>(readLength));
- applyVolume(audioBuffer, data + readBytes, actualLength);
- }
-
-#ifdef DEBUG_PULSE
- qDebug() << "QPulseAudioSource::read -- wrote " << actualLength << " to client";
-#endif
-
- if (actualLength < qint64(readLength)) {
-#ifdef DEBUG_PULSE
- qDebug() << "QPulseAudioSource::read -- appending " << readLength - actualLength << " bytes of data to temp buffer";
-#endif
- int diff = readLength - actualLength;
- int oldSize = m_tempBuffer.size();
- m_tempBuffer.resize(m_tempBuffer.size() + diff);
- applyVolume(static_cast<const char *>(audioBuffer) + actualLength, m_tempBuffer.data() + oldSize, diff);
- QMetaObject::invokeMethod(this, "userFeed", Qt::QueuedConnection);
- }
-
- m_totalTimeValue += actualLength;
- readBytes += actualLength;
-
- pa_stream_drop(m_stream);
- pulseEngine->unlock();
-
- if (!m_pullMode && readBytes >= len)
- break;
- }
-
-#ifdef DEBUG_PULSE
- qDebug() << "QPulseAudioSource::read -- returning after reading " << readBytes << " bytes";
-#endif
-
- return readBytes;
-}
-
-void QPulseAudioSource::applyVolume(const void *src, void *dest, int len)
-{
- if (m_volume < 1.f)
- QAudioHelperInternal::qMultiplySamples(m_volume, m_format, src, dest, len);
- else
- memcpy(dest, src, len);
-}
-
-void QPulseAudioSource::resume()
-{
- if (m_deviceState == QAudio::SuspendedState || m_deviceState == QAudio::IdleState) {
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
- pa_operation *operation;
-
- pulseEngine->lock();
-
- operation = pa_stream_cork(m_stream, 0, inputStreamSuccessCallback, nullptr);
- pulseEngine->wait(operation);
- pa_operation_unref(operation);
-
- pulseEngine->unlock();
-
- m_timer->start(m_periodTime);
-
- setState(QAudio::ActiveState);
- setError(QAudio::NoError);
- }
-}
-
-void QPulseAudioSource::setVolume(qreal vol)
-{
- if (qFuzzyCompare(m_volume, vol))
- return;
-
- m_volume = qBound(qreal(0), vol, qreal(1));
-}
-
-qreal QPulseAudioSource::volume() const
-{
- return m_volume;
-}
-
-void QPulseAudioSource::setBufferSize(qsizetype value)
-{
- m_bufferSize = value;
-}
-
-qsizetype QPulseAudioSource::bufferSize() const
-{
- return m_bufferSize;
-}
-
-qint64 QPulseAudioSource::processedUSecs() const
-{
- pa_sample_spec spec = QPulseAudioInternal::audioFormatToSampleSpec(m_format);
- qint64 result = pa_bytes_to_usec(m_totalTimeValue, &spec);
-
- return result;
-}
-
-void QPulseAudioSource::suspend()
-{
- if (m_deviceState == QAudio::ActiveState) {
- setError(QAudio::NoError);
- setState(QAudio::SuspendedState);
-
- m_timer->stop();
-
- QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
- pa_operation *operation;
-
- pulseEngine->lock();
-
- operation = pa_stream_cork(m_stream, 1, inputStreamSuccessCallback, nullptr);
- pulseEngine->wait(operation);
- pa_operation_unref(operation);
-
- pulseEngine->unlock();
- }
-}
-
-void QPulseAudioSource::userFeed()
-{
- if (m_deviceState == QAudio::StoppedState || m_deviceState == QAudio::SuspendedState)
- return;
-#ifdef DEBUG_PULSE
-// QTime now(QTime::currentTime());
-// qDebug()<< now.second() << "s " << now.msec() << "ms :userFeed() IN";
-#endif
- deviceReady();
-}
-
-bool QPulseAudioSource::deviceReady()
-{
- if (m_pullMode) {
- // reads some audio data and writes it to QIODevice
- read(nullptr,0);
- } else {
- // emits readyRead() so user will call read() on QIODevice to get some audio data
- if (m_audioSource != nullptr) {
- PulseInputPrivate *a = qobject_cast<PulseInputPrivate*>(m_audioSource);
- a->trigger();
- }
- }
- m_bytesAvailable = checkBytesReady();
-
- if (m_deviceState != QAudio::ActiveState)
- return true;
-
- return true;
-}
-
-void QPulseAudioSource::reset()
-{
- stop();
- m_bytesAvailable = 0;
-}
-
-void QPulseAudioSource::onPulseContextFailed()
-{
- close();
-
- setError(QAudio::FatalError);
- setState(QAudio::StoppedState);
-}
-
-PulseInputPrivate::PulseInputPrivate(QPulseAudioSource *audio)
-{
- m_audioDevice = qobject_cast<QPulseAudioSource*>(audio);
-}
-
-qint64 PulseInputPrivate::readData(char *data, qint64 len)
-{
- return m_audioDevice->read(data, len);
-}
-
-qint64 PulseInputPrivate::writeData(const char *data, qint64 len)
-{
- Q_UNUSED(data);
- Q_UNUSED(len);
- return 0;
-}
-
-void PulseInputPrivate::trigger()
-{
- emit readyRead();
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qpulseaudiosource_p.cpp"
diff --git a/src/multimedia/platform/pulseaudio/qpulseaudiosource_p.h b/src/multimedia/platform/pulseaudio/qpulseaudiosource_p.h
deleted file mode 100644
index 7a9f047dd..000000000
--- a/src/multimedia/platform/pulseaudio/qpulseaudiosource_p.h
+++ /dev/null
@@ -1,154 +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$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#ifndef QAUDIOINPUTPULSE_H
-#define QAUDIOINPUTPULSE_H
-
-#include <QtCore/qfile.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qelapsedtimer.h>
-#include <QtCore/qiodevice.h>
-
-#include "qaudio.h"
-#include "qaudiodevice.h"
-#include <private/qaudiosystem_p.h>
-
-#include <pulse/pulseaudio.h>
-
-QT_BEGIN_NAMESPACE
-
-class PulseInputPrivate;
-
-class QPulseAudioSource : public QPlatformAudioSource
-{
- Q_OBJECT
-
-public:
- QPulseAudioSource(const QByteArray &device);
- ~QPulseAudioSource();
-
- qint64 read(char *data, qint64 len);
-
- void start(QIODevice *device) override;
- QIODevice *start() override;
- void stop() override;
- void reset() override;
- void suspend() override;
- void resume() override;
- qsizetype bytesReady() const override;
- void setBufferSize(qsizetype value) override;
- qsizetype bufferSize() const override;
- qint64 processedUSecs() const override;
- QAudio::Error error() const override;
- QAudio::State state() const override;
- void setFormat(const QAudioFormat &format) override;
- QAudioFormat format() const override;
-
- void setVolume(qreal volume) override;
- qreal volume() const override;
-
- qint64 m_totalTimeValue;
- QIODevice *m_audioSource;
- QAudioFormat m_format;
- QAudio::Error m_errorState;
- QAudio::State m_deviceState;
- qreal m_volume;
-
-private slots:
- void userFeed();
- bool deviceReady();
- void onPulseContextFailed();
-
-private:
- void setState(QAudio::State state);
- void setError(QAudio::Error error);
-
- void applyVolume(const void *src, void *dest, int len);
-
- int checkBytesReady();
- bool open();
- void close();
-
- bool m_pullMode;
- bool m_opened;
- int m_bytesAvailable;
- int m_bufferSize;
- int m_periodSize;
- unsigned int m_periodTime;
- QTimer *m_timer;
- qint64 m_elapsedTimeOffset;
- pa_stream *m_stream;
- QByteArray m_streamName;
- QByteArray m_device;
- QByteArray m_tempBuffer;
- pa_sample_spec m_spec;
-};
-
-class PulseInputPrivate : public QIODevice
-{
- Q_OBJECT
-public:
- PulseInputPrivate(QPulseAudioSource *audio);
- ~PulseInputPrivate() {};
-
- qint64 readData(char *data, qint64 len) override;
- qint64 writeData(const char *data, qint64 len) override;
-
- void trigger();
-
-private:
- QPulseAudioSource *m_audioDevice;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/pulseaudio/qpulsehelpers.cpp b/src/multimedia/platform/pulseaudio/qpulsehelpers.cpp
deleted file mode 100644
index c3ca6f8c9..000000000
--- a/src/multimedia/platform/pulseaudio/qpulsehelpers.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 "qpulsehelpers_p.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace QPulseAudioInternal
-{
-pa_sample_spec audioFormatToSampleSpec(const QAudioFormat &format)
-{
- pa_sample_spec spec;
-
- spec.rate = format.sampleRate();
- spec.channels = format.channelCount();
- spec.format = PA_SAMPLE_INVALID;
- const bool isBigEndian = QSysInfo::ByteOrder == QSysInfo::BigEndian;
-
- if (format.sampleFormat() == QAudioFormat::UInt8) {
- spec.format = PA_SAMPLE_U8;
- } else if (format.sampleFormat() == QAudioFormat::Int16) {
- spec.format = isBigEndian ? PA_SAMPLE_S16BE : PA_SAMPLE_S16LE;
- } else if (format.sampleFormat() == QAudioFormat::Int32) {
- spec.format = isBigEndian ? PA_SAMPLE_S32BE : PA_SAMPLE_S32LE;
- } else if (format.sampleFormat() == QAudioFormat::Float) {
- spec.format = isBigEndian ? PA_SAMPLE_FLOAT32BE : PA_SAMPLE_FLOAT32LE;
- }
-
- return spec;
-}
-
-#ifdef DEBUG_PULSE
-QString stateToQString(pa_stream_state_t state)
-{
- switch (state)
- {
- case PA_STREAM_UNCONNECTED: return "Unconnected";
- case PA_STREAM_CREATING: return "Creating";
- case PA_STREAM_READY: return "Ready";
- case PA_STREAM_FAILED: return "Failed";
- case PA_STREAM_TERMINATED: return "Terminated";
- }
-
- return QString("Unknown state: %0").arg(state);
-}
-
-QString sampleFormatToQString(pa_sample_format format)
-{
- switch (format)
- {
- case PA_SAMPLE_U8: return "Unsigned 8 Bit PCM.";
- case PA_SAMPLE_ALAW: return "8 Bit a-Law ";
- case PA_SAMPLE_ULAW: return "8 Bit mu-Law";
- case PA_SAMPLE_S16LE: return "Signed 16 Bit PCM, little endian (PC).";
- case PA_SAMPLE_S16BE: return "Signed 16 Bit PCM, big endian.";
- case PA_SAMPLE_FLOAT32LE: return "32 Bit IEEE floating point, little endian (PC), range -1.0 to 1.0";
- case PA_SAMPLE_FLOAT32BE: return "32 Bit IEEE floating point, big endian, range -1.0 to 1.0";
- case PA_SAMPLE_S32LE: return "Signed 32 Bit PCM, little endian (PC).";
- case PA_SAMPLE_S32BE: return "Signed 32 Bit PCM, big endian.";
- case PA_SAMPLE_S24LE: return "Signed 24 Bit PCM packed, little endian (PC).";
- case PA_SAMPLE_S24BE: return "Signed 24 Bit PCM packed, big endian.";
- case PA_SAMPLE_S24_32LE: return "Signed 24 Bit PCM in LSB of 32 Bit words, little endian (PC).";
- case PA_SAMPLE_S24_32BE: return "Signed 24 Bit PCM in LSB of 32 Bit words, big endian.";
- case PA_SAMPLE_MAX: return "Upper limit of valid sample types.";
- case PA_SAMPLE_INVALID: return "Invalid sample format";
- }
-
- return QString("Invalid value: %0").arg(format);
-}
-
-QString stateToQString(pa_context_state_t state)
-{
- switch (state)
- {
- case PA_CONTEXT_UNCONNECTED: return "Unconnected";
- case PA_CONTEXT_CONNECTING: return "Connecting";
- case PA_CONTEXT_AUTHORIZING: return "Authorizing";
- case PA_CONTEXT_SETTING_NAME: return "Setting Name";
- case PA_CONTEXT_READY: return "Ready";
- case PA_CONTEXT_FAILED: return "Failed";
- case PA_CONTEXT_TERMINATED: return "Terminated";
- }
-
- return QString("Unknown state: %0").arg(state);
-}
-#endif
-
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/pulseaudio/qpulsehelpers_p.h b/src/multimedia/platform/pulseaudio/qpulsehelpers_p.h
deleted file mode 100644
index 5663e73ed..000000000
--- a/src/multimedia/platform/pulseaudio/qpulsehelpers_p.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 QPULSEHELPER_H
-#define QPULSEHELPER_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 "qaudiodevice.h"
-#include <qaudioformat.h>
-#include <pulse/pulseaudio.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QPulseAudioInternal
-{
-pa_sample_spec audioFormatToSampleSpec(const QAudioFormat &format);
-QString stateToQString(pa_stream_state_t state);
-QString stateToQString(pa_context_state_t state);
-QString sampleFormatToQString(pa_sample_format format);
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qgstreamer_platformspecificinterface.cpp b/src/multimedia/platform/qgstreamer_platformspecificinterface.cpp
new file mode 100644
index 000000000..b0fee3327
--- /dev/null
+++ b/src/multimedia/platform/qgstreamer_platformspecificinterface.cpp
@@ -0,0 +1,21 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+//
+// 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 <QtMultimedia/private/qgstreamer_platformspecificinterface_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QGStreamerPlatformSpecificInterface::~QGStreamerPlatformSpecificInterface() = default;
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qgstreamer_platformspecificinterface_p.h b/src/multimedia/platform/qgstreamer_platformspecificinterface_p.h
new file mode 100644
index 000000000..87dd4f5aa
--- /dev/null
+++ b/src/multimedia/platform/qgstreamer_platformspecificinterface_p.h
@@ -0,0 +1,34 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#ifndef GSTREAMER_PLATFORMSPECIFICINTERFACE_P_H
+#define GSTREAMER_PLATFORMSPECIFICINTERFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtMultimedia/private/qplatformmediaintegration_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_MULTIMEDIA_EXPORT QGStreamerPlatformSpecificInterface
+ : public QAbstractPlatformSpecificInterface
+{
+public:
+ ~QGStreamerPlatformSpecificInterface() override;
+
+public:
+ virtual QAudioDevice makeCustomGStreamerAudioInput(const QByteArray &gstreamerPipeline) = 0;
+ virtual QAudioDevice makeCustomGStreamerAudioOutput(const QByteArray &gstreamerPipeline) = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // GSTREAMER_PLATFORMSPECIFICINTERFACE_P_H
diff --git a/src/multimedia/platform/qnx/audio/qnxaudioutils.cpp b/src/multimedia/platform/qnx/audio/qnxaudioutils.cpp
deleted file mode 100644
index 7aa31e408..000000000
--- a/src/multimedia/platform/qnx/audio/qnxaudioutils.cpp
+++ /dev/null
@@ -1,128 +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 "qnxaudioutils_p.h"
-
-QT_BEGIN_NAMESPACE
-
-snd_pcm_channel_params_t QnxAudioUtils::formatToChannelParams(const QAudioFormat &format, QAudioDevice::Mode mode, int fragmentSize)
-{
- snd_pcm_channel_params_t params;
- memset(&params, 0, sizeof(params));
- params.channel = (mode == QAudioDevice::Output) ? SND_PCM_CHANNEL_PLAYBACK : SND_PCM_CHANNEL_CAPTURE;
- params.mode = SND_PCM_MODE_BLOCK;
- params.start_mode = SND_PCM_START_DATA;
- params.stop_mode = SND_PCM_STOP_ROLLOVER;
- params.buf.block.frag_size = fragmentSize;
- params.buf.block.frags_min = 1;
- params.buf.block.frags_max = 1;
- strcpy(params.sw_mixer_subchn_name, "QAudio Channel");
-
- params.format.interleave = 1;
- params.format.rate = format.sampleRate();
- params.format.voices = format.channelCount();
-
- switch (format.sampleSize()) {
- case 8:
- switch (format.sampleType()) {
- case QAudioFormat::SignedInt:
- params.format.format = SND_PCM_SFMT_S8;
- break;
- case QAudioFormat::UnSignedInt:
- params.format.format = SND_PCM_SFMT_U8;
- break;
- default:
- break;
- }
- break;
-
- case 16:
- switch (format.sampleType()) {
- case QAudioFormat::SignedInt:
- if (format.byteOrder() == QAudioFormat::LittleEndian) {
- params.format.format = SND_PCM_SFMT_S16_LE;
- } else {
- params.format.format = SND_PCM_SFMT_S16_BE;
- }
- break;
- case QAudioFormat::UnSignedInt:
- if (format.byteOrder() == QAudioFormat::LittleEndian) {
- params.format.format = SND_PCM_SFMT_U16_LE;
- } else {
- params.format.format = SND_PCM_SFMT_U16_BE;
- }
- break;
- default:
- break;
- }
- break;
-
- case 32:
- switch (format.sampleType()) {
- case QAudioFormat::SignedInt:
- if (format.byteOrder() == QAudioFormat::LittleEndian) {
- params.format.format = SND_PCM_SFMT_S32_LE;
- } else {
- params.format.format = SND_PCM_SFMT_S32_BE;
- }
- break;
- case QAudioFormat::UnSignedInt:
- if (format.byteOrder() == QAudioFormat::LittleEndian) {
- params.format.format = SND_PCM_SFMT_U32_LE;
- } else {
- params.format.format = SND_PCM_SFMT_U32_BE;
- }
- break;
- case QAudioFormat::Float:
- if (format.byteOrder() == QAudioFormat::LittleEndian) {
- params.format.format = SND_PCM_SFMT_FLOAT_LE;
- } else {
- params.format.format = SND_PCM_SFMT_FLOAT_BE;
- }
- break;
- default:
- break;
- }
- break;
- }
-
- return params;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qnx/audio/qnxaudioutils_p.h b/src/multimedia/platform/qnx/audio/qnxaudioutils_p.h
deleted file mode 100644
index d8e454de2..000000000
--- a/src/multimedia/platform/qnx/audio/qnxaudioutils_p.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 QNXAUDIOUTILS_H
-#define QNXAUDIOUTILS_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 "qaudiosystem_p.h"
-#include <sys/asoundlib.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QnxAudioUtils
-{
- snd_pcm_channel_params_t formatToChannelParams(const QAudioFormat &format, QAudioDevice::Mode mode, int fragmentSize);
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/audio/qqnxaudiodevice.cpp b/src/multimedia/platform/qnx/audio/qqnxaudiodevice.cpp
deleted file mode 100644
index ff7d23192..000000000
--- a/src/multimedia/platform/qnx/audio/qqnxaudiodevice.cpp
+++ /dev/null
@@ -1,122 +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 "qqnxaudiodevice_p.h"
-
-#include "qnxaudioutils_p.h"
-
-#include <sys/asoundlib.h>
-
-QT_BEGIN_NAMESPACE
-
-QnxAudioDeviceInfo::QnxAudioDeviceInfo(const QByteArray &deviceName, QAudioDevice::Mode mode)
- : QAudioDevicePrivate(deviceName, mode)
-{
-}
-
-QnxAudioDeviceInfo::~QnxAudioDeviceInfo()
-{
-}
-
-QAudioFormat QnxAudioDeviceInfo::preferredFormat() const
-{
- QAudioFormat format;
- format.setSampleRate(44100);
- format.setByteOrder(QAudioFormat::LittleEndian);
- format.setSampleType(QAudioFormat::SignedInt);
- format.setSampleSize(16);
- format.setChannelCount(2);
- if(mode == QAudioDevice::Input && !isFormatSupported(format))
- format.setChannelCount(1);
- return format;
-}
-
-bool QnxAudioDeviceInfo::isFormatSupported(const QAudioFormat &format) const
-{
- const int pcmMode = (mode == QAudioDevice::Output) ? SND_PCM_OPEN_PLAYBACK : SND_PCM_OPEN_CAPTURE;
- snd_pcm_t *handle;
-
- int card = 0;
- int device = 0;
- if (snd_pcm_open_preferred(&handle, &card, &device, pcmMode) < 0)
- return false;
-
- snd_pcm_channel_info_t info;
- memset (&info, 0, sizeof(info));
- info.channel = (mode == QAudioDevice::Output) ? SND_PCM_CHANNEL_PLAYBACK : SND_PCM_CHANNEL_CAPTURE;
-
- if (snd_pcm_plugin_info(handle, &info) < 0) {
- qWarning("QAudioDevice: couldn't get channel info");
- snd_pcm_close(handle);
- return false;
- }
-
- snd_pcm_channel_params_t params = QnxAudioUtils::formatToChannelParams(format, mode, info.max_fragment_size);
- const int errorCode = snd_pcm_plugin_params(handle, &params);
- snd_pcm_close(handle);
-
- return errorCode == 0;
-}
-
-QList<int> QnxAudioDeviceInfo::supportedSampleRates() const
-{
- return QList<int>() << 8000 << 11025 << 22050 << 44100 << 48000;
-}
-
-QList<int> QnxAudioDeviceInfo::supportedChannelCounts() const
-{
- return QList<int>() << 1 << 2;
-}
-
-QList<int> QnxAudioDeviceInfo::supportedSampleSizes() const
-{
- return QList<int>() << 8 << 16 << 32;
-}
-
-QList<QAudioFormat::Endian> QnxAudioDeviceInfo::supportedByteOrders() const
-{
- return QList<QAudioFormat::Endian>() << QAudioFormat::LittleEndian << QAudioFormat::BigEndian;
-}
-
-QList<QAudioFormat::SampleType> QnxAudioDeviceInfo::supportedSampleTypes() const
-{
- return QList<QAudioFormat::SampleType>() << QAudioFormat::SignedInt << QAudioFormat::UnSignedInt << QAudioFormat::Float;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qnx/audio/qqnxaudiodevice_p.h b/src/multimedia/platform/qnx/audio/qqnxaudiodevice_p.h
deleted file mode 100644
index 96e65759a..000000000
--- a/src/multimedia/platform/qnx/audio/qqnxaudiodevice_p.h
+++ /dev/null
@@ -1,77 +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 QNXAUDIODEVICEINFO_H
-#define QNXAUDIODEVICEINFO_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 "qaudiosystem_p.h"
-#include <private/qaudiodevice_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QnxAudioDeviceInfo : public QAudioDevicePrivate
-{
-public:
- QnxAudioDeviceInfo(const QByteArray &deviceName, QAudioDevice::Mode mode);
- ~QnxAudioDeviceInfo();
-
- QAudioFormat preferredFormat() const override;
- bool isFormatSupported(const QAudioFormat &format) const override;
- QString description() const override { return QString::fromUtf8(id()); }
- QList<int> supportedSampleRates() const override;
- QList<int> supportedChannelCounts() const override;
- QList<int> supportedSampleSizes() const override;
- QList<QAudioFormat::Endian> supportedByteOrders() const override;
- QList<QAudioFormat::SampleType> supportedSampleTypes() const override;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/audio/qqnxaudiosink.cpp b/src/multimedia/platform/qnx/audio/qqnxaudiosink.cpp
deleted file mode 100644
index d2c1f98c7..000000000
--- a/src/multimedia/platform/qnx/audio/qqnxaudiosink.cpp
+++ /dev/null
@@ -1,533 +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 "qqnxaudiosink_p.h"
-
-#include "qnxaudioutils_p.h"
-
-#include <private/qaudiohelpers_p.h>
-
-#pragma GCC diagnostic ignored "-Wvla"
-
-QT_BEGIN_NAMESPACE
-
-QQnxAudioSink::QQnxAudioSink()
- : m_source(0)
- , m_pushSource(false)
- , m_error(QAudio::NoError)
- , m_state(QAudio::StoppedState)
- , m_volume(1.0)
- , m_periodSize(0)
- , m_pcmHandle(0)
- , m_bytesWritten(0)
-#if _NTO_VERSION >= 700
- , m_pcmNotifier(0)
-#endif
-{
- m_timer.setSingleShot(false);
- m_timer.setInterval(20);
- connect(&m_timer, SIGNAL(timeout()), this, SLOT(pullData()));
-}
-
-QQnxAudioSink::~QQnxAudioSink()
-{
- stop();
-}
-
-void QQnxAudioSink::start(QIODevice *source)
-{
- if (m_state != QAudio::StoppedState)
- stop();
-
- m_error = QAudio::NoError;
- m_source = source;
- m_pushSource = false;
-
- if (open()) {
- setState(QAudio::ActiveState);
- m_timer.start();
- } else {
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- }
-}
-
-QIODevice *QQnxAudioSink::start()
-{
- if (m_state != QAudio::StoppedState)
- stop();
-
- m_error = QAudio::NoError;
- m_source = new QnxPushIODevice(this);
- m_source->open(QIODevice::WriteOnly|QIODevice::Unbuffered);
- m_pushSource = true;
-
- if (open())
- setState(QAudio::IdleState);
- else {
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- }
-
- return m_source;
-}
-
-void QQnxAudioSink::stop()
-{
- if (m_state == QAudio::StoppedState)
- return;
-
- setError(QAudio::NoError);
- setState(QAudio::StoppedState);
- close();
-}
-
-void QQnxAudioSink::reset()
-{
- if (m_pcmHandle)
-#if SND_PCM_VERSION < SND_PROTOCOL_VERSION('P',3,0,2)
- snd_pcm_playback_drain(m_pcmHandle);
-#else
- snd_pcm_channel_drain(m_pcmHandle, SND_PCM_CHANNEL_PLAYBACK);
-#endif
- stop();
-}
-
-void QQnxAudioSink::suspend()
-{
- snd_pcm_playback_pause(m_pcmHandle);
- suspendInternal(QAudio::SuspendedState);
-}
-
-void QQnxAudioSink::resume()
-{
- snd_pcm_playback_resume(m_pcmHandle);
- resumeInternal();
-}
-
-qsizetype QQnxAudioSink::bytesFree() const
-{
- if (m_state != QAudio::ActiveState && m_state != QAudio::IdleState)
- return 0;
-
- snd_pcm_channel_status_t status;
- memset(&status, 0, sizeof(status));
- status.channel = SND_PCM_CHANNEL_PLAYBACK;
- const int errorCode = snd_pcm_plugin_status(m_pcmHandle, &status);
-
- if (errorCode)
- return 0;
- else
- return status.free;
-}
-
-qint64 QQnxAudioSink::processedUSecs() const
-{
- return qint64(1000000) * m_format.framesForBytes(m_bytesWritten) / m_format.sampleRate();
-}
-
-QAudio::Error QQnxAudioSink::error() const
-{
- return m_error;
-}
-
-QAudio::State QQnxAudioSink::state() const
-{
- return m_state;
-}
-
-void QQnxAudioSink::setFormat(const QAudioFormat &format)
-{
- if (m_state == QAudio::StoppedState)
- m_format = format;
-}
-
-QAudioFormat QQnxAudioSink::format() const
-{
- return m_format;
-}
-
-void QQnxAudioSink::setVolume(qreal volume)
-{
- m_volume = qBound(qreal(0.0), volume, qreal(1.0));
-}
-
-qreal QQnxAudioSink::volume() const
-{
- return m_volume;
-}
-
-void QQnxAudioSink::pullData()
-{
- if (m_state == QAudio::StoppedState
- || m_state == QAudio::SuspendedState)
- return;
-
- const int bytesAvailable = bytesFree();
- const int frames = m_format.framesForBytes(bytesAvailable);
-
- if (frames == 0 || bytesAvailable < periodSize())
- return;
-
- // The buffer is placed on the stack so no more than 64K or 1 frame
- // whichever is larger.
- const int maxFrames = qMax(m_format.framesForBytes(64 * 1024), 1);
- const int bytesRequested = m_format.bytesForFrames(qMin(frames, maxFrames));
-
- char buffer[bytesRequested];
- const int bytesRead = m_source->read(buffer, bytesRequested);
-
- // reading can take a while and stream may have been stopped
- if (!m_pcmHandle)
- return;
-
- if (bytesRead > 0) {
- // Got some data to output
- if (m_state != QAudio::ActiveState)
- return;
-
- const qint64 bytesWritten = write(buffer, bytesRead);
- if (bytesWritten != bytesRead)
- m_source->seek(m_source->pos()-(bytesRead-bytesWritten));
-
- } else {
- // We're done
- close();
- if (bytesRead != 0)
- setError(QAudio::IOError);
- setState(QAudio::StoppedState);
- }
-
- if (m_state != QAudio::ActiveState)
- return;
-}
-
-bool QQnxAudioSink::open()
-{
- if (!m_format.isValid() || m_format.sampleRate() <= 0) {
- if (!m_format.isValid())
- qWarning("QQnxAudioSink: open error, invalid format.");
- else
- qWarning("QQnxAudioSink: open error, invalid sample rate (%d).", m_format.sampleRate());
-
- return false;
- }
-
- int errorCode = 0;
-
- int card = 0;
- int device = 0;
- if ((errorCode = snd_pcm_open_preferred(&m_pcmHandle, &card, &device, SND_PCM_OPEN_PLAYBACK)) < 0) {
- qWarning("QQnxAudioSink: open error, couldn't open card (0x%x)", -errorCode);
- return false;
- }
-
- if ((errorCode = snd_pcm_nonblock_mode(m_pcmHandle, 0)) < 0) {
- qWarning("QQnxAudioSink: open error, couldn't set non block mode (0x%x)", -errorCode);
- close();
- return false;
- }
-
- addPcmEventFilter();
-
- // Necessary so that bytesFree() which uses the "free" member of the status struct works
- snd_pcm_plugin_set_disable(m_pcmHandle, PLUGIN_MMAP);
-
- snd_pcm_channel_info_t info;
- memset(&info, 0, sizeof(info));
- info.channel = SND_PCM_CHANNEL_PLAYBACK;
- if ((errorCode = snd_pcm_plugin_info(m_pcmHandle, &info)) < 0) {
- qWarning("QQnxAudioSink: open error, couldn't get channel info (0x%x)", -errorCode);
- close();
- return false;
- }
-
- snd_pcm_channel_params_t params = QnxAudioUtils::formatToChannelParams(m_format, QAudioDevice::Output, info.max_fragment_size);
- setTypeName(&params);
-
- if ((errorCode = snd_pcm_plugin_params(m_pcmHandle, &params)) < 0) {
- qWarning("QQnxAudioSink: open error, couldn't set channel params (0x%x)", -errorCode);
- close();
- return false;
- }
-
- if ((errorCode = snd_pcm_plugin_prepare(m_pcmHandle, SND_PCM_CHANNEL_PLAYBACK)) < 0) {
- qWarning("QQnxAudioSink: open error, couldn't prepare channel (0x%x)", -errorCode);
- close();
- return false;
- }
-
- snd_pcm_channel_setup_t setup;
- memset(&setup, 0, sizeof(setup));
- setup.channel = SND_PCM_CHANNEL_PLAYBACK;
- if ((errorCode = snd_pcm_plugin_setup(m_pcmHandle, &setup)) < 0) {
- qWarning("QQnxAudioSink: open error, couldn't get channel setup (0x%x)", -errorCode);
- close();
- return false;
- }
-
- m_periodSize = qMin(2048, setup.buf.block.frag_size);
- m_bytesWritten = 0;
-
- createPcmNotifiers();
-
- return true;
-}
-
-void QQnxAudioSink::close()
-{
- m_timer.stop();
-
- destroyPcmNotifiers();
-
- if (m_pcmHandle) {
-#if SND_PCM_VERSION < SND_PROTOCOL_VERSION('P',3,0,2)
- snd_pcm_plugin_flush(m_pcmHandle, SND_PCM_CHANNEL_PLAYBACK);
-#else
- snd_pcm_plugin_drop(m_pcmHandle, SND_PCM_CHANNEL_PLAYBACK);
-#endif
- snd_pcm_close(m_pcmHandle);
- m_pcmHandle = 0;
- }
-
- if (m_pushSource) {
- delete m_source;
- m_source = 0;
- }
-}
-
-void QQnxAudioSink::setError(QAudio::Error error)
-{
- if (m_error != error) {
- m_error = error;
- emit errorChanged(error);
- }
-}
-
-void QQnxAudioSink::setState(QAudio::State state)
-{
- if (m_state != state) {
- m_state = state;
- emit stateChanged(state);
- }
-}
-
-qint64 QQnxAudioSink::write(const char *data, qint64 len)
-{
- if (!m_pcmHandle)
- return 0;
-
- // Make sure we're writing (N * frame) worth of bytes
- const int size = m_format.bytesForFrames(qBound(qint64(0), qint64(bytesFree()), len) / m_format.bytesPerFrame());
-
- if (size == 0)
- return 0;
-
- int written = 0;
-
- if (m_volume < 1.0f) {
- char out[size];
- QAudioHelperInternal::qMultiplySamples(m_volume, m_format, data, out, size);
- written = snd_pcm_plugin_write(m_pcmHandle, out, size);
- } else {
- written = snd_pcm_plugin_write(m_pcmHandle, data, size);
- }
-
- if (written > 0) {
- m_bytesWritten += written;
- setError(QAudio::NoError);
- setState(QAudio::ActiveState);
- return written;
- } else {
- close();
- setError(QAudio::FatalError);
- setState(QAudio::StoppedState);
- return 0;
- }
-}
-
-void QQnxAudioSink::suspendInternal(QAudio::State suspendState)
-{
- m_timer.stop();
- setState(suspendState);
-}
-
-void QQnxAudioSink::resumeInternal()
-{
- if (m_pushSource) {
- setState(QAudio::IdleState);
- } else {
- setState(QAudio::ActiveState);
- m_timer.start();
- }
-}
-
-#if _NTO_VERSION >= 700
-
-QAudio::State suspendState(const snd_pcm_event_t &event)
-{
- Q_ASSERT(event.type == SND_PCM_EVENT_AUDIOMGMT_STATUS);
- Q_ASSERT(event.data.audiomgmt_status.new_status == SND_PCM_STATUS_SUSPENDED);
- return QAudio::SuspendedState;
-}
-
-void QQnxAudioSink::addPcmEventFilter()
-{
- /* Enable PCM events */
- snd_pcm_filter_t filter;
- memset(&filter, 0, sizeof(filter));
- filter.enable = (1<<SND_PCM_EVENT_AUDIOMGMT_STATUS) |
- (1<<SND_PCM_EVENT_AUDIOMGMT_MUTE) |
- (1<<SND_PCM_EVENT_OUTPUTCLASS);
- snd_pcm_set_filter(m_pcmHandle, SND_PCM_CHANNEL_PLAYBACK, &filter);
-}
-
-void QQnxAudioSink::createPcmNotifiers()
-{
- // QSocketNotifier::Read for poll based event dispatcher. Exception for
- // select based event dispatcher.
- m_pcmNotifier = new QSocketNotifier(snd_pcm_file_descriptor(m_pcmHandle,
- SND_PCM_CHANNEL_PLAYBACK),
- QSocketNotifier::Read, this);
- connect(m_pcmNotifier, &QSocketNotifier::activated,
- this, &QQnxAudioSink::pcmNotifierActivated);
-}
-
-void QQnxAudioSink::destroyPcmNotifiers()
-{
- if (m_pcmNotifier) {
- delete m_pcmNotifier;
- m_pcmNotifier = 0;
- }
-}
-
-void QQnxAudioSink::setTypeName(snd_pcm_channel_params_t *params)
-{
-#if 0
-// Use some mapping from QAudio::Role
- if (m_category.isEmpty())
- return;
-
- QByteArray latin1Category = m_category.toLatin1();
-
- if (QString::fromLatin1(latin1Category) != m_category) {
- qWarning("QQnxAudioSink: audio category name isn't a Latin1 string.");
- return;
- }
-
- if (latin1Category.size() >= static_cast<int>(sizeof(params->audio_type_name))) {
- qWarning("QQnxAudioSink: audio category name too long.");
- return;
- }
-
- strcpy(params->audio_type_name, latin1Category.constData());
-#endif
-}
-
-void QQnxAudioSink::pcmNotifierActivated(int socket)
-{
- Q_UNUSED(socket);
-
- snd_pcm_event_t pcm_event;
- memset(&pcm_event, 0, sizeof(pcm_event));
- while (snd_pcm_channel_read_event(m_pcmHandle, SND_PCM_CHANNEL_PLAYBACK, &pcm_event) == 0) {
- if (pcm_event.type == SND_PCM_EVENT_AUDIOMGMT_STATUS) {
- if (pcm_event.data.audiomgmt_status.new_status == SND_PCM_STATUS_SUSPENDED)
- suspendInternal(suspendState(pcm_event));
- else if (pcm_event.data.audiomgmt_status.new_status == SND_PCM_STATUS_RUNNING)
- resumeInternal();
- else if (pcm_event.data.audiomgmt_status.new_status == SND_PCM_STATUS_PAUSED)
- suspendInternal(QAudio::SuspendedState);
- }
- }
-}
-
-#else
-
-void QQnxAudioSink::addPcmEventFilter() {}
-void QQnxAudioSink::createPcmNotifiers() {}
-void QQnxAudioSink::destroyPcmNotifiers() {}
-void QQnxAudioSink::setTypeName(snd_pcm_channel_params_t *) {}
-
-#endif
-
-QnxPushIODevice::QnxPushIODevice(QQnxAudioSink *output)
- : QIODevice(output),
- m_output(output)
-{
-}
-
-QnxPushIODevice::~QnxPushIODevice()
-{
-}
-
-qint64 QnxPushIODevice::readData(char *data, qint64 len)
-{
- Q_UNUSED(data);
- Q_UNUSED(len);
- return 0;
-}
-
-qint64 QnxPushIODevice::writeData(const char *data, qint64 len)
-{
- int retry = 0;
- qint64 written = 0;
-
- if (m_output->state() == QAudio::ActiveState
- || m_output->state() == QAudio::IdleState) {
- while (written < len) {
- const int writeSize = m_output->write(data + written, len - written);
-
- if (writeSize <= 0) {
- retry++;
- if (retry > 10)
- return written;
- else
- continue;
- }
-
- retry = 0;
- written += writeSize;
- }
- }
-
- return written;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qnx/audio/qqnxaudiosink_p.h b/src/multimedia/platform/qnx/audio/qqnxaudiosink_p.h
deleted file mode 100644
index 2ce38315a..000000000
--- a/src/multimedia/platform/qnx/audio/qqnxaudiosink_p.h
+++ /dev/null
@@ -1,150 +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 QNXAUDIOOUTPUT_H
-#define QNXAUDIOOUTPUT_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 "qaudiosystem_p.h"
-
-#include <QElapsedTimer>
-#include <QTimer>
-#include <QIODevice>
-#include <QSocketNotifier>
-
-#include <sys/asoundlib.h>
-#include <sys/neutrino.h>
-
-QT_BEGIN_NAMESPACE
-
-class QnxPushIODevice;
-
-class QQnxAudioSink : public QPlatformAudioSink
-{
- Q_OBJECT
-
-public:
- QQnxAudioSink();
- ~QQnxAudioSink();
-
- void start(QIODevice *source) override;
- QIODevice *start() override;
- void stop() override;
- void reset() override;
- void suspend() override;
- void resume() override;
- qsizetype bytesFree() const override;
- void setBufferSize(qsizetype) override {}
- qsizetype bufferSize() const override { return 0; }
- qint64 processedUSecs() const override;
- QAudio::Error error() const override;
- QAudio::State state() const override;
- void setFormat(const QAudioFormat &format) override;
- QAudioFormat format() const override;
- void setVolume(qreal volume) override;
- qreal volume() const override;
-
-private slots:
- void pullData();
-
-private:
- bool open();
- void close();
- void setError(QAudio::Error error);
- void setState(QAudio::State state);
-
- void addPcmEventFilter();
- void createPcmNotifiers();
- void destroyPcmNotifiers();
- void setTypeName(snd_pcm_channel_params_t *params);
-
- void suspendInternal(QAudio::State suspendState);
- void resumeInternal();
-
- friend class QnxPushIODevice;
- qint64 write(const char *data, qint64 len);
-
- QIODevice *m_source;
- bool m_pushSource;
- QTimer m_timer;
-
- QAudio::Error m_error;
- QAudio::State m_state;
- QAudioFormat m_format;
- qreal m_volume;
- int m_periodSize;
-
- snd_pcm_t *m_pcmHandle;
- qint64 m_bytesWritten;
-
-#if _NTO_VERSION >= 700
- QSocketNotifier *m_pcmNotifier;
-
-private slots:
- void pcmNotifierActivated(int socket);
-#endif
-};
-
-class QnxPushIODevice : public QIODevice
-{
- Q_OBJECT
-public:
- explicit QnxPushIODevice(QQnxAudioSink *output);
- ~QnxPushIODevice();
-
- qint64 readData(char *data, qint64 len);
- qint64 writeData(const char *data, qint64 len);
-
-private:
- QQnxAudioSink *m_output;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/audio/qqnxaudiosource.cpp b/src/multimedia/platform/qnx/audio/qqnxaudiosource.cpp
deleted file mode 100644
index b90681a83..000000000
--- a/src/multimedia/platform/qnx/audio/qqnxaudiosource.cpp
+++ /dev/null
@@ -1,421 +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 "qqnxaudiosource_p.h"
-
-#include "qnxaudioutils_p.h"
-
-#include <private/qaudiohelpers_p.h>
-
-#include <QDebug>
-
-QT_BEGIN_NAMESPACE
-
-QQnxAudioSource::QQnxAudioSource()
- : m_audioSource(0)
- , m_pcmHandle(0)
- , m_pcmNotifier(0)
- , m_error(QAudio::NoError)
- , m_state(QAudio::StoppedState)
- , m_bytesRead(0)
- , m_elapsedTimeOffset(0)
- , m_totalTimeValue(0)
- , m_volume(qreal(1.0f))
- , m_bytesAvailable(0)
- , m_bufferSize(0)
- , m_periodSize(0)
- , m_pullMode(true)
-{
-}
-
-QQnxAudioSource::~QQnxAudioSource()
-{
- close();
-}
-
-void QQnxAudioSource::start(QIODevice *device)
-{
- if (m_state != QAudio::StoppedState)
- close();
-
- if (!m_pullMode && m_audioSource)
- delete m_audioSource;
-
- m_pullMode = true;
- m_audioSource = device;
-
- if (open()) {
- setError(QAudio::NoError);
- setState(QAudio::ActiveState);
- } else {
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- }
-}
-
-QIODevice *QQnxAudioSource::start()
-{
- if (m_state != QAudio::StoppedState)
- close();
-
- if (!m_pullMode && m_audioSource)
- delete m_audioSource;
-
- m_pullMode = false;
- m_audioSource = new InputPrivate(this);
- m_audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
-
- if (open()) {
- setError(QAudio::NoError);
- setState(QAudio::IdleState);
- } else {
- delete m_audioSource;
- m_audioSource = 0;
-
- setError(QAudio::OpenError);
- setState(QAudio::StoppedState);
- }
-
- return m_audioSource;
-}
-
-void QQnxAudioSource::stop()
-{
- if (m_state == QAudio::StoppedState)
- return;
-
- setError(QAudio::NoError);
- setState(QAudio::StoppedState);
- close();
-}
-
-void QQnxAudioSource::reset()
-{
- stop();
- m_bytesAvailable = 0;
-}
-
-void QQnxAudioSource::suspend()
-{
- snd_pcm_capture_pause(m_pcmHandle);
-
- if (m_pcmNotifier)
- m_pcmNotifier->setEnabled(false);
-
- setState(QAudio::SuspendedState);
-}
-
-void QQnxAudioSource::resume()
-{
- snd_pcm_capture_resume(m_pcmHandle);
-
- if (m_pcmNotifier)
- m_pcmNotifier->setEnabled(true);
-
- if (m_pullMode) {
- setState(QAudio::ActiveState);
- } else {
- setState(QAudio::IdleState);
- }
-}
-
-qsizetype QQnxAudioSource::bytesReady() const
-{
- return qMax(m_bytesAvailable, 0);
-}
-
-void QQnxAudioSource::setBufferSize(qsizetype bufferSize)
-{
- m_bufferSize = bufferSize;
-}
-
-qsizetype QQnxAudioSource::bufferSize() const
-{
- return m_bufferSize;
-}
-
-qint64 QQnxAudioSource::processedUSecs() const
-{
- return qint64(1000000) * m_format.framesForBytes(m_bytesRead) / m_format.sampleRate();
-}
-
-QAudio::Error QQnxAudioSource::error() const
-{
- return m_error;
-}
-
-QAudio::State QQnxAudioSource::state() const
-{
- return m_state;
-}
-
-void QQnxAudioSource::setFormat(const QAudioFormat &format)
-{
- if (m_state == QAudio::StoppedState)
- m_format = format;
-}
-
-QAudioFormat QQnxAudioSource::format() const
-{
- return m_format;
-}
-
-void QQnxAudioSource::setVolume(qreal volume)
-{
- m_volume = qBound(qreal(0.0), volume, qreal(1.0));
-}
-
-qreal QQnxAudioSource::volume() const
-{
- return m_volume;
-}
-
-void QQnxAudioSource::userFeed()
-{
- if (m_state == QAudio::StoppedState || m_state == QAudio::SuspendedState)
- return;
-
- deviceReady();
-}
-
-bool QQnxAudioSource::deviceReady()
-{
- if (m_pullMode) {
- // reads some audio data and writes it to QIODevice
- read(0, 0);
- } else {
- m_bytesAvailable = m_periodSize;
-
- // emits readyRead() so user will call read() on QIODevice to get some audio data
- if (m_audioSource != 0) {
- InputPrivate *input = qobject_cast<InputPrivate*>(m_audioSource);
- input->trigger();
- }
- }
-
- if (m_state != QAudio::ActiveState)
- return true;
-
- return true;
-}
-
-bool QQnxAudioSource::open()
-{
- if (!m_format.isValid() || m_format.sampleRate() <= 0) {
- if (!m_format.isValid())
- qWarning("QQnxAudioSource: open error, invalid format.");
- else
- qWarning("QQnxAudioSource: open error, invalid sample rate (%d).", m_format.sampleRate());
-
- return false;
- }
-
- int errorCode = 0;
-
- int card = 0;
- int device = 0;
- if ((errorCode = snd_pcm_open_preferred(&m_pcmHandle, &card, &device, SND_PCM_OPEN_CAPTURE)) < 0) {
- qWarning("QQnxAudioSource: open error, couldn't open card (0x%x)", -errorCode);
- return false;
- }
-
- // Necessary so that bytesFree() which uses the "free" member of the status struct works
- snd_pcm_plugin_set_disable(m_pcmHandle, PLUGIN_MMAP);
-
- snd_pcm_channel_info_t info;
- memset(&info, 0, sizeof(info));
- info.channel = SND_PCM_CHANNEL_CAPTURE;
- if ((errorCode = snd_pcm_plugin_info(m_pcmHandle, &info)) < 0) {
- qWarning("QQnxAudioSource: open error, couldn't get channel info (0x%x)", -errorCode);
- close();
- return false;
- }
-
- snd_pcm_channel_params_t params = QnxAudioUtils::formatToChannelParams(m_format, QAudioDevice::Input, info.max_fragment_size);
-
- if ((errorCode = snd_pcm_plugin_params(m_pcmHandle, &params)) < 0) {
- qWarning("QQnxAudioSource: open error, couldn't set channel params (0x%x)", -errorCode);
- close();
- return false;
- }
-
- if ((errorCode = snd_pcm_plugin_prepare(m_pcmHandle, SND_PCM_CHANNEL_CAPTURE)) < 0) {
- qWarning("QQnxAudioSource: open error, couldn't prepare channel (0x%x)", -errorCode);
- close();
- return false;
- }
-
- snd_pcm_channel_setup_t setup;
-
- memset(&setup, 0, sizeof(setup));
- setup.channel = SND_PCM_CHANNEL_CAPTURE;
- if ((errorCode = snd_pcm_plugin_setup(m_pcmHandle, &setup)) < 0) {
- qWarning("QQnxAudioSource: open error, couldn't get channel setup (0x%x)", -errorCode);
- close();
- return false;
- }
-
- m_periodSize = qMin(2048, setup.buf.block.frag_size);
-
- m_elapsedTimeOffset = 0;
- m_totalTimeValue = 0;
- m_bytesRead = 0;
-
- m_pcmNotifier = new QSocketNotifier(snd_pcm_file_descriptor(m_pcmHandle, SND_PCM_CHANNEL_CAPTURE),
- QSocketNotifier::Read, this);
- connect(m_pcmNotifier, SIGNAL(activated(QSocketDescriptor)), SLOT(userFeed()));
-
- return true;
-}
-
-void QQnxAudioSource::close()
-{
- if (m_pcmHandle)
-#if SND_PCM_VERSION < SND_PROTOCOL_VERSION('P',3,0,2)
- snd_pcm_plugin_flush(m_pcmHandle, SND_PCM_CHANNEL_CAPTURE);
-#else
- snd_pcm_plugin_drop(m_pcmHandle, SND_PCM_CHANNEL_CAPTURE);
-#endif
-
- if (m_pcmNotifier) {
- delete m_pcmNotifier;
- m_pcmNotifier = 0;
- }
-
- if (m_pcmHandle) {
- snd_pcm_close(m_pcmHandle);
- m_pcmHandle = 0;
- }
-
- if (!m_pullMode && m_audioSource) {
- delete m_audioSource;
- m_audioSource = 0;
- }
-}
-
-qint64 QQnxAudioSource::read(char *data, qint64 len)
-{
- int errorCode = 0;
- QByteArray tempBuffer(m_periodSize, 0);
-
- const int actualRead = snd_pcm_plugin_read(m_pcmHandle, tempBuffer.data(), m_periodSize);
- if (actualRead < 1) {
- snd_pcm_channel_status_t status;
- memset(&status, 0, sizeof(status));
- status.channel = SND_PCM_CHANNEL_CAPTURE;
- if ((errorCode = snd_pcm_plugin_status(m_pcmHandle, &status)) < 0) {
- qWarning("QQnxAudioSource: read error, couldn't get plugin status (0x%x)", -errorCode);
- close();
- setError(QAudio::FatalError);
- setState(QAudio::StoppedState);
- return -1;
- }
-
- if (status.status == SND_PCM_STATUS_READY
- || status.status == SND_PCM_STATUS_OVERRUN) {
- if ((errorCode = snd_pcm_plugin_prepare(m_pcmHandle, SND_PCM_CHANNEL_CAPTURE)) < 0) {
- qWarning("QQnxAudioSource: read error, couldn't prepare plugin (0x%x)", -errorCode);
- close();
- setError(QAudio::FatalError);
- setState(QAudio::StoppedState);
- return -1;
- }
- }
- } else {
- setError(QAudio::NoError);
- setState(QAudio::ActiveState);
- }
-
- if (m_volume < 1.0f)
- QAudioHelperInternal::qMultiplySamples(m_volume, m_format, tempBuffer.data(), tempBuffer.data(), actualRead);
-
- m_bytesRead += actualRead;
-
- if (m_pullMode) {
- m_audioSource->write(tempBuffer.data(), actualRead);
- } else {
- memcpy(data, tempBuffer.data(), qMin(static_cast<qint64>(actualRead), len));
- }
-
- m_bytesAvailable = 0;
-
- return actualRead;
-}
-
-void QQnxAudioSource::setError(QAudio::Error error)
-{
- if (m_error == error)
- return;
-
- m_error = error;
- emit errorChanged(m_error);
-}
-
-void QQnxAudioSource::setState(QAudio::State state)
-{
- if (m_state == state)
- return;
-
- m_state = state;
- emit stateChanged(m_state);
-}
-
-InputPrivate::InputPrivate(QQnxAudioSource *audio)
- : m_audioDevice(audio)
-{
-}
-
-qint64 InputPrivate::readData(char *data, qint64 len)
-{
- return m_audioDevice->read(data, len);
-}
-
-qint64 InputPrivate::writeData(const char *data, qint64 len)
-{
- Q_UNUSED(data);
- Q_UNUSED(len);
- return 0;
-}
-
-void InputPrivate::trigger()
-{
- emit readyRead();
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qnx/audio/qqnxaudiosource_p.h b/src/multimedia/platform/qnx/audio/qqnxaudiosource_p.h
deleted file mode 100644
index 3432f7544..000000000
--- a/src/multimedia/platform/qnx/audio/qqnxaudiosource_p.h
+++ /dev/null
@@ -1,142 +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 QNXAUDIOINPUT_H
-#define QNXAUDIOINPUT_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 "qaudiosystem_p.h"
-
-#include <QSocketNotifier>
-#include <QIODevice>
-#include <QElapsedTimer>
-#include <QTimer>
-
-#include <sys/asoundlib.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQnxAudioSource : public QPlatformAudioSource
-{
- Q_OBJECT
-
-public:
- QQnxAudioSource();
- ~QQnxAudioSource();
-
- void start(QIODevice*) override;
- QIODevice* start() override;
- void stop() override;
- void reset() override;
- void suspend() override;
- void resume() override;
- qsizetype bytesReady() const override;
- void setBufferSize(qsizetype ) override;
- qsizetype bufferSize() const override;
- qint64 processedUSecs() const override;
- QAudio::Error error() const override;
- QAudio::State state() const override;
- void setFormat(const QAudioFormat&) override;
- QAudioFormat format() const override;
- void setVolume(qreal) override;
- qreal volume() const override;
-
-private slots:
- void userFeed();
- bool deviceReady();
-
-private:
- friend class InputPrivate;
-
- bool open();
- void close();
- qint64 read(char *data, qint64 len);
- void setError(QAudio::Error error);
- void setState(QAudio::State state);
-
- QAudioFormat m_format;
-
- QIODevice *m_audioSource;
- snd_pcm_t *m_pcmHandle;
- QSocketNotifier *m_pcmNotifier;
-
- QAudio::Error m_error;
- QAudio::State m_state;
-
- qint64 m_bytesRead;
- qint64 m_elapsedTimeOffset;
- qint64 m_totalTimeValue;
-
- qreal m_volume;
-
- int m_bytesAvailable;
- int m_bufferSize;
- int m_periodSize;
-
- bool m_pullMode;
-};
-
-class InputPrivate : public QIODevice
-{
- Q_OBJECT
-public:
- InputPrivate(QQnxAudioSource *audio);
-
- qint64 readData(char *data, qint64 len) override;
- qint64 writeData(const char *data, qint64 len) override;
-
- void trigger();
-
-private:
- QQnxAudioSource *m_audioDevice;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/camera/bbcameraaudioencodersettingscontrol.cpp b/src/multimedia/platform/qnx/camera/bbcameraaudioencodersettingscontrol.cpp
deleted file mode 100644
index 2c0529bc4..000000000
--- a/src/multimedia/platform/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_p.h"
-
-#include "bbcamerasession_p.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/multimedia/platform/qnx/camera/bbcameraaudioencodersettingscontrol_p.h b/src/multimedia/platform/qnx/camera/bbcameraaudioencodersettingscontrol_p.h
deleted file mode 100644
index cdc384537..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameraaudioencodersettingscontrol_p.h
+++ /dev/null
@@ -1,77 +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
-
-//
-// 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 <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/multimedia/platform/qnx/camera/bbcameracontrol.cpp b/src/multimedia/platform/qnx/camera/bbcameracontrol.cpp
deleted file mode 100644
index 335b7c584..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameracontrol.cpp
+++ /dev/null
@@ -1,97 +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_p.h"
-
-#include "bbcamerasession_p.h"
-#include <qcameradevice.h>
-
-QT_BEGIN_NAMESPACE
-
-BbCameraControl::BbCameraControl(BbCameraSession *session, QObject *parent)
- : QPlatformCamera(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()));
-}
-
-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();
-}
-
-void BbCameraControl::setCamera(const QCameraDevice &camera)
-{
- m_session->setDevice(camera.id());
-}
-
-bool BbCameraControl::isCaptureModeSupported(QCamera::CaptureModes mode) const
-{
- return m_session->isCaptureModeSupported(mode);
-}
-
-void BbCameraControl::cameraOpened()
-{
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qnx/camera/bbcameracontrol_p.h b/src/multimedia/platform/qnx/camera/bbcameracontrol_p.h
deleted file mode 100644
index 4990f6517..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameracontrol_p.h
+++ /dev/null
@@ -1,96 +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
-
-//
-// 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 <private/qplatformcamera_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class BbCameraSession;
-
-class BbCameraControl : public QPlatformCamera
-{
- 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;
-
- void setCamera(const QCameraDevice &camera) override;
-
- QCamera::CaptureModes captureMode() const override;
- void setCaptureMode(QCamera::CaptureModes) override;
- bool isCaptureModeSupported(QCamera::CaptureModes mode) const override;
-
- enum LocksApplyMode
- {
- IndependentMode,
- FocusExposureBoundMode,
- AllBoundMode,
- FocusOnlyMode
- };
-
-private Q_SLOTS:
- void cameraOpened();
-
-private:
- BbCameraSession *m_session;
-
-private:
- BbCameraSession *m_session;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/camera/bbcameraexposurecontrol.cpp b/src/multimedia/platform/qnx/camera/bbcameraexposurecontrol.cpp
deleted file mode 100644
index 81ab2ba7f..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameraexposurecontrol.cpp
+++ /dev/null
@@ -1,288 +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_p.h"
-
-#include "bbcamerasession_p.h"
-
-#include <QDebug>
-
-QT_BEGIN_NAMESPACE
-
-BbCameraExposureControl::BbCameraExposureControl(BbCameraSession *session, QObject *parent)
- : QPlatformCameraExposure(parent)
- , m_session(session)
- , m_requestedExposureMode(QCamera::ExposureAuto)
-{
- connect(m_session, SIGNAL(statusChanged(QCamera::Status)), this, SLOT(statusChanged(QCamera::Status)));
-}
-
-bool BbCameraExposureControl::isParameterSupported(ExposureParameter parameter) const
-{
- switch (parameter) {
- case QPlatformCameraExposure::ISO:
- return false;
- case QPlatformCameraExposure::ShutterSpeed:
- return false;
- case QPlatformCameraExposure::ExposureCompensation:
- return false;
- case QPlatformCameraExposure::FlashPower:
- return false;
- case QPlatformCameraExposure::FlashCompensation:
- return false;
- case QPlatformCameraExposure::TorchPower:
- return false;
- case QPlatformCameraExposure::ExposureMode:
- return true;
- case QPlatformCameraExposure::MeteringMode:
- return false;
- default:
- return false;
- }
-}
-
-QVariantList BbCameraExposureControl::supportedParameterRange(ExposureParameter parameter, bool *continuous) const
-{
- if (parameter != QPlatformCameraExposure::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(QCamera::ExposureAuto);
- break;
- case CAMERA_SCENE_SPORTS:
- exposureModes << QVariant::fromValue(QCamera::ExposureSports);
- break;
- case CAMERA_SCENE_CLOSEUP:
- exposureModes << QVariant::fromValue(QCamera::ExposurePortrait);
- break;
- case CAMERA_SCENE_ACTION:
- exposureModes << QVariant::fromValue(QCamera::ExposureSports);
- break;
- case CAMERA_SCENE_BEACHANDSNOW:
- exposureModes << QVariant::fromValue(QCamera::ExposureBeach) << QVariant::fromValue(QCamera::ExposureSnow);
- break;
- case CAMERA_SCENE_NIGHT:
- exposureModes << QVariant::fromValue(QCamera::ExposureNight);
- break;
- default: break;
- }
- }
-
- return exposureModes;
-}
-
-QVariant BbCameraExposureControl::requestedValue(ExposureParameter parameter) const
-{
- if (parameter != QPlatformCameraExposure::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 != QPlatformCameraExposure::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(QCamera::ExposureAuto);
- case CAMERA_SCENE_SPORTS:
- return QVariant::fromValue(QCamera::ExposureSports);
- case CAMERA_SCENE_CLOSEUP:
- return QVariant::fromValue(QCamera::ExposurePortrait);
- case CAMERA_SCENE_ACTION:
- return QVariant::fromValue(QCamera::ExposureSports);
- case CAMERA_SCENE_BEACHANDSNOW:
- return (m_requestedExposureMode == QCamera::ExposureBeach ? QVariant::fromValue(QCamera::ExposureBeach)
- : QVariant::fromValue(QCamera::ExposureSnow));
- case CAMERA_SCENE_NIGHT:
- return QVariant::fromValue(QCamera::ExposureNight);
- default:
- break;
- }
-
- return QVariant();
-}
-
-bool BbCameraExposureControl::setValue(ExposureParameter parameter, const QVariant& value)
-{
- if (parameter != QPlatformCameraExposure::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<QCamera::ExposureMode>();
- emit requestedValueChanged(QPlatformCameraExposure::ExposureMode);
-
- switch (m_requestedExposureMode) {
- case QCamera::ExposureAuto:
- sceneMode = CAMERA_SCENE_AUTO;
- break;
- case QCamera::ExposureSports:
- sceneMode = CAMERA_SCENE_SPORTS;
- break;
- case QCamera::ExposurePortrait:
- sceneMode = CAMERA_SCENE_CLOSEUP;
- break;
- case QCamera::ExposureBeach:
- sceneMode = CAMERA_SCENE_BEACHANDSNOW;
- break;
- case QCamera::ExposureSnow:
- sceneMode = CAMERA_SCENE_BEACHANDSNOW;
- break;
- case QCamera::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(QPlatformCameraExposure::ExposureMode);
-
- return true;
-}
-
-void BbCameraExposureControl::statusChanged(QCamera::Status status)
-{
- if (status == QCamera::ActiveStatus || status == QCamera::LoadedStatus)
- emit parameterRangeChanged(QPlatformCameraExposure::ExposureMode);
-}
-
-QCamera::FlashModes BbCameraExposureControl::flashMode() const
-{
- return m_flashMode;
-}
-
-void BbCameraExposureControl::setFlashMode(QCamera::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 == QCamera::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 == QCamera::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 == QCamera::FlashAuto)
- flashMode = CAMERA_FLASH_AUTO;
- else if (mode == QCamera::FlashOff)
- flashMode = CAMERA_FLASH_OFF;
- else if (mode == QCamera::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(QCamera::FlashModes mode) const
-{
- // ### Videolight maps to QCamera::TorchOn.
-// bool supportsVideoLight = false;
-// if (m_session->handle() != CAMERA_HANDLE_INVALID) {
-// supportsVideoLight = camera_has_feature(m_session->handle(), CAMERA_FEATURE_VIDEOLIGHT);
-// }
-
- // ### is this correct?
- return true;
-}
-
-bool BbCameraExposureControl::isFlashReady() const
-{
- //TODO: check for flash charge-level here?!?
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qnx/camera/bbcameraexposurecontrol_p.h b/src/multimedia/platform/qnx/camera/bbcameraexposurecontrol_p.h
deleted file mode 100644
index 60ffcd0f0..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameraexposurecontrol_p.h
+++ /dev/null
@@ -1,89 +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
-
-//
-// 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 <private/qplatformcameraexposure_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class BbCameraSession;
-
-class BbCameraExposureControl : public QPlatformCameraExposure
-{
- 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;
-
- QCamera::FlashMode flashMode() const override;
- void setFlashMode(QCamera::FlashMode mode) override;
- bool isFlashModeSupported(QCamera::FlashMode mode) const override;
- bool isFlashReady() const override;
-
-private Q_SLOTS:
- void statusChanged(QCamera::Status status);
-
-private:
- BbCameraSession *m_session;
- QCamera::ExposureMode m_requestedExposureMode;
-
- QCamera::FlashMode m_flashMode = QCamera::FlashAuto;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/camera/bbcamerafocuscontrol.cpp b/src/multimedia/platform/qnx/camera/bbcamerafocuscontrol.cpp
deleted file mode 100644
index 20d2d540a..000000000
--- a/src/multimedia/platform/qnx/camera/bbcamerafocuscontrol.cpp
+++ /dev/null
@@ -1,300 +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_p.h"
-
-#include "bbcamerasession_p.h"
-
-#include <QDebug>
-
-QT_BEGIN_NAMESPACE
-
-BbCameraFocusControl::BbCameraFocusControl(BbCameraSession *session, QObject *parent)
- : QPlatformCameraFocus(parent)
- , m_session(session)
- , m_focusMode(QCamera::FocusModeAuto)
- , m_customFocusPoint(QPointF(0, 0))
-{
- connect(m_session, SIGNAL(statusChanged(QCamera::Status)), this, SLOT(statusChanged(QCamera::Status)));
-}
-
-QCamera::FocusMode 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 QCamera::FocusModeAuto;
- }
-
- switch (focusMode) {
- case CAMERA_FOCUSMODE_EDOF:
- return QCamera::FocusModeHyperfocal;
- case CAMERA_FOCUSMODE_MANUAL:
- return QCamera::FocusModeManual;
- case CAMERA_FOCUSMODE_CONTINUOUS_MACRO: // fall through
- case CAMERA_FOCUSMODE_MACRO:
- return QCamera::FocusModeAutoNear;
- case CAMERA_FOCUSMODE_AUTO: // fall through
- case CAMERA_FOCUSMODE_CONTINUOUS_AUTO:
- return QCamera::FocusModeAuto;
- case CAMERA_FOCUSMODE_OFF:
- default:
- return QCamera::FocusModeAuto;
- }
-}
-
-void BbCameraFocusControl::setFocusMode(QCamera::FocusMode mode)
-{
- if (m_focusMode == mode)
- return;
-
- camera_focusmode_t focusMode = CAMERA_FOCUSMODE_OFF;
-
- switch (mode) {
- case QCamera::FocusModeHyperfocal:
- case QCamera::FocusModeInfinity: // not 100%, but close
- focusMode = CAMERA_FOCUSMODE_EDOF;
- break;
- case QCamera::FocusModeManual:
- focusMode = CAMERA_FOCUSMODE_MANUAL;
- break;
- case QCamera::FocusModeAutoNear:
- focusMode = CAMERA_FOCUSMODE_MACRO;
- break;
- case QCamera::FocusModeAuto:
- case QCamera::FocusModeAutoFar:
- focusMode = CAMERA_FOCUSMODE_CONTINUOUS_AUTO;
- break;
- }
-
- 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(QCamera::FocusMode mode) const
-{
- if (m_session->state() == QCamera::UnloadedState)
- return false;
-
- if (mode == QCamera::FocusModeHyperfocal)
- return false; //TODO how to check?
- else if (mode == QCamera::FocusModeManual)
- return camera_has_feature(m_session->handle(), CAMERA_FEATURE_MANUALFOCUS);
- else if (mode == QCamera::FocusModeAuto)
- return camera_has_feature(m_session->handle(), CAMERA_FEATURE_AUTOFOCUS);
- else if (mode == QCamera::FocusModeAutoNear)
- return camera_has_feature(m_session->handle(), CAMERA_FEATURE_MACROFOCUS);
-
- return false;
-}
-
-QPointF BbCameraFocusControl::focusPoint() const
-{
- return m_customFocusPoint;
-}
-
-void BbCameraFocusControl::setCustomFocusPoint(const QPointF &point)
-{
- if (m_customFocusPoint == point)
- return;
-
- m_customFocusPoint = point;
- emit customFocusPointChanged(m_customFocusPoint);
-
- updateCustomFocusRegion();
-}
-
-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);
-}
-
-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/multimedia/platform/qnx/camera/bbcamerafocuscontrol_p.h b/src/multimedia/platform/qnx/camera/bbcamerafocuscontrol_p.h
deleted file mode 100644
index 895701283..000000000
--- a/src/multimedia/platform/qnx/camera/bbcamerafocuscontrol_p.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 BBCAMERAFOCUSCONTROL_H
-#define BBCAMERAFOCUSCONTROL_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 <private/qplatformcamerafocus_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class BbCameraSession;
-
-class BbCameraFocusControl : public QPlatformCameraFocus
-{
- Q_OBJECT
-public:
- explicit BbCameraFocusControl(BbCameraSession *session, QObject *parent = 0);
-
- QCamera::FocusMode focusMode() const override;
- void setFocusMode(QCamera::FocusMode mode) override;
- bool isFocusModeSupported(QCamera::FocusMode mode) const override;
- QPointF focusPoint() const override;
- void setCustomFocusPoint(const QPointF &point) 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;
-
- QCamera::FocusMode m_focusMode;
- QPointF m_customFocusPoint;
-
- qreal m_minimumZoomFactor;
- qreal m_maximumZoomFactor;
- bool m_supportsSmoothZoom;
- qreal m_requestedZoomFactor;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/camera/bbcameraimagecapturecontrol.cpp b/src/multimedia/platform/qnx/camera/bbcameraimagecapturecontrol.cpp
deleted file mode 100644
index 5a78e1ee0..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameraimagecapturecontrol.cpp
+++ /dev/null
@@ -1,89 +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_p.h"
-
-#include "bbcamerasession_p.h"
-
-QT_BEGIN_NAMESPACE
-
-BbCameraImageCaptureControl::BbCameraImageCaptureControl(BbCameraSession *session, QObject *parent)
- : QPlatformImageCapture(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();
-}
-
-int BbCameraImageCaptureControl::capture(const QString &fileName)
-{
- return m_session->capture(fileName);
-}
-
-int BbCameraImageCaptureControl::captureToBuffer()
-{
- // ### implement me
- return -1;
-}
-
-void BbCameraImageCaptureControl::cancelCapture()
-{
- m_session->cancelCapture();
-}
-
-QImageEncoderSettings BbCameraImageCaptureControl::imageSettings() const
-{
- return m_session->imageSettings();
-}
-
-void BbCameraImageCaptureControl::setImageSettings(const QImageEncoderSettings &settings)
-{
- m_session->setImageSettings(settings);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qnx/camera/bbcameraimagecapturecontrol_p.h b/src/multimedia/platform/qnx/camera/bbcameraimagecapturecontrol_p.h
deleted file mode 100644
index 62ba19c97..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameraimagecapturecontrol_p.h
+++ /dev/null
@@ -1,80 +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
-
-//
-// 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 <private/qplatformimagecapture_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class BbCameraSession;
-
-class BbCameraImageCaptureControl : public QPlatformImageCapture
-{
- Q_OBJECT
-public:
- explicit BbCameraImageCaptureControl(BbCameraSession *session, QObject *parent = 0);
-
- bool isReadyForCapture() const override;
-
- int capture(const QString &fileName) override;
- int captureToBuffer() override;
- void cancelCapture() override;
-
- QImageEncoderSettings imageSettings() const override;
- void setImageSettings(const QImageEncoderSettings &settings) override;
-
-private:
- BbCameraSession *m_session;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/camera/bbcameraimageprocessingcontrol.cpp b/src/multimedia/platform/qnx/camera/bbcameraimageprocessingcontrol.cpp
deleted file mode 100644
index 08e468eea..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameraimageprocessingcontrol.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 "bbcameraimageprocessingcontrol_p.h"
-
-#include "bbcamerasession_p.h"
-
-#include <QDebug>
-
-QT_BEGIN_NAMESPACE
-
-BbCameraImageProcessingControl::BbCameraImageProcessingControl(BbCameraSession *session, QObject *parent)
- : QPlatformCameraImageProcessing(parent)
- , m_session(session)
-{
-}
-
-bool BbCameraImageProcessingControl::isParameterSupported(ProcessingParameter parameter) const
-{
- return (parameter == QPlatformCameraImageProcessing::WhiteBalancePreset);
-}
-
-bool BbCameraImageProcessingControl::isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const
-{
- if (parameter != QPlatformCameraImageProcessing::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<QCamera::WhiteBalanceMode> supportedModes;
- for (int i = 0; i < supported; ++i) {
- switch (modes[i]) {
- case CAMERA_WHITEBALANCEMODE_AUTO:
- supportedModes.insert(QCamera::WhiteBalanceAuto);
- break;
- case CAMERA_WHITEBALANCEMODE_MANUAL:
- supportedModes.insert(QCamera::WhiteBalanceManual);
- break;
- default:
- break;
- }
- }
-
- return supportedModes.contains(value.value<QCamera::WhiteBalanceMode>());
-}
-
-void BbCameraImageProcessingControl::setParameter(ProcessingParameter parameter, const QVariant &value)
-{
- if (parameter != QPlatformCameraImageProcessing::WhiteBalancePreset)
- return;
-
- if (m_session->handle() == CAMERA_HANDLE_INVALID)
- return;
-
- camera_whitebalancemode_t mode = CAMERA_WHITEBALANCEMODE_DEFAULT;
- switch (value.value<QCamera::WhiteBalanceMode>()) {
- case QCamera::WhiteBalanceAuto:
- mode = CAMERA_WHITEBALANCEMODE_AUTO;
- break;
- case QCamera::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/multimedia/platform/qnx/camera/bbcameraimageprocessingcontrol_p.h b/src/multimedia/platform/qnx/camera/bbcameraimageprocessingcontrol_p.h
deleted file mode 100644
index 6a0af4a85..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameraimageprocessingcontrol_p.h
+++ /dev/null
@@ -1,75 +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
-
-//
-// 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 <private/qplatformcameraimageprocessing_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class BbCameraSession;
-
-class BbCameraImageProcessingControl : public QPlatformCameraImageProcessing
-{
- Q_OBJECT
-public:
- explicit BbCameraImageProcessingControl(BbCameraSession *session, QObject *parent = 0);
-
- bool isParameterSupported(ProcessingParameter) const override;
- bool isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const override;
- void setParameter(ProcessingParameter parameter, const QVariant &value) override;
-
-private:
- BbCameraSession *m_session;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/camera/bbcameramediarecordercontrol.cpp b/src/multimedia/platform/qnx/camera/bbcameramediarecordercontrol.cpp
deleted file mode 100644
index a90ae33be..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameramediarecordercontrol.cpp
+++ /dev/null
@@ -1,149 +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_p.h"
-
-#include "bbcamerasession_p.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)
- : QPlatformMediaEncoder(parent)
- , m_session(session)
-{
- connect(m_session, SIGNAL(videoStateChanged(QMediaRecorder::RecorderState)), this, SIGNAL(stateChanged(QMediaRecorder::RecorderState)));
- 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)));
-}
-
-bool BbCameraMediaRecorderControl::isLocationWritable(const QUrl &location) const
-{
- return true;
-}
-
-QMediaRecorder::RecorderState BbCameraMediaRecorderControl::state() const
-{
- return m_session->videoState();
-}
-
-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::record(QMediaEncoderSettings &)
-{
- if (m_session) {
- m_session->applyVideoSettings();
- m_session->startVideoRecording(outputLocation());
- }
-}
-
-void BbCameraMediaRecorderControl::stop()
-{
- if (m_session)
- m_session->stopVideoRecording();
-}
-
-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/multimedia/platform/qnx/camera/bbcameramediarecordercontrol_p.h b/src/multimedia/platform/qnx/camera/bbcameramediarecordercontrol_p.h
deleted file mode 100644
index 5ea453a0b..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameramediarecordercontrol_p.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 BBCAMERAMEDIARECORDERCONTROL_H
-#define BBCAMERAMEDIARECORDERCONTROL_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 <private/qplatformmediaencoder_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class BbCameraSession;
-
-class BbCameraMediaRecorderControl : public QPlatformMediaEncoder
-{
- Q_OBJECT
-public:
- explicit BbCameraMediaRecorderControl(BbCameraSession *session, QObject *parent = 0);
-
- QMediaRecorder::RecorderState state() const override;
- bool isLocationWritable(const QUrl &location) const override;
- qint64 duration() const override;
- bool isMuted() const override;
- qreal volume() const override;
- void record(QMediaEncoderSettings &settings) override;
- void stop() override;
-
-
-public Q_SLOTS:
- void setMuted(bool muted) override;
- void setVolume(qreal volume) override;
-
-private:
- BbCameraSession *m_session;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/camera/bbcameraorientationhandler.cpp b/src/multimedia/platform/qnx/camera/bbcameraorientationhandler.cpp
deleted file mode 100644
index d600f3db0..000000000
--- a/src/multimedia/platform/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/multimedia/platform/qnx/camera/bbcameraorientationhandler_p.h b/src/multimedia/platform/qnx/camera/bbcameraorientationhandler_p.h
deleted file mode 100644
index ace5118ef..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameraorientationhandler_p.h
+++ /dev/null
@@ -1,80 +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>
-
-//
-// 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.
-//
-
-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/multimedia/platform/qnx/camera/bbcameraservice.cpp b/src/multimedia/platform/qnx/camera/bbcameraservice.cpp
deleted file mode 100644
index 6f68e68ed..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameraservice.cpp
+++ /dev/null
@@ -1,96 +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_p.h"
-
-#include "bbcameraaudioencodersettingscontrol_p.h"
-#include "bbcameracontrol_p.h"
-#include "bbcameraexposurecontrol_p.h"
-#include "bbcamerafocuscontrol_p.h"
-#include "bbcameraimagecapturecontrol_p.h"
-#include "bbcameraimageprocessingcontrol_p.h"
-#include "bbcameramediarecordercontrol_p.h"
-#include "bbcamerasession_p.h"
-#include "bbcameravideoencodersettingscontrol_p.h"
-#include "bbvideorenderercontrol_p.h"
-
-#include <QDebug>
-#include <QVariant>
-
-QT_BEGIN_NAMESPACE
-
-BbCameraService::BbCameraService(QObject *parent)
- : QObject(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_videoRendererControl(new BbVideoRendererControl(m_cameraSession, this))
-{
-}
-
-BbCameraService::~BbCameraService()
-{
-}
-
-QPlatformCamera *BbCameraService::camera()
-{
- return m_cameraControl;
-}
-
-QPlatformImageCapture *BbCameraService::imageCapture()
-{
- return m_cameraImageCaptureControl;
-}
-
-QPlatformMediaEncoder *BbCameraService::mediaEncoder()
-{
- return m_cameraMediaRecorderControl;
-}
-
-void BbCameraService::setVideoPreview(QVideoSink *surface)
-{
- // ####
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qnx/camera/bbcameraservice_p.h b/src/multimedia/platform/qnx/camera/bbcameraservice_p.h
deleted file mode 100644
index 128fc1154..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameraservice_p.h
+++ /dev/null
@@ -1,100 +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
-
-//
-// 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 <QObject>
-
-#include <private/qplatformmediacapture_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class BbCameraAudioEncoderSettingsControl;
-class BbCameraControl;
-class BbCameraExposureControl;
-class BbCameraFocusControl;
-class BbCameraImageCaptureControl;
-class BbCameraImageProcessingControl;
-class BbCameraMediaRecorderControl;
-class BbCameraSession;
-class BbCameraVideoEncoderSettingsControl;
-class BbVideoRendererControl;
-
-class BbCameraService : public QPlatformMediaCaptureSession
-{
- Q_OBJECT
-
-public:
- explicit BbCameraService(QObject *parent = 0);
- ~BbCameraService();
-
- QPlatformCamera *camera() override;
- QPlatformImageCapture *imageCapture() override;
- QPlatformMediaEncoder *mediaEncoder() override;
-
- void setVideoPreview(QVideoSink *surface) override;
-
-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;
- BbVideoRendererControl* m_videoRendererControl;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/camera/bbcamerasession.cpp b/src/multimedia/platform/qnx/camera/bbcamerasession.cpp
deleted file mode 100644
index d82cbe482..000000000
--- a/src/multimedia/platform/qnx/camera/bbcamerasession.cpp
+++ /dev/null
@@ -1,1049 +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_p.h"
-
-#include "bbcameraorientationhandler_p.h"
-#include "windowgrabber_p.h"
-
-#include <QBuffer>
-#include <QDebug>
-#include <QImage>
-#include <QUrl>
-#include <QVideoFrameFormat>
-#include <qmath.h>
-#include <private/qmediarecorder_p.h>
-#include <private/qplatformimagecapture_p.h>
-#include <private/qmediastoragelocation_p.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_lastImageCaptureId(0)
- , m_videoState(QMediaRecorder::StoppedState)
- , 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;
-}
-
-void BbCameraSession::setSurface(QVideoSink *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;
-}
-
-/**
- * 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(QImageCapture::Error, QImageCapture::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(QImageCapture::Error, QImageCapture::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, QImageCapture::NotReadyError,
- QPlatformImageCapture::msgCameraNotReady());
- return m_lastImageCaptureId;
- }
-
- // 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;
-
- return m_lastImageCaptureId;
-}
-
-void BbCameraSession::cancelCapture()
-{
- // BB10 API doesn't provide functionality for that
-}
-
-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"));
-}
-
-QMediaRecorder::RecorderState BbCameraSession::videoState() const
-{
- return m_videoState;
-}
-
-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 (/* capture to buffer */ fileName.isEmpty()) {
- QVideoFrame frame(image);
- emit imageAvailable(requestId, frame);
- } else {
- const QString actualFileName = QMediaStorageLocation::generateFileName(fileName, QStandardPaths::PicturesLocation, QLatin1String("jpg"));
- QFile file(actualFileName);
- if (file.open(QFile::WriteOnly)) {
- if (image.save(&file, "jpg")) {
- emit imageSaved(requestId, actualFileName);
- } else {
- emit imageCaptureError(requestId, QImageCapture::OutOfSpaceError, file.errorString());
- }
- } else {
- const QString errorMessage = tr("Could not open destination file:\n%1").arg(actualFileName);
- emit imageCaptureError(requestId, QImageCapture::ResourceError, errorMessage);
- }
- }
-}
-
-void BbCameraSession::handleVideoRecordingPaused()
-{
- //TODO: implement once BB10 API supports pausing a video
-}
-
-void BbCameraSession::handleVideoRecordingResumed()
-{
- if (m_videoRecordingDuration.isValid())
- 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(QVideoFrameFormat(frame.size(), QVideoFrameFormat::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(QVideoFrameFormat(rotatedSize, QVideoFrameFormat::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 QMediaRecorder::VeryLowQuality:
- jpegQuality = 20;
- break;
- case QMediaRecorder::LowQuality:
- jpegQuality = 40;
- break;
- case QMediaRecorder::NormalQuality:
- jpegQuality = 60;
- break;
- case QMediaRecorder::HighQuality:
- jpegQuality = 80;
- break;
- case QMediaRecorder::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);
- }
-}
-
-void BbCameraSession::startVideoRecording(const QUrl &outputLocation)
-{
- if (m_videoState == QMediaRecorder::RecordingState)
- return;
-
- m_videoRecordingDuration.invalidate();
-
- auto videoOutputLocation = QMediaStorageLocation::generateFileName(outputLocation.toLocalFile(), QStandardPaths::MoviesLocation, QLatin1String("mp4"));
-
- emit actualLocationChanged(videoOutputLocation);
-
- const camera_error_t result = camera_start_video(m_handle, QFile::encodeName(videoOutputLocation), 0, videoRecordingStatusCallback, this);
- if (result != CAMERA_EOK) {
- emit videoError(QMediaRecorder::ResourceError,
- QMediaRecorderPrivate::msgFailedStartRecording());
- } else {
- m_videoState = QMediaRecorder::RecordingState;
- }
- emit videoStateChanged(m_videoState);
-}
-
-void BbCameraSession::stopVideoRecording()
-{
- if (m_videoState == QMediaRecorder::StoppedState)
- return;
-
- 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_videoRecordingDuration.invalidate();
- m_videoState = QMediaRecorder::StoppedState;
- emit videoStateChanged(m_videoState);
-}
-
-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/multimedia/platform/qnx/camera/bbcamerasession_p.h b/src/multimedia/platform/qnx/camera/bbcamerasession_p.h
deleted file mode 100644
index 4ea7110e7..000000000
--- a/src/multimedia/platform/qnx/camera/bbcamerasession_p.h
+++ /dev/null
@@ -1,202 +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
-
-//
-// 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 <QCamera>
-#include <QImageCapture>
-#include <QElapsedTimer>
-#include <QMediaRecorder>
-#include <QMutex>
-#include <QObject>
-#include <QPointer>
-#include <qvideosink.h>
-
-#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
- void setSurface(QVideoSink *surface);
-
- // image capture control
- bool isReadyForCapture() const;
- int capture(const QString &fileName);
- void cancelCapture();
-
- // image encoder control
- QList<QSize> supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const;
- QImageEncoderSettings imageSettings() const;
- void setImageSettings(const QImageEncoderSettings &settings);
-
- // media recorder control
- QMediaRecorder::RecorderState videoState() const;
- qint64 duration() const;
- void applyVideoSettings();
-
- bool startVideoRecording(const QUrl &outputLocation);
- void stopVideoRecording();
-
- // 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 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);
-
- // media recorder control
- void videoStateChanged(QMediaRecorder::RecorderState state);
- 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 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<QVideoSink> m_surface;
- QMutex m_surfaceMutex;
-
- int m_lastImageCaptureId;
-
- QImageEncoderSettings m_imageEncoderSettings;
-
- QMediaRecorder::RecorderState m_videoState;
- QElapsedTimer m_videoRecordingDuration;
-
- QVideoEncoderSettings m_videoEncoderSettings;
- QAudioEncoderSettings m_audioEncoderSettings;
-
- camera_handle_t m_handle;
-
- WindowGrabber* m_windowGrabber;
-};
-
-QDebug operator<<(QDebug debug, camera_error_t error);
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/camera/bbcameravideoencodersettingscontrol.cpp b/src/multimedia/platform/qnx/camera/bbcameravideoencodersettingscontrol.cpp
deleted file mode 100644
index d16d7a307..000000000
--- a/src/multimedia/platform/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_p.h"
-
-#include "bbcamerasession_p.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/multimedia/platform/qnx/camera/bbcameravideoencodersettingscontrol_p.h b/src/multimedia/platform/qnx/camera/bbcameravideoencodersettingscontrol_p.h
deleted file mode 100644
index 893b26d5d..000000000
--- a/src/multimedia/platform/qnx/camera/bbcameravideoencodersettingscontrol_p.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 BBCAMERAVIDEOENCODERSETTINGSCONTROL_H
-#define BBCAMERAVIDEOENCODERSETTINGSCONTROL_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 <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/multimedia/platform/qnx/common/windowgrabber.cpp b/src/multimedia/platform/qnx/common/windowgrabber.cpp
deleted file mode 100644
index e4c8c926d..000000000
--- a/src/multimedia/platform/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_p.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/multimedia/platform/qnx/common/windowgrabber_p.h b/src/multimedia/platform/qnx/common/windowgrabber_p.h
deleted file mode 100644
index 79a234b2d..000000000
--- a/src/multimedia/platform/qnx/common/windowgrabber_p.h
+++ /dev/null
@@ -1,155 +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
-
-//
-// 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.
-//
-
-#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/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp b/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
deleted file mode 100644
index 4eff994e4..000000000
--- a/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
+++ /dev/null
@@ -1,630 +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_p.h"
-#include "mmrenderermediaplayercontrol_p.h"
-#include "mmrendererplayervideorenderercontrol_p.h"
-#include "mmrendererutil_p.h"
-#include "mmrenderervideowindowcontrol_p.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(QMediaPlayer *parent)
- : QPlatformMediaPlayer(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 &bufferProgress)
-{
- if (m_state == QMediaPlayer::StoppedState)
- return;
-
- if (bufferProgress == 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 = 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 bufferProgressChanged(m_bufferLevel/100.);
-}
-
-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);
- }
-}
-
-float MmRendererMediaPlayerControl::bufferProgress() const
-{
- // mm-renderer has buffer properties "status" and "level"
- // QMediaPlayer's buffer status maps to mm-renderer's buffer level
- return m_bufferLevel/100.;
-}
-
-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;
-
- // 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);
-}
-
-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::setMmPosition(qint64 newPosition)
-{
- if (newPosition != 0 && newPosition != m_position) {
- m_position = newPosition;
- emit positionChanged(m_position);
- }
-}
-
-void MmRendererMediaPlayerControl::setMmBufferStatus(const QString &bufferProgress)
-{
- if (bufferProgress == QLatin1String("buffering"))
- setMediaStatus(QMediaPlayer::BufferingMedia);
- else if (bufferProgress == 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 bufferProgressChanged(m_bufferLevel/100.);
-}
-
-void MmRendererMediaPlayerControl::updateMetaData(const strm_dict *dict)
-{
- m_metaData.update(dict);
-
- if (m_videoWindowControl)
- m_videoWindowControl->setMetaData(m_metaData);
-
- // ### convert to QMediaMetaData and notify the player about metadata changes
- 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/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol_p.h b/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol_p.h
deleted file mode 100644
index 63ae3c407..000000000
--- a/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol_p.h
+++ /dev/null
@@ -1,183 +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
-
-//
-// 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 "mmrenderermetadata_p.h"
-#include <private/qplatformmediaplayer_p.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 MmRendererPlayerVideoRendererControl;
-class MmRendererVideoWindowControl;
-
-class MmRendererMediaPlayerControl : public QPlatformMediaPlayer, public QAbstractNativeEventFilter
-{
- Q_OBJECT
-public:
- explicit MmRendererMediaPlayerControl(QMediaPlayer *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;
-
- float bufferProgress() 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;
-
- MmRendererPlayerVideoRendererControl *videoRendererControl() const;
- void setVideoRendererControl(MmRendererPlayerVideoRendererControl *videoControl);
-
- MmRendererVideoWindowControl *videoWindowControl() const;
- void setVideoWindowControl(MmRendererVideoWindowControl *videoControl);
-
-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 &bufferProgress);
- void setMmBufferLevel(int level, int capacity);
- void handleMmStopped();
- void handleMmSuspend(const QString &reason);
- void handleMmSuspendRemoval(const QString &bufferProgress);
- 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;
- 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/multimedia/platform/qnx/mediaplayer/mmrenderermetadata.cpp b/src/multimedia/platform/qnx/mediaplayer/mmrenderermetadata.cpp
deleted file mode 100644
index d369ea560..000000000
--- a/src/multimedia/platform/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_p.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/multimedia/platform/qnx/mediaplayer/mmrenderermetadata_p.h b/src/multimedia/platform/qnx/mediaplayer/mmrenderermetadata_p.h
deleted file mode 100644
index 72b10a110..000000000
--- a/src/multimedia/platform/qnx/mediaplayer/mmrenderermetadata_p.h
+++ /dev/null
@@ -1,110 +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
-
-//
-// 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 <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/multimedia/platform/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp b/src/multimedia/platform/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp
deleted file mode 100644
index dbcfad245..000000000
--- a/src/multimedia/platform/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp
+++ /dev/null
@@ -1,192 +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_p.h"
-
-#include "windowgrabber.h"
-
-#include <QCoreApplication>
-#include <QDebug>
-#include <QVideoFrameFormat>
-#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();
-}
-
-QVideoSink *MmRendererPlayerVideoRendererControl::sink() const
-{
- return m_sink;
-}
-
-void MmRendererPlayerVideoRendererControl::setSink(QVideoSink *surface)
-{
- m_sink = QPointer<QAbstractVideoSurface>(surface);
- if (QOpenGLContext::currentContext())
- m_windowGrabber->checkForEglImageExtension();
- else if (m_sink)
- m_sink->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_sink)
- m_sink->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(QVideoFrame::GLTextureHandle)
- {
- m_windowGrabber = windowGrabber;
- m_handle = 0;
- }
- MapMode mapMode() const {
- return QVideoFrame::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_sink) {
- // 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, QVideoFrameFormat(size, QVideoFrameFormat::Format_BGR32));
- m_sink->setVideoFrame(actualFrame);
- } else {
- m_sink->setVideoFrame(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/multimedia/platform/qnx/mediaplayer/mmrendererplayervideorenderercontrol_p.h b/src/multimedia/platform/qnx/mediaplayer/mmrendererplayervideorenderercontrol_p.h
deleted file mode 100644
index 3c529e0b4..000000000
--- a/src/multimedia/platform/qnx/mediaplayer/mmrendererplayervideorenderercontrol_p.h
+++ /dev/null
@@ -1,95 +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
-
-//
-// 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 <QPointer>
-#include <qobject.h>
-
-typedef struct mmr_context mmr_context_t;
-
-QT_BEGIN_NAMESPACE
-
-class WindowGrabber;
-class QVideoSink;
-
-class MmRendererPlayerVideoRendererControl : public QObject
-{
- Q_OBJECT
-public:
- explicit MmRendererPlayerVideoRendererControl(QObject *parent = 0);
- ~MmRendererPlayerVideoRendererControl();
-
- QVideoSink *sink() const;
- void setSink(QVideoSink *sink);
-
- // 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<QVideoSink> m_sink;
-
- WindowGrabber* m_windowGrabber;
- mmr_context_t *m_context;
-
- int m_videoId;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/mediaplayer/mmrendererutil.cpp b/src/multimedia/platform/qnx/mediaplayer/mmrendererutil.cpp
deleted file mode 100644
index 89cf8489b..000000000
--- a/src/multimedia/platform/qnx/mediaplayer/mmrendererutil.cpp
+++ /dev/null
@@ -1,165 +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_p.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::GameRole + 1];
-
-template <typename T, size_t N>
-constexpr size_t countof(T (&)[N])
-{
- return N;
-}
-
-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();
-}
-
-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;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qnx/mediaplayer/mmrendererutil_p.h b/src/multimedia/platform/qnx/mediaplayer/mmrendererutil_p.h
deleted file mode 100644
index e1f972840..000000000
--- a/src/multimedia/platform/qnx/mediaplayer/mmrendererutil_p.h
+++ /dev/null
@@ -1,68 +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
-
-//
-// 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 <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();
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/mediaplayer/mmrenderervideowindowcontrol.cpp b/src/multimedia/platform/qnx/mediaplayer/mmrenderervideowindowcontrol.cpp
deleted file mode 100644
index aca860828..000000000
--- a/src/multimedia/platform/qnx/mediaplayer/mmrenderervideowindowcontrol.cpp
+++ /dev/null
@@ -1,378 +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_p.h"
-#include "mmrendererutil_p.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)
- : QPlatformVideoSink(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;
-}
-
-void MmRendererVideoWindowControl::setDisplayRect(const QRect &rect)
-{
- if (m_displayRect != rect) {
- m_displayRect = rect;
- updateVideoPosition();
- }
-}
-
-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
-}
-
-Qt::AspectRatioMode MmRendererVideoWindowControl::aspectRatioMode() const
-{
- return m_aspectRatioMode;
-}
-
-void MmRendererVideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode)
-{
- m_aspectRatioMode = mode;
-}
-
-void MmRendererVideoWindowControl::setBrightness(float brightness)
-{
- if (m_brightness != brightness) {
- m_brightness = brightness;
- updateBrightness();
- emit brightnessChanged(m_brightness);
- }
-}
-
-void MmRendererVideoWindowControl::setContrast(float contrast)
-{
- if (m_contrast != contrast) {
- m_contrast = contrast;
- updateContrast();
- emit contrastChanged(m_contrast);
- }
-}
-
-void MmRendererVideoWindowControl::setHue(float hue)
-{
- if (m_hue != hue) {
- m_hue = hue;
- updateHue();
- emit hueChanged(m_hue);
- }
-}
-
-void MmRendererVideoWindowControl::setSaturation(float 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 * 255f;
- 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 * 127f;
- 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 * 127f;
- 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 * 127f;
- 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;
- setNativeSize(QSize(m_metaData.width(), m_metaData.height());)
-
- // 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/multimedia/platform/qnx/mediaplayer/mmrenderervideowindowcontrol_p.h b/src/multimedia/platform/qnx/mediaplayer/mmrenderervideowindowcontrol_p.h
deleted file mode 100644
index 6e9cc92f3..000000000
--- a/src/multimedia/platform/qnx/mediaplayer/mmrenderervideowindowcontrol_p.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
-
-//
-// 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 "mmrenderermetadata_p.h"
-#include "private/qplatformvideosink_p.h"
-#include <screen/screen.h>
-
-typedef struct mmr_context mmr_context_t;
-
-QT_BEGIN_NAMESPACE
-
-class MmRendererVideoWindowControl : public QPlatformVideoSink
-{
- Q_OBJECT
-public:
- explicit MmRendererVideoWindowControl(QObject *parent = 0);
- ~MmRendererVideoWindowControl();
-
- WId winId() const override;
- void setWinId(WId id) override;
-
- void setDisplayRect(const QRect &rect) override;
-
- void setFullScreen(bool fullScreen) override;
-
- void repaint() override;
-
- Qt::AspectRatioMode aspectRatioMode() const override;
- void setAspectRatioMode(Qt::AspectRatioMode mode) override;
-
- void setBrightness(float brightness) override;
- void setContrast(float contrast) override;
- void setHue(float hue) override;
- void setSaturation(float 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;
- float m_hue;
- float m_brightness;
- float m_contrast;
- float m_saturation;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/mediaplayer/mmreventmediaplayercontrol.cpp b/src/multimedia/platform/qnx/mediaplayer/mmreventmediaplayercontrol.cpp
deleted file mode 100644
index 218fab7e9..000000000
--- a/src/multimedia/platform/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_p.h"
-#include "mmreventthread_p.h"
-#include "mmrenderervideowindowcontrol_p.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_bufferProgress("")
- , 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_bufferProgress = "";
- 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_bufferProgress = QByteArray(strm_string_get(value));
- if (!m_suspended)
- setMmBufferStatus(m_bufferProgress);
- }
-
- 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_bufferProgress);
- }
- }
-
- 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/multimedia/platform/qnx/mediaplayer/mmreventmediaplayercontrol_p.h b/src/multimedia/platform/qnx/mediaplayer/mmreventmediaplayercontrol_p.h
deleted file mode 100644
index d8e437b1d..000000000
--- a/src/multimedia/platform/qnx/mediaplayer/mmreventmediaplayercontrol_p.h
+++ /dev/null
@@ -1,95 +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
-
-//
-// 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 "mmrenderermediaplayercontrol_p.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_bufferProgress;
- 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/multimedia/platform/qnx/mediaplayer/mmreventthread.cpp b/src/multimedia/platform/qnx/mediaplayer/mmreventthread.cpp
deleted file mode 100644
index 25f26e216..000000000
--- a/src/multimedia/platform/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/multimedia/platform/qnx/mediaplayer/mmreventthread_p.h b/src/multimedia/platform/qnx/mediaplayer/mmreventthread_p.h
deleted file mode 100644
index 946548686..000000000
--- a/src/multimedia/platform/qnx/mediaplayer/mmreventthread_p.h
+++ /dev/null
@@ -1,90 +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
-
-//
-// 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 <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/multimedia/platform/qnx/qqnxdevicemanager.cpp b/src/multimedia/platform/qnx/qqnxdevicemanager.cpp
deleted file mode 100644
index 23bc0bcf0..000000000
--- a/src/multimedia/platform/qnx/qqnxdevicemanager.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qqnxmediadevices_p.h"
-#include "qmediadevices.h"
-#include "qcameradevice_p.h"
-
-#include "private/qqnxaudiosource_p.h"
-#include "private/qqnxaudiosink_p.h"
-#include "private/qqnxaudiodevice_p.h"
-#include "bbcamerasession_p.h"
-
-QT_BEGIN_NAMESPACE
-
-static QList<QCameraDevice> enumerateCameras()
-{
-
- 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 {};
- }
-
- QList<QCameraDevice> cameras;
- for (unsigned int i = 0; i < knownCameras; ++i) {
- QCameraDevicePrivate *p = new QCameraDevicePrivate;
- switch (cameras[i]) {
- case CAMERA_UNIT_FRONT:
- p->id = BbCameraSession::cameraIdentifierFront();
- p->description = tr("Front Camera");
- p->position = QCameraDevice::FrontFace;
- break;
- case CAMERA_UNIT_REAR:
- p->id = BbCameraSession::cameraIdentifierRear();
- p->description = tr("Rear Camera");
- p->position = QCameraDevice::BackFace;
- break;
- case CAMERA_UNIT_DESKTOP:
- p->id = devices->append(BbCameraSession::cameraIdentifierDesktop();
- p->description = tr("Desktop Camera");
- p->position = QCameraDevice::UnspecifiedPosition;
- break;
- default:
- break;
- }
- if (i == 0)
- p->isDefault = true;
- cameras.append(p->create());
- }
- return cameras;
-}
-
-QQnxMediaDevices::QQnxMediaDevices()
- : QMediaPlatformMediaDevices()
-{
-}
-
-QList<QAudioDevice> QQnxMediaDevices::audioInputs() const
-{
- return { QAudioDevice(new QnxAudioDeviceInfo("default", QAudioDevice::Input)) };
-}
-
-QList<QAudioDevice> QQnxMediaDevices::audioOutputs() const
-{
- return { QAudioDevice(new QnxAudioDeviceInfo("default", QAudioDevice::Output)) };
-}
-
-QList<QCameraDevice> QQnxMediaDevices::videoInputs() const
-{
- return enumerateCameras();
-}
-
-QPlatformAudioSource *QQnxMediaDevices::createAudioSource(const QAudioDevice &deviceInfo)
-{
- return new QQnxAudioSource();
-}
-
-QPlatformAudioSink *QQnxMediaDevices::createAudioSink(const QAudioDevice &deviceInfo)
-{
- return new QNxAudioOutput();
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qnx/qqnxdevicemanager_p.h b/src/multimedia/platform/qnx/qqnxdevicemanager_p.h
deleted file mode 100644
index a23d451c8..000000000
--- a/src/multimedia/platform/qnx/qqnxdevicemanager_p.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QQNXMEDIADEVICES_H
-#define QQNXMEDIADEVICES_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 <private/qplatformmediadevices_p.h>
-#include <qaudio.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQnxMediaDevices : public QPlatformMediaDevices
-{
-public:
- QQnxMediaDevices();
-
- QList<QAudioDevice> audioInputs() const override;
- QList<QAudioDevice> audioOutputs() const override;
- QList<QCameraDevice> videoInputs() const override;
- QPlatformAudioSource *createAudioSource(const QAudioDevice &deviceInfo) override;
- QPlatformAudioSink *createAudioSink(const QAudioDevice &deviceInfo) override;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qnx/qqnxintegration.cpp b/src/multimedia/platform/qnx/qqnxintegration.cpp
deleted file mode 100644
index 2e5496434..000000000
--- a/src/multimedia/platform/qnx/qqnxintegration.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qqnxintegration_p.h"
-#include "qqnxmediadevices_p.h"
-#include "private/mmrenderermediaplayercontrol_p.h"
-#include "private/mmrendererutil_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QQnxIntegration::QQnxIntegration()
-{
-
-}
-
-QQnxIntegration::~QQnxIntegration()
-{
- delete m_devices;
-}
-
-QMediaPlatformMediaDevices *QQnxIntegration::devices()
-{
- if (!m_devices)
- m_devices = new QQnxMediaDevices();
- return m_devices;
-}
-
-QPlatformMediaPlayer *QQnxIntegration::createPlayer(QMediaPlayer *parent)
-{
- return new MmRendererMediaPlayerControl(parent);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qnx/qqnxintegration_p.h b/src/multimedia/platform/qnx/qqnxintegration_p.h
deleted file mode 100644
index 8cc4ce9fb..000000000
--- a/src/multimedia/platform/qnx/qqnxintegration_p.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QQNXINTEGRATION_H
-#define QQNXINTEGRATION_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 <private/qplatformmediaintegration_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQnxMediaDevices;
-class QQnxPlayerInterface;
-
-class QQnxIntegration : public QPlatformMediaIntegration
-{
-public:
- QQnxIntegration();
- ~QQnxIntegration();
-
- QPlatformMediaDevices *devices() override;
-
- QPlatformMediaPlayer *createPlayer(QMediaPlayer *parent) override;
-
- QQnxMediaDevices *m_devices = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/qplatformaudiodecoder.cpp b/src/multimedia/platform/qplatformaudiodecoder.cpp
index 61492defb..0bf472410 100644
--- a/src/multimedia/platform/qplatformaudiodecoder.cpp
+++ b/src/multimedia/platform/qplatformaudiodecoder.cpp
@@ -1,122 +1,14 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qplatformaudiodecoder_p.h"
#include "qthread.h"
QT_BEGIN_NAMESPACE
+QPlatformAudioDecoder::QPlatformAudioDecoder(QAudioDecoder *parent) : q(parent) { }
-/*!
- \class QPlatformAudioDecoder
- \obsolete
- \inmodule QtMultimedia
-
-
- \ingroup multimedia_control
-
- \brief The QPlatformAudioDecoder class provides access to audio decoding
- functionality.
-
- \preliminary
-*/
-
-/*!
- Constructs a new audio decoder control with the given \a parent.
-*/
-QPlatformAudioDecoder::QPlatformAudioDecoder(QAudioDecoder *parent)
- : QObject(parent),
- q(parent)
-{
-}
-
-/*!
- \fn QPlatformAudioDecoder::source() const
-
- Returns the current media source filename, or a null QString if none (or a device)
-*/
-
-/*!
- \fn QPlatformAudioDecoder::setSource(const QUrl &fileName)
-
- Sets the current source to \a fileName. Changing the source will
- stop any current decoding and discard any buffers.
-
- Sources are exclusive, so only one can be set.
-*/
-
-/*!
- \fn QPlatformAudioDecoder::sourceDevice() const
-
- Returns the current media source QIODevice, or 0 if none (or a file).
-*/
-
-/*!
- \fn QPlatformAudioDecoder::setSourceDevice(QIODevice *device)
-
- Sets the current source to \a device. Changing the source will
- stop any current decoding and discard any buffers.
-
- Sources are exclusive, so only one can be set.
-*/
-
-/*!
- \fn QPlatformAudioDecoder::start()
-
- Starts decoding the current media.
-
- \sa read()
-*/
-
-/*!
- \fn QPlatformAudioDecoder::stop()
-
- Stops playback of the current media and discards any buffers.
-
- If successful, the player control will immediately stop decoding.
-*/
-
-/*!
- \fn QPlatformAudioDecoder::error(int error, const QString &errorString)
-
- Signals that an \a error has occurred. The \a errorString provides a more detailed explanation.
-*/
+QPlatformAudioDecoder::~QPlatformAudioDecoder() = default;
void QPlatformAudioDecoder::error(int error, const QString &errorString)
{
@@ -124,29 +16,25 @@ void QPlatformAudioDecoder::error(int error, const QString &errorString)
return;
m_error = QAudioDecoder::Error(error);
m_errorString = errorString;
- setIsDecoding(false);
- emit q->error(m_error);
+ if (m_error != QAudioDecoder::NoError) {
+ setIsDecoding(false);
+ emit q->error(m_error);
+ }
}
-/*!
- \fn QPlatformAudioDecoder::bufferAvailableChanged(bool available)
-
- Signals that the bufferAvailable property has changed to \a available.
-*/
void QPlatformAudioDecoder::bufferAvailableChanged(bool available)
{
+ if (m_bufferAvailable == available)
+ return;
+ m_bufferAvailable = available;
+
if (QThread::currentThread() != q->thread())
QMetaObject::invokeMethod(q, "bufferAvailableChanged", Qt::QueuedConnection, Q_ARG(bool, available));
else
emit q->bufferAvailableChanged(available);
}
-/*!
- \fn QPlatformAudioDecoder::bufferReady()
-
- Signals that a new buffer is ready for reading.
-*/
void QPlatformAudioDecoder::bufferReady()
{
if (QThread::currentThread() != q->thread())
@@ -155,82 +43,39 @@ void QPlatformAudioDecoder::bufferReady()
emit q->bufferReady();
}
-/*!
- \fn QPlatformAudioDecoder::sourceChanged()
-
- Signals that the current source of the decoder has changed.
-
- \sa source(), sourceDevice()
-*/
void QPlatformAudioDecoder::sourceChanged()
{
emit q->sourceChanged();
}
-/*!
- \fn QPlatformAudioDecoder::formatChanged(const QAudioFormat &format)
-
- Signals that the current audio format of the decoder has changed to \a format.
-*/
void QPlatformAudioDecoder::formatChanged(const QAudioFormat &format)
{
emit q->formatChanged(format);
}
-/*!
- \fn void QPlatformAudioDecoder::finished()
-
- Signals that the decoding has finished successfully.
- If decoding fails, error signal is emitted instead.
-
- \sa start(), stop(), error()
-*/
void QPlatformAudioDecoder::finished()
{
+ durationChanged(-1);
setIsDecoding(false);
emit q->finished();
}
-/*!
- \fn void QPlatformAudioDecoder::positionChanged(qint64 position)
-
- Signals that the current \a position of the decoder has changed.
-
- \sa durationChanged()
-*/
void QPlatformAudioDecoder::positionChanged(qint64 position)
{
- q->positionChanged(position);
+ if (m_position == position)
+ return;
+ m_position = position;
+ emit q->positionChanged(position);
}
-/*!
- \fn void QPlatformAudioDecoder::durationChanged(qint64 duration)
-
- Signals that the estimated \a duration of the decoded data has changed.
-
- \sa positionChanged()
-*/
void QPlatformAudioDecoder::durationChanged(qint64 duration)
{
- q->durationChanged(duration);
+ if (m_duration == duration)
+ return;
+ m_duration = duration;
+ emit q->durationChanged(duration);
}
-/*!
- \fn QPlatformAudioDecoder::read()
- Attempts to read a buffer from the decoder, without blocking. Returns invalid buffer if there are
- no decoded buffers available, or on error.
-*/
-
-/*!
- \fn QPlatformAudioDecoder::position() const
- Returns position (in milliseconds) of the last buffer read from
- the decoder or -1 if no buffers have been read.
-*/
-
-/*!
- \fn QPlatformAudioDecoder::duration() const
- Returns total duration (in milliseconds) of the audio stream
- or -1 if not available.
-*/
-
QT_END_NAMESPACE
+
+#include "moc_qplatformaudiodecoder_p.cpp"
diff --git a/src/multimedia/platform/qplatformaudiodecoder_p.h b/src/multimedia/platform/qplatformaudiodecoder_p.h
index b9334102a..1159a37ca 100644
--- a/src/multimedia/platform/qplatformaudiodecoder_p.h
+++ b/src/multimedia/platform/qplatformaudiodecoder_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QAUDIODECODERCONTROL_H
#define QAUDIODECODERCONTROL_H
@@ -51,12 +15,11 @@
// We mean it.
//
-#include <QtMultimedia/qaudiodecoder.h>
-
-#include <QtCore/qpair.h>
-
#include <QtMultimedia/qaudiobuffer.h>
#include <QtMultimedia/qaudiodecoder.h>
+#include <QtCore/qpair.h>
+#include <QtCore/qurl.h>
+#include <QtCore/private/qglobal_p.h>
QT_BEGIN_NAMESPACE
@@ -79,10 +42,10 @@ public:
virtual void setAudioFormat(const QAudioFormat &format) = 0;
virtual QAudioBuffer read() = 0;
- virtual bool bufferAvailable() const = 0;
+ virtual bool bufferAvailable() const { return m_bufferAvailable; }
- virtual qint64 position() const = 0;
- virtual qint64 duration() const = 0;
+ virtual qint64 position() const { return m_position; }
+ virtual qint64 duration() const { return m_duration; }
void formatChanged(const QAudioFormat &format);
@@ -108,14 +71,20 @@ public:
QAudioDecoder::Error error() const { return m_error; }
QString errorString() const { return m_errorString; }
+ virtual ~QPlatformAudioDecoder();
+
protected:
explicit QPlatformAudioDecoder(QAudioDecoder *parent);
+
private:
QAudioDecoder *q = nullptr;
+ qint64 m_duration = -1;
+ qint64 m_position = -1;
QAudioDecoder::Error m_error = QAudioDecoder::NoError;
QString m_errorString;
bool m_isDecoding = false;
+ bool m_bufferAvailable = false;
};
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qplatformaudioinput_p.h b/src/multimedia/platform/qplatformaudioinput_p.h
index c4e4334b3..d6497c06e 100644
--- a/src/multimedia/platform/qplatformaudioinput_p.h
+++ b/src/multimedia/platform/qplatformaudioinput_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPLATFORMAUDIOINPUT_H
#define QPLATFORMAUDIOINPUT_H
@@ -53,6 +17,8 @@
#include <private/qtmultimediaglobal_p.h>
#include <qaudiodevice.h>
+#include <functional>
+
QT_BEGIN_NAMESPACE
class QAudioInput;
@@ -60,10 +26,10 @@ class QAudioInput;
class Q_MULTIMEDIA_EXPORT QPlatformAudioInput
{
public:
- QPlatformAudioInput(QAudioInput *qq) : q(qq) {}
- virtual ~QPlatformAudioInput() {}
+ explicit QPlatformAudioInput(QAudioInput *qq) : q(qq) { }
+ virtual ~QPlatformAudioInput() = default;
- virtual void setAudioDevice(const QAudioDevice &/*device*/) {}
+ virtual void setAudioDevice(const QAudioDevice & /*device*/) { }
virtual void setMuted(bool /*muted*/) {}
virtual void setVolume(float /*volume*/) {}
@@ -71,6 +37,7 @@ public:
QAudioDevice device;
float volume = 1.;
bool muted = false;
+ std::function<void()> disconnectFunction;
};
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qplatformaudiooutput_p.h b/src/multimedia/platform/qplatformaudiooutput_p.h
index 594d59ed0..b8f5af6f3 100644
--- a/src/multimedia/platform/qplatformaudiooutput_p.h
+++ b/src/multimedia/platform/qplatformaudiooutput_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPLATFORMAUDIOOUTPUT_H
#define QPLATFORMAUDIOOUTPUT_H
@@ -60,8 +24,8 @@ class QAudioOutput;
class Q_MULTIMEDIA_EXPORT QPlatformAudioOutput
{
public:
- QPlatformAudioOutput(QAudioOutput *qq) : q(qq) {}
- virtual ~QPlatformAudioOutput() {}
+ explicit QPlatformAudioOutput(QAudioOutput *qq) : q(qq) { }
+ virtual ~QPlatformAudioOutput() = default;
virtual void setAudioDevice(const QAudioDevice &/*device*/) {}
virtual void setMuted(bool /*muted*/) {}
@@ -71,6 +35,7 @@ public:
QAudioDevice device;
float volume = 1.;
bool muted = false;
+ std::function<void()> disconnectFunction;
};
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qplatformaudioresampler_p.h b/src/multimedia/platform/qplatformaudioresampler_p.h
new file mode 100644
index 000000000..fd8edc2be
--- /dev/null
+++ b/src/multimedia/platform/qplatformaudioresampler_p.h
@@ -0,0 +1,33 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPLATFORMAUDIORESAMPLER_P_H
+#define QPLATFORMAUDIORESAMPLER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qtmultimediaglobal_p.h>
+#include <qaudiobuffer.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPlatformAudioResampler
+{
+public:
+ virtual ~QPlatformAudioResampler() = default;
+
+ virtual QAudioBuffer resample(const char *data, size_t size) = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPLATFORMAUDIORESAMPLER_P_H
diff --git a/src/multimedia/platform/qplatformcamera.cpp b/src/multimedia/platform/qplatformcamera.cpp
index 21a13ea97..d03c19d67 100644
--- a/src/multimedia/platform/qplatformcamera.cpp
+++ b/src/multimedia/platform/qplatformcamera.cpp
@@ -1,93 +1,59 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qplatformcamera_p.h"
+#include "private/qcameradevice_p.h"
QT_BEGIN_NAMESPACE
-/*!
- \class QPlatformCamera
- \obsolete
-
+QPlatformCamera::QPlatformCamera(QCamera *parent) : QPlatformVideoSource(parent), m_camera(parent)
+{
+ qRegisterMetaType<QVideoFrame>();
+}
+QCameraFormat QPlatformCamera::findBestCameraFormat(const QCameraDevice &camera) const
+{
+ // check if fmt is better. We try to find the highest resolution that offers
+ // at least 30 FPS
+ // we use 29 FPS to compare against as some cameras report 29.97 FPS...
- \brief The QPlatformCamera class is an abstract base class for
- classes that control still cameras or video cameras.
+ auto makeCriteria = [this](const QCameraFormat &fmt) {
+ constexpr float MinSufficientFrameRate = 29.f;
- \inmodule QtMultimedia
+ const auto isValid = fmt.pixelFormat() != QVideoFrameFormat::Format_Invalid;
+ const auto resolution = fmt.resolution();
+ const auto sufficientFrameRate = std::min(fmt.maxFrameRate(), MinSufficientFrameRate);
+ const auto pixelFormatScore =
+ cameraPixelFormatScore(fmt.pixelFormat(), QCameraFormatPrivate::getColorRange(fmt));
- \ingroup multimedia_control
-*/
+ return std::make_tuple(
+ isValid, // 1st: ensure valid formats
+ sufficientFrameRate, // 2nd: ensure the highest frame rate in the range [0; 29]*/
+ resolution.width() * resolution.height(), // 3rd: ensure the highest resolution
+ pixelFormatScore, // 4th: eshure the best pixel format
+ fmt.maxFrameRate()); // 5th: ensure the highest framerate in the whole range
+ };
-/*!
- Constructs a camera control object with \a parent.
-*/
+ const auto formats = camera.videoFormats();
+ const auto found =
+ std::max_element(formats.begin(), formats.end(),
+ [makeCriteria](const QCameraFormat &fmtA, const QCameraFormat &fmtB) {
+ return makeCriteria(fmtA) < makeCriteria(fmtB);
+ });
-QPlatformCamera::QPlatformCamera(QCamera *parent)
- : QObject(parent),
- m_camera(parent)
-{
+ return found == formats.end() ? QCameraFormat{} : *found;
}
-QCameraFormat QPlatformCamera::findBestCameraFormat(const QCameraDevice &camera)
+QVideoFrameFormat QPlatformCamera::frameFormat() const
{
- QCameraFormat f;
- const auto formats = camera.videoFormats();
- for (const auto &fmt : formats) {
- // check if fmt is better. We try to find the highest resolution that offers
- // at least 30 FPS
- if (f.maxFrameRate() < 30 && fmt.maxFrameRate() > f.maxFrameRate())
- f = fmt;
- else if (f.maxFrameRate() == fmt.maxFrameRate() &&
- f.resolution().width()*f.resolution().height() < fmt.resolution().width()*fmt.resolution().height())
- f = fmt;
- }
- return f;
+ QVideoFrameFormat result(m_cameraFormat.resolution(),
+ m_framePixelFormat == QVideoFrameFormat::Format_Invalid
+ ? m_cameraFormat.pixelFormat()
+ : m_framePixelFormat);
+ result.setStreamFrameRate(m_cameraFormat.maxFrameRate());
+ return result;
}
-/*!
- \fn void QPlatformCamera::error(int error, const QString &errorString)
-
- Signal emitted when an error occurs with error code \a error and
- a description of the error \a errorString.
-*/
-
void QPlatformCamera::supportedFeaturesChanged(QCamera::Features f)
{
if (m_supportedFeatures == f)
@@ -255,7 +221,12 @@ int QPlatformCamera::colorTemperatureForWhiteBalance(QCamera::WhiteBalanceMode m
return 0;
}
-
+void QPlatformCamera::updateError(QCamera::Error error, const QString &errorString)
+{
+ QMetaObject::invokeMethod(this, [this, error, errorString]() {
+ m_error.setAndNotify(error, errorString, *this);
+ });
+}
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qplatformcamera_p.h b/src/multimedia/platform/qplatformcamera_p.h
index 8ddaf51ae..341bf9121 100644
--- a/src/multimedia/platform/qplatformcamera_p.h
+++ b/src/multimedia/platform/qplatformcamera_p.h
@@ -1,44 +1,8 @@
-/****************************************************************************
-**
-** 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 QCAMERACONTROL_H
-#define QCAMERACONTROL_H
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPLATFORMCAMERA_H
+#define QPLATFORMCAMERA_H
//
// W A R N I N G
@@ -51,25 +15,20 @@
// We mean it.
//
-#include <QtCore/qobject.h>
-#include <QtMultimedia/qtmultimediaglobal.h>
-
+#include "qplatformvideosource_p.h"
+#include "private/qerrorinfo_p.h"
#include <QtMultimedia/qcamera.h>
QT_BEGIN_NAMESPACE
-class Q_MULTIMEDIA_EXPORT QPlatformCamera : public QObject
+class Q_MULTIMEDIA_EXPORT QPlatformCamera : public QPlatformVideoSource
{
Q_OBJECT
public:
- virtual bool isActive() const = 0;
- virtual void setActive(bool active) = 0;
-
virtual void setCamera(const QCameraDevice &camera) = 0;
virtual bool setCameraFormat(const QCameraFormat &/*format*/) { return false; }
-
- virtual void setCaptureSession(QPlatformMediaCaptureSession *) {}
+ QCameraFormat cameraFormat() const { return m_cameraFormat; }
virtual bool isFocusModeSupported(QCamera::FocusMode mode) const { return mode == QCamera::FocusModeAuto; }
virtual void setFocusMode(QCamera::FocusMode /*mode*/) {}
@@ -100,6 +59,8 @@ public:
virtual void setWhiteBalanceMode(QCamera::WhiteBalanceMode /*mode*/) {}
virtual void setColorTemperature(int /*temperature*/) {}
+ QVideoFrameFormat frameFormat() const override;
+
QCamera::Features supportedFeatures() const { return m_supportedFeatures; }
QCamera::FocusMode focusMode() const { return m_focusMode; }
@@ -149,14 +110,27 @@ public:
static int colorTemperatureForWhiteBalance(QCamera::WhiteBalanceMode mode);
+ QCamera::Error error() const { return m_error.code(); }
+ QString errorString() const final { return m_error.description(); }
+
+ void updateError(QCamera::Error error, const QString &errorString);
+
Q_SIGNALS:
- void activeChanged(bool);
- void error(int error, const QString &errorString);
+ void errorOccurred(QCamera::Error error, const QString &errorString);
protected:
explicit QPlatformCamera(QCamera *parent);
- static QCameraFormat findBestCameraFormat(const QCameraDevice &camera);
+ virtual int cameraPixelFormatScore(QVideoFrameFormat::PixelFormat /*format*/,
+ QVideoFrameFormat::ColorRange /*colorRange*/) const
+ {
+ return 0;
+ }
+
+ QCameraFormat findBestCameraFormat(const QCameraDevice &camera) const;
+ QCameraFormat m_cameraFormat;
+ QVideoFrameFormat::PixelFormat m_framePixelFormat = QVideoFrameFormat::Format_Invalid;
+
private:
QCamera *m_camera = nullptr;
QCamera::Features m_supportedFeatures = {};
@@ -181,10 +155,11 @@ private:
float m_maxExposureTime = -1.;
QCamera::WhiteBalanceMode m_whiteBalance = QCamera::WhiteBalanceAuto;
int m_colorTemperature = 0;
+ QErrorInfo<QCamera::Error> m_error;
};
QT_END_NAMESPACE
-#endif // QCAMERACONTROL_H
+#endif // QPLATFORMCAMERA_H
diff --git a/src/multimedia/platform/qplatformcapturablewindows_p.h b/src/multimedia/platform/qplatformcapturablewindows_p.h
new file mode 100644
index 000000000..41949aaac
--- /dev/null
+++ b/src/multimedia/platform/qplatformcapturablewindows_p.h
@@ -0,0 +1,44 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPLATFORMCAPTURABLEWINDOWS_P_H
+#define QPLATFORMCAPTURABLEWINDOWS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qtmultimediaglobal_p.h"
+#include "qcapturablewindow.h"
+
+#include <qlist.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCapturableWindow;
+class QCapturableWindowPrivate;
+
+class QPlatformCapturableWindows
+{
+public:
+ QPlatformCapturableWindows() = default;
+
+ virtual ~QPlatformCapturableWindows() = default;
+
+ virtual QList<QCapturableWindow> windows() const { return {}; }
+
+ virtual bool isWindowValid(const QCapturableWindowPrivate &) const { return false; }
+
+ Q_DISABLE_COPY(QPlatformCapturableWindows);
+};
+
+QT_END_NAMESPACE
+
+#endif // QPLATFORMCAPTURABLEWINDOWS_P_H
diff --git a/src/multimedia/platform/qplatformimagecapture.cpp b/src/multimedia/platform/qplatformimagecapture.cpp
index 5cfc7e31e..5d8349256 100644
--- a/src/multimedia/platform/qplatformimagecapture.cpp
+++ b/src/multimedia/platform/qplatformimagecapture.cpp
@@ -1,58 +1,16 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qplatformimagecapture_p.h"
#include <QtCore/qstringlist.h>
QT_BEGIN_NAMESPACE
-/*!
- \class QPlatformImageCapture
- \obsolete
-
- \brief The QPlatformImageCapture class provides a control interface
- for image capture services.
-
- \inmodule QtMultimedia
- \ingroup multimedia_control
-
-*/
+QPlatformImageCapture::QPlatformImageCapture(QImageCapture *parent)
+ : QObject(parent),
+ m_imageCapture(parent)
+{
+}
QString QPlatformImageCapture::msgCameraNotReady()
{
@@ -64,114 +22,6 @@ QString QPlatformImageCapture::msgImageCaptureNotSet()
return QImageCapture::tr("No instance of QImageCapture set on QMediaCaptureSession.");
}
-/*!
- Constructs a new image capture control object with the given \a parent
-*/
-QPlatformImageCapture::QPlatformImageCapture(QImageCapture *parent)
- : QObject(parent),
- m_imageCapture(parent)
-{
-}
-
-/*!
- \fn QPlatformImageCapture::isReadyForCapture() const
-
- Identifies if a capture control is ready to perform a capture
- immediately (all the resources necessary for image capture are allocated,
- hardware initialized, flash is charged, etc).
-
- Returns true if the camera is ready for capture; and false if it is not.
-
- It's permissible to call capture() while the camera status is QCamera::ActiveStatus
- regardless of isReadyForCapture property value.
- If camera is not ready to capture image immediately,
- the capture request is queued with all the related camera settings
- to be executed as soon as possible.
-*/
-
-/*!
- \fn QPlatformImageCapture::readyForCaptureChanged(bool ready)
-
- Signals that a capture control's \a ready state has changed.
-*/
-
-/*!
- \fn QPlatformImageCapture::capture(const QString &fileName)
-
- Initiates the capture of an image to \a fileName.
- The \a fileName can be relative or empty,
- in this case the service should use the system specific place
- and file naming scheme.
-
- The Camera service should save all the capture parameters
- like exposure settings or image processing parameters,
- so changes to camera parameters after capture() is called
- do not affect previous capture requests.
-
- Returns the capture request id number, which is used later
- with imageExposed(), imageCaptured() and imageSaved() signals.
-*/
-
-/*!
- \fn QPlatformImageCapture::imageExposed(int requestId)
-
- Signals that an image with it \a requestId
- has just been exposed.
- This signal can be used for the shutter sound or other indicaton.
-*/
-
-/*!
- \fn QPlatformImageCapture::imageCaptured(int requestId, const QImage &preview)
-
- Signals that an image with it \a requestId
- has been captured and a \a preview is available.
-*/
-
-/*!
- \fn QPlatformImageCapture::imageMetadataAvailable(int id, const QMediaMetaData &metaData)
-
- Signals that a metadata for an image with request \a id is available.
-
- This signal should be emitted between imageExposed and imageSaved signals.
-*/
-
-/*!
- \fn QPlatformImageCapture::imageAvailable(int requestId, const QVideoFrame &buffer)
-
- Signals that a captured \a buffer with a \a requestId is available.
-*/
-
-/*!
- \fn QPlatformImageCapture::imageSaved(int requestId, const QString &fileName)
-
- Signals that a captured image with a \a requestId has been saved
- to \a fileName.
-*/
-
-/*!
- \fn QPlatformImageCapture::imageSettings() const
-
- Returns the currently used image encoder settings.
-
- The returned value may be different than passed to setImageSettings()
- if the settings contains defaulted or undefined parameters.
-*/
-
-/*!
- \fn QPlatformImageCapture::setImageSettings(const QImageEncoderSettings &settings)
-
- Sets the selected image encoder \a settings.
-*/
-
-/*!
- \fn QPlatformImageCapture::error(int id, int error, const QString &errorString)
-
- Signals the capture request \a id failed with \a error code and message \a errorString.
-
- \sa QImageCapture::Error
-*/
-
-
QT_END_NAMESPACE
#include "moc_qplatformimagecapture_p.cpp"
diff --git a/src/multimedia/platform/qplatformimagecapture_p.h b/src/multimedia/platform/qplatformimagecapture_p.h
index 01842987d..5bfb15ced 100644
--- a/src/multimedia/platform/qplatformimagecapture_p.h
+++ b/src/multimedia/platform/qplatformimagecapture_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCAMERAIMAGECAPTURECONTROL_H
#define QCAMERAIMAGECAPTURECONTROL_H
@@ -54,6 +18,7 @@
#include <QtMultimedia/qimagecapture.h>
#include <QtMultimedia/qmediametadata.h>
#include <QtMultimedia/qimagecapture.h>
+#include <QtCore/private/qglobal_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/multimedia/platform/qplatformmediacapture.cpp b/src/multimedia/platform/qplatformmediacapture.cpp
index b041f69db..c8aded824 100644
--- a/src/multimedia/platform/qplatformmediacapture.cpp
+++ b/src/multimedia/platform/qplatformmediacapture.cpp
@@ -1,52 +1,44 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 <qtmultimediaglobal_p.h>
-#include "qplatformmediacapture_p.h"
-#include "qaudiodevice.h"
-#include "qaudioinput.h"
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include <QtMultimedia/qaudiodevice.h>
+#include <QtMultimedia/qaudioinput.h>
+#include <QtMultimedia/qmediacapturesession.h>
+#include <QtMultimedia/private/qplatformcamera_p.h>
+#include <QtMultimedia/private/qplatformmediacapture_p.h>
+#include <QtMultimedia/private/qmediacapturesession_p.h>
+#include <QtMultimedia/private/qplatformsurfacecapture_p.h>
+#include <QtMultimedia/private/qtmultimediaglobal_p.h>
QT_BEGIN_NAMESPACE
-QPlatformMediaCaptureSession::~QPlatformMediaCaptureSession()
+QPlatformMediaCaptureSession::~QPlatformMediaCaptureSession() = default;
+
+std::vector<QPlatformVideoSource *> QPlatformMediaCaptureSession::activeVideoSources()
{
+ std::vector<QPlatformVideoSource *> result;
+
+ auto checkSource = [&result](QPlatformVideoSource *source) {
+ if (source && source->isActive())
+ result.push_back(source);
+ };
+
+ checkSource(camera());
+ checkSource(screenCapture());
+ checkSource(windowCapture());
+
+ return result;
+}
+
+void *QPlatformMediaCaptureSession::nativePipeline(QMediaCaptureSession *session)
+{
+ auto sessionPrivate = session->d_func();
+ if (!sessionPrivate || !sessionPrivate->captureSession)
+ return nullptr;
+
+ return sessionPrivate->captureSession->nativePipeline();
}
QT_END_NAMESPACE
+#include "moc_qplatformmediacapture_p.cpp"
diff --git a/src/multimedia/platform/qplatformmediacapture_p.h b/src/multimedia/platform/qplatformmediacapture_p.h
index a988f3de4..981cf199b 100644
--- a/src/multimedia/platform/qplatformmediacapture_p.h
+++ b/src/multimedia/platform/qplatformmediacapture_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPLATFORMMEDIACAPTURE_H
#define QPLATFORMMEDIACAPTURE_H
@@ -56,28 +20,40 @@
QT_BEGIN_NAMESPACE
class QPlatformCamera;
class QPlatformImageCapture;
-class QPlatformMediaEncoder;
+class QPlatformMediaRecorder;
class QAudioDevice;
class QCameraDevice;
class QVideoSink;
class QPlatformAudioInput;
class QPlatformAudioOutput;
+class QMediaCaptureSession;
+class QPlatformSurfaceCapture;
+class QPlatformVideoSource;
class Q_MULTIMEDIA_EXPORT QPlatformMediaCaptureSession : public QObject
{
Q_OBJECT
public:
QPlatformMediaCaptureSession() = default;
- virtual ~QPlatformMediaCaptureSession();
+ ~QPlatformMediaCaptureSession() override;
+
+ void setCaptureSession(QMediaCaptureSession *session) { m_session = session; }
+ QMediaCaptureSession *captureSession() const { return m_session; }
virtual QPlatformCamera *camera() = 0;
virtual void setCamera(QPlatformCamera *) {}
+ virtual QPlatformSurfaceCapture *screenCapture() { return nullptr; }
+ virtual void setScreenCapture(QPlatformSurfaceCapture *) {}
+
+ virtual QPlatformSurfaceCapture *windowCapture() { return nullptr; }
+ virtual void setWindowCapture(QPlatformSurfaceCapture *) { }
+
virtual QPlatformImageCapture *imageCapture() = 0;
virtual void setImageCapture(QPlatformImageCapture *) {}
- virtual QPlatformMediaEncoder *mediaEncoder() = 0;
- virtual void setMediaEncoder(QPlatformMediaEncoder *) {}
+ virtual QPlatformMediaRecorder *mediaRecorder() = 0;
+ virtual void setMediaRecorder(QPlatformMediaRecorder *) {}
virtual void setAudioInput(QPlatformAudioInput *input) = 0;
@@ -85,10 +61,23 @@ public:
virtual void setAudioOutput(QPlatformAudioOutput *) {}
+ // TBD: implement ordering of the sources basing on the order of adding
+ std::vector<QPlatformVideoSource *> activeVideoSources();
+
+ virtual void *nativePipeline() { return nullptr; }
+
+ // private API, the purpose is getting GstPipeline
+ static void *nativePipeline(QMediaCaptureSession *);
+
Q_SIGNALS:
void cameraChanged();
+ void screenCaptureChanged();
+ void windowCaptureChanged();
void imageCaptureChanged();
void encoderChanged();
+
+private:
+ QMediaCaptureSession *m_session = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qplatformmediadevices.cpp b/src/multimedia/platform/qplatformmediadevices.cpp
index 4ac1ec14c..a6029228d 100644
--- a/src/multimedia/platform/qplatformmediadevices.cpp
+++ b/src/multimedia/platform/qplatformmediadevices.cpp
@@ -1,125 +1,114 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qplatformmediadevices_p.h"
-#include "qmediadevices.h"
-#include "qaudiodevice.h"
+#include "qplatformmediaintegration_p.h"
#include "qcameradevice.h"
#include "qaudiosystem_p.h"
+#include "qaudiodevice.h"
+#include "qplatformvideodevices_p.h"
+
+#if defined(Q_OS_ANDROID)
+#include <qandroidmediadevices_p.h>
+#elif defined(Q_OS_DARWIN)
+#include <qdarwinmediadevices_p.h>
+#elif defined(Q_OS_WINDOWS) && QT_CONFIG(wmf)
+#include <qwindowsmediadevices_p.h>
+#elif QT_CONFIG(alsa)
+#include <qalsamediadevices_p.h>
+#elif QT_CONFIG(pulseaudio)
+#include <qpulseaudiomediadevices_p.h>
+#elif defined(Q_OS_QNX)
+#include <qqnxmediadevices_p.h>
+#elif defined(Q_OS_WASM)
+#include <private/qwasmmediadevices_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
+std::unique_ptr<QPlatformMediaDevices> QPlatformMediaDevices::create()
+{
+#ifdef Q_OS_DARWIN
+ return std::make_unique<QDarwinMediaDevices>();
+#elif defined(Q_OS_WINDOWS) && QT_CONFIG(wmf)
+ return std::make_unique<QWindowsMediaDevices>();
+#elif defined(Q_OS_ANDROID)
+ return std::make_unique<QAndroidMediaDevices>();
+#elif QT_CONFIG(alsa)
+ return std::make_unique<QAlsaMediaDevices>();
+#elif QT_CONFIG(pulseaudio)
+ return std::make_unique<QPulseAudioMediaDevices>();
+#elif defined(Q_OS_QNX)
+ return std::make_unique<QQnxMediaDevices>();
+#elif defined(Q_OS_WASM)
+ return std::make_unique<QWasmMediaDevices>();
+#else
+ return std::make_unique<QPlatformMediaDevices>();
+#endif
+}
+
QPlatformMediaDevices::QPlatformMediaDevices() = default;
+void QPlatformMediaDevices::initVideoDevicesConnection()
+{
+ // Make sure we are notified if video inputs changed
+ if (const auto videoDevices = QPlatformMediaIntegration::instance()->videoDevices())
+ connect(videoDevices, &QPlatformVideoDevices::videoInputsChanged, this,
+ &QPlatformMediaDevices::videoInputsChanged, Qt::UniqueConnection);
+}
+
QPlatformMediaDevices::~QPlatformMediaDevices() = default;
-QAudioDevice QPlatformMediaDevices::audioInput(const QByteArray &id) const
+QList<QAudioDevice> QPlatformMediaDevices::audioInputs() const
{
- const auto inputs = audioInputs();
- for (auto i : inputs) {
- if (i.id() == id)
- return i;
- }
return {};
}
-QAudioDevice QPlatformMediaDevices::audioOutput(const QByteArray &id) const
+QList<QAudioDevice> QPlatformMediaDevices::audioOutputs() const
{
- const auto outputs = audioOutputs();
- for (auto o : outputs) {
- if (o.id() == id)
- return o;
- }
return {};
}
-QCameraDevice QPlatformMediaDevices::videoInput(const QByteArray &id) const
+QPlatformAudioSource *QPlatformMediaDevices::createAudioSource(const QAudioDevice &, QObject *)
+{
+ return nullptr;
+}
+QPlatformAudioSink *QPlatformMediaDevices::createAudioSink(const QAudioDevice &, QObject *)
{
- const auto inputs = videoInputs();
- for (auto i : inputs) {
- if (i.id() == id)
- return i;
- }
- return QCameraDevice();
+ return nullptr;
}
-QPlatformAudioSource* QPlatformMediaDevices::audioInputDevice(const QAudioFormat &format, const QAudioDevice &deviceInfo)
+QPlatformAudioSource *QPlatformMediaDevices::audioInputDevice(const QAudioFormat &format,
+ const QAudioDevice &deviceInfo,
+ QObject *parent)
{
QAudioDevice info = deviceInfo;
if (info.isNull())
info = audioInputs().value(0);
- QPlatformAudioSource* p = createAudioSource(info);
+ QPlatformAudioSource* p = !info.isNull() ? createAudioSource(info, parent) : nullptr;
if (p)
p->setFormat(format);
return p;
}
-QPlatformAudioSink* QPlatformMediaDevices::audioOutputDevice(const QAudioFormat &format, const QAudioDevice &deviceInfo)
+QPlatformAudioSink *QPlatformMediaDevices::audioOutputDevice(const QAudioFormat &format,
+ const QAudioDevice &deviceInfo,
+ QObject *parent)
{
QAudioDevice info = deviceInfo;
if (info.isNull())
info = audioOutputs().value(0);
- QPlatformAudioSink* p = createAudioSink(info);
+ QPlatformAudioSink* p = !info.isNull() ? createAudioSink(info, parent) : nullptr;
if (p)
p->setFormat(format);
return p;
}
-void QPlatformMediaDevices::audioInputsChanged() const
-{
- for (auto m : m_devices)
- emit m->audioInputsChanged();
-}
-
-void QPlatformMediaDevices::audioOutputsChanged() const
-{
- for (auto m : m_devices)
- emit m->audioOutputsChanged();
-}
-
-void QPlatformMediaDevices::videoInputsChanged() const
-{
- for (auto m : m_devices)
- emit m->videoInputsChanged();
-}
-
+void QPlatformMediaDevices::prepareAudio() { }
QT_END_NAMESPACE
+
+#include "moc_qplatformmediadevices_p.cpp"
diff --git a/src/multimedia/platform/qplatformmediadevices_p.h b/src/multimedia/platform/qplatformmediadevices_p.h
index 62b7229ab..0de41a973 100644
--- a/src/multimedia/platform/qplatformmediadevices_p.h
+++ b/src/multimedia/platform/qplatformmediadevices_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPLATFORMMEDIADEVICES_H
#define QPLATFORMMEDIADEVICES_H
@@ -53,51 +17,44 @@
#include <private/qtmultimediaglobal_p.h>
#include <qlist.h>
+#include <qobject.h>
+#include <memory>
QT_BEGIN_NAMESPACE
-class QMediaDevices;
class QAudioDevice;
-class QCameraDevice;
class QPlatformAudioSource;
class QPlatformAudioSink;
class QAudioFormat;
-class Q_MULTIMEDIA_EXPORT QPlatformMediaDevices
+class Q_MULTIMEDIA_EXPORT QPlatformMediaDevices : public QObject
{
+ Q_OBJECT
public:
QPlatformMediaDevices();
- virtual ~QPlatformMediaDevices();
-
- virtual QList<QAudioDevice> audioInputs() const = 0;
- virtual QList<QAudioDevice> audioOutputs() const = 0;
- virtual QList<QCameraDevice> videoInputs() const = 0;
- virtual QPlatformAudioSource *createAudioSource(const QAudioDevice &deviceInfo) = 0;
- virtual QPlatformAudioSink *createAudioSink(const QAudioDevice &deviceInfo) = 0;
-
- QAudioDevice audioInput(const QByteArray &id) const;
- QAudioDevice audioOutput(const QByteArray &id) const;
- QCameraDevice videoInput(const QByteArray &id) const;
-
- QPlatformAudioSource *audioInputDevice(const QAudioFormat &format, const QAudioDevice &deviceInfo);
- QPlatformAudioSink *audioOutputDevice(const QAudioFormat &format, const QAudioDevice &deviceInfo);
-
- void addDevices(QMediaDevices *m)
- {
- m_devices.append(m);
- }
- void removeDevices(QMediaDevices *m)
- {
- m_devices.removeAll(m);
- }
-
-protected:
- void audioInputsChanged() const;
- void audioOutputsChanged() const;
- void videoInputsChanged() const;
-
-private:
- QList<QMediaDevices *> m_devices;
+ ~QPlatformMediaDevices() override;
+
+ static std::unique_ptr<QPlatformMediaDevices> create();
+
+ virtual QList<QAudioDevice> audioInputs() const;
+ virtual QList<QAudioDevice> audioOutputs() const;
+
+ virtual QPlatformAudioSource *createAudioSource(const QAudioDevice &, QObject *parent);
+ virtual QPlatformAudioSink *createAudioSink(const QAudioDevice &, QObject *parent);
+
+ QPlatformAudioSource *audioInputDevice(const QAudioFormat &format,
+ const QAudioDevice &deviceInfo, QObject *parent);
+ QPlatformAudioSink *audioOutputDevice(const QAudioFormat &format,
+ const QAudioDevice &deviceInfo, QObject *parent);
+
+ virtual void prepareAudio();
+
+ void initVideoDevicesConnection();
+
+Q_SIGNALS:
+ void audioInputsChanged();
+ void audioOutputsChanged();
+ void videoInputsChanged();
};
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qplatformmediaencoder.cpp b/src/multimedia/platform/qplatformmediaencoder.cpp
deleted file mode 100644
index b803740c3..000000000
--- a/src/multimedia/platform/qplatformmediaencoder.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 "qplatformmediaencoder_p.h"
-#include <QObject>
-
-QT_BEGIN_NAMESPACE
-
-
-/*!
- \class QPlatformMediaEncoder
- \obsolete
- \inmodule QtMultimedia
-
-
- \ingroup multimedia_control
-
- \brief The QPlatformMediaEncoder class provides access to the recording
- functionality.
-
- This control provides a means to set the \l {outputLocation()}{output location},
- and record(), pause(), resume(), and stop() recording. It also
- provides feedback on the \l {duration()}{duration} of the recording.
-
- \sa QMediaRecorder
-
-*/
-
-/*!
- Constructs a media recorder control with the given \a parent.
-*/
-
-QPlatformMediaEncoder::QPlatformMediaEncoder(QMediaRecorder *parent)
- : q(parent)
-{
-}
-
-/*!
- \fn QUrl QPlatformMediaEncoder::outputLocation() const
-
- Returns the current output location being used.
-*/
-
-/*!
- \fn bool QPlatformMediaEncoder::setOutputLocation(const QUrl &location)
-
- Sets the output \a location and returns if this operation is successful.
- If file at the output location already exists, it should be overwritten.
-
- The \a location can be relative or empty;
- in this case the service should use the system specific place and file naming scheme.
-
- After recording has started, the backend should report the actual file location
- with actualLocationChanged() signal.
-*/
-
-/*!
- \fn QMediaRecorder::RecorderState QPlatformMediaEncoder::state() const
-
- Return the current recording state.
-*/
-
-/*!
- \fn qint64 QPlatformMediaEncoder::duration() const
-
- Return the current duration in milliseconds.
-*/
-
-/*!
- \fn void QPlatformMediaEncoder::record(QMediaEncoderSettings &settings)
-
- Start media recording in accordance with \a{settings}.
-*/
-
-/*!
- \fn void QPlatformMediaEncoder::pause()
-
- Pause media recording. Not all platforms supports this operation
-*/
-void QPlatformMediaEncoder::pause() {
- error(QMediaRecorder::FormatError, QMediaRecorder::tr("Pause not supported"));
-}
-
-/*!
- \fn void QPlatformMediaEncoder::resume()
-
- Resume media recording. Not all platforms supports this operation
-*/
-void QPlatformMediaEncoder::resume() {
- error(QMediaRecorder::FormatError, QMediaRecorder::tr("Resume not supported"));
-}
-
-/*!
- \fn void QPlatformMediaEncoder::stop()
-
- Stop media recording
-*/
-
-/*!
- \fn void QPlatformMediaEncoder::stateChanged(QMediaRecorder::RecorderState state)
-
- Signals that the \a state of a media recorder has changed.
-*/
-void QPlatformMediaEncoder::stateChanged(QMediaRecorder::RecorderState state)
-{
- if (m_state == state)
- return;
- m_state = state;
- emit q->recorderStateChanged(state);
-}
-
-/*!
- \fn void QPlatformMediaEncoder::durationChanged(qint64 duration)
-
- Signals that the \a duration of the recorded media has changed.
-
- This only emitted when there is a discontinuous change in the duration such as being reset to 0.
-*/
-void QPlatformMediaEncoder::durationChanged(qint64 duration)
-{
- emit q->durationChanged(duration);
-}
-
-/*!
- \fn void QPlatformMediaEncoder::actualLocationChanged(const QUrl &location)
-
- Signals that the actual media \a location has changed.
- This signal should be emitted at start of recording.
-*/
-void QPlatformMediaEncoder::actualLocationChanged(const QUrl &location)
-{
- if (m_actualLocation == location)
- return;
- m_actualLocation = location;
- emit q->actualLocationChanged(location);
-}
-
-/*!
- \fn void QPlatformMediaEncoder::error(QMediaRecorder::Error error, const QString &errorString)
-
- Signals that an \a error has occurred. The \a errorString describes the error.
-*/
-void QPlatformMediaEncoder::error(QMediaRecorder::Error error, const QString &errorString)
-{
- if (error == m_error && errorString == m_errorString)
- return;
- m_error = error;
- m_errorString = errorString;
- if (error != QMediaRecorder::NoError)
- emit q->errorOccurred(error, errorString);
- emit q->errorChanged();
-}
-
-void QPlatformMediaEncoder::metaDataChanged()
-{
- emit q->metaDataChanged();
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qplatformmediaformatinfo.cpp b/src/multimedia/platform/qplatformmediaformatinfo.cpp
index d4bfecafc..e69b32ed3 100644
--- a/src/multimedia/platform/qplatformmediaformatinfo.cpp
+++ b/src/multimedia/platform/qplatformmediaformatinfo.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qplatformmediaformatinfo_p.h"
#include <qset.h>
diff --git a/src/multimedia/platform/qplatformmediaformatinfo_p.h b/src/multimedia/platform/qplatformmediaformatinfo_p.h
index 8842304ca..4229a3c4c 100644
--- a/src/multimedia/platform/qplatformmediaformatinfo_p.h
+++ b/src/multimedia/platform/qplatformmediaformatinfo_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPLATFORMMEDIAFORMATINFO_H
#define QPLATFORMMEDIAFORMATINFO_H
diff --git a/src/multimedia/platform/qplatformmediaintegration.cpp b/src/multimedia/platform/qplatformmediaintegration.cpp
index c3b4f1444..4bacc488f 100644
--- a/src/multimedia/platform/qplatformmediaintegration.cpp
+++ b/src/multimedia/platform/qplatformmediaintegration.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <qtmultimediaglobal_p.h>
#include "qplatformmediaintegration_p.h"
@@ -43,88 +7,216 @@
#include <qmutex.h>
#include <qplatformaudioinput_p.h>
#include <qplatformaudiooutput_p.h>
+#include <qplatformaudioresampler_p.h>
+#include <qplatformvideodevices_p.h>
+#include <qmediadevices.h>
+#include <qcameradevice.h>
+#include <qloggingcategory.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qapplicationstatic.h>
-#if QT_CONFIG(gstreamer)
-#include <private/qgstreamerintegration_p.h>
-using PlatformIntegration = QGstreamerIntegration;
-#elif QT_CONFIG(pulseaudio)
-#include <private/qpulseaudiointegration_p.h>
-using PlatformIntegration = QPulseAudioIntegration;
-#elif QT_CONFIG(alsa)
-#include <private/qalsaintegration_p.h>
-using PlatformIntegration = QAlsaIntegration;
-#elif QT_CONFIG(avfoundation)
-#include <private/qdarwinintegration_p.h>
-using PlatformIntegration = QDarwinIntegration;
-#elif QT_CONFIG(wmf)
-#include <private/qwindowsintegration_p.h>
-using PlatformIntegration = QWindowsMediaIntegration;
-#elif defined(Q_OS_ANDROID)
-#include <private/qandroidintegration_p.h>
-using PlatformIntegration = QAndroidIntegration;
-#elif defined(Q_OS_WASM)
-#include <private/qwasmmediaintegration_p.h>
-using PlatformIntegration = QWasmMediaIntegration;
-#else
-class QDummyIntegration : public QPlatformMediaIntegration
+#include "qplatformcapturablewindows_p.h"
+#include "qplatformmediadevices_p.h"
+#include <QtCore/private/qfactoryloader_p.h>
+#include <QtCore/private/qcoreapplication_p.h>
+#include <private/qplatformmediaformatinfo_p.h>
+#include "qplatformmediaplugin_p.h"
+
+namespace {
+
+class QFallbackIntegration : public QPlatformMediaIntegration
{
public:
- QDummyIntegration() { qFatal("QtMultimedia is not currently supported on this platform or compiler."); }
- QPlatformMediaDevices *devices() override { return nullptr; }
- QPlatformMediaFormatInfo *formatInfo() override { return nullptr; }
+ QFallbackIntegration() : QPlatformMediaIntegration(QLatin1String("fallback"))
+ {
+ qWarning("No QtMultimedia backends found. Only QMediaDevices, QAudioDevice, QSoundEffect, QAudioSink, and QAudioSource are available.");
+ }
};
-using PlatformIntegration = QDummyIntegration;
+
+static Q_LOGGING_CATEGORY(qLcMediaPlugin, "qt.multimedia.plugin")
+
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+ (QPlatformMediaPlugin_iid,
+ QLatin1String("/multimedia")))
+
+static const auto FFmpegBackend = QStringLiteral("ffmpeg");
+
+static QString defaultBackend(const QStringList &backends)
+{
+#ifdef QT_DEFAULT_MEDIA_BACKEND
+ auto backend = QString::fromUtf8(QT_DEFAULT_MEDIA_BACKEND);
+ if (backends.contains(backend))
+ return backend;
#endif
-QT_BEGIN_NAMESPACE
+#if defined(Q_OS_DARWIN) || defined(Q_OS_LINUX) || defined(Q_OS_WINDOWS) || defined(Q_OS_ANDROID)
+ // Return ffmpeg backend by default.
+ // Platform backends for the OS list are optionally available but have limited support.
+ if (backends.contains(FFmpegBackend))
+ return FFmpegBackend;
+#else
+ // Return platform backend (non-ffmpeg) by default.
+ if (backends.size() > 1 && backends[0] == FFmpegBackend)
+ return backends[1];
+#endif
-namespace {
-struct Holder {
- ~Holder()
+ return backends[0];
+}
+
+struct InstanceHolder
+{
+ InstanceHolder()
{
- QMutexLocker locker(&mutex);
- delete nativeInstance;
- nativeInstance = nullptr;
- instance = nullptr;
+ if (!QCoreApplication::instance())
+ qCCritical(qLcMediaPlugin()) << "Qt Multimedia requires a QCoreApplication instance";
+
+ const QStringList backends = QPlatformMediaIntegration::availableBackends();
+ QString backend = QString::fromUtf8(qgetenv("QT_MEDIA_BACKEND"));
+ if (backend.isEmpty() && !backends.isEmpty())
+ backend = defaultBackend(backends);
+
+ qCDebug(qLcMediaPlugin) << "Loading media backend" << backend;
+ instance.reset(
+ qLoadPlugin<QPlatformMediaIntegration, QPlatformMediaPlugin>(loader(), backend));
+
+ if (!instance) {
+ // No backends found. Use fallback to support basic functionality
+ instance = std::make_unique<QFallbackIntegration>();
+ }
}
- QBasicMutex mutex;
- QPlatformMediaIntegration *instance = nullptr;
- QAtomicPointer<QPlatformMediaIntegration> nativeInstance = nullptr;
-} holder;
-}
+ ~InstanceHolder()
+ {
+ instance.reset();
+ qCDebug(qLcMediaPlugin) << "Released media backend";
+ }
+
+ std::unique_ptr<QPlatformMediaIntegration> instance;
+};
+
+Q_APPLICATION_STATIC(InstanceHolder, s_instanceHolder);
+
+} // namespace
+
+QT_BEGIN_NAMESPACE
QPlatformMediaIntegration *QPlatformMediaIntegration::instance()
{
- if (!holder.nativeInstance.loadRelaxed()) {
- QMutexLocker locker(&holder.mutex);
- if (!holder.nativeInstance.loadAcquire())
- holder.nativeInstance.storeRelease(new PlatformIntegration);
- }
- if (!holder.instance)
- holder.instance = holder.nativeInstance.loadRelaxed();
- return holder.instance;
+ return s_instanceHolder->instance.get();
}
-/*
- This API is there to be able to test with a mock backend.
-*/
-void QPlatformMediaIntegration::setIntegration(QPlatformMediaIntegration *integration)
+QList<QCameraDevice> QPlatformMediaIntegration::videoInputs()
{
- holder.instance = integration;
+ auto devices = videoDevices();
+ return devices ? devices->videoDevices() : QList<QCameraDevice>{};
}
-QPlatformAudioInput *QPlatformMediaIntegration::createAudioInput(QAudioInput *q)
+QMaybe<std::unique_ptr<QPlatformAudioResampler>>
+QPlatformMediaIntegration::createAudioResampler(const QAudioFormat &, const QAudioFormat &)
+{
+ return notAvailable;
+}
+
+QMaybe<QPlatformAudioInput *> QPlatformMediaIntegration::createAudioInput(QAudioInput *q)
{
return new QPlatformAudioInput(q);
}
-QPlatformAudioOutput *QPlatformMediaIntegration::createAudioOutput(QAudioOutput *q)
+QMaybe<QPlatformAudioOutput *> QPlatformMediaIntegration::createAudioOutput(QAudioOutput *q)
{
return new QPlatformAudioOutput(q);
}
-QPlatformMediaIntegration::~QPlatformMediaIntegration()
-= default;
+QList<QCapturableWindow> QPlatformMediaIntegration::capturableWindowsList()
+{
+ const auto capturableWindows = this->capturableWindows();
+ return capturableWindows ? capturableWindows->windows() : QList<QCapturableWindow>{};
+}
+
+bool QPlatformMediaIntegration::isCapturableWindowValid(const QCapturableWindowPrivate &window)
+{
+ const auto capturableWindows = this->capturableWindows();
+ return capturableWindows && capturableWindows->isWindowValid(window);
+}
+
+const QPlatformMediaFormatInfo *QPlatformMediaIntegration::formatInfo()
+{
+ std::call_once(m_formatInfoOnceFlg, [this]() {
+ m_formatInfo.reset(createFormatInfo());
+ Q_ASSERT(m_formatInfo);
+ });
+ return m_formatInfo.get();
+}
+
+QPlatformMediaFormatInfo *QPlatformMediaIntegration::createFormatInfo()
+{
+ return new QPlatformMediaFormatInfo;
+}
+
+std::unique_ptr<QPlatformMediaDevices> QPlatformMediaIntegration::createMediaDevices()
+{
+ return QPlatformMediaDevices::create();
+}
+
+// clang-format off
+QPlatformVideoDevices *QPlatformMediaIntegration::videoDevices()
+{
+ std::call_once(m_videoDevicesOnceFlag,
+ [this]() {
+ m_videoDevices.reset(createVideoDevices());
+ });
+ return m_videoDevices.get();
+}
+
+QPlatformCapturableWindows *QPlatformMediaIntegration::capturableWindows()
+{
+ std::call_once(m_capturableWindowsOnceFlag,
+ [this]() {
+ m_capturableWindows.reset(createCapturableWindows());
+ });
+ return m_capturableWindows.get();
+}
+
+QPlatformMediaDevices *QPlatformMediaIntegration::mediaDevices()
+{
+ std::call_once(m_mediaDevicesOnceFlag, [this] {
+ m_mediaDevices = createMediaDevices();
+ });
+ return m_mediaDevices.get();
+}
+
+// clang-format on
+
+QStringList QPlatformMediaIntegration::availableBackends()
+{
+ QStringList list;
+
+ if (QFactoryLoader *fl = loader()) {
+ const auto keyMap = fl->keyMap();
+ for (auto it = keyMap.constBegin(); it != keyMap.constEnd(); ++it)
+ if (!list.contains(it.value()))
+ list << it.value();
+ }
+
+ qCDebug(qLcMediaPlugin) << "Available backends" << list;
+ return list;
+}
+
+QLatin1String QPlatformMediaIntegration::name()
+{
+ return m_backendName;
+}
+
+QVideoFrame QPlatformMediaIntegration::convertVideoFrame(QVideoFrame &,
+ const QVideoFrameFormat &)
+{
+ return {};
+}
+
+QPlatformMediaIntegration::QPlatformMediaIntegration(QLatin1String name) : m_backendName(name) { }
+
+QPlatformMediaIntegration::~QPlatformMediaIntegration() = default;
QT_END_NAMESPACE
+
+#include "moc_qplatformmediaintegration_p.cpp"
diff --git a/src/multimedia/platform/qplatformmediaintegration_p.h b/src/multimedia/platform/qplatformmediaintegration_p.h
index 67938d910..d03d0c794 100644
--- a/src/multimedia/platform/qplatformmediaintegration_p.h
+++ b/src/multimedia/platform/qplatformmediaintegration_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPLATFORMMEDIAINTEGRATION_H
#define QPLATFORMMEDIAINTEGRATION_H
@@ -51,13 +15,21 @@
//
#include <private/qtmultimediaglobal_p.h>
+#include <private/qmultimediautils_p.h>
+#include <qcapturablewindow.h>
#include <qmediarecorder.h>
+#include <qstring.h>
+
+#include <memory>
+#include <mutex>
QT_BEGIN_NAMESPACE
class QMediaPlayer;
class QAudioDecoder;
class QCamera;
+class QScreenCapture;
+class QWindowCapture;
class QMediaRecorder;
class QImageCapture;
class QMediaDevices;
@@ -65,8 +37,10 @@ class QPlatformMediaDevices;
class QPlatformMediaCaptureSession;
class QPlatformMediaPlayer;
class QPlatformAudioDecoder;
+class QPlatformAudioResampler;
class QPlatformCamera;
-class QPlatformMediaEncoder;
+class QPlatformSurfaceCapture;
+class QPlatformMediaRecorder;
class QPlatformImageCapture;
class QPlatformMediaFormatInfo;
class QObject;
@@ -76,30 +50,87 @@ class QAudioInput;
class QAudioOutput;
class QPlatformAudioInput;
class QPlatformAudioOutput;
+class QPlatformVideoDevices;
+class QCapturableWindow;
+class QPlatformCapturableWindows;
+class QVideoFrame;
-class Q_MULTIMEDIA_EXPORT QPlatformMediaIntegration
+class Q_MULTIMEDIA_EXPORT QAbstractPlatformSpecificInterface
{
public:
- static QPlatformMediaIntegration *instance();
+ virtual ~QAbstractPlatformSpecificInterface() = default;
+};
- // API to be able to test with a mock backend
- static void setIntegration(QPlatformMediaIntegration *);
+class Q_MULTIMEDIA_EXPORT QPlatformMediaIntegration : public QObject
+{
+ Q_OBJECT
+ inline static const QString notAvailable = QStringLiteral("Not available");
+public:
+ static QPlatformMediaIntegration *instance();
+ explicit QPlatformMediaIntegration(QLatin1String);
virtual ~QPlatformMediaIntegration();
- virtual QPlatformMediaDevices *devices() = 0;
- virtual QPlatformMediaFormatInfo *formatInfo() = 0;
+ const QPlatformMediaFormatInfo *formatInfo();
+
+ virtual QList<QCameraDevice> videoInputs();
+ virtual QMaybe<QPlatformCamera *> createCamera(QCamera *) { return notAvailable; }
+ virtual QPlatformSurfaceCapture *createScreenCapture(QScreenCapture *) { return nullptr; }
+ virtual QPlatformSurfaceCapture *createWindowCapture(QWindowCapture *) { return nullptr; }
+
+ virtual QMaybe<QPlatformAudioDecoder *> createAudioDecoder(QAudioDecoder *) { return notAvailable; }
+ virtual QMaybe<std::unique_ptr<QPlatformAudioResampler>>
+ createAudioResampler(const QAudioFormat & /*inputFormat*/,
+ const QAudioFormat & /*outputFormat*/);
+ virtual QMaybe<QPlatformMediaCaptureSession *> createCaptureSession() { return notAvailable; }
+ virtual QMaybe<QPlatformMediaPlayer *> createPlayer(QMediaPlayer *) { return notAvailable; }
+ virtual QMaybe<QPlatformMediaRecorder *> createRecorder(QMediaRecorder *) { return notAvailable; }
+ virtual QMaybe<QPlatformImageCapture *> createImageCapture(QImageCapture *) { return notAvailable; }
+
+ virtual QMaybe<QPlatformAudioInput *> createAudioInput(QAudioInput *);
+ virtual QMaybe<QPlatformAudioOutput *> createAudioOutput(QAudioOutput *);
+
+ virtual QMaybe<QPlatformVideoSink *> createVideoSink(QVideoSink *) { return notAvailable; }
+
+ QList<QCapturableWindow> capturableWindowsList();
+ bool isCapturableWindowValid(const QCapturableWindowPrivate &);
+
+ QPlatformVideoDevices *videoDevices();
+
+ QPlatformCapturableWindows *capturableWindows();
+
+ QPlatformMediaDevices *mediaDevices();
+
+ static QStringList availableBackends();
+ QLatin1String name(); // for unit tests
+
+ // Convert a QVideoFrame to the destination format
+ virtual QVideoFrame convertVideoFrame(QVideoFrame &, const QVideoFrameFormat &);
+
+ virtual QAbstractPlatformSpecificInterface *platformSpecificInterface() { return nullptr; }
+
+protected:
+ virtual QPlatformMediaFormatInfo *createFormatInfo();
+
+ virtual QPlatformVideoDevices *createVideoDevices() { return nullptr; }
+
+ virtual QPlatformCapturableWindows *createCapturableWindows() { return nullptr; }
+
+ virtual std::unique_ptr<QPlatformMediaDevices> createMediaDevices();
+
+private:
+ std::unique_ptr<QPlatformVideoDevices> m_videoDevices;
+ std::once_flag m_videoDevicesOnceFlag;
+
+ std::unique_ptr<QPlatformCapturableWindows> m_capturableWindows;
+ std::once_flag m_capturableWindowsOnceFlag;
- virtual QPlatformAudioDecoder *createAudioDecoder(QAudioDecoder *) { return nullptr; }
- virtual QPlatformMediaCaptureSession *createCaptureSession() { return nullptr; }
- virtual QPlatformMediaPlayer *createPlayer(QMediaPlayer *) { return nullptr; }
- virtual QPlatformCamera *createCamera(QCamera *) { return nullptr; }
- virtual QPlatformMediaEncoder *createEncoder(QMediaRecorder *) { return nullptr; }
- virtual QPlatformImageCapture *createImageCapture(QImageCapture *) { return nullptr; }
+ mutable std::unique_ptr<QPlatformMediaFormatInfo> m_formatInfo;
+ mutable std::once_flag m_formatInfoOnceFlg;
- virtual QPlatformAudioInput *createAudioInput(QAudioInput *);
- virtual QPlatformAudioOutput *createAudioOutput(QAudioOutput *);
+ std::unique_ptr<QPlatformMediaDevices> m_mediaDevices;
+ std::once_flag m_mediaDevicesOnceFlag;
- virtual QPlatformVideoSink *createVideoSink(QVideoSink *) { return nullptr; }
+ const QLatin1String m_backendName;
};
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qplatformmediaplayer.cpp b/src/multimedia/platform/qplatformmediaplayer.cpp
index 21e25ec9b..ea22f94df 100644
--- a/src/multimedia/platform/qplatformmediaplayer.cpp
+++ b/src/multimedia/platform/qplatformmediaplayer.cpp
@@ -1,92 +1,23 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qplatformmediaplayer_p.h"
#include <private/qmediaplayer_p.h>
#include "qmediaplayer.h"
+#include "qplatformmediadevices_p.h"
+#include "qplatformmediaintegration_p.h"
QT_BEGIN_NAMESPACE
-
-/*!
- \class QPlatformMediaPlayer
- \internal
-
- \brief The QPlatformMediaPlayer class provides access to the media playing
- functionality.
-
- This control provides a means to set the \l {setMedia()}{media} to play,
- \l {play()}{start}, \l {pause()} {pause} and \l {stop()}{stop} playback,
- \l {setPosition()}{seek}, and control the \l {setVolume()}{volume}.
- It also provides feedback on the \l {duration()}{duration} of the media,
- the current \l {position()}{position}, and \l {bufferProgress()}{buffering}
- progress.
-
- The functionality provided by this control is exposed to application
- code through the QMediaPlayer class.
-
- \sa QMediaPlayer
-*/
+QPlatformMediaPlayer::QPlatformMediaPlayer(QMediaPlayer *parent) : player(parent)
+{
+ QPlatformMediaIntegration::instance()->mediaDevices()->prepareAudio();
+}
QPlatformMediaPlayer::~QPlatformMediaPlayer()
{
}
-/*! \fn QPlatformMediaPlayer::QPlatformMediaPlayer(QMediaPlayer *parent)
-
- Constructs a new media player control with the given \a parent.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::state() const
-
- Returns the state of a player control.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::stateChanged(QMediaPlayer::State newState)
-
- Signals that the state of a player control has changed to \a newState.
-
- \sa state()
-*/
-
void QPlatformMediaPlayer::stateChanged(QMediaPlayer::PlaybackState newState)
{
if (newState == m_state)
@@ -95,20 +26,6 @@ void QPlatformMediaPlayer::stateChanged(QMediaPlayer::PlaybackState newState)
player->d_func()->setState(newState);
}
-/*!
- \fn QPlatformMediaPlayer::mediaStatus() const
-
- Returns the status of the current media.
-*/
-
-
-/*!
- \fn QPlatformMediaPlayer::mediaStatusChanged(QMediaPlayer::MediaStatus status)
-
- Signals that the \a status of the current media has changed.
-
- \sa mediaStatus()
-*/
void QPlatformMediaPlayer::mediaStatusChanged(QMediaPlayer::MediaStatus status)
{
if (m_status == status)
@@ -119,254 +36,19 @@ void QPlatformMediaPlayer::mediaStatusChanged(QMediaPlayer::MediaStatus status)
void QPlatformMediaPlayer::error(int error, const QString &errorString)
{
- player->d_func()->setError(error, errorString);
+ player->d_func()->setError(QMediaPlayer::Error(error), errorString);
}
-/*!
- \fn QPlatformMediaPlayer::duration() const
-
- Returns the duration of the current media in milliseconds.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::durationChanged(qint64 duration)
-
- Signals that the \a duration of the current media has changed.
-
- \sa duration()
-*/
-
-/*!
- \fn QPlatformMediaPlayer::position() const
-
- Returns the current playback position in milliseconds.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::setPosition(qint64 position)
-
- Sets the playback \a position of the current media. This will initiate a seek and it may take
- some time for playback to reach the position set.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::positionChanged(qint64 position)
-
- Signals the playback \a position has changed.
-
- This is only emitted in when there has been a discontinous change in the playback postion, such
- as a seek or the position being reset.
-
- \sa position()
-*/
-
-/*!
- \fn QPlatformMediaPlayer::volume() const
-
- Returns the audio volume of a player control.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::setVolume(int volume)
-
- Sets the audio \a volume of a player control.
-
- The volume is scaled linearly, ranging from \c 0 (silence) to \c 100 (full volume).
-*/
-
-/*!
- \fn QPlatformMediaPlayer::volumeChanged(int volume)
-
- Signals the audio \a volume of a player control has changed.
-
- \sa volume()
-*/
-
-/*!
- \fn QPlatformMediaPlayer::isMuted() const
-
- Returns the mute state of a player control.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::setMuted(bool mute)
-
- Sets the \a mute state of a player control.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::mutedChanged(bool mute)
-
- Signals a change in the \a mute status of a player control.
-
- \sa isMuted()
-*/
-
-/*!
- \fn QPlatformMediaPlayer::bufferProgress() const
-
- Returns the buffering progress of the current media. Progress is measured as a number between
- 0 and 1.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::bufferProgressChanged(float filled)
-
- Signal the amount of the local buffer filled as a relative number between 0 and 1.
-
- \sa bufferProgress()
-*/
-
-/*!
- \fn QPlatformMediaPlayer::isAudioAvailable() const
-
- Identifies if there is audio output available for the current media.
-
- Returns true if audio output is available and false otherwise.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::audioAvailableChanged(bool audioAvailable)
-
- Signals that there has been a change in the availability of audio output \a audioAvailable.
-
- \sa isAudioAvailable()
-*/
-
-/*!
- \fn QPlatformMediaPlayer::isVideoAvailable() const
-
- Identifies if there is video output available for the current media.
-
- Returns true if video output is available and false otherwise.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::videoAvailableChanged(bool videoAvailable)
-
- Signal that the availability of visual content has changed to \a videoAvailable.
-
- \sa isVideoAvailable()
-*/
-
-/*!
- \fn QPlatformMediaPlayer::isSeekable() const
-
- Identifies if the current media is seekable.
-
- Returns true if it possible to seek within the current media, and false otherwise.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::seekableChanged(bool seekable)
-
- Signals that the \a seekable state of a player control has changed.
-
- \sa isSeekable()
-*/
-
-/*!
- \fn QPlatformMediaPlayer::availablePlaybackRanges() const
-
- Returns a range of times in milliseconds that can be played back.
-
- Usually for local files this is a continuous interval equal to [0..duration()]
- or an empty time range if seeking is not supported, but for network sources
- it refers to the buffered parts of the media.
-*/
-
-/*!
- \fn qreal QPlatformMediaPlayer::playbackRate() const
-
- Returns the rate of playback.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::setPlaybackRate(qreal rate)
-
- Sets the \a rate of playback.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::media() const
-
- Returns the current media source.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::mediaStream() const
-
- Returns the current media stream. This is only a valid if a stream was passed to setMedia().
-
- \sa setMedia()
-*/
-
-/*!
- \fn QPlatformMediaPlayer::setMedia(const QUrl &media, QIODevice *stream)
-
- Sets the current \a media source. If a \a stream is supplied; data will be read from that
- instead of attempting to resolve the media source. The media source may still be used to
- supply media information such as mime type.
-
- Setting the media to a null QUrl will cause the control to discard all
- information relating to the current media source and to cease all I/O operations related
- to that media.
-
- Qt resource files are never passed as is. If the control supports
- stream playback, a \a stream is supplied, pointing to an opened
- QFile. Otherwise, the resource is copied into a temporary file and \a media contains the
- url to that file.
-
- \sa streamPlaybackSupported()
-*/
-
-/*!
- \fn QPlatformMediaPlayer::mediaChanged(const QUrl& content)
-
- Signals that the current media \a content has changed.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::play()
-
- Starts playback of the current media.
-
- If successful the player control will immediately enter the \l {QMediaPlayer::PlayingState}
- {playing} state.
-
- \sa state()
-*/
-
-/*!
- \fn QPlatformMediaPlayer::pause()
-
- Pauses playback of the current media.
-
- If successful the player control will immediately enter the \l {QMediaPlayer::PausedState}
- {paused} state.
-
- \sa state(), play(), stop()
-*/
-
-/*!
- \fn QPlatformMediaPlayer::stop()
-
- Stops playback of the current media.
-
- If successful the player control will immediately enter the \l {QMediaPlayer::StoppedState}
- {stopped} state.
-*/
-
-/*!
- \fn QPlatformMediaPlayer::error(int error, const QString &errorString)
-
- Signals that an \a error has occurred. The \a errorString provides a more detailed explanation.
-*/
+void *QPlatformMediaPlayer::nativePipeline(QMediaPlayer *player)
+{
+ if (!player)
+ return nullptr;
-/*!
- \fn QPlatformMediaPlayer::playbackRateChanged(qreal rate)
+ auto playerPrivate = player->d_func();
+ if (!playerPrivate || !playerPrivate->control)
+ return nullptr;
- Signal emitted when playback rate changes to \a rate.
-*/
+ return playerPrivate->control->nativePipeline();
+}
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qplatformmediaplayer_p.h b/src/multimedia/platform/qplatformmediaplayer_p.h
index cc9297229..6e3590763 100644
--- a/src/multimedia/platform/qplatformmediaplayer_p.h
+++ b/src/multimedia/platform/qplatformmediaplayer_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -57,6 +21,7 @@
#include <QtMultimedia/qmediametadata.h>
#include <QtCore/qpair.h>
+#include <QtCore/private/qglobal_p.h>
QT_BEGIN_NAMESPACE
@@ -72,7 +37,7 @@ public:
virtual qint64 duration() const = 0;
- virtual qint64 position() const = 0;
+ virtual qint64 position() const { return m_position; }
virtual void setPosition(qint64 position) = 0;
virtual float bufferProgress() const = 0;
@@ -111,40 +76,62 @@ public:
virtual int activeTrack(TrackType) { return -1; }
virtual void setActiveTrack(TrackType, int /*streamNumber*/) {}
- void durationChanged(qint64 duration) { player->durationChanged(duration); }
- void positionChanged(qint64 position) { player->positionChanged(position); }
+ void durationChanged(qint64 duration) { emit player->durationChanged(duration); }
+ void positionChanged(qint64 position) {
+ if (m_position == position)
+ return;
+ m_position = position;
+ emit player->positionChanged(position);
+ }
void audioAvailableChanged(bool audioAvailable) {
if (m_audioAvailable == audioAvailable)
return;
m_audioAvailable = audioAvailable;
- player->hasAudioChanged(audioAvailable);
+ emit player->hasAudioChanged(audioAvailable);
}
void videoAvailableChanged(bool videoAvailable) {
if (m_videoAvailable == videoAvailable)
return;
m_videoAvailable = videoAvailable;
- player->hasVideoChanged(videoAvailable);
+ emit player->hasVideoChanged(videoAvailable);
}
void seekableChanged(bool seekable) {
if (m_seekable == seekable)
return;
m_seekable = seekable;
- player->seekableChanged(seekable);
+ emit player->seekableChanged(seekable);
}
- void playbackRateChanged(qreal rate) { player->playbackRateChanged(rate); }
- void bufferProgressChanged(float progress) { player->bufferProgressChanged(progress); }
- void metaDataChanged() { player->metaDataChanged(); }
- void tracksChanged() { player->tracksChanged(); }
- void activeTracksChanged() { player->activeTracksChanged(); }
+ void playbackRateChanged(qreal rate) { emit player->playbackRateChanged(rate); }
+ void bufferProgressChanged(float progress) { emit player->bufferProgressChanged(progress); }
+ void metaDataChanged() { emit player->metaDataChanged(); }
+ void tracksChanged() { emit player->tracksChanged(); }
+ void activeTracksChanged() { emit player->activeTracksChanged(); }
void stateChanged(QMediaPlayer::PlaybackState newState);
void mediaStatusChanged(QMediaPlayer::MediaStatus status);
void error(int error, const QString &errorString);
+ void resetCurrentLoop() { m_currentLoop = 0; }
+ bool doLoop() {
+ return isSeekable() && (m_loops < 0 || ++m_currentLoop < m_loops);
+ }
+ int loops() { return m_loops; }
+ virtual void setLoops(int loops)
+ {
+ if (m_loops == loops)
+ return;
+ m_loops = loops;
+ Q_EMIT player->loopsChanged();
+ }
+
+ virtual void *nativePipeline() { return nullptr; }
+
+ // private API, the purpose is getting GstPipeline
+ static void *nativePipeline(QMediaPlayer *player);
+
protected:
- explicit QPlatformMediaPlayer(QMediaPlayer *parent = nullptr)
- : player(parent)
- {}
+ explicit QPlatformMediaPlayer(QMediaPlayer *parent = nullptr);
+
private:
QMediaPlayer *player = nullptr;
QMediaPlayer::MediaStatus m_status = QMediaPlayer::NoMedia;
@@ -152,6 +139,9 @@ private:
bool m_seekable = false;
bool m_videoAvailable = false;
bool m_audioAvailable = false;
+ int m_loops = 1;
+ int m_currentLoop = 0;
+ qint64 m_position = 0;
};
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qplatformmediaplugin.cpp b/src/multimedia/platform/qplatformmediaplugin.cpp
new file mode 100644
index 000000000..7828fa08e
--- /dev/null
+++ b/src/multimedia/platform/qplatformmediaplugin.cpp
@@ -0,0 +1,14 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qplatformmediaplugin_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QPlatformMediaPlugin::QPlatformMediaPlugin(QObject *parent) : QObject(parent) { }
+
+QPlatformMediaPlugin::~QPlatformMediaPlugin() = default;
+
+QT_END_NAMESPACE
+
+#include "moc_qplatformmediaplugin_p.cpp"
diff --git a/src/multimedia/platform/qplatformmediaplugin_p.h b/src/multimedia/platform/qplatformmediaplugin_p.h
new file mode 100644
index 000000000..4c8b9e458
--- /dev/null
+++ b/src/multimedia/platform/qplatformmediaplugin_p.h
@@ -0,0 +1,42 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+//
+// 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.
+//
+
+#ifndef QPLATFORMMEDIAPLUGIN_P_H
+#define QPLATFORMMEDIAPLUGIN_P_H
+
+#include <QtMultimedia/qtmultimediaglobal.h>
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+#include <QtCore/private/qglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPlatformMediaIntegration;
+
+#define QPlatformMediaPlugin_iid "org.qt-project.Qt.QPlatformMediaPlugin"
+
+class Q_MULTIMEDIA_EXPORT QPlatformMediaPlugin : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QPlatformMediaPlugin(QObject *parent = nullptr);
+ ~QPlatformMediaPlugin() override;
+
+ virtual QPlatformMediaIntegration *create(const QString &key) = 0;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QPLATFORMMEDIAPLUGIN_P_H
diff --git a/src/multimedia/platform/qplatformmediarecorder.cpp b/src/multimedia/platform/qplatformmediarecorder.cpp
new file mode 100644
index 000000000..30dba0a45
--- /dev/null
+++ b/src/multimedia/platform/qplatformmediarecorder.cpp
@@ -0,0 +1,75 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qplatformmediarecorder_p.h"
+#include "qstandardpaths.h"
+#include "qmediastoragelocation_p.h"
+#include <QObject>
+
+QT_BEGIN_NAMESPACE
+
+QPlatformMediaRecorder::QPlatformMediaRecorder(QMediaRecorder *parent)
+ : q(parent)
+{
+}
+
+void QPlatformMediaRecorder::pause()
+{
+ updateError(QMediaRecorder::FormatError, QMediaRecorder::tr("Pause not supported"));
+}
+
+void QPlatformMediaRecorder::resume()
+{
+ updateError(QMediaRecorder::FormatError, QMediaRecorder::tr("Resume not supported"));
+}
+
+void QPlatformMediaRecorder::stateChanged(QMediaRecorder::RecorderState state)
+{
+ if (m_state == state)
+ return;
+ m_state = state;
+ emit q->recorderStateChanged(state);
+}
+
+void QPlatformMediaRecorder::durationChanged(qint64 duration)
+{
+ if (m_duration == duration)
+ return;
+ m_duration = duration;
+ emit q->durationChanged(duration);
+}
+
+void QPlatformMediaRecorder::actualLocationChanged(const QUrl &location)
+{
+ if (m_actualLocation == location)
+ return;
+ m_actualLocation = location;
+ emit q->actualLocationChanged(location);
+}
+
+void QPlatformMediaRecorder::updateError(QMediaRecorder::Error error, const QString &errorString)
+{
+ m_error.setAndNotify(error, errorString, *q);
+}
+
+void QPlatformMediaRecorder::metaDataChanged()
+{
+ emit q->metaDataChanged();
+}
+
+QString QPlatformMediaRecorder::findActualLocation(const QMediaEncoderSettings &settings) const
+{
+ const auto audioOnly = settings.videoCodec() == QMediaFormat::VideoCodec::Unspecified;
+
+ const auto primaryLocation =
+ audioOnly ? QStandardPaths::MusicLocation : QStandardPaths::MoviesLocation;
+ const QString suffix = settings.mimeType().preferredSuffix();
+ const QString location = QMediaStorageLocation::generateFileName(
+ outputLocation().toString(QUrl::PreferLocalFile), primaryLocation, suffix);
+
+ Q_ASSERT(!location.isEmpty());
+
+ return location;
+}
+
+QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qplatformmediaencoder_p.h b/src/multimedia/platform/qplatformmediarecorder_p.h
index 354998b5c..dea45ac70 100644
--- a/src/multimedia/platform/qplatformmediaencoder_p.h
+++ b/src/multimedia/platform/qplatformmediarecorder_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
//
// W A R N I N G
@@ -48,16 +12,20 @@
// We mean it.
//
-#ifndef QPLATFORMMEDIAENCODER_H
-#define QPLATFORMMEDIAENCODER_H
+#ifndef QPLATFORMMEDIARECORDER_H
+#define QPLATFORMMEDIARECORDER_H
#include <QtCore/qurl.h>
#include <QtCore/qsize.h>
#include <QtCore/qmimetype.h>
+#include <QtCore/qpointer.h>
+#include <QtCore/qiodevice.h>
#include <QtMultimedia/qmediarecorder.h>
#include <QtMultimedia/qmediametadata.h>
#include <QtMultimedia/qmediaformat.h>
+#include <QtMultimedia/private/qerrorinfo_p.h>
+#include <QtCore/private/qglobal_p.h>
QT_BEGIN_NAMESPACE
@@ -132,10 +100,10 @@ public:
{ return !operator==(other); }
};
-class Q_MULTIMEDIA_EXPORT QPlatformMediaEncoder
+class Q_MULTIMEDIA_EXPORT QPlatformMediaRecorder
{
public:
- virtual ~QPlatformMediaEncoder() {}
+ virtual ~QPlatformMediaRecorder() {}
virtual bool isLocationWritable(const QUrl &location) const = 0;
@@ -145,35 +113,43 @@ public:
virtual void resume();
virtual void stop() = 0;
- virtual qint64 duration() const = 0;
+ virtual qint64 duration() const { return m_duration; }
virtual void setMetaData(const QMediaMetaData &) {}
virtual QMediaMetaData metaData() const { return {}; }
- QMediaRecorder::Error error() const { return m_error;}
- QString errorString() const { return m_errorString; }
+ QMediaRecorder::Error error() const { return m_error.code(); }
+ QString errorString() const { return m_error.description(); }
QUrl outputLocation() const { return m_outputLocation; }
virtual void setOutputLocation(const QUrl &location) { m_outputLocation = location; }
QUrl actualLocation() const { return m_actualLocation; }
void clearActualLocation() { m_actualLocation.clear(); }
- void clearError() { error(QMediaRecorder::NoError, QString()); }
+ void clearError() { updateError(QMediaRecorder::NoError, QString()); }
+
+ QIODevice *outputDevice() const { return m_outputDevice; }
+ void setOutputDevice(QIODevice *device) { m_outputDevice = device; }
protected:
- explicit QPlatformMediaEncoder(QMediaRecorder *parent);
+ explicit QPlatformMediaRecorder(QMediaRecorder *parent);
void stateChanged(QMediaRecorder::RecorderState state);
void durationChanged(qint64 position);
void actualLocationChanged(const QUrl &location);
- void error(QMediaRecorder::Error error, const QString &errorString);
+ void updateError(QMediaRecorder::Error error, const QString &errorString);
void metaDataChanged();
+ QMediaRecorder *mediaRecorder() { return q; }
+
+ QString findActualLocation(const QMediaEncoderSettings &settings) const;
+
private:
QMediaRecorder *q = nullptr;
- QMediaRecorder::Error m_error = QMediaRecorder::NoError;
- QString m_errorString;
+ QErrorInfo<QMediaRecorder::Error> m_error;
QUrl m_actualLocation;
QUrl m_outputLocation;
+ QPointer<QIODevice> m_outputDevice;
+ qint64 m_duration = 0;
QMediaRecorder::RecorderState m_state = QMediaRecorder::StoppedState;
};
diff --git a/src/multimedia/platform/qplatformsurfacecapture.cpp b/src/multimedia/platform/qplatformsurfacecapture.cpp
new file mode 100644
index 000000000..a56f48b62
--- /dev/null
+++ b/src/multimedia/platform/qplatformsurfacecapture.cpp
@@ -0,0 +1,83 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "platform/qplatformsurfacecapture_p.h"
+#include "qvideoframe.h"
+#include "qguiapplication.h"
+#include "qdebug.h"
+
+QT_BEGIN_NAMESPACE
+
+QPlatformSurfaceCapture::QPlatformSurfaceCapture(Source initialSource) : m_source(initialSource)
+{
+ Q_ASSERT(std::visit([](auto source) { return source == decltype(source){}; }, initialSource));
+ qRegisterMetaType<QVideoFrame>();
+}
+
+void QPlatformSurfaceCapture::setActive(bool active)
+{
+ if (m_active == active)
+ return;
+
+ if (!setActiveInternal(active))
+ return;
+
+ m_active = active;
+ emit activeChanged(active);
+}
+
+bool QPlatformSurfaceCapture::isActive() const
+{
+ return m_active;
+}
+
+void QPlatformSurfaceCapture::setSource(Source source)
+{
+ Q_ASSERT(source.index() == m_source.index());
+
+ if (m_source == source)
+ return;
+
+ if (m_active)
+ setActiveInternal(false);
+
+ m_source = source;
+
+ if (m_active && !setActiveInternal(true)) {
+ m_active = false;
+ emit activeChanged(false);
+ }
+
+ std::visit([this](auto source) { emit sourceChanged(source); }, m_source);
+}
+
+QPlatformSurfaceCapture::Error QPlatformSurfaceCapture::error() const
+{
+ return m_error.code();
+}
+
+QString QPlatformSurfaceCapture::errorString() const
+{
+ return m_error.description();
+}
+
+void QPlatformSurfaceCapture::updateError(Error error, const QString &errorString)
+{
+ m_error.setAndNotify(error, errorString, *this);
+}
+
+bool QPlatformSurfaceCapture::checkScreenWithError(ScreenSource &screen)
+{
+ if (!screen)
+ screen = QGuiApplication::primaryScreen();
+
+ if (screen)
+ return true;
+
+ updateError(NotFound, QLatin1String("No screens found"));
+ return false;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qplatformsurfacecapture_p.cpp"
diff --git a/src/multimedia/platform/qplatformsurfacecapture_p.h b/src/multimedia/platform/qplatformsurfacecapture_p.h
new file mode 100644
index 000000000..e4c59c6f4
--- /dev/null
+++ b/src/multimedia/platform/qplatformsurfacecapture_p.h
@@ -0,0 +1,87 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPLATFORMSURFACECAPTURE_H
+#define QPLATFORMSURFACECAPTURE_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 "qplatformvideosource_p.h"
+#include "qscreen.h"
+#include "qcapturablewindow.h"
+#include "qpointer.h"
+#include "private/qerrorinfo_p.h"
+
+#include <optional>
+#include <variant>
+
+QT_BEGIN_NAMESPACE
+
+class QVideoFrame;
+
+class Q_MULTIMEDIA_EXPORT QPlatformSurfaceCapture : public QPlatformVideoSource
+{
+ Q_OBJECT
+
+public:
+ enum Error {
+ NoError = 0,
+ InternalError = 1,
+ CapturingNotSupported = 2,
+ CaptureFailed = 4,
+ NotFound = 5,
+ };
+
+ using ScreenSource = QPointer<QScreen>;
+ using WindowSource = QCapturableWindow;
+
+ using Source = std::variant<ScreenSource, WindowSource>;
+
+ explicit QPlatformSurfaceCapture(Source initialSource);
+
+ void setActive(bool active) override;
+ bool isActive() const override;
+
+ void setSource(Source source);
+
+ template<typename Type>
+ Type source() const {
+ return *q_check_ptr(std::get_if<Type>(&m_source));
+ }
+
+ Source source() const { return m_source; }
+
+ Error error() const;
+ QString errorString() const final;
+
+protected:
+ virtual bool setActiveInternal(bool) = 0;
+
+ bool checkScreenWithError(ScreenSource &screen);
+
+public Q_SLOTS:
+ void updateError(Error error, const QString &errorString);
+
+Q_SIGNALS:
+ void sourceChanged(WindowSource);
+ void sourceChanged(ScreenSource);
+ void errorOccurred(Error error, QString errorString);
+
+private:
+ QErrorInfo<Error> m_error;
+ Source m_source;
+ bool m_active = false;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPLATFORMSURFACECAPTURE_H
diff --git a/src/multimedia/platform/qplatformvideodevices.cpp b/src/multimedia/platform/qplatformvideodevices.cpp
new file mode 100644
index 000000000..bcf664cd2
--- /dev/null
+++ b/src/multimedia/platform/qplatformvideodevices.cpp
@@ -0,0 +1,12 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qplatformvideodevices_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QPlatformVideoDevices::~QPlatformVideoDevices() = default;
+
+QT_END_NAMESPACE
+
+#include "moc_qplatformvideodevices_p.cpp"
diff --git a/src/multimedia/platform/qplatformvideodevices_p.h b/src/multimedia/platform/qplatformvideodevices_p.h
new file mode 100644
index 000000000..008322be2
--- /dev/null
+++ b/src/multimedia/platform/qplatformvideodevices_p.h
@@ -0,0 +1,46 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#ifndef QPLATFORMVIDEODEVICES_H
+#define QPLATFORMVIDEODEVICES_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 <private/qtmultimediaglobal_p.h>
+#include <qmediarecorder.h>
+#include <qobject.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPlatformMediaIntegration;
+
+class Q_MULTIMEDIA_EXPORT QPlatformVideoDevices : public QObject
+{
+ Q_OBJECT
+public:
+ QPlatformVideoDevices(QPlatformMediaIntegration *integration)
+ : m_integration(integration)
+ {}
+
+ ~QPlatformVideoDevices() override;
+
+ virtual QList<QCameraDevice> videoDevices() const = 0;
+
+Q_SIGNALS:
+ void videoInputsChanged();
+
+protected:
+ QPlatformMediaIntegration *m_integration = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/multimedia/platform/qplatformvideosink.cpp b/src/multimedia/platform/qplatformvideosink.cpp
index d3e5e24b2..abf82af0f 100644
--- a/src/multimedia/platform/qplatformvideosink.cpp
+++ b/src/multimedia/platform/qplatformvideosink.cpp
@@ -1,99 +1,77 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qplatformvideosink_p.h"
+#include "qmultimediautils_p.h"
QT_BEGIN_NAMESPACE
-/*!
- \class QPlatformVideoSink
- \obsolete
+QPlatformVideoSink::QPlatformVideoSink(QVideoSink *parent) : QObject(parent), m_sink(parent) { }
- \inmodule QtMultimedia
+QPlatformVideoSink::~QPlatformVideoSink() = default;
- \ingroup multimedia_control
- \brief The QPlatformVideoSink class provides a media control for rendering video to a window.
-
- QPlatformVideoSink is one of a number of possible video output controls.
-
- \sa QVideoWidget
-*/
-
-/*!
- Constructs a new video window control with the given \a parent.
-*/
-QPlatformVideoSink::QPlatformVideoSink(QVideoSink *parent)
- : QObject(parent),
- sink(parent)
+QSize QPlatformVideoSink::nativeSize() const
{
+ QMutexLocker locker(&m_mutex);
+ return m_nativeSize;
}
-/*!
- \fn QPlatformVideoSink::setWinId(WId id)
-
- Sets the \a id of the window a video overlay end point renders to.
-*/
-
-/*!
- \fn QPlatformVideoSink::setDisplayRect(const QRect &rect)
- Sets the sub-\a rect of a window where video is displayed.
-*/
-
-/*!
- \fn QPlatformVideoSink::setFullScreen(bool fullScreen)
-
- Sets whether a video overlay is a \a fullScreen overlay.
-*/
+void QPlatformVideoSink::setNativeSize(QSize s)
+{
+ {
+ QMutexLocker locker(&m_mutex);
+ if (m_nativeSize == s)
+ return;
+ m_nativeSize = s;
+ }
+ emit m_sink->videoSizeChanged();
+}
-/*!
- \fn QPlatformVideoSink::nativeSize() const
+void QPlatformVideoSink::setVideoFrame(const QVideoFrame &frame)
+{
+ bool sizeChanged = false;
+
+ {
+ QMutexLocker locker(&m_mutex);
+ if (frame == m_currentVideoFrame)
+ return;
+ m_currentVideoFrame = frame;
+ m_currentVideoFrame.setSubtitleText(m_subtitleText);
+ const auto size = qRotatedFrameSize(frame);
+ if (size != m_nativeSize) {
+ m_nativeSize = size;
+ sizeChanged = true;
+ }
+ }
+
+ // emit signals outside the mutex to avoid deadlocks on the user side
+ if (sizeChanged)
+ emit m_sink->videoSizeChanged();
+ emit m_sink->videoFrameChanged(frame);
+}
- Returns a suggested size for the video display based on the resolution and aspect ratio of the
- video.
-*/
+QVideoFrame QPlatformVideoSink::currentVideoFrame() const
+{
+ QMutexLocker locker(&m_mutex);
+ return m_currentVideoFrame;
+}
-/*!
- \fn QPlatformVideoSink::setAspectRatioMode(Qt::AspectRatioMode mode)
+void QPlatformVideoSink::setSubtitleText(const QString &subtitleText)
+{
+ {
+ QMutexLocker locker(&m_mutex);
+ if (m_subtitleText == subtitleText)
+ return;
+ m_subtitleText = subtitleText;
+ }
+ emit m_sink->subtitleTextChanged(subtitleText);
+}
- Sets the aspect ratio \a mode which determines how video is scaled to the fit the display region
- with respect to its aspect ratio.
-*/
+QString QPlatformVideoSink::subtitleText() const
+{
+ QMutexLocker locker(&m_mutex);
+ return m_subtitleText;
+}
QT_END_NAMESPACE
diff --git a/src/multimedia/platform/qplatformvideosink_p.h b/src/multimedia/platform/qplatformvideosink_p.h
index 95d1aa085..53eca374f 100644
--- a/src/multimedia/platform/qplatformvideosink_p.h
+++ b/src/multimedia/platform/qplatformvideosink_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPLATFORMVIDEOSINK_H
#define QPLATFORMVIDEOSINK_H
@@ -60,6 +24,7 @@
#include <qvideosink.h>
#include <qvideoframe.h>
#include <qdebug.h>
+#include <private/qglobal_p.h>
QT_BEGIN_NAMESPACE
@@ -71,6 +36,8 @@ class Q_MULTIMEDIA_EXPORT QPlatformVideoSink : public QObject
Q_OBJECT
public:
+ ~QPlatformVideoSink() override;
+
virtual void setRhi(QRhi * /*rhi*/) {}
virtual void setWinId(WId) {}
@@ -78,54 +45,34 @@ public:
virtual void setFullScreen(bool) {}
virtual void setAspectRatioMode(Qt::AspectRatioMode) {}
- // ### make non virtual, once Windows is ported
- virtual QSize nativeSize() const
- {
- QMutexLocker locker(&mutex);
- return m_nativeSize;
- }
+ QSize nativeSize() const;
virtual void setBrightness(float /*brightness*/) {}
virtual void setContrast(float /*contrast*/) {}
virtual void setHue(float /*hue*/) {}
virtual void setSaturation(float /*saturation*/) {}
- QVideoSink *videoSink() { return sink; }
-
- void setNativeSize(QSize s) {
- QMutexLocker locker(&mutex);
- if (m_nativeSize == s)
- return;
- m_nativeSize = s;
- sink->videoSizeChanged();
- }
- void setVideoFrame(const QVideoFrame &frame) {
- setNativeSize(frame.size());
- m_currentVideoFrame = frame;
- m_currentVideoFrame.setSubtitleText(subtitleText());
- sink->videoFrameChanged(m_currentVideoFrame);
- }
- QVideoFrame currentVideoFrame() const { return m_currentVideoFrame; }
-
- void setSubtitleText(const QString &subtitleText)
- {
- QMutexLocker locker(&mutex);
- if (m_subtitleText == subtitleText)
- return;
- m_subtitleText = subtitleText;
- sink->subtitleTextChanged(subtitleText);
- }
- QString subtitleText() const
- {
- QMutexLocker locker(&mutex);
- return m_subtitleText;
- }
+ QVideoSink *videoSink() { return m_sink; }
+
+ void setNativeSize(QSize s);
+
+ virtual void setVideoFrame(const QVideoFrame &frame);
+
+ QVideoFrame currentVideoFrame() const;
+
+ void setSubtitleText(const QString &subtitleText);
+
+ QString subtitleText() const;
protected:
explicit QPlatformVideoSink(QVideoSink *parent);
- QVideoSink *sink = nullptr;
- mutable QMutex mutex;
+
+Q_SIGNALS:
+ void rhiChanged(QRhi *rhi);
+
private:
+ QVideoSink *m_sink = nullptr;
+ mutable QMutex m_mutex;
QSize m_nativeSize;
QString m_subtitleText;
QVideoFrame m_currentVideoFrame;
diff --git a/src/multimedia/platform/qplatformvideosource.cpp b/src/multimedia/platform/qplatformvideosource.cpp
new file mode 100644
index 000000000..a23ed91ae
--- /dev/null
+++ b/src/multimedia/platform/qplatformvideosource.cpp
@@ -0,0 +1,15 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "qplatformvideosource_p.h"
+
+QT_BEGIN_NAMESPACE
+
+std::optional<int> QPlatformVideoSource::ffmpegHWPixelFormat() const
+{
+ return {};
+};
+
+QT_END_NAMESPACE
+
+//#include "moc_qplatformvideosource_p.cpp
diff --git a/src/multimedia/platform/qplatformvideosource_p.h b/src/multimedia/platform/qplatformvideosource_p.h
new file mode 100644
index 000000000..b11524226
--- /dev/null
+++ b/src/multimedia/platform/qplatformvideosource_p.h
@@ -0,0 +1,58 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QPLATFORMVIDEOSOURCE_P_H
+#define QPLATFORMVIDEOSOURCE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qvideoframeformat.h"
+
+#include <QtCore/qobject.h>
+#include <QtCore/qnativeinterface.h>
+#include <QtCore/private/qglobal_p.h>
+
+#include <optional>
+
+QT_BEGIN_NAMESPACE
+
+class QVideoFrame;
+class QPlatformMediaCaptureSession;
+
+class Q_MULTIMEDIA_EXPORT QPlatformVideoSource : public QObject
+{
+ Q_OBJECT
+public:
+ using QObject::QObject;
+
+ virtual void setActive(bool active) = 0;
+ virtual bool isActive() const = 0;
+
+ virtual QVideoFrameFormat frameFormat() const = 0;
+
+ virtual std::optional<int> ffmpegHWPixelFormat() const;
+
+ virtual void setCaptureSession(QPlatformMediaCaptureSession *) { }
+
+ virtual QString errorString() const = 0;
+
+ bool hasError() const { return !errorString().isEmpty(); }
+
+Q_SIGNALS:
+ void newVideoFrame(const QVideoFrame &);
+ void activeChanged(bool);
+ void errorChanged();
+};
+
+QT_END_NAMESPACE
+
+#endif // QPLATFORMVIDEOSOURCE_P_H
diff --git a/src/multimedia/platform/wasm/audio/qwasmaudiodevice.cpp b/src/multimedia/platform/wasm/audio/qwasmaudiodevice.cpp
deleted file mode 100644
index 5eb6a3816..000000000
--- a/src/multimedia/platform/wasm/audio/qwasmaudiodevice.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwasmaudiodevice_p.h"
-#include <emscripten.h>
-#include <AL/al.h>
-#include <AL/alc.h>
-
-QT_BEGIN_NAMESPACE
-
-QWasmAudioDevice::QWasmAudioDevice(const char *device, const char *desc, bool isDef, QAudioDevice::Mode mode)
- : QAudioDevicePrivate(device, mode)
-{
- description = QString::fromUtf8(desc);
- isDefault = isDef;
-
- minimumChannelCount = 1;
- maximumChannelCount = 2;
- minimumSampleRate = 1;
- maximumSampleRate = 192'000;
-
- // native openAL formats
- supportedSampleFormats.append(QAudioFormat::UInt8);
- supportedSampleFormats.append(QAudioFormat::Int16);
-
- // Browsers use 32bit floats as native, but emscripten reccomends checking for the exension.
- if (alIsExtensionPresent("AL_EXT_float32"))
- supportedSampleFormats.append(QAudioFormat::Float);
-
- preferredFormat.setChannelCount(2);
-
- preferredFormat.setSampleRate(EM_ASM_INT({
- var AudioContext = window.AudioContext || window.webkitAudioContext;
- var ctx = new AudioContext();
- var sr = ctx.sampleRate;
- ctx.close();
- return sr;
- }));
-
- auto f = QAudioFormat::Float;
-
- if (!supportedSampleFormats.contains(f))
- f = QAudioFormat::Int16;
- preferredFormat.setSampleFormat(f);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/wasm/audio/qwasmaudiodevice_p.h b/src/multimedia/platform/wasm/audio/qwasmaudiodevice_p.h
deleted file mode 100644
index fbe14e6e2..000000000
--- a/src/multimedia/platform/wasm/audio/qwasmaudiodevice_p.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWASMAUDIODEVICEINFO_H
-#define QWASMAUDIODEVICEINFO_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 "qaudiodevice_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QWasmAudioDevice : public QAudioDevicePrivate
-{
-public:
- QWasmAudioDevice(const char *device, const char *description, bool isDefault, QAudioDevice::Mode mode);
-
-};
-
-QT_END_NAMESPACE
-
-#endif // QWASMAUDIODEVICEINFO_H
diff --git a/src/multimedia/platform/wasm/audio/qwasmaudiosink.cpp b/src/multimedia/platform/wasm/audio/qwasmaudiosink.cpp
deleted file mode 100644
index 82456e0b6..000000000
--- a/src/multimedia/platform/wasm/audio/qwasmaudiosink.cpp
+++ /dev/null
@@ -1,487 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwasmaudiosink_p.h"
-
-
-#include <emscripten.h>
-#include <AL/al.h>
-#include <AL/alc.h>
-#include <QDebug>
-#include <QtMath>
-#include <QIODevice>
-
-// non native al formats (AL_EXT_float32)
-#define AL_FORMAT_MONO_FLOAT32 0x10010
-#define AL_FORMAT_STEREO_FLOAT32 0x10011
-
-constexpr unsigned int DEFAULT_BUFFER_DURATION = 50'000;
-
-class ALData {
-public:
- ALCcontext *context = nullptr;
- ALCdevice *device = nullptr;
- ALuint source;
- ALuint *buffers = nullptr;
- ALuint *buffer = nullptr;
- ALenum format;
-};
-
-QT_BEGIN_NAMESPACE
-
-class QWasmAudioSinkDevice : public QIODevice {
-
- QWasmAudioSink *m_out;
-
-public:
- QWasmAudioSinkDevice(QWasmAudioSink *parent);
-
-protected:
- qint64 readData(char *data, qint64 maxlen) override;
- qint64 writeData(const char *data, qint64 len) override;
-};
-
-QWasmAudioSink::QWasmAudioSink(const QByteArray &device) : m_name(device)
-{
- m_timer.setSingleShot(false);
- aldata = new ALData();
- connect(&m_timer, &QTimer::timeout, this, [this](){
- if (m_pullMode)
- nextALBuffers();
- else {
- unloadALBuffers();
- m_device->write(nullptr, 0);
- updateState();
- }
- });
-}
-
-QWasmAudioSink::~QWasmAudioSink()
-{
- delete aldata;
- if (m_tmpData)
- delete[] m_tmpData;
-}
-
-void QWasmAudioSink::start(QIODevice *device)
-{
- Q_ASSERT(device);
- Q_ASSERT(device->openMode().testFlag(QIODevice::ReadOnly));
- m_device = device;
- start(true);
-}
-
-QIODevice *QWasmAudioSink::start()
-{
- m_device = new QWasmAudioSinkDevice(this);
- m_device->open(QIODevice::WriteOnly);
- start(false);
- return m_device;
-}
-
-void QWasmAudioSink::start(bool mode)
-{
- auto formatError = [this](){
- qWarning() << "Unsupported audio format " << m_format;
- setError(QAudio::OpenError);
- };
- switch (m_format.sampleFormat()) {
- case QAudioFormat::UInt8:
- switch (m_format.channelCount()) {
- case 1:
- aldata->format = AL_FORMAT_MONO8;
- break;
- case 2:
- aldata->format = AL_FORMAT_STEREO8;
- break;
- default:
- return formatError();
- }
- break;
- case QAudioFormat::Int16:
- switch (m_format.channelCount()) {
- case 1:
- aldata->format = AL_FORMAT_MONO16;
- break;
- case 2:
- aldata->format = AL_FORMAT_STEREO16;
- break;
- default:
- return formatError();
- }
- break;
- case QAudioFormat::Float:
- switch (m_format.channelCount()) {
- case 1:
- aldata->format = AL_FORMAT_MONO_FLOAT32;
- break;
- case 2:
- aldata->format = AL_FORMAT_STEREO_FLOAT32;
- break;
- default:
- return formatError();
- }
- break;
- default:
- return formatError();
- }
-
- alGetError();
- aldata->device = alcOpenDevice(m_name.data());
- if (!aldata->device) {
- qWarning() << "Failed to open audio device" << alGetString(alGetError());
- return setError(QAudio::OpenError);
- }
- ALint attrlist[] = {ALC_FREQUENCY, m_format.sampleRate(), 0};
- aldata->context = alcCreateContext(aldata->device, attrlist);
-
- if (!aldata->context) {
- qWarning() << "Failed to create audio context" << alGetString(alGetError());
- return setError(QAudio::OpenError);
- }
- alcMakeContextCurrent(aldata->context);
-
-
- alGenSources(1, &aldata->source);
-
- if (m_bufferSize > 0)
- m_bufferFragmentsCount = qMax(2,qCeil((qreal)m_bufferSize/(m_bufferFragmentSize)));
- m_bufferSize = m_bufferFragmentsCount * m_bufferFragmentSize;
- aldata->buffers = new ALuint[m_bufferFragmentsCount];
- aldata->buffer = aldata->buffers;
- alGenBuffers(m_bufferFragmentsCount, aldata->buffers);
- m_processed = 0;
- m_tmpDataOffset = 0;
- m_pullMode = mode;
- alSourcef(aldata->source, AL_GAIN, m_volume);
- if (m_pullMode)
- loadALBuffers();
- m_timer.setInterval(DEFAULT_BUFFER_DURATION / 3000);
- m_timer.start();
- if (m_pullMode)
- alSourcePlay(aldata->source);
- m_running = true;
- m_elapsedTimer.start();
- updateState();
-}
-
-void QWasmAudioSink::stop()
-{
- if (!m_running)
- return;
- m_elapsedTimer.invalidate();
- alSourceStop(aldata->source);
- alSourceRewind(aldata->source);
- m_timer.stop();
- m_bufferFragmentsBusyCount = 0;
- alDeleteSources(1, &aldata->source);
- alDeleteBuffers(m_bufferFragmentsCount, aldata->buffers);
- delete[] aldata->buffers;
- alcMakeContextCurrent(nullptr);
- alcDestroyContext(aldata->context);
- alcCloseDevice(aldata->device);
- m_running = false;
- m_processed = 0;
- if (!m_pullMode)
- m_device->deleteLater();
- updateState();
-}
-
-void QWasmAudioSink::reset()
-{
- stop();
- m_error = QAudio::NoError;
-}
-
-void QWasmAudioSink::suspend()
-{
- if (!m_running)
- return;
-
- alSourcePause(aldata->source);
-}
-
-void QWasmAudioSink::resume()
-{
- if (!m_running)
- return;
-
- alSourcePlay(aldata->source);
-}
-
-int QWasmAudioSink::bytesFree() const
-{
- int processed;
- alGetSourcei(aldata->source, AL_BUFFERS_PROCESSED, &processed);
- return m_running ? m_bufferFragmentSize * (m_bufferFragmentsCount - m_bufferFragmentsBusyCount
- + processed) : 0;
-}
-
-void QWasmAudioSink::setBufferSize(int value)
-{
- if (m_running)
- return;
-
- m_bufferSize = value;
-}
-
-int QWasmAudioSink::bufferSize() const
-{
- return m_bufferSize;
-}
-
-qint64 QWasmAudioSink::processedUSecs() const
-{
- int processed;
- alGetSourcei(aldata->source, AL_BUFFERS_PROCESSED, &processed);
- return m_format.durationForBytes(m_processed + m_format.bytesForDuration(
- DEFAULT_BUFFER_DURATION * processed));
-}
-
-QAudio::Error QWasmAudioSink::error() const
-{
- return m_error;
-}
-
-QAudio::State QWasmAudioSink::state() const
-{
- if (!m_running)
- return QAudio::StoppedState;
- ALint state;
- alGetSourcei(aldata->source, AL_SOURCE_STATE, &state);
- switch (state) {
- case AL_INITIAL:
- return QAudio::IdleState;
- case AL_PLAYING:
- return QAudio::ActiveState;
- case AL_PAUSED:
- return QAudio::SuspendedState;
- case AL_STOPPED:
- return m_running ? QAudio::IdleState : QAudio::StoppedState;
- }
- return QAudio::StoppedState;
-}
-
-void QWasmAudioSink::setFormat(const QAudioFormat &fmt)
-{
- if (m_running)
- return;
- m_format = fmt;
- if (m_tmpData)
- delete[] m_tmpData;
- m_bufferFragmentSize = m_format.bytesForDuration(DEFAULT_BUFFER_DURATION);
- m_bufferSize = m_bufferFragmentSize * m_bufferFragmentsCount;
- m_tmpData = new char[m_bufferFragmentSize];
-}
-
-QAudioFormat QWasmAudioSink::format() const
-{
- return m_format;
-}
-
-void QWasmAudioSink::setVolume(qreal volume)
-{
- if (m_volume == volume)
- return;
- m_volume = volume;
- if (m_running)
- alSourcef(aldata->source, AL_GAIN, volume);
-}
-
-qreal QWasmAudioSink::volume() const
-{
- return m_volume;
-}
-
-void QWasmAudioSink::loadALBuffers()
-{
- if (m_bufferFragmentsBusyCount == m_bufferFragmentsCount)
- return;
-
- auto size = m_device->read(m_tmpData + m_tmpDataOffset, m_bufferFragmentSize -
- m_tmpDataOffset);
- m_tmpDataOffset += size;
- if (!m_tmpDataOffset || (m_tmpDataOffset != m_bufferFragmentSize &&
- m_bufferFragmentsBusyCount >= m_bufferFragmentsCount * 2 / 3))
- return;
-
- alBufferData(*aldata->buffer, aldata->format, m_tmpData, m_tmpDataOffset,
- m_format.sampleRate());
- m_tmpDataOffset = 0;
- alGetError();
- alSourceQueueBuffers(aldata->source, 1, aldata->buffer);
- if (alGetError())
- return;
-
- m_bufferFragmentsBusyCount++;
- m_processed += size;
- if (++aldata->buffer == aldata->buffers + m_bufferFragmentsCount)
- aldata->buffer = aldata->buffers;
-}
-
-void QWasmAudioSink::unloadALBuffers()
-{
- int processed;
- alGetSourcei(aldata->source, AL_BUFFERS_PROCESSED, &processed);
-
- if (processed) {
- auto head = aldata->buffer - m_bufferFragmentsBusyCount;
- if (head < aldata->buffers) {
- if (head + processed > aldata->buffers) {
- auto batch = m_bufferFragmentsBusyCount - (aldata->buffer - aldata->buffers);
- alGetError();
- alSourceUnqueueBuffers(aldata->source, batch, head + m_bufferFragmentsCount);
- if (!alGetError()) {
- m_bufferFragmentsBusyCount -= batch;
- m_processed += m_bufferFragmentSize*batch;
- }
- processed -= batch;
- if (!processed)
- return;
- head = aldata->buffers;
- } else {
- head += m_bufferFragmentsCount;
- }
- }
- alGetError();
- alSourceUnqueueBuffers(aldata->source, processed, head);
- if (!alGetError())
- m_bufferFragmentsBusyCount -= processed;
- }
-}
-
-void QWasmAudioSink::nextALBuffers()
-{
- updateState();
- unloadALBuffers();
- loadALBuffers();
- ALint state;
- alGetSourcei(aldata->source, AL_SOURCE_STATE, &state);
- if (state != AL_PLAYING)
- alSourcePlay(aldata->source);
- updateState();
-}
-
-void QWasmAudioSink::updateState()
-{
- auto current = state();
- if (m_state == current)
- return;
- m_state = current;
-
- if (m_state == QAudio::IdleState && m_running)
- setError(QAudio::UnderrunError);
-
- emit stateChanged(m_state);
-
-}
-
-void QWasmAudioSink::setError(QAudio::Error error)
-{
- if (error == m_error)
- return;
- m_error = error;
- emit errorChanged(error);
-}
-
-QWasmAudioSinkDevice::QWasmAudioSinkDevice(QWasmAudioSink *parent) : QIODevice(parent),
- m_out(parent)
-{
-}
-
-qint64 QWasmAudioSinkDevice::readData(char *data, qint64 maxlen)
-{
- Q_UNUSED(data)
- Q_UNUSED(maxlen)
- return 0;
-}
-
-
-qint64 QWasmAudioSinkDevice::writeData(const char *data, qint64 len)
-{
- ALint state;
- alGetSourcei(m_out->aldata->source, AL_SOURCE_STATE, &state);
- if (state != AL_INITIAL)
- m_out->unloadALBuffers();
- if (m_out->m_bufferFragmentsBusyCount < m_out->m_bufferFragmentsCount) {
- bool exceeds = m_out->m_tmpDataOffset + len > m_out->m_bufferFragmentSize;
- bool flush = m_out->m_bufferFragmentsBusyCount < m_out->m_bufferFragmentsCount * 2 / 3 ||
- m_out->m_tmpDataOffset + len >= m_out->m_bufferFragmentSize;
- const char *read;
- char *tmp = m_out->m_tmpData;
- int size = 0;
- if (m_out->m_tmpDataOffset && exceeds) {
- size = m_out->m_tmpDataOffset + len;
- tmp = new char[m_out->m_tmpDataOffset + len];
- std::memcpy(tmp, m_out->m_tmpData, m_out->m_tmpDataOffset);
- }
- if (flush && !m_out->m_tmpDataOffset) {
- read = data;
- size = len;
- } else {
- std::memcpy(tmp + m_out->m_tmpDataOffset, data, len);
- read = tmp;
- if (!exceeds) {
- m_out->m_tmpDataOffset += len;
- size = m_out->m_tmpDataOffset;
- }
- }
- m_out->m_processed += size;
- if (size && flush) {
- alBufferData(*m_out->aldata->buffer, m_out->aldata->format, read, size,
- m_out->m_format.sampleRate());
- if (tmp && tmp != m_out->m_tmpData)
- delete[] tmp;
- m_out->m_tmpDataOffset = 0;
- alGetError();
- alSourceQueueBuffers(m_out->aldata->source, 1, m_out->aldata->buffer);
- if (alGetError())
- return 0;
- m_out->m_bufferFragmentsBusyCount++;
- if (++m_out->aldata->buffer == m_out->aldata->buffers + m_out->m_bufferFragmentsCount)
- m_out->aldata->buffer = m_out->aldata->buffers;
- if (state != AL_PLAYING)
- alSourcePlay(m_out->aldata->source);
- }
- return len;
- }
- return 0;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/wasm/audio/qwasmaudiosink_p.h b/src/multimedia/platform/wasm/audio/qwasmaudiosink_p.h
deleted file mode 100644
index 1c75ec258..000000000
--- a/src/multimedia/platform/wasm/audio/qwasmaudiosink_p.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWASMAUDIOSINK_H
-#define QWASMAUDIOSINK_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 <private/qaudiosystem_p.h>
-#include <QTimer>
-#include <QElapsedTimer>
-
-class ALData;
-class QIODevice;
-
-QT_BEGIN_NAMESPACE
-
-class QWasmAudioSink : public QPlatformAudioSink
-{
- Q_OBJECT
-
- QByteArray m_name;
- ALData *aldata = nullptr;
- QTimer m_timer;
- QIODevice *m_device = nullptr;
- QAudioFormat m_format;
- QAudio::Error m_error = QAudio::NoError;
- bool m_running = false;
- QAudio::State m_state = QAudio::StoppedState;
- int m_bufferSize = 0;
- quint64 m_processed = 0;
- QElapsedTimer m_elapsedTimer;
- int m_bufferFragmentsCount = 10;
- int m_notifyInterval = 0;
- char *m_tmpData = nullptr;
- int m_bufferFragmentSize = 0;
- int m_lastNotified = 0;
- int m_tmpDataOffset = 0;
- int m_bufferFragmentsBusyCount = 0;
- bool m_pullMode;
- qreal m_volume = 1;
-
- void loadALBuffers();
- void unloadALBuffers();
- void nextALBuffers();
-
-private slots:
- void updateState();
- void setError(QAudio::Error);
-
-public:
- QWasmAudioSink(const QByteArray &device);
- ~QWasmAudioSink();
-
-public:
- void start(QIODevice *device) override;
- QIODevice *start() override;
- void start(bool mode);
- void stop() override;
- void reset() override;
- void suspend() override;
- void resume() override;
- int bytesFree() const override;
- void setBufferSize(int value) override;
- int bufferSize() const override;
- qint64 processedUSecs() const override;
- QAudio::Error error() const override;
- QAudio::State state() const override;
- void setFormat(const QAudioFormat &fmt) override;
- QAudioFormat format() const override;
- void setVolume(qreal volume) override;
- qreal volume() const override;
-
- friend class QWasmAudioSinkDevice;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWASMAUDIOSINK_H
diff --git a/src/multimedia/platform/wasm/audio/qwasmaudiosource.cpp b/src/multimedia/platform/wasm/audio/qwasmaudiosource.cpp
deleted file mode 100644
index 981eeefc0..000000000
--- a/src/multimedia/platform/wasm/audio/qwasmaudiosource.cpp
+++ /dev/null
@@ -1,347 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwasmaudiosource_p.h"
-
-#include <emscripten.h>
-#include <AL/al.h>
-#include <AL/alc.h>
-#include <QDataStream>
-#include <QDebug>
-#include <QtMath>
-#include <private/qaudiohelpers_p.h>
-#include <QIODevice>
-
-QT_BEGIN_NAMESPACE
-
-#define AL_FORMAT_MONO_FLOAT32 0x10010
-#define AL_FORMAT_STEREO_FLOAT32 0x10011
-
-constexpr unsigned int DEFAULT_BUFFER_DURATION = 50'000;
-
-class QWasmAudioSourceDevice : public QIODevice
-{
- QWasmAudioSource *m_in;
-
-public:
- explicit QWasmAudioSourceDevice(QWasmAudioSource *in);
-
-protected:
- qint64 readData(char *data, qint64 maxlen) override;
- qint64 writeData(const char *data, qint64 len) override;
-};
-
-class ALData {
-public:
- ALCdevice *device = nullptr;
- ALCcontext *context = nullptr;
-};
-
-void QWasmAudioSource::setError(const QAudio::Error &error)
-{
- if (m_error == error)
- return;
- m_error = error;
- emit errorChanged(error);
-}
-
-void QWasmAudioSource::writeBuffer()
-{
- int samples = 0;
- alcGetIntegerv(aldata->device, ALC_CAPTURE_SAMPLES, 1, &samples);
- samples = qMin(samples, m_format.framesForBytes(m_bufferSize));
- auto bytes = m_format.bytesForFrames(samples);
- auto err = alcGetError(aldata->device);
- alcCaptureSamples(aldata->device, m_tmpData, samples);
- err = alcGetError(aldata->device);
- if (err) {
- qWarning() << alcGetString(aldata->device, err);
- return setError(QAudio::FatalError);
- }
- if (m_volume < 1)
- QAudioHelperInternal::qMultiplySamples(m_volume, m_format, m_tmpData, m_tmpData, bytes);
- m_processed += bytes;
- m_device->write(m_tmpData,bytes);
-}
-
-QWasmAudioSource::QWasmAudioSource(const QByteArray &device)
- : QPlatformAudioSource(), m_name(device)
-{
- aldata = new ALData();
- connect(&m_timer, &QTimer::timeout, this, [this](){
- Q_ASSERT(m_running);
- if (m_pullMode)
- writeBuffer();
- else
- if (bytesReady() > 0)
- emit m_device->readyRead();
- });
-}
-
-void QWasmAudioSource::start(QIODevice *device)
-{
- m_device = device;
- start(true);
-}
-
-QIODevice *QWasmAudioSource::start()
-{
- m_device = new QWasmAudioSourceDevice(this);
- m_device->open(QIODevice::ReadOnly);
- start(false);
- return m_device;
-}
-
-void QWasmAudioSource::start(bool mode)
-{
- m_pullMode = mode;
- auto formatError = [this](){
- qWarning() << "Unsupported audio format " << m_format;
- setError(QAudio::OpenError);
- };
- ALCenum format;
- switch (m_format.sampleFormat()) {
- case QAudioFormat::UInt8:
- switch (m_format.channelCount()) {
- case 1:
- format = AL_FORMAT_MONO8;
- break;
- case 2:
- format = AL_FORMAT_STEREO8;
- break;
- default:
- return formatError();
- }
- break;
- case QAudioFormat::Int16:
- switch (m_format.channelCount()) {
- case 1:
- format = AL_FORMAT_MONO16;
- break;
- case 2:
- format = AL_FORMAT_STEREO16;
- break;
- default:
- return formatError();
- }
- break;
- case QAudioFormat::Float:
- switch (m_format.channelCount()) {
- case 1:
- format = AL_FORMAT_MONO_FLOAT32;
- break;
- case 2:
- format = AL_FORMAT_STEREO_FLOAT32;
- break;
- default:
- return formatError();
- }
- break;
- default:
- return formatError();
- }
- if (m_tmpData)
- delete[] m_tmpData;
- if (m_pullMode)
- m_tmpData = new char[m_bufferSize];
- else
- m_tmpData = nullptr;
- m_timer.setInterval(m_format.durationForBytes(m_bufferSize) / 3'000);
-
- aldata->device = alcCaptureOpenDevice(m_name.data(), m_format.sampleRate(), format,
- m_format.framesForBytes(m_bufferSize));
-
- auto err = alcGetError(aldata->device);
- if (err) {
- qWarning() << "alcCaptureOpenDevice" << alcGetString(aldata->device, err);
- return setError(QAudio::OpenError);
- }
- alcCaptureStart(aldata->device);
- m_elapsedTimer.start();
- auto cerr = alcGetError(aldata->device);
- if (cerr) {
- qWarning() << "alcCaptureStart" << alcGetString(aldata->device, cerr);
- return setError(QAudio::OpenError);
- }
- m_processed = 0;
- m_running = true;
- m_timer.start();
-}
-
-void QWasmAudioSource::stop()
-{
- if (m_pullMode)
- writeBuffer();
- alcCaptureStop(aldata->device);
- alcCaptureCloseDevice(aldata->device);
- m_elapsedTimer.invalidate();
- if (m_tmpData) {
- delete[] m_tmpData;
- m_tmpData = nullptr;
- }
- if (!m_pullMode)
- m_device->deleteLater();
- m_timer.stop();
- m_running = false;
-}
-
-void QWasmAudioSource::reset()
-{
- stop();
- if (m_tmpData) {
- delete[] m_tmpData;
- m_tmpData = nullptr;
- }
- m_running = false;
- m_processed = 0;
- m_error = QAudio::NoError;
-}
-
-void QWasmAudioSource::suspend()
-{
- if (!m_running)
- return;
-
- m_suspended = true;
- alcCaptureStop(aldata->device);
-}
-
-void QWasmAudioSource::resume()
-{
- if (!m_running)
- return;
-
- m_suspended = false;
- alcCaptureStart(aldata->device);
-}
-
-int QWasmAudioSource::bytesReady() const
-{
- if (!m_running)
- return 0;
- int samples;
- alcGetIntegerv(aldata->device, ALC_CAPTURE_SAMPLES, 1, &samples);
- return m_format.bytesForFrames(samples);
-}
-
-void QWasmAudioSource::setBufferSize(int value)
-{
- if (!m_running)
- return;
- m_bufferSize = value;
-}
-
-int QWasmAudioSource::bufferSize() const
-{
- return m_bufferSize;
-}
-
-qint64 QWasmAudioSource::processedUSecs() const
-{
- return m_format.durationForBytes(m_processed);
-}
-
-QAudio::Error QWasmAudioSource::error() const
-{
- return m_error;
-}
-
-QAudio::State QWasmAudioSource::state() const
-{
- if (m_running)
- return QAudio::ActiveState;
- else
- return QAudio::StoppedState;
-}
-
-void QWasmAudioSource::setFormat(const QAudioFormat &fmt)
-{
- m_format = fmt;
- m_bufferSize = m_format.bytesForDuration(DEFAULT_BUFFER_DURATION);
-}
-
-QAudioFormat QWasmAudioSource::format() const
-{
- return m_format;
-}
-
-void QWasmAudioSource::setVolume(qreal volume)
-{
- m_volume = volume;
-}
-
-qreal QWasmAudioSource::volume() const
-{
- return m_volume;
-}
-
-QWasmAudioSourceDevice::QWasmAudioSourceDevice(QWasmAudioSource *in) : QIODevice(in), m_in(in)
-{
-
-}
-
-qint64 QWasmAudioSourceDevice::readData(char *data, qint64 maxlen)
-{
- int samples;
- alcGetIntegerv(m_in->aldata->device, ALC_CAPTURE_SAMPLES, 1, &samples);
- samples = qMin(samples, m_in->m_format.framesForBytes(maxlen));
- auto bytes = m_in->m_format.bytesForFrames(samples);
- alcGetError(m_in->aldata->device);
- alcCaptureSamples(m_in->aldata->device, data, samples);
- if (m_in->m_volume < 1)
- QAudioHelperInternal::qMultiplySamples(m_in->m_volume, m_in->m_format, data, data, bytes);
- auto err = alcGetError(m_in->aldata->device);
- if (err) {
- qWarning() << alcGetString(m_in->aldata->device, err);
- m_in->setError(QAudio::FatalError);
- return 0;
- }
- m_in->m_processed += bytes;
- return bytes;
-}
-
-qint64 QWasmAudioSourceDevice::writeData(const char *data, qint64 len)
-{
- Q_UNREACHABLE();
- Q_UNUSED(data);
- Q_UNUSED(len);
- return 0;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/wasm/audio/qwasmaudiosource_p.h b/src/multimedia/platform/wasm/audio/qwasmaudiosource_p.h
deleted file mode 100644
index aef81d75b..000000000
--- a/src/multimedia/platform/wasm/audio/qwasmaudiosource_p.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWASMAUDIOSOURCE_H
-#define QWASMAUDIOSOURCE_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 <private/qaudiosystem_p.h>
-#include <QTimer>
-#include <QElapsedTimer>
-
-QT_BEGIN_NAMESPACE
-
-class ALData;
-
-class QWasmAudioSource : public QPlatformAudioSource
-{
- Q_OBJECT
-
- QByteArray m_name;
- ALData *aldata = nullptr;
- QTimer m_timer;
- QIODevice *m_device = nullptr;
- QAudioFormat m_format;
- qreal m_volume = 1;
- int m_bufferSize;
- bool m_running = false;
- bool m_suspended = false;
- QAudio::Error m_error;
- bool m_pullMode;
- char *m_tmpData = nullptr;
- QElapsedTimer m_elapsedTimer;
- int m_notifyInterval = 0;
- quint64 m_processed = 0;
-
- void writeBuffer();
-public:
- QWasmAudioSource(const QByteArray &device);
-
-public:
- void start(QIODevice *device) override;
- QIODevice *start() override;
- void start(bool mode);
- void stop() override;
- void reset() override;
- void suspend() override;
- void resume() override;
- int bytesReady() const override;
- void setBufferSize(int value) override;
- int bufferSize() const override;
- qint64 processedUSecs() const override;
- QAudio::Error error() const override;
- QAudio::State state() const override;
- void setFormat(const QAudioFormat &fmt) override;
- QAudioFormat format() const override;
- void setVolume(qreal volume) override;
- qreal volume() const override;
-
- friend class QWasmAudioSourceDevice;
- void setError(const QAudio::Error &error);
-};
-
-QT_END_NAMESPACE
-
-#endif // QWASMAUDIOSOURCE_H
diff --git a/src/multimedia/platform/wasm/qwasmmediadevices.cpp b/src/multimedia/platform/wasm/qwasmmediadevices.cpp
deleted file mode 100644
index c21533943..000000000
--- a/src/multimedia/platform/wasm/qwasmmediadevices.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwasmmediadevices_p.h"
-#include "qcameradevice_p.h"
-
-#include "audio/qwasmaudiosource_p.h"
-#include "audio/qwasmaudiosink_p.h"
-#include "audio/qwasmaudiodevice_p.h"
-#include <AL/al.h>
-#include <AL/alc.h>
-
-QT_BEGIN_NAMESPACE
-
-QWasmMediaDevices::QWasmMediaDevices()
- : QPlatformMediaDevices()
-{
- auto capture = alcGetString(nullptr, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
- // present even if there is no capture device
- if (capture)
- m_ins.append((new QWasmAudioDevice(capture, "WebAssembly audio capture device", true,
- QAudioDevice::Input))->create());
-
- auto playback = alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER);
- // present even if there is no playback device
- if (playback)
- m_outs.append((new QWasmAudioDevice(playback, "WebAssembly audio playback device", true,
- QAudioDevice::Output))->create());
-}
-
-QList<QAudioDevice> QWasmMediaDevices::audioInputs() const
-{
- return m_ins;
-}
-
-QList<QAudioDevice> QWasmMediaDevices::audioOutputs() const
-{
- return m_outs;
-}
-
-QList<QCameraDevice> QWasmMediaDevices::videoInputs() const
-{
- return {};
-}
-
-QPlatformAudioSource *QWasmMediaDevices::createAudioSource(const QAudioDevice &deviceInfo)
-{
- return new QWasmAudioSource(deviceInfo.id());
-}
-
-QPlatformAudioSink *QWasmMediaDevices::createAudioSink(const QAudioDevice &deviceInfo)
-{
- return new QWasmAudioSink(deviceInfo.id());
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/wasm/qwasmmediadevices_p.h b/src/multimedia/platform/wasm/qwasmmediadevices_p.h
deleted file mode 100644
index 63fa05476..000000000
--- a/src/multimedia/platform/wasm/qwasmmediadevices_p.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWASMMEDIADEVICES_H
-#define QWASMMEDIADEVICES_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 <private/qplatformmediadevices_p.h>
-#include <qset.h>
-#include <qaudio.h>
-#include <qaudiodevice.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWasmAudioEngine;
-
-class QWasmMediaDevices : public QPlatformMediaDevices
-{
-public:
- QWasmMediaDevices();
-
- QList<QAudioDevice> audioInputs() const override;
- QList<QAudioDevice> audioOutputs() const override;
- QList<QCameraDevice> videoInputs() const override;
- QPlatformAudioSource *createAudioSource(const QAudioDevice &deviceInfo) override;
- QPlatformAudioSink *createAudioSink(const QAudioDevice &deviceInfo) override;
-
-private:
- QList<QAudioDevice> m_outs;
- QList<QAudioDevice> m_ins;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/wasm/qwasmmediaintegration.cpp b/src/multimedia/platform/wasm/qwasmmediaintegration.cpp
deleted file mode 100644
index 30ee3cca9..000000000
--- a/src/multimedia/platform/wasm/qwasmmediaintegration.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwasmmediaintegration_p.h"
-#include "qwasmmediadevices_p.h"
-#include <QLoggingCategory>
-
-#include <private/qplatformmediaformatinfo_p.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(qtWasmMediaPlugin, "qt.multimedia.wasm")
-
-QWasmMediaIntegration::QWasmMediaIntegration()
-{
-
-}
-
-QWasmMediaIntegration::~QWasmMediaIntegration()
-{
- delete m_devices;
- delete m_formatInfo;
-}
-
-QPlatformMediaFormatInfo *QWasmMediaIntegration::formatInfo()
-{
- if (!m_formatInfo)
- m_formatInfo = new QPlatformMediaFormatInfo();
- return m_formatInfo;
-}
-
-QPlatformMediaDevices *QWasmMediaIntegration::devices()
-{
- if (!m_devices)
- m_devices = new QWasmMediaDevices();
- return m_devices;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/wasm/qwasmmediaintegration_p.h b/src/multimedia/platform/wasm/qwasmmediaintegration_p.h
deleted file mode 100644
index 1251dc9f5..000000000
--- a/src/multimedia/platform/wasm/qwasmmediaintegration_p.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWASMMEDIAINTEGRATION_H
-#define QWASMMEDIAINTEGRATION_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 <private/qplatformmediaintegration_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWasmMediaDevices;
-
-class QWasmMediaIntegration : public QPlatformMediaIntegration
-{
-public:
- QWasmMediaIntegration();
- ~QWasmMediaIntegration();
-
- QPlatformMediaFormatInfo *formatInfo() override;
-
- QWasmMediaDevices *m_devices = nullptr;
- QPlatformMediaFormatInfo *m_formatInfo = nullptr;
-
- QPlatformMediaDevices *devices() override;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWASMMEDIAINTEGRATION_H
diff --git a/src/multimedia/platform/windows/audio/qwindowsaudiodevice.cpp b/src/multimedia/platform/windows/audio/qwindowsaudiodevice.cpp
deleted file mode 100644
index 793d1472f..000000000
--- a/src/multimedia/platform/windows/audio/qwindowsaudiodevice.cpp
+++ /dev/null
@@ -1,230 +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$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// INTERNAL USE ONLY: Do NOT use for any other purpose.
-//
-
-
-#include <QtCore/qt_windows.h>
-#include <QtCore/QDataStream>
-#include <QtCore/QIODevice>
-#include <mmsystem.h>
-#include "qwindowsaudiodevice_p.h"
-#include "qwindowsaudioutils_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QWindowsAudioDeviceInfo::QWindowsAudioDeviceInfo(QByteArray dev, int waveID, const QString &description, QAudioDevice::Mode mode)
- : QAudioDevicePrivate(dev, mode),
- devId(waveID)
-{
- this->description = description;
- preferredFormat.setSampleRate(44100);
- preferredFormat.setChannelCount(2);
- preferredFormat.setSampleFormat(QAudioFormat::Int16);
-
- DWORD fmt = 0;
-
- if(mode == QAudioDevice::Output) {
- WAVEOUTCAPS woc;
- if (waveOutGetDevCaps(devId, &woc, sizeof(WAVEOUTCAPS)) == MMSYSERR_NOERROR)
- fmt = woc.dwFormats;
- } else {
- WAVEINCAPS woc;
- if (waveInGetDevCaps(devId, &woc, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR)
- fmt = woc.dwFormats;
- }
-
- if (!fmt)
- return;
-
- // Check sample size
- if ((fmt & WAVE_FORMAT_1M08)
- || (fmt & WAVE_FORMAT_1S08)
- || (fmt & WAVE_FORMAT_2M08)
- || (fmt & WAVE_FORMAT_2S08)
- || (fmt & WAVE_FORMAT_4M08)
- || (fmt & WAVE_FORMAT_4S08)
- || (fmt & WAVE_FORMAT_48M08)
- || (fmt & WAVE_FORMAT_48S08)
- || (fmt & WAVE_FORMAT_96M08)
- || (fmt & WAVE_FORMAT_96S08)) {
- supportedSampleFormats.append(QAudioFormat::UInt8);
- }
- if ((fmt & WAVE_FORMAT_1M16)
- || (fmt & WAVE_FORMAT_1S16)
- || (fmt & WAVE_FORMAT_2M16)
- || (fmt & WAVE_FORMAT_2S16)
- || (fmt & WAVE_FORMAT_4M16)
- || (fmt & WAVE_FORMAT_4S16)
- || (fmt & WAVE_FORMAT_48M16)
- || (fmt & WAVE_FORMAT_48S16)
- || (fmt & WAVE_FORMAT_96M16)
- || (fmt & WAVE_FORMAT_96S16)) {
- supportedSampleFormats.append(QAudioFormat::Int16);
- }
-
- minimumSampleRate = std::numeric_limits<int>::max();
- maximumSampleRate = 0;
- // Check sample rate
- if ((fmt & WAVE_FORMAT_1M08)
- || (fmt & WAVE_FORMAT_1S08)
- || (fmt & WAVE_FORMAT_1M16)
- || (fmt & WAVE_FORMAT_1S16)) {
- minimumSampleRate = qMin(minimumSampleRate, 11025);
- maximumSampleRate = qMax(maximumSampleRate, 11025);
- }
- if ((fmt & WAVE_FORMAT_2M08)
- || (fmt & WAVE_FORMAT_2S08)
- || (fmt & WAVE_FORMAT_2M16)
- || (fmt & WAVE_FORMAT_2S16)) {
- minimumSampleRate = qMin(minimumSampleRate, 22050);
- maximumSampleRate = qMax(maximumSampleRate, 22050);
- }
- if ((fmt & WAVE_FORMAT_4M08)
- || (fmt & WAVE_FORMAT_4S08)
- || (fmt & WAVE_FORMAT_4M16)
- || (fmt & WAVE_FORMAT_4S16)) {
- minimumSampleRate = qMin(minimumSampleRate, 44100);
- maximumSampleRate = qMax(maximumSampleRate, 44100);
- }
- if ((fmt & WAVE_FORMAT_48M08)
- || (fmt & WAVE_FORMAT_48S08)
- || (fmt & WAVE_FORMAT_48M16)
- || (fmt & WAVE_FORMAT_48S16)) {
- minimumSampleRate = qMin(minimumSampleRate, 48000);
- maximumSampleRate = qMax(maximumSampleRate, 48000);
- }
- if ((fmt & WAVE_FORMAT_96M08)
- || (fmt & WAVE_FORMAT_96S08)
- || (fmt & WAVE_FORMAT_96M16)
- || (fmt & WAVE_FORMAT_96S16)) {
- minimumSampleRate = qMin(minimumSampleRate, 96000);
- maximumSampleRate = qMax(maximumSampleRate, 96000);
- }
- if (minimumSampleRate == std::numeric_limits<int>::max())
- minimumSampleRate = 0;
-
- minimumChannelCount = std::numeric_limits<int>::max();
- maximumChannelCount = 0;
- // Check channel count
- if (fmt & WAVE_FORMAT_1M08
- || fmt & WAVE_FORMAT_1M16
- || fmt & WAVE_FORMAT_2M08
- || fmt & WAVE_FORMAT_2M16
- || fmt & WAVE_FORMAT_4M08
- || fmt & WAVE_FORMAT_4M16
- || fmt & WAVE_FORMAT_48M08
- || fmt & WAVE_FORMAT_48M16
- || fmt & WAVE_FORMAT_96M08
- || fmt & WAVE_FORMAT_96M16) {
- minimumChannelCount = 1;
- maximumChannelCount = 1;
- }
- if (fmt & WAVE_FORMAT_1S08
- || fmt & WAVE_FORMAT_1S16
- || fmt & WAVE_FORMAT_2S08
- || fmt & WAVE_FORMAT_2S16
- || fmt & WAVE_FORMAT_4S08
- || fmt & WAVE_FORMAT_4S16
- || fmt & WAVE_FORMAT_48S08
- || fmt & WAVE_FORMAT_48S16
- || fmt & WAVE_FORMAT_96S08
- || fmt & WAVE_FORMAT_96S16) {
- minimumChannelCount = qMin(minimumChannelCount, 2);
- maximumChannelCount = qMax(maximumChannelCount, 2);
- }
-
- if (minimumChannelCount == std::numeric_limits<int>::max())
- minimumChannelCount = 0;
-
- // WAVEOUTCAPS and WAVEINCAPS contains information only for the previously tested parameters.
- // WaveOut and WaveInt might actually support more formats, the only way to know is to try
- // opening the device with it.
- QAudioFormat testFormat;
- testFormat.setChannelCount(maximumChannelCount);
- testFormat.setSampleRate(maximumSampleRate);
- const QAudioFormat defaultTestFormat(testFormat);
-
- // Check if float samples are supported
- testFormat.setSampleFormat(QAudioFormat::Float);
- if (testSettings(testFormat))
- supportedSampleFormats.append(QAudioFormat::Float);
-
- // Check channel counts > 2
- testFormat = defaultTestFormat;
- for (int i = 18; i > 2; --i) { // <mmreg.h> defines 18 different channels
- testFormat.setChannelCount(i);
- if (testSettings(testFormat)) {
- maximumChannelCount = i;
- break;
- }
- }
-}
-
-QWindowsAudioDeviceInfo::~QWindowsAudioDeviceInfo()
-{
-}
-
-bool QWindowsAudioDeviceInfo::testSettings(const QAudioFormat& format) const
-{
- WAVEFORMATEXTENSIBLE wfx;
- if (qt_convertFormat(format, &wfx)) {
- // query only, do not open device
- if (mode == QAudioDevice::Output) {
- return (waveOutOpen(NULL, UINT_PTR(devId), &wfx.Format, 0, 0,
- WAVE_FORMAT_QUERY) == MMSYSERR_NOERROR);
- } else { // AudioInput
- return (waveInOpen(NULL, UINT_PTR(devId), &wfx.Format, 0, 0,
- WAVE_FORMAT_QUERY) == MMSYSERR_NOERROR);
- }
- }
-
- return false;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/audio/qwindowsaudiodevice_p.h b/src/multimedia/platform/windows/audio/qwindowsaudiodevice_p.h
deleted file mode 100644
index 7d55a5820..000000000
--- a/src/multimedia/platform/windows/audio/qwindowsaudiodevice_p.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$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-
-#ifndef QWINDOWSAUDIODEVICEINFO_H
-#define QWINDOWSAUDIODEVICEINFO_H
-
-#include <QtCore/qbytearray.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qdebug.h>
-
-#include <QtMultimedia/qaudiodevice.h>
-#include <private/qaudiosystem_p.h>
-#include <private/qaudiodevice_p.h>
-
-
-QT_BEGIN_NAMESPACE
-
-const unsigned int MAX_SAMPLE_RATES = 5;
-const unsigned int SAMPLE_RATES[] = { 8000, 11025, 22050, 44100, 48000 };
-
-class QWindowsAudioDeviceInfo : public QAudioDevicePrivate
-{
-public:
- QWindowsAudioDeviceInfo(QByteArray dev, int waveID, const QString &description, QAudioDevice::Mode mode);
- ~QWindowsAudioDeviceInfo();
-
- bool open();
- void close();
-
- bool testSettings(const QAudioFormat& format) const;
-
- int waveId() const { return devId; }
-private:
- quint32 devId;
-};
-
-
-
-QT_END_NAMESPACE
-
-
-#endif // QWINDOWSAUDIODEVICEINFO_H
diff --git a/src/multimedia/platform/windows/audio/qwindowsaudiosink.cpp b/src/multimedia/platform/windows/audio/qwindowsaudiosink.cpp
deleted file mode 100644
index 8cc4d33cf..000000000
--- a/src/multimedia/platform/windows/audio/qwindowsaudiosink.cpp
+++ /dev/null
@@ -1,608 +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$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// INTERNAL USE ONLY: Do NOT use for any other purpose.
-//
-
-#include "qwindowsaudiosink_p.h"
-#include "qwindowsaudiodevice_p.h"
-#include "qwindowsaudioutils_p.h"
-#include <QtEndian>
-#include <QtCore/QDataStream>
-#include <QtCore/qtimer.h>
-#include <private/qaudiohelpers_p.h>
-
-#include <qloggingcategory.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(qLcAudioOutput, "qt.multimedia.audiooutput")
-
-QWindowsAudioSink::QWindowsAudioSink(int deviceId)
-{
- bytesAvailable = 0;
- buffer_size = 0;
- period_size = 0;
- m_deviceId = deviceId;
- totalTimeValue = 0;
- errorState = QAudio::NoError;
- deviceState = QAudio::StoppedState;
- audioSource = 0;
- pullMode = true;
- volumeCache = qreal(1.0);
- blocks_count = 5;
-}
-
-QWindowsAudioSink::~QWindowsAudioSink()
-{
- close();
-}
-
-void CALLBACK QWindowsAudioSink::waveOutProc( HWAVEOUT hWaveOut, UINT uMsg,
- DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 )
-{
- Q_UNUSED(dwParam1);
- Q_UNUSED(dwParam2);
- Q_UNUSED(hWaveOut);
-
- QWindowsAudioSink* qAudio;
- qAudio = (QWindowsAudioSink*)(dwInstance);
- if(!qAudio)
- return;
-
- QMutexLocker locker(&qAudio->mutex);
-
- switch(uMsg) {
- case WOM_OPEN:
- qAudio->feedback();
- break;
- case WOM_CLOSE:
- return;
- case WOM_DONE:
- if(qAudio->buffer_size == 0 || qAudio->period_size == 0) {
- return;
- }
- qAudio->waveFreeBlockCount++;
- if (qAudio->waveFreeBlockCount >= qAudio->blocks_count)
- qAudio->waveFreeBlockCount = qAudio->blocks_count;
-
- qAudio->feedback();
- break;
- default:
- return;
- }
-}
-
-WAVEHDR* QWindowsAudioSink::allocateBlocks(int size, int count)
-{
- int i;
- unsigned char* buffer;
- WAVEHDR* blocks;
- DWORD totalBufferSize = (size + sizeof(WAVEHDR))*count;
-
- if((buffer=(unsigned char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
- totalBufferSize)) == 0) {
- qWarning("QAudioSink: Memory allocation error");
- return 0;
- }
- blocks = (WAVEHDR*)buffer;
- buffer += sizeof(WAVEHDR)*count;
- for(i = 0; i < count; i++) {
- blocks[i].dwBufferLength = size;
- blocks[i].lpData = (LPSTR)buffer;
- buffer += size;
- }
- return blocks;
-}
-
-void QWindowsAudioSink::freeBlocks(WAVEHDR* blockArray)
-{
- WAVEHDR* blocks = blockArray;
- for (int i = 0; i < blocks_count; ++i) {
- waveOutUnprepareHeader(hWaveOut,blocks, sizeof(WAVEHDR));
- blocks++;
- }
- HeapFree(GetProcessHeap(), 0, blockArray);
-}
-
-QAudioFormat QWindowsAudioSink::format() const
-{
- return settings;
-}
-
-void QWindowsAudioSink::setFormat(const QAudioFormat& fmt)
-{
- if (deviceState == QAudio::StoppedState)
- settings = fmt;
-}
-
-void QWindowsAudioSink::start(QIODevice* device)
-{
- qCDebug(qLcAudioOutput) << "start(ioDevice)";
- if(deviceState != QAudio::StoppedState)
- close();
-
- if(!pullMode && audioSource)
- delete audioSource;
-
- pullMode = true;
- audioSource = device;
-
- deviceState = QAudio::ActiveState;
-
- if(!open())
- return;
-
- emit stateChanged(deviceState);
-}
-
-QIODevice* QWindowsAudioSink::start()
-{
- qCDebug(qLcAudioOutput) << "start()";
- if(deviceState != QAudio::StoppedState)
- close();
-
- if(!pullMode && audioSource)
- delete audioSource;
-
- pullMode = false;
- audioSource = new OutputPrivate(this);
- audioSource->open(QIODevice::WriteOnly|QIODevice::Unbuffered);
-
- deviceState = QAudio::IdleState;
-
- if(!open())
- return 0;
-
- emit stateChanged(deviceState);
-
- return audioSource;
-}
-
-void QWindowsAudioSink::stop()
-{
- qCDebug(qLcAudioOutput) << "stop()";
- if(deviceState == QAudio::StoppedState)
- return;
- close();
- if(!pullMode && audioSource) {
- delete audioSource;
- audioSource = 0;
- }
- emit stateChanged(deviceState);
-}
-
-bool QWindowsAudioSink::open()
-{
- qCDebug(qLcAudioOutput) << "open()";
-
- period_size = 0;
-
- if (!qt_convertFormat(settings, &wfx)) {
- qWarning("QAudioSink: open error, invalid format.");
- } else if (buffer_size == 0) {
- // Default buffer size, 200ms, default period size is 40ms
- buffer_size
- = (settings.sampleRate()
- * settings.bytesPerFrame()
- + 39) / 5;
- period_size = buffer_size / 5;
- } else {
- period_size = buffer_size / 5;
- }
-
- // Make even size of wave block to prevent crackling
- // due to waveOutWrite() does not like odd buffer length
- period_size &= ~1;
-
- if (period_size == 0) {
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- return false;
- }
-
- const int periods = buffer_size / period_size;
- bool ok = false;
- static int wave_buffers = qEnvironmentVariableIntValue("QT_WAVE_BUFFERS", &ok);
- if (wave_buffers < periods) {
- if (ok)
- qWarning("Number of WAVE buffers (QT_WAVE_BUFFERS=%d) cannot be less than %d.", wave_buffers, periods);
- wave_buffers = periods;
- }
-
- blocks_count = wave_buffers;
- waveBlocks = allocateBlocks(period_size, blocks_count);
-
- mutex.lock();
- waveFreeBlockCount = blocks_count;
- mutex.unlock();
-
- waveCurrentBlock = 0;
-
- if (audioBuffer == nullptr)
- audioBuffer = new char[blocks_count * period_size];
-
- elapsedTimeOffset = 0;
-
- if (waveOutOpen(&hWaveOut, UINT_PTR(m_deviceId), &wfx.Format,
- (DWORD_PTR)&waveOutProc,
- (DWORD_PTR) this,
- CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- qWarning("QAudioSink: open error");
- return false;
- }
-
- totalTimeValue = 0;
- elapsedTimeOffset = 0;
-
- errorState = QAudio::NoError;
- if(pullMode) {
- deviceState = QAudio::ActiveState;
- QTimer::singleShot(10, this, SLOT(feedback()));
- } else
- deviceState = QAudio::IdleState;
-
- return true;
-}
-
-void QWindowsAudioSink::pauseAndSleep()
-{
- waveOutPause(hWaveOut);
- int bitrate = settings.sampleRate() * settings.bytesPerFrame();
- // Time of written data.
- int delay = (buffer_size - bytesFree()) * 1000 / bitrate;
- Sleep(delay + 10);
-}
-
-void QWindowsAudioSink::close()
-{
- qCDebug(qLcAudioOutput) << "close()";
- if(deviceState == QAudio::StoppedState)
- return;
-
- // Pause playback before reset to avoid uneeded crackling at the end.
- pauseAndSleep();
- QMutexLocker locker(&mutex);
- deviceState = QAudio::StoppedState;
- errorState = QAudio::NoError;
- locker.unlock();
- waveOutReset(hWaveOut);
-
- freeBlocks(waveBlocks);
- waveOutClose(hWaveOut);
- locker.relock();
- delete [] audioBuffer;
- audioBuffer = nullptr;
- buffer_size = 0;
- qCDebug(qLcAudioOutput) << "end close()";
-}
-
-qsizetype QWindowsAudioSink::bytesFree() const
-{
- int buf;
- QMutexLocker locker(&mutex);
- buf = waveFreeBlockCount*period_size;
-
- return buf;
-}
-
-void QWindowsAudioSink::setBufferSize(qsizetype value)
-{
- if(deviceState == QAudio::StoppedState)
- buffer_size = value;
-}
-
-qsizetype QWindowsAudioSink::bufferSize() const
-{
- return buffer_size;
-}
-
-qint64 QWindowsAudioSink::processedUSecs() const
-{
- if (deviceState == QAudio::StoppedState)
- return 0;
- qint64 result = qint64(1000000) * totalTimeValue /
- settings.bytesPerFrame() / settings.sampleRate();
-
- return result;
-}
-
-qint64 QWindowsAudioSink::write(const char *data, qint64 len)
-{
- qCDebug(qLcAudioOutput) << "write()" << len << deviceState << period_size;
-
- // Write out some audio data
- if (deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
- return 0;
-
- WAVEHDR* current;
- qint64 written = 0;
- current = &waveBlocks[waveCurrentBlock];
- while(len > 0) {
- mutex.lock();
- if(waveFreeBlockCount==0) {
- mutex.unlock();
- break;
- }
- mutex.unlock();
-
- if(current->dwFlags & WHDR_PREPARED)
- waveOutUnprepareHeader(hWaveOut, current, sizeof(WAVEHDR));
-
- qint64 remain;
- if(len < period_size)
- remain = len;
- else
- remain = period_size;
-
- if (volumeCache < qreal(1.0))
- QAudioHelperInternal::qMultiplySamples(volumeCache, settings, data, current->lpData, remain);
- else
- memcpy(current->lpData, data, remain);
-
- len -= remain;
- data += remain;
- current->dwBufferLength = remain;
- written += remain;
- waveOutPrepareHeader(hWaveOut, current, sizeof(WAVEHDR));
- waveOutWrite(hWaveOut, current, sizeof(WAVEHDR));
-
- mutex.lock();
- waveFreeBlockCount--;
- qCDebug(qLcAudioOutput) << "write out" << current->dwBufferLength << "waveFreeBlockCount" << waveFreeBlockCount;
- mutex.unlock();
-
- totalTimeValue += current->dwBufferLength;
- waveCurrentBlock++;
- waveCurrentBlock %= blocks_count;
- current = &waveBlocks[waveCurrentBlock];
- current->dwUser = 0;
- errorState = QAudio::NoError;
- if (deviceState != QAudio::ActiveState) {
- deviceState = QAudio::ActiveState;
- emit stateChanged(deviceState);
- }
- }
- return written;
-}
-
-void QWindowsAudioSink::resume()
-{
- qCDebug(qLcAudioOutput) << "resume()";
- if(deviceState == QAudio::SuspendedState) {
- deviceState = pullMode ? QAudio::ActiveState : QAudio::IdleState;
- errorState = QAudio::NoError;
- waveOutRestart(hWaveOut);
- QTimer::singleShot(10, this, SLOT(feedback()));
- emit stateChanged(deviceState);
- }
-}
-
-void QWindowsAudioSink::suspend()
-{
- qCDebug(qLcAudioOutput) << "suspend()";
- if(deviceState == QAudio::ActiveState || deviceState == QAudio::IdleState) {
- pauseAndSleep();
- deviceState = QAudio::SuspendedState;
- errorState = QAudio::NoError;
- emit stateChanged(deviceState);
- }
-}
-
-void QWindowsAudioSink::feedback()
-{
- qCDebug(qLcAudioOutput) << "feedback()";
- bytesAvailable = waveFreeBlockCount * period_size;
-
- if (deviceState != QAudio::StoppedState && deviceState != QAudio::SuspendedState) {
- if (bytesAvailable >= period_size) {
- qCDebug(qLcAudioOutput) << " ->invoke()";
- QMetaObject::invokeMethod(this, "deviceReady", Qt::QueuedConnection);
- }
- }
-}
-
-bool QWindowsAudioSink::deviceReady()
-{
- qCDebug(qLcAudioOutput) << ">>>> deviceReady() state=" << deviceState << pullMode;
-
- if(deviceState == QAudio::StoppedState || deviceState == QAudio::SuspendedState)
- return false;
-
- if(pullMode) {
- qCDebug(qLcAudioOutput) << "deviceReady() avail="<<bytesAvailable<<" bytes, period size="<<period_size<<" bytes";
- bool startup = false;
- if(totalTimeValue == 0)
- startup = true;
-
- bool full=false;
-
- mutex.lock();
- if (waveFreeBlockCount == 0)
- full = true;
- mutex.unlock();
-
- if (full) {
- qCDebug(qLcAudioOutput) << "Skipping data as unable to write";
- return true;
- }
-
- if(startup)
- waveOutPause(hWaveOut);
- int input = bytesAvailable;
- int l = audioSource->read(audioBuffer,input);
- if(l > 0) {
- int out = write(audioBuffer, l);
- if(out > 0) {
- if (deviceState != QAudio::ActiveState) {
- deviceState = QAudio::ActiveState;
- emit stateChanged(deviceState);
- }
- }
- if ( out < l) {
- // Didn't write all data
- audioSource->seek(audioSource->pos()-(l-out));
- }
- qCDebug(qLcAudioOutput) << "wrote" << out << "bytes out of" << l << "read";
-
- if (startup)
- waveOutRestart(hWaveOut);
- } else if(l == 0) {
- bytesAvailable = bytesFree();
-
- int check = 0;
-
- mutex.lock();
- check = waveFreeBlockCount;
- mutex.unlock();
-
- if (check == blocks_count) {
- if (deviceState != QAudio::IdleState) {
- errorState = QAudio::UnderrunError;
- deviceState = QAudio::IdleState;
- emit stateChanged(deviceState);
- }
- }
-
- } else if(l < 0) {
- bytesAvailable = bytesFree();
- if (errorState != QAudio::IOError)
- errorState = QAudio::IOError;
- }
- } else {
- int buffered;
-
- mutex.lock();
- buffered = waveFreeBlockCount;
- mutex.unlock();
-
- if (buffered >= blocks_count && deviceState == QAudio::ActiveState) {
- if (deviceState != QAudio::IdleState) {
- errorState = QAudio::UnderrunError;
- deviceState = QAudio::IdleState;
- emit stateChanged(deviceState);
- }
- }
- }
- qCDebug(qLcAudioOutput) << "<<<< end deviceReady() state=" << deviceState;
-
- return true;
-}
-
-QAudio::Error QWindowsAudioSink::error() const
-{
- return errorState;
-}
-
-QAudio::State QWindowsAudioSink::state() const
-{
- return deviceState;
-}
-
-void QWindowsAudioSink::setVolume(qreal v)
-{
- if (qFuzzyCompare(volumeCache, v))
- return;
-
- volumeCache = qBound(qreal(0), v, qreal(1));
-}
-
-qreal QWindowsAudioSink::volume() const
-{
- return volumeCache;
-}
-
-void QWindowsAudioSink::reset()
-{
- stop();
-}
-
-OutputPrivate::OutputPrivate(QWindowsAudioSink* audio)
-{
- audioDevice = qobject_cast<QWindowsAudioSink*>(audio);
-}
-
-OutputPrivate::~OutputPrivate() {}
-
-qint64 OutputPrivate::readData( char* data, qint64 len)
-{
- Q_UNUSED(data);
- Q_UNUSED(len);
-
- return 0;
-}
-
-qint64 OutputPrivate::writeData(const char* data, qint64 len)
-{
- int retry = 0;
- qint64 written = 0;
-
- if((audioDevice->deviceState == QAudio::ActiveState)
- ||(audioDevice->deviceState == QAudio::IdleState)) {
- qint64 l = len;
- while(written < l) {
- int chunk = audioDevice->write(data+written,(l-written));
- if(chunk <= 0)
- retry++;
- else
- written+=chunk;
-
- if(retry > 10)
- return written;
- }
- audioDevice->deviceState = QAudio::ActiveState;
- }
- return written;
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qwindowsaudiosink_p.cpp"
diff --git a/src/multimedia/platform/windows/audio/qwindowsaudiosink_p.h b/src/multimedia/platform/windows/audio/qwindowsaudiosink_p.h
deleted file mode 100644
index d865011b5..000000000
--- a/src/multimedia/platform/windows/audio/qwindowsaudiosink_p.h
+++ /dev/null
@@ -1,160 +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$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#ifndef QWINDOWSAUDIOOUTPUT_H
-#define QWINDOWSAUDIOOUTPUT_H
-
-#include "qwindowsaudioutils_p.h"
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qelapsedtimer.h>
-#include <QtCore/qiodevice.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qdatetime.h>
-#include <QtCore/qmutex.h>
-
-#include <QtMultimedia/qaudio.h>
-#include <QtMultimedia/qaudiodevice.h>
-#include <private/qaudiosystem_p.h>
-
-// For compat with 4.6
-#if !defined(QT_WIN_CALLBACK)
-# if defined(Q_CC_MINGW)
-# define QT_WIN_CALLBACK CALLBACK __attribute__ ((force_align_arg_pointer))
-# else
-# define QT_WIN_CALLBACK CALLBACK
-# endif
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsAudioSink : public QPlatformAudioSink
-{
- Q_OBJECT
-public:
- QWindowsAudioSink(int deviceId);
- ~QWindowsAudioSink();
-
- qint64 write( const char *data, qint64 len );
-
- void setFormat(const QAudioFormat& fmt);
- QAudioFormat format() const;
- QIODevice* start();
- void start(QIODevice* device);
- void stop();
- void reset();
- void suspend();
- void resume();
- qsizetype bytesFree() const;
- void setBufferSize(qsizetype value);
- qsizetype bufferSize() const;
- qint64 processedUSecs() const;
- QAudio::Error error() const;
- QAudio::State state() const;
- void setVolume(qreal);
- qreal volume() const;
-
- QIODevice* audioSource;
- QAudioFormat settings;
- QAudio::Error errorState;
- QAudio::State deviceState;
-
-private slots:
- void feedback();
- bool deviceReady();
-
-private:
- void pauseAndSleep();
- int m_deviceId;
- int bytesAvailable;
- qint64 elapsedTimeOffset;
- qint32 buffer_size;
- qint32 period_size;
- qint32 blocks_count;
- qint64 totalTimeValue;
- bool pullMode;
- qreal volumeCache;
- static void QT_WIN_CALLBACK waveOutProc( HWAVEOUT hWaveOut, UINT uMsg,
- DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 );
-
- mutable QMutex mutex;
-
- WAVEHDR* allocateBlocks(int size, int count);
- void freeBlocks(WAVEHDR* blockArray);
- bool open();
- void close();
-
- WAVEFORMATEXTENSIBLE wfx;
- HWAVEOUT hWaveOut;
- WAVEHDR* waveBlocks;
- int waveFreeBlockCount = 0;
- int waveCurrentBlock = 0;
- char *audioBuffer = nullptr;
-};
-
-class OutputPrivate : public QIODevice
-{
- Q_OBJECT
-public:
- OutputPrivate(QWindowsAudioSink* audio);
- ~OutputPrivate();
-
- qint64 readData( char* data, qint64 len);
- qint64 writeData(const char* data, qint64 len);
-
-private:
- QWindowsAudioSink *audioDevice;
-};
-
-QT_END_NAMESPACE
-
-
-#endif // QWINDOWSAUDIOOUTPUT_H
diff --git a/src/multimedia/platform/windows/audio/qwindowsaudiosource.cpp b/src/multimedia/platform/windows/audio/qwindowsaudiosource.cpp
deleted file mode 100644
index 9eb6e98fa..000000000
--- a/src/multimedia/platform/windows/audio/qwindowsaudiosource.cpp
+++ /dev/null
@@ -1,698 +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$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// INTERNAL USE ONLY: Do NOT use for any other purpose.
-//
-
-
-#include "qwindowsaudiosource_p.h"
-
-#include <QtCore/QDataStream>
-#include <QtCore/qtimer.h>
-
-QT_BEGIN_NAMESPACE
-
-//#define DEBUG_AUDIO 1
-
-QWindowsAudioSource::QWindowsAudioSource(int deviceId)
-{
- bytesAvailable = 0;
- buffer_size = 0;
- period_size = 0;
- m_deviceId = deviceId;
- totalTimeValue = 0;
- errorState = QAudio::NoError;
- deviceState = QAudio::StoppedState;
- audioSource = 0;
- pullMode = true;
- resuming = false;
- finished = false;
- waveBlockOffset = 0;
-
- mixerID = 0;
- cachedVolume = -1.0f;
- memset(&mixerLineControls, 0, sizeof(mixerLineControls));
-}
-
-QWindowsAudioSource::~QWindowsAudioSource()
-{
- stop();
-}
-
-void QT_WIN_CALLBACK QWindowsAudioSource::waveInProc( HWAVEIN hWaveIn, UINT uMsg,
- DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 )
-{
- Q_UNUSED(dwParam1);
- Q_UNUSED(dwParam2);
- Q_UNUSED(hWaveIn);
-
- QWindowsAudioSource* qAudio;
- qAudio = (QWindowsAudioSource*)(dwInstance);
- if(!qAudio)
- return;
-
- QMutexLocker locker(&qAudio->mutex);
-
- switch(uMsg) {
- case WIM_OPEN:
- break;
- case WIM_DATA:
- if(qAudio->waveFreeBlockCount > 0)
- qAudio->waveFreeBlockCount--;
- qAudio->feedback();
- break;
- case WIM_CLOSE:
- qAudio->finished = true;
- break;
- default:
- return;
- }
-}
-
-WAVEHDR* QWindowsAudioSource::allocateBlocks(int size, int count)
-{
- int i;
- unsigned char* buffer;
- WAVEHDR* blocks;
- DWORD totalBufferSize = (size + sizeof(WAVEHDR))*count;
-
- if((buffer=(unsigned char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
- totalBufferSize)) == 0) {
- qWarning("QAudioSource: Memory allocation error");
- return 0;
- }
- blocks = (WAVEHDR*)buffer;
- buffer += sizeof(WAVEHDR)*count;
- for(i = 0; i < count; i++) {
- blocks[i].dwBufferLength = size;
- blocks[i].lpData = (LPSTR)buffer;
- blocks[i].dwBytesRecorded=0;
- blocks[i].dwUser = 0L;
- blocks[i].dwFlags = 0L;
- blocks[i].dwLoops = 0L;
- result = waveInPrepareHeader(hWaveIn,&blocks[i], sizeof(WAVEHDR));
- if(result != MMSYSERR_NOERROR) {
- qWarning("QAudioSource: Can't prepare block %d",i);
- return 0;
- }
- buffer += size;
- }
- return blocks;
-}
-
-void QWindowsAudioSource::freeBlocks(WAVEHDR* blockArray)
-{
- WAVEHDR* blocks = blockArray;
-
- int count = buffer_size/period_size;
-
- for(int i = 0; i < count; i++) {
- waveInUnprepareHeader(hWaveIn,blocks, sizeof(WAVEHDR));
- blocks++;
- }
- HeapFree(GetProcessHeap(), 0, blockArray);
-}
-
-QAudio::Error QWindowsAudioSource::error() const
-{
- return errorState;
-}
-
-QAudio::State QWindowsAudioSource::state() const
-{
- return deviceState;
-}
-
-#ifndef DRVM_MAPPER_CONSOLEVOICECOM_GET
- #ifndef DRVM_MAPPER
- #define DRVM_MAPPER 0x2000
- #endif
- #ifndef DRVM_MAPPER_STATUS
- #define DRVM_MAPPER_STATUS (DRVM_MAPPER+0)
- #endif
- #define DRVM_USER 0x4000
- #define DRVM_MAPPER_RECONFIGURE (DRVM_MAPPER+1)
- #define DRVM_MAPPER_PREFERRED_GET (DRVM_MAPPER+21)
- #define DRVM_MAPPER_CONSOLEVOICECOM_GET (DRVM_MAPPER+23)
-#endif
-
-void QWindowsAudioSource::setVolume(qreal volume)
-{
- cachedVolume = volume;
- for (DWORD i = 0; i < mixerLineControls.cControls; i++) {
-
- MIXERCONTROLDETAILS controlDetails;
- controlDetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
- controlDetails.dwControlID = mixerLineControls.pamxctrl[i].dwControlID;
- controlDetails.cChannels = 1;
-
- if ((mixerLineControls.pamxctrl[i].dwControlType == MIXERCONTROL_CONTROLTYPE_FADER) ||
- (mixerLineControls.pamxctrl[i].dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)) {
- MIXERCONTROLDETAILS_UNSIGNED controlDetailsUnsigned;
- controlDetailsUnsigned.dwValue = qBound(DWORD(0), DWORD(65535.0 * volume + 0.5), DWORD(65535));
- controlDetails.cMultipleItems = 0;
- controlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
- controlDetails.paDetails = &controlDetailsUnsigned;
- mixerSetControlDetails(mixerID, &controlDetails, MIXER_SETCONTROLDETAILSF_VALUE);
- }
- }
-}
-
-qreal QWindowsAudioSource::volume() const
-{
- for (DWORD i = 0; i < mixerLineControls.cControls; i++) {
- if ((mixerLineControls.pamxctrl[i].dwControlType != MIXERCONTROL_CONTROLTYPE_FADER) &&
- (mixerLineControls.pamxctrl[i].dwControlType != MIXERCONTROL_CONTROLTYPE_VOLUME)) {
- continue;
- }
-
- MIXERCONTROLDETAILS controlDetails;
- controlDetails.cbStruct = sizeof(controlDetails);
- controlDetails.dwControlID = mixerLineControls.pamxctrl[i].dwControlID;
- controlDetails.cChannels = 1;
- controlDetails.cMultipleItems = 0;
- controlDetails.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
- MIXERCONTROLDETAILS_UNSIGNED detailsUnsigned;
- controlDetails.paDetails = &detailsUnsigned;
- memset(controlDetails.paDetails, 0, controlDetails.cbDetails);
-
- MMRESULT result = mixerGetControlDetails(mixerID, &controlDetails, MIXER_GETCONTROLDETAILSF_VALUE);
- if (result != MMSYSERR_NOERROR)
- continue;
- if (controlDetails.cbDetails < sizeof(MIXERCONTROLDETAILS_UNSIGNED))
- continue;
- return detailsUnsigned.dwValue / 65535.0;
- }
-
- return qFuzzyCompare(cachedVolume, qreal(-1.0f)) ? 1.0f : cachedVolume;
-}
-
-void QWindowsAudioSource::setFormat(const QAudioFormat& fmt)
-{
- if (deviceState == QAudio::StoppedState)
- settings = fmt;
-}
-
-QAudioFormat QWindowsAudioSource::format() const
-{
- return settings;
-}
-
-void QWindowsAudioSource::start(QIODevice* device)
-{
- if(deviceState != QAudio::StoppedState)
- close();
-
- if(!pullMode && audioSource)
- delete audioSource;
-
- pullMode = true;
- audioSource = device;
-
- deviceState = QAudio::ActiveState;
-
- if(!open())
- return;
-
- emit stateChanged(deviceState);
-}
-
-QIODevice* QWindowsAudioSource::start()
-{
- if(deviceState != QAudio::StoppedState)
- close();
-
- if(!pullMode && audioSource)
- delete audioSource;
-
- pullMode = false;
- audioSource = new InputPrivate(this);
- audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
-
- deviceState = QAudio::IdleState;
-
- if(!open())
- return 0;
-
- emit stateChanged(deviceState);
-
- return audioSource;
-}
-
-void QWindowsAudioSource::stop()
-{
- if(deviceState == QAudio::StoppedState)
- return;
-
- close();
- emit stateChanged(deviceState);
-}
-
-bool QWindowsAudioSource::open()
-{
-#ifdef DEBUG_AUDIO
- QTime now(QTime::currentTime());
- qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
-#endif
- header = 0;
-
- period_size = 0;
-
- if (!qt_convertFormat(settings, &wfx)) {
- qWarning("QAudioSource: open error, invalid format.");
- } else if (buffer_size == 0) {
- buffer_size
- = (settings.sampleRate()
- * settings.channelCount()
- * settings.bytesPerSample()
- + 39) / 5;
- period_size = buffer_size / 5;
- } else {
- period_size = buffer_size / 5;
- }
-
- if (period_size == 0) {
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- return false;
- }
-
- elapsedTimeOffset = 0;
-
- if (waveInOpen(&hWaveIn, UINT_PTR(m_deviceId), &wfx.Format,
- (DWORD_PTR)&waveInProc,
- (DWORD_PTR) this,
- CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- qWarning("QAudioSource: failed to open audio device");
- return false;
- }
- waveBlocks = allocateBlocks(period_size, buffer_size/period_size);
- waveBlockOffset = 0;
-
- if(waveBlocks == 0) {
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- qWarning("QAudioSource: failed to allocate blocks. open failed");
- return false;
- }
-
- mutex.lock();
- waveFreeBlockCount = buffer_size/period_size;
- mutex.unlock();
-
- for(int i=0; i<buffer_size/period_size; i++) {
- result = waveInAddBuffer(hWaveIn, &waveBlocks[i], sizeof(WAVEHDR));
- if(result != MMSYSERR_NOERROR) {
- qWarning("QAudioSource: failed to setup block %d,err=%d",i,result);
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- return false;
- }
- }
- result = waveInStart(hWaveIn);
- if(result) {
- qWarning("QAudioSource: failed to start audio input");
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- return false;
- }
- elapsedTimeOffset = 0;
- totalTimeValue = 0;
- errorState = QAudio::NoError;
- initMixer();
- return true;
-}
-
-void QWindowsAudioSource::close()
-{
- if(deviceState == QAudio::StoppedState)
- return;
-
- deviceState = QAudio::StoppedState;
- waveInReset(hWaveIn);
-
- mutex.lock();
- for (int i=0; i<waveFreeBlockCount; i++)
- waveInUnprepareHeader(hWaveIn,&waveBlocks[i],sizeof(WAVEHDR));
- freeBlocks(waveBlocks);
- mutex.unlock();
-
- waveInClose(hWaveIn);
- closeMixer();
-
- int count = 0;
- while(!finished && count < 500) {
- count++;
- Sleep(10);
- }
-}
-
-void QWindowsAudioSource::initMixer()
-{
- // Get the Mixer ID from the Sound Device ID
- UINT mixerIntID = 0;
- if (mixerGetID(reinterpret_cast<HMIXEROBJ>(hWaveIn),
- &mixerIntID, MIXER_OBJECTF_HWAVEIN) != MMSYSERR_NOERROR)
- return;
- mixerID = reinterpret_cast<HMIXEROBJ>(quintptr(mixerIntID));
-
- // Get the Destination (Recording) Line Information
- MIXERLINE mixerLine;
- mixerLine.cbStruct = sizeof(MIXERLINE);
- mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
- if (mixerGetLineInfo(mixerID, &mixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE) != MMSYSERR_NOERROR)
- return;
-
- // Set all the Destination (Recording) Line Controls
- if (mixerLine.cControls > 0) {
- mixerLineControls.cbStruct = sizeof(MIXERLINECONTROLS);
- mixerLineControls.dwLineID = mixerLine.dwLineID;
- mixerLineControls.cControls = mixerLine.cControls;
- mixerLineControls.cbmxctrl = sizeof(MIXERCONTROL);
- mixerLineControls.pamxctrl = new MIXERCONTROL[mixerLineControls.cControls];
- if (mixerGetLineControls(mixerID, &mixerLineControls, MIXER_GETLINECONTROLSF_ALL) != MMSYSERR_NOERROR)
- closeMixer();
- else if (!qFuzzyCompare(cachedVolume, qreal(-1.0f)))
- setVolume(cachedVolume);
- }
-}
-
-void QWindowsAudioSource::closeMixer()
-{
- delete[] mixerLineControls.pamxctrl;
- memset(&mixerLineControls, 0, sizeof(mixerLineControls));
-}
-
-qsizetype QWindowsAudioSource::bytesReady() const
-{
- if (period_size == 0 || buffer_size == 0)
- return 0;
- if (deviceState == QAudio::StoppedState || deviceState == QAudio::SuspendedState)
- return 0;
-
- int buf = ((buffer_size/period_size)-waveFreeBlockCount)*period_size;
- if(buf < 0)
- buf = 0;
- return buf;
-}
-
-qint64 QWindowsAudioSource::read(char* data, qint64 len)
-{
- bool done = false;
-
- char* p = data;
- qint64 l = 0;
- qint64 written = 0;
- while(!done) {
- // Read in some audio data
- if(waveBlocks[header].dwBytesRecorded > 0 && waveBlocks[header].dwFlags & WHDR_DONE) {
- if(pullMode) {
- l = audioSource->write(waveBlocks[header].lpData + waveBlockOffset,
- waveBlocks[header].dwBytesRecorded - waveBlockOffset);
-#ifdef DEBUG_AUDIO
- qDebug()<<"IN: "<<waveBlocks[header].dwBytesRecorded<<", OUT: "<<l;
-#endif
- if(l < 0) {
- // error
- qWarning("QAudioSource: IOError");
- errorState = QAudio::IOError;
-
- } else if(l == 0) {
- // cant write to IODevice
- qWarning("QAudioSource: IOError, can't write to QIODevice");
- errorState = QAudio::IOError;
-
- } else {
- totalTimeValue += l;
- errorState = QAudio::NoError;
- if (deviceState != QAudio::ActiveState) {
- deviceState = QAudio::ActiveState;
- emit stateChanged(deviceState);
- }
- resuming = false;
- }
- } else {
- l = qMin<qint64>(len, waveBlocks[header].dwBytesRecorded - waveBlockOffset);
- // push mode
- memcpy(p, waveBlocks[header].lpData + waveBlockOffset, l);
-
- len -= l;
-
-#ifdef DEBUG_AUDIO
- qDebug()<<"IN: "<<waveBlocks[header].dwBytesRecorded<<", OUT: "<<l;
-#endif
- totalTimeValue += l;
- errorState = QAudio::NoError;
- if (deviceState != QAudio::ActiveState) {
- deviceState = QAudio::ActiveState;
- emit stateChanged(deviceState);
- }
- resuming = false;
- }
- } else {
- //no data, not ready yet, next time
- break;
- }
-
- if (l < waveBlocks[header].dwBytesRecorded - waveBlockOffset) {
- waveBlockOffset += l;
- done = true;
- } else {
- waveBlockOffset = 0;
-
- waveInUnprepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR));
-
- mutex.lock();
- waveFreeBlockCount++;
- mutex.unlock();
-
- waveBlocks[header].dwBytesRecorded=0;
- waveBlocks[header].dwFlags = 0L;
- result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR));
- if(result != MMSYSERR_NOERROR) {
- result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR));
- qWarning("QAudioSource: failed to prepare block %d,err=%d",header,result);
- errorState = QAudio::IOError;
-
- mutex.lock();
- waveFreeBlockCount--;
- mutex.unlock();
-
- return 0;
- }
- result = waveInAddBuffer(hWaveIn, &waveBlocks[header], sizeof(WAVEHDR));
- if(result != MMSYSERR_NOERROR) {
- qWarning("QAudioSource: failed to setup block %d,err=%d",header,result);
- errorState = QAudio::IOError;
-
- mutex.lock();
- waveFreeBlockCount--;
- mutex.unlock();
-
- return 0;
- }
- header++;
- if(header >= buffer_size/period_size)
- header = 0;
- p+=l;
-
- mutex.lock();
- if(!pullMode) {
- if(len < period_size || waveFreeBlockCount == buffer_size/period_size)
- done = true;
- } else {
- if(waveFreeBlockCount == buffer_size/period_size)
- done = true;
- }
- mutex.unlock();
- }
-
- written+=l;
- }
-#ifdef DEBUG_AUDIO
- qDebug()<<"read in len="<<written;
-#endif
- return written;
-}
-
-void QWindowsAudioSource::resume()
-{
- if (deviceState == QAudio::SuspendedState) {
- deviceState = QAudio::ActiveState;
- for(int i=0; i<buffer_size/period_size; i++) {
- result = waveInAddBuffer(hWaveIn, &waveBlocks[i], sizeof(WAVEHDR));
- if(result != MMSYSERR_NOERROR) {
- qWarning("QAudioSource: failed to setup block %d,err=%d",i,result);
- errorState = QAudio::OpenError;
- deviceState = QAudio::StoppedState;
- emit stateChanged(deviceState);
- return;
- }
- }
-
- mutex.lock();
- waveFreeBlockCount = buffer_size/period_size;
- mutex.unlock();
-
- header = 0;
- resuming = true;
- waveBlockOffset = 0;
- waveInStart(hWaveIn);
- QTimer::singleShot(20,this,SLOT(feedback()));
- emit stateChanged(deviceState);
- }
-}
-
-void QWindowsAudioSource::setBufferSize(qsizetype value)
-{
- buffer_size = value;
-}
-
-qsizetype QWindowsAudioSource::bufferSize() const
-{
- return buffer_size;
-}
-
-qint64 QWindowsAudioSource::processedUSecs() const
-{
- if (deviceState == QAudio::StoppedState)
- return 0;
- qint64 result = qint64(1000000) * totalTimeValue /
- settings.bytesPerFrame() / settings.sampleRate();
-
- return result;
-}
-
-void QWindowsAudioSource::suspend()
-{
- if(deviceState == QAudio::ActiveState) {
- deviceState = QAudio::SuspendedState;
- waveInReset(hWaveIn);
- emit stateChanged(deviceState);
- }
-}
-
-void QWindowsAudioSource::feedback()
-{
-#ifdef DEBUG_AUDIO
- QTime now(QTime::currentTime());
- qDebug()<<now.second()<<"s "<<now.msec()<<"ms :feedback() INPUT "<<this;
-#endif
- if(deviceState != QAudio::StoppedState && deviceState != QAudio::SuspendedState)
- QMetaObject::invokeMethod(this, "deviceReady", Qt::QueuedConnection);
-}
-
-bool QWindowsAudioSource::deviceReady()
-{
- bytesAvailable = bytesReady();
-#ifdef DEBUG_AUDIO
- QTime now(QTime::currentTime());
- qDebug()<<now.second()<<"s "<<now.msec()<<"ms :deviceReady() INPUT" << bytesReady();
-#endif
- if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
- return true;
-
- if(pullMode) {
- // reads some audio data and writes it to QIODevice
- read(0, buffer_size);
- } else {
- // emits readyRead() so user will call read() on QIODevice to get some audio data
- InputPrivate* a = qobject_cast<InputPrivate*>(audioSource);
- a->trigger();
- }
-
- return true;
-}
-
-void QWindowsAudioSource::reset()
-{
- stop();
- if (period_size > 0)
- waveFreeBlockCount = buffer_size / period_size;
-}
-
-InputPrivate::InputPrivate(QWindowsAudioSource* audio)
-{
- audioDevice = qobject_cast<QWindowsAudioSource*>(audio);
-}
-
-InputPrivate::~InputPrivate() {}
-
-qint64 InputPrivate::readData( char* data, qint64 len)
-{
- // push mode, user read() called
- if(audioDevice->deviceState != QAudio::ActiveState &&
- audioDevice->deviceState != QAudio::IdleState)
- return 0;
- // Read in some audio data
- return audioDevice->read(data,len);
-}
-
-qint64 InputPrivate::writeData(const char* data, qint64 len)
-{
- Q_UNUSED(data);
- Q_UNUSED(len);
-
- emit readyRead();
- return 0;
-}
-
-void InputPrivate::trigger()
-{
- emit readyRead();
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qwindowsaudiosource_p.cpp"
diff --git a/src/multimedia/platform/windows/audio/qwindowsaudiosource_p.h b/src/multimedia/platform/windows/audio/qwindowsaudiosource_p.h
deleted file mode 100644
index ff68daab6..000000000
--- a/src/multimedia/platform/windows/audio/qwindowsaudiosource_p.h
+++ /dev/null
@@ -1,170 +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$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#ifndef QWINDOWSAUDIOINPUT_H
-#define QWINDOWSAUDIOINPUT_H
-
-#include "qwindowsaudioutils_p.h"
-
-#include <QtCore/qfile.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qelapsedtimer.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qdatetime.h>
-#include <QtCore/qmutex.h>
-
-#include <QtMultimedia/qaudio.h>
-#include <QtMultimedia/qaudiodevice.h>
-#include <private/qaudiosystem_p.h>
-
-
-QT_BEGIN_NAMESPACE
-
-
-// For compat with 4.6
-#if !defined(QT_WIN_CALLBACK)
-# if defined(Q_CC_MINGW)
-# define QT_WIN_CALLBACK CALLBACK __attribute__ ((force_align_arg_pointer))
-# else
-# define QT_WIN_CALLBACK CALLBACK
-# endif
-#endif
-
-class QWindowsAudioSource : public QPlatformAudioSource
-{
- Q_OBJECT
-public:
- QWindowsAudioSource(int deviceId);
- ~QWindowsAudioSource();
-
- qint64 read(char* data, qint64 len);
-
- void setFormat(const QAudioFormat& fmt);
- QAudioFormat format() const;
- QIODevice* start();
- void start(QIODevice* device);
- void stop();
- void reset();
- void suspend();
- void resume();
- qsizetype bytesReady() const;
- void setBufferSize(qsizetype value);
- qsizetype bufferSize() const;
- qint64 processedUSecs() const;
- QAudio::Error error() const;
- QAudio::State state() const;
- void setVolume(qreal volume);
- qreal volume() const;
-
- QIODevice* audioSource;
- QAudioFormat settings;
- QAudio::Error errorState;
- QAudio::State deviceState;
-
-private:
- qint32 buffer_size;
- qint32 period_size;
- qint32 header;
- int m_deviceId;
- int bytesAvailable;
- qint64 elapsedTimeOffset;
- qint64 totalTimeValue;
- bool pullMode;
- bool resuming;
- WAVEFORMATEXTENSIBLE wfx;
- HWAVEIN hWaveIn;
- MMRESULT result;
- WAVEHDR* waveBlocks;
- volatile bool finished;
- volatile int waveFreeBlockCount;
- int waveBlockOffset;
-
- QMutex mutex;
- static void QT_WIN_CALLBACK waveInProc( HWAVEIN hWaveIn, UINT uMsg,
- DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 );
-
- WAVEHDR* allocateBlocks(int size, int count);
- void freeBlocks(WAVEHDR* blockArray);
- bool open();
- void close();
-
- void initMixer();
- void closeMixer();
- HMIXEROBJ mixerID;
- MIXERLINECONTROLS mixerLineControls;
- qreal cachedVolume;
-
-private slots:
- void feedback();
- bool deviceReady();
-
-signals:
- void processMore();
-};
-
-class InputPrivate : public QIODevice
-{
- Q_OBJECT
-public:
- InputPrivate(QWindowsAudioSource* audio);
- ~InputPrivate();
-
- qint64 readData( char* data, qint64 len);
- qint64 writeData(const char* data, qint64 len);
-
- void trigger();
-private:
- QWindowsAudioSource *audioDevice;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/windows/audio/qwindowsaudioutils.cpp b/src/multimedia/platform/windows/audio/qwindowsaudioutils.cpp
deleted file mode 100644
index 69e50a9a6..000000000
--- a/src/multimedia/platform/windows/audio/qwindowsaudioutils.cpp
+++ /dev/null
@@ -1,114 +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 "qwindowsaudioutils_p.h"
-
-#ifndef SPEAKER_FRONT_LEFT
- #define SPEAKER_FRONT_LEFT 0x00000001
- #define SPEAKER_FRONT_RIGHT 0x00000002
- #define SPEAKER_FRONT_CENTER 0x00000004
- #define SPEAKER_LOW_FREQUENCY 0x00000008
- #define SPEAKER_BACK_LEFT 0x00000010
- #define SPEAKER_BACK_RIGHT 0x00000020
- #define SPEAKER_FRONT_LEFT_OF_CENTER 0x00000040
- #define SPEAKER_FRONT_RIGHT_OF_CENTER 0x00000080
- #define SPEAKER_BACK_CENTER 0x00000100
- #define SPEAKER_SIDE_LEFT 0x00000200
- #define SPEAKER_SIDE_RIGHT 0x00000400
- #define SPEAKER_TOP_CENTER 0x00000800
- #define SPEAKER_TOP_FRONT_LEFT 0x00001000
- #define SPEAKER_TOP_FRONT_CENTER 0x00002000
- #define SPEAKER_TOP_FRONT_RIGHT 0x00004000
- #define SPEAKER_TOP_BACK_LEFT 0x00008000
- #define SPEAKER_TOP_BACK_CENTER 0x00010000
- #define SPEAKER_TOP_BACK_RIGHT 0x00020000
- #define SPEAKER_RESERVED 0x7FFC0000
- #define SPEAKER_ALL 0x80000000
-#endif
-
-#ifndef WAVE_FORMAT_EXTENSIBLE
- #define WAVE_FORMAT_EXTENSIBLE 0xFFFE
-#endif
-
-#ifndef WAVE_FORMAT_IEEE_FLOAT
- #define WAVE_FORMAT_IEEE_FLOAT 0x0003
-#endif
-
-static const GUID _KSDATAFORMAT_SUBTYPE_PCM = {
- 0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
-
-static const GUID _KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = {
- 0x00000003, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
-
-QT_BEGIN_NAMESPACE
-
-bool qt_convertFormat(const QAudioFormat &format, WAVEFORMATEXTENSIBLE *wfx)
-{
- if (!wfx
- || !format.isValid()
- || format.sampleRate() <= 0
- || format.channelCount() <= 0) {
- return false;
- }
-
- wfx->Format.nSamplesPerSec = format.sampleRate();
- wfx->Format.wBitsPerSample = wfx->Samples.wValidBitsPerSample = format.bytesPerSample()*8;
- wfx->Format.nChannels = format.channelCount();
- wfx->Format.nBlockAlign = (wfx->Format.wBitsPerSample / 8) * wfx->Format.nChannels;
- wfx->Format.nAvgBytesPerSec = wfx->Format.nBlockAlign * wfx->Format.nSamplesPerSec;
- wfx->Format.cbSize = 0;
-
- if (format.sampleFormat() == QAudioFormat::Float) {
- wfx->Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
- wfx->SubFormat = _KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
- } else {
- wfx->Format.wFormatTag = WAVE_FORMAT_PCM;
- wfx->SubFormat = _KSDATAFORMAT_SUBTYPE_PCM;
- }
-
- if (format.channelCount() > 2) {
- wfx->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
- wfx->Format.cbSize = 22;
- wfx->dwChannelMask = 0xFFFFFFFF >> (32 - format.channelCount());
- }
-
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/audio/qwindowsaudioutils_p.h b/src/multimedia/platform/windows/audio/qwindowsaudioutils_p.h
deleted file mode 100644
index 15bd50b2b..000000000
--- a/src/multimedia/platform/windows/audio/qwindowsaudioutils_p.h
+++ /dev/null
@@ -1,153 +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 QWINDOWSAUDIOUTILS_H
-#define QWINDOWSAUDIOUTILS_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 <qaudioformat.h>
-#include <QtCore/qt_windows.h>
-#include <mmsystem.h>
-
-#ifndef _WAVEFORMATEXTENSIBLE_
-
- #define _WAVEFORMATEXTENSIBLE_
- typedef struct
- {
- WAVEFORMATEX Format; // Base WAVEFORMATEX data
- union
- {
- WORD wValidBitsPerSample; // Valid bits in each sample container
- WORD wSamplesPerBlock; // Samples per block of audio data; valid
- // if wBitsPerSample=0 (but rarely used).
- WORD wReserved; // Zero if neither case above applies.
- } Samples;
- DWORD dwChannelMask; // Positions of the audio channels
- GUID SubFormat; // Format identifier GUID
- } WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE, *LPPWAVEFORMATEXTENSIBLE;
- typedef const WAVEFORMATEXTENSIBLE* LPCWAVEFORMATEXTENSIBLE;
-
-#endif
-
-#if defined(Q_CC_MINGW) && !defined(__MINGW64_VERSION_MAJOR)
-struct IBaseFilter; // Needed for strmif.h from stock MinGW.
-struct _DDPIXELFORMAT;
-typedef struct _DDPIXELFORMAT* LPDDPIXELFORMAT;
-#endif
-
-#include <strmif.h>
-#if !defined(Q_CC_MINGW) || defined(__MINGW64_VERSION_MAJOR)
-# include <uuids.h>
-#else
-
-extern GUID CLSID_AudioInputDeviceCategory;
-extern GUID CLSID_AudioRendererCategory;
-extern GUID IID_ICreateDevEnum;
-extern GUID CLSID_SystemDeviceEnum;
-
-#ifndef __ICreateDevEnum_INTERFACE_DEFINED__
-#define __ICreateDevEnum_INTERFACE_DEFINED__
-
-DECLARE_INTERFACE_(ICreateDevEnum, IUnknown)
-{
- STDMETHOD(CreateClassEnumerator)(REFCLSID clsidDeviceClass,
- IEnumMoniker **ppEnumMoniker,
- DWORD dwFlags) PURE;
-};
-
-#endif // __ICreateDevEnum_INTERFACE_DEFINED__
-
-#ifndef __IErrorLog_INTERFACE_DEFINED__
-#define __IErrorLog_INTERFACE_DEFINED__
-
-DECLARE_INTERFACE_(IErrorLog, IUnknown)
-{
- STDMETHOD(AddError)(THIS_ LPCOLESTR, EXCEPINFO *) PURE;
-};
-
-#endif /* __IErrorLog_INTERFACE_DEFINED__ */
-
-#ifndef __IPropertyBag_INTERFACE_DEFINED__
-#define __IPropertyBag_INTERFACE_DEFINED__
-
-const GUID IID_IPropertyBag = {0x55272A00, 0x42CB, 0x11CE, {0x81, 0x35, 0x00, 0xAA, 0x00, 0x4B, 0xB8, 0x51}};
-
-DECLARE_INTERFACE_(IPropertyBag, IUnknown)
-{
- STDMETHOD(Read)(THIS_ LPCOLESTR, VARIANT *, IErrorLog *) PURE;
- STDMETHOD(Write)(THIS_ LPCOLESTR, VARIANT *) PURE;
-};
-
-#endif /* __IPropertyBag_INTERFACE_DEFINED__ */
-
-#endif // defined(Q_CC_MINGW) && !defined(__MINGW64_VERSION_MAJOR)
-
-// For mingw toolchain mmsystem.h only defines half the defines, so add if needed.
-#ifndef WAVE_FORMAT_44M08
-#define WAVE_FORMAT_44M08 0x00000100
-#define WAVE_FORMAT_44S08 0x00000200
-#define WAVE_FORMAT_44M16 0x00000400
-#define WAVE_FORMAT_44S16 0x00000800
-#define WAVE_FORMAT_48M08 0x00001000
-#define WAVE_FORMAT_48S08 0x00002000
-#define WAVE_FORMAT_48M16 0x00004000
-#define WAVE_FORMAT_48S16 0x00008000
-#define WAVE_FORMAT_96M08 0x00010000
-#define WAVE_FORMAT_96S08 0x00020000
-#define WAVE_FORMAT_96M16 0x00040000
-#define WAVE_FORMAT_96S16 0x00080000
-#endif
-
-QT_BEGIN_NAMESPACE
-
-bool qt_convertFormat(const QAudioFormat &format, WAVEFORMATEXTENSIBLE *wfx);
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSAUDIOUTILS_H
diff --git a/src/multimedia/platform/windows/common/mfmetadata.cpp b/src/multimedia/platform/windows/common/mfmetadata.cpp
deleted file mode 100644
index ebc884759..000000000
--- a/src/multimedia/platform/windows/common/mfmetadata.cpp
+++ /dev/null
@@ -1,521 +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 <quuid.h>
-
-#include <mfapi.h>
-#include <mfidl.h>
-#include <propvarutil.h>
-#include <propkey.h>
-
-#include "qwindowsmultimediautils_p.h"
-#include "mfmetadata_p.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");
-}
-
-static QVariant convertValue(const PROPVARIANT& var)
-{
- QVariant value;
- switch (var.vt) {
- case VT_LPWSTR:
- value = QString::fromUtf16(reinterpret_cast<const char16_t *>(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 t;
- if (!FileTimeToSystemTime(&var.filetime, &t))
- break;
-
- value = QDateTime(QDate(t.wYear, t.wMonth, t.wDay),
- QTime(t.wHour, t.wMinute, t.wSecond, t.wMilliseconds),
- Qt::UTC);
- 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 char16_t *>(var.calpwstr.pElems[i])));
- value = vList;
- break;
- }
- return value;
-}
-
-static QVariant metaDataValue(IPropertyStore *content, const PROPERTYKEY &key)
-{
- QVariant value;
-
- PROPVARIANT var;
- PropVariantInit(&var);
- HRESULT hr = S_FALSE;
- if (content)
- hr = content->GetValue(key, &var);
-
- if (SUCCEEDED(hr)) {
- value = convertValue(var);
-
- // some metadata needs to be reformatted
- if (value.isValid() && content) {
- if (key == PKEY_Media_ClassPrimaryID /*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 == PKEY_Media_Duration) {
- // duration is provided in 100-nanosecond units, convert to milliseconds
- value = (value.toLongLong() + 10000) / 10000;
- } else if (key == PKEY_Video_Compression) {
- value = int(QWindowsMultimediaUtils::codecForVideoFormat(value.toUuid()));
- } else if (key == PKEY_Audio_Format) {
- value = int(QWindowsMultimediaUtils::codecForAudioFormat(value.toUuid()));
- } else if (key == PKEY_Video_FrameHeight /*Resolution*/) {
- QSize res;
- res.setHeight(value.toUInt());
- if (content && SUCCEEDED(content->GetValue(PKEY_Video_FrameWidth, &var)))
- res.setWidth(convertValue(var).toUInt());
- value = res;
- } else if (key == PKEY_Video_Orientation) {
- uint orientation = 0;
- if (content && SUCCEEDED(content->GetValue(PKEY_Video_Orientation, &var)))
- orientation = convertValue(var).toUInt();
- value = orientation;
- } else if (key == PKEY_Video_FrameRate) {
- value = value.toReal() / 1000.f;
- }
- }
- }
-
- PropVariantClear(&var);
- return value;
-}
-
-QMediaMetaData MFMetaData::fromNative(IMFMediaSource* mediaSource)
-{
- QMediaMetaData metaData;
-
- IPropertyStore *content = nullptr;
- if (!SUCCEEDED(MFGetService(mediaSource, MF_PROPERTY_HANDLER_SERVICE, IID_PPV_ARGS(&content))))
- return metaData;
-
- Q_ASSERT(content);
- DWORD cProps;
- if (SUCCEEDED(content->GetCount(&cProps))) {
- for (DWORD i = 0; i < cProps; i++)
- {
- PROPERTYKEY key;
- if (FAILED(content->GetAt(i, &key)))
- continue;
- QMediaMetaData::Key mediaKey;
- if (key == PKEY_Author) {
- mediaKey = QMediaMetaData::Author;
- } else if (key == PKEY_Title) {
- mediaKey = QMediaMetaData::Title;
-// } else if (key == PKEY_Media_SubTitle) {
-// mediaKey = QMediaMetaData::SubTitle;
-// } else if (key == PKEY_ParentalRating) {
-// mediaKey = QMediaMetaData::ParentalRating;
- } else if (key == PKEY_Media_EncodingSettings) {
- mediaKey = QMediaMetaData::Description;
- } else if (key == PKEY_Copyright) {
- mediaKey = QMediaMetaData::Copyright;
- } else if (key == PKEY_Comment) {
- mediaKey = QMediaMetaData::Comment;
- } else if (key == PKEY_Media_ProviderStyle) {
- mediaKey = QMediaMetaData::Genre;
- } else if (key == PKEY_Media_DateEncoded) {
- mediaKey = QMediaMetaData::Date;
-// } else if (key == PKEY_Rating) {
-// mediaKey = QMediaMetaData::UserRating;
-// } else if (key == PKEY_Keywords) {
-// mediaKey = QMediaMetaData::Keywords;
- } else if (key == PKEY_Language) {
- mediaKey = QMediaMetaData::Language;
- } else if (key == PKEY_Media_Publisher) {
- mediaKey = QMediaMetaData::Publisher;
- } else if (key == PKEY_Media_ClassPrimaryID) {
- mediaKey = QMediaMetaData::MediaType;
- } else if (key == PKEY_Media_Duration) {
- mediaKey = QMediaMetaData::Duration;
- } else if (key == PKEY_Audio_EncodingBitrate) {
- mediaKey = QMediaMetaData::AudioBitRate;
- } else if (key == PKEY_Audio_Format) {
- mediaKey = QMediaMetaData::AudioCodec;
-// } else if (key == PKEY_Media_AverageLevel) {
-// mediaKey = QMediaMetaData::AverageLevel;
-// } else if (key == PKEY_Audio_ChannelCount) {
-// mediaKey = QMediaMetaData::ChannelCount;
-// } else if (key == PKEY_Audio_PeakValue) {
-// mediaKey = QMediaMetaData::PeakValue;
-// } else if (key == PKEY_Audio_SampleRate) {
-// mediaKey = QMediaMetaData::SampleRate;
- } else if (key == PKEY_Music_AlbumTitle) {
- mediaKey = QMediaMetaData::AlbumTitle;
- } else if (key == PKEY_Music_AlbumArtist) {
- mediaKey = QMediaMetaData::AlbumArtist;
- } else if (key == PKEY_Music_Artist) {
- mediaKey = QMediaMetaData::ContributingArtist;
- } else if (key == PKEY_Music_Composer) {
- mediaKey = QMediaMetaData::Composer;
-// } else if (key == PKEY_Music_Conductor) {
-// mediaKey = QMediaMetaData::Conductor;
-// } else if (key == PKEY_Music_Lyrics) {
-// mediaKey = QMediaMetaData::Lyrics;
-// } else if (key == PKEY_Music_Mood) {
-// mediaKey = QMediaMetaData::Mood;
- } else if (key == PKEY_Music_TrackNumber) {
- mediaKey = QMediaMetaData::TrackNumber;
- } else if (key == PKEY_Music_Genre) {
- mediaKey = QMediaMetaData::Genre;
- } else if (key == PKEY_ThumbnailStream) {
- mediaKey = QMediaMetaData::ThumbnailImage;
- } else if (key == PKEY_Video_FrameHeight) {
- mediaKey = QMediaMetaData::Resolution;
- } else if (key == PKEY_Video_Orientation) {
- mediaKey = QMediaMetaData::Orientation;
-// } else if (key == PKEY_Video_FrameRate) {
-// mediaKey = QMediaMetaData::VideoFrameRate;
- } else if (key == PKEY_Video_EncodingBitrate) {
- mediaKey = QMediaMetaData::VideoBitRate;
- } else if (key == PKEY_Video_Compression) {
- mediaKey = QMediaMetaData::VideoCodec;
-// } else if (key == PKEY_Video_Director) {
-// mediaKey = QMediaMetaData::Director;
-// } else if (key == PKEY_Media_Writer) {
-// mediaKey = QMediaMetaData::Writer;
- } else {
- continue;
- }
- metaData.insert(mediaKey, metaDataValue(content, key));
- }
- }
-
- content->Release();
-
- return metaData;
-}
-
-static REFPROPERTYKEY propertyKeyForMetaDataKey(QMediaMetaData::Key key)
-{
- switch (key) {
- case QMediaMetaData::Key::Title:
- return PKEY_Title;
- case QMediaMetaData::Key::Author:
- return PKEY_Author;
- case QMediaMetaData::Key::Comment:
- return PKEY_Comment;
- case QMediaMetaData::Key::Genre:
- return PKEY_Music_Genre;
- case QMediaMetaData::Key::Copyright:
- return PKEY_Copyright;
- case QMediaMetaData::Key::Publisher:
- return PKEY_Media_Publisher;
- case QMediaMetaData::Key::Url:
- return PKEY_Media_AuthorUrl;
- case QMediaMetaData::Key::AlbumTitle:
- return PKEY_Music_AlbumTitle;
- case QMediaMetaData::Key::AlbumArtist:
- return PKEY_Music_AlbumArtist;
- case QMediaMetaData::Key::TrackNumber:
- return PKEY_Music_TrackNumber;
- case QMediaMetaData::Key::Date:
- return PKEY_Media_DateEncoded;
- case QMediaMetaData::Key::Composer:
- return PKEY_Music_Composer;
- case QMediaMetaData::Key::Duration:
- return PKEY_Media_Duration;
- case QMediaMetaData::Key::Language:
- return PKEY_Language;
- case QMediaMetaData::Key::Description:
- return PKEY_Media_EncodingSettings;
- case QMediaMetaData::Key::AudioBitRate:
- return PKEY_Audio_EncodingBitrate;
- case QMediaMetaData::Key::ContributingArtist:
- return PKEY_Music_Artist;
- case QMediaMetaData::Key::ThumbnailImage:
- return PKEY_ThumbnailStream;
- case QMediaMetaData::Key::Orientation:
- return PKEY_Video_Orientation;
- case QMediaMetaData::Key::VideoFrameRate:
- return PKEY_Video_FrameRate;
- case QMediaMetaData::Key::VideoBitRate:
- return PKEY_Video_EncodingBitrate;
- case QMediaMetaData::MediaType:
- return PKEY_Media_ClassPrimaryID;
- default:
- return PKEY_Null;
- }
-}
-
-static void setStringProperty(IPropertyStore *content, REFPROPERTYKEY key, const QString &value)
-{
- PROPVARIANT propValue = {};
- if (SUCCEEDED(InitPropVariantFromString(reinterpret_cast<LPCWSTR>(value.utf16()), &propValue))) {
- if (SUCCEEDED(PSCoerceToCanonicalValue(key, &propValue)))
- content->SetValue(key, propValue);
- PropVariantClear(&propValue);
- }
-}
-
-static void setUInt32Property(IPropertyStore *content, REFPROPERTYKEY key, quint32 value)
-{
- PROPVARIANT propValue = {};
- if (SUCCEEDED(InitPropVariantFromUInt32(ULONG(value), &propValue))) {
- if (SUCCEEDED(PSCoerceToCanonicalValue(key, &propValue)))
- content->SetValue(key, propValue);
- PropVariantClear(&propValue);
- }
-}
-
-static void setUInt64Property(IPropertyStore *content, REFPROPERTYKEY key, quint64 value)
-{
- PROPVARIANT propValue = {};
- if (SUCCEEDED(InitPropVariantFromUInt64(ULONGLONG(value), &propValue))) {
- if (SUCCEEDED(PSCoerceToCanonicalValue(key, &propValue)))
- content->SetValue(key, propValue);
- PropVariantClear(&propValue);
- }
-}
-
-static void setFileTimeProperty(IPropertyStore *content, REFPROPERTYKEY key, const FILETIME *ft)
-{
- PROPVARIANT propValue = {};
- if (SUCCEEDED(InitPropVariantFromFileTime(ft, &propValue))) {
- if (SUCCEEDED(PSCoerceToCanonicalValue(key, &propValue)))
- content->SetValue(key, propValue);
- PropVariantClear(&propValue);
- }
-}
-
-void MFMetaData::toNative(const QMediaMetaData &metaData, IPropertyStore *content)
-{
- if (content) {
-
- for (const auto &key : metaData.keys()) {
-
- QVariant value = metaData.value(key);
-
- if (key == QMediaMetaData::Key::MediaType) {
-
- QString strValue = metaData.stringValue(key);
- QString v;
-
- // Sets property to one of the MediaClassPrimaryID values defined by Microsoft:
- // https://docs.microsoft.com/en-us/windows/win32/wmformat/wm-mediaprimaryid
- if (strValue == QLatin1String("Music"))
- v = QLatin1String("{D1607DBC-E323-4BE2-86A1-48A42A28441E}");
- else if (strValue == QLatin1String("Video"))
- v = QLatin1String("{DB9830BD-3AB3-4FAB-8A37-1A995F7FF74B}");
- else if (strValue == QLatin1String("Audio"))
- v = QLatin1String("{01CD0F29-DA4E-4157-897B-6275D50C4F11}");
- else
- v = QLatin1String("{FCF24A76-9A57-4036-990D-E35DD8B244E1}");
-
- setStringProperty(content, PKEY_Media_ClassPrimaryID, v);
-
- } else if (key == QMediaMetaData::Key::Duration) {
-
- setUInt64Property(content, PKEY_Media_Duration, value.toULongLong() * 10000);
-
- } else if (key == QMediaMetaData::Key::Resolution) {
-
- QSize res = value.toSize();
- setUInt32Property(content, PKEY_Video_FrameWidth, quint32(res.width()));
- setUInt32Property(content, PKEY_Video_FrameHeight, quint32(res.height()));
-
- } else if (key == QMediaMetaData::Key::Orientation) {
-
- setUInt32Property(content, PKEY_Video_Orientation, value.toUInt());
-
- } else if (key == QMediaMetaData::Key::VideoFrameRate) {
-
- qreal fps = value.toReal();
- setUInt32Property(content, PKEY_Video_FrameRate, quint32(fps * 1000));
-
- } else if (key == QMediaMetaData::Key::TrackNumber) {
-
- setUInt32Property(content, PKEY_Music_TrackNumber, value.toUInt());
-
- } else if (key == QMediaMetaData::Key::AudioBitRate) {
-
- setUInt32Property(content, PKEY_Audio_EncodingBitrate, value.toUInt());
-
- } else if (key == QMediaMetaData::Key::VideoBitRate) {
-
- setUInt32Property(content, PKEY_Video_EncodingBitrate, value.toUInt());
-
- } else if (key == QMediaMetaData::Key::Date) {
-
- // Convert QDateTime to FILETIME by converting to 100-nsecs since
- // 01/01/1970 UTC and adding the difference from 1601 to 1970.
- ULARGE_INTEGER t = {};
- t.QuadPart = ULONGLONG(value.toDateTime().toUTC().toMSecsSinceEpoch() * 10000
- + 116444736000000000LL);
-
- FILETIME ft = {};
- ft.dwHighDateTime = t.HighPart;
- ft.dwLowDateTime = t.LowPart;
-
- setFileTimeProperty(content, PKEY_Media_DateEncoded, &ft);
-
- } else {
-
- // By default use as string and let PSCoerceToCanonicalValue()
- // do validation and type conversion.
- REFPROPERTYKEY propKey = propertyKeyForMetaDataKey(key);
-
- if (propKey != PKEY_Null) {
- QString strValue = metaData.stringValue(key);
- if (!strValue.isEmpty())
- setStringProperty(content, propKey, strValue);
- }
- }
- }
- }
-}
-
diff --git a/src/multimedia/platform/windows/common/mfmetadata_p.h b/src/multimedia/platform/windows/common/mfmetadata_p.h
deleted file mode 100644
index d1846e9c5..000000000
--- a/src/multimedia/platform/windows/common/mfmetadata_p.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 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
-
-//
-// 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 <qmediametadata.h>
-#include "Mfidl.h"
-
-QT_USE_NAMESPACE
-
-class MFMetaData
-{
-public:
- static QMediaMetaData fromNative(IMFMediaSource* mediaSource);
- static void toNative(const QMediaMetaData &metaData, IPropertyStore *content);
-};
-
-#endif
diff --git a/src/multimedia/platform/windows/common/qwindowsiupointer_p.h b/src/multimedia/platform/windows/common/qwindowsiupointer_p.h
deleted file mode 100644
index a5c08ccc9..000000000
--- a/src/multimedia/platform/windows/common/qwindowsiupointer_p.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWINDOWSIUPOINTER_H
-#define QWINDOWSIUPOINTER_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.
-//
-
-template <class T>
-class QWindowsIUPointer
-{
-public:
- explicit QWindowsIUPointer(T *ptr = nullptr) : m_ptr(ptr) {}
- QWindowsIUPointer(const QWindowsIUPointer<T> &uiPtr) : m_ptr(uiPtr.m_ptr) { if (m_ptr) m_ptr->AddRef(); }
- QWindowsIUPointer(QWindowsIUPointer<T> &&uiPtr) : m_ptr(uiPtr.m_ptr) { uiPtr.m_ptr = nullptr; }
- ~QWindowsIUPointer() { if (m_ptr) m_ptr->Release(); }
-
- QWindowsIUPointer& operator=(const QWindowsIUPointer<T> &rhs) {
- if (m_ptr)
- m_ptr->Release();
- m_ptr = rhs.m_ptr;
- m_ptr->AddRef();
- return *this;
- }
-
- QWindowsIUPointer& operator=(QWindowsIUPointer<T> &&rhs) noexcept {
- if (m_ptr)
- m_ptr->Release();
- m_ptr = rhs.m_ptr;
- rhs.m_ptr = nullptr;
- return *this;
- }
-
- explicit operator bool() const { return m_ptr != nullptr; }
- operator T*() const { return m_ptr; }
- T* operator->() const { return m_ptr; }
-
- T** address() { Q_ASSERT(m_ptr == nullptr); return &m_ptr; }
- void reset(T* ptr = nullptr) { if (m_ptr) m_ptr->Release(); m_ptr = ptr; }
-
-private:
- T* m_ptr;
-};
-
-#endif
diff --git a/src/multimedia/platform/windows/common/qwindowsmultimediautils.cpp b/src/multimedia/platform/windows/common/qwindowsmultimediautils.cpp
deleted file mode 100644
index ad6a234eb..000000000
--- a/src/multimedia/platform/windows/common/qwindowsmultimediautils.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwindowsmultimediautils_p.h"
-
-#include <mfapi.h>
-#include <mfidl.h>
-
-QT_BEGIN_NAMESPACE
-
-QVideoFrameFormat::PixelFormat QWindowsMultimediaUtils::pixelFormatFromMediaSubtype(const GUID &subtype)
-{
- if (subtype == MFVideoFormat_ARGB32)
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- return QVideoFrameFormat::Format_BGRA8888;
-#else
- return QVideoFrameFormat::Format_ARGB8888;
-#endif
- if (subtype == MFVideoFormat_RGB32)
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- return QVideoFrameFormat::Format_BGRX8888;
-#else
- return QVideoFrameFormat::Format_XRGB8888;
-#endif
- if (subtype == MFVideoFormat_AYUV)
- return QVideoFrameFormat::Format_AYUV;
- if (subtype == MFVideoFormat_I420)
- return QVideoFrameFormat::Format_YUV420P;
- if (subtype == MFVideoFormat_UYVY)
- return QVideoFrameFormat::Format_UYVY;
- if (subtype == MFVideoFormat_YV12)
- return QVideoFrameFormat::Format_YV12;
- if (subtype == MFVideoFormat_NV12)
- return QVideoFrameFormat::Format_NV12;
- if (subtype == MFVideoFormat_YUY2)
- return QVideoFrameFormat::Format_YUYV;
- if (subtype == MFVideoFormat_P010)
- return QVideoFrameFormat::Format_P010;
- if (subtype == MFVideoFormat_P016)
- return QVideoFrameFormat::Format_P016;
- if (subtype == MFVideoFormat_L8)
- return QVideoFrameFormat::Format_Y8;
- if (subtype == MFVideoFormat_L16)
- return QVideoFrameFormat::Format_Y16;
-
- return QVideoFrameFormat::Format_Invalid;
-}
-
-GUID QWindowsMultimediaUtils::videoFormatForCodec(QMediaFormat::VideoCodec codec)
-{
- switch (codec) {
- case QMediaFormat::VideoCodec::MPEG1:
- return MFVideoFormat_MPG1;
- case QMediaFormat::VideoCodec::MPEG2:
- return MFVideoFormat_MPEG2;
- case QMediaFormat::VideoCodec::MPEG4:
- return MFVideoFormat_MP4V;
- case QMediaFormat::VideoCodec::H264:
- return MFVideoFormat_H264;
- case QMediaFormat::VideoCodec::H265:
- return MFVideoFormat_H265;
- case QMediaFormat::VideoCodec::VP8:
- return MFVideoFormat_VP80;
- case QMediaFormat::VideoCodec::VP9:
- return MFVideoFormat_VP90;
- case QMediaFormat::VideoCodec::AV1:
- return MFVideoFormat_AV1;
- case QMediaFormat::VideoCodec::WMV:
- return MFVideoFormat_WMV3;
- case QMediaFormat::VideoCodec::MotionJPEG:
- return MFVideoFormat_MJPG;
- default:
- return MFVideoFormat_H264;
- }
-}
-
-QMediaFormat::VideoCodec QWindowsMultimediaUtils::codecForVideoFormat(GUID format)
-{
- if (format == MFVideoFormat_MPG1)
- return QMediaFormat::VideoCodec::MPEG1;
- if (format == MFVideoFormat_MPEG2)
- return QMediaFormat::VideoCodec::MPEG2;
- if (format == MFVideoFormat_MP4V
- || format == MFVideoFormat_M4S2
- || format == MFVideoFormat_MP4S
- || format == MFVideoFormat_MP43)
- return QMediaFormat::VideoCodec::MPEG4;
- if (format == MFVideoFormat_H264)
- return QMediaFormat::VideoCodec::H264;
- if (format == MFVideoFormat_H265)
- return QMediaFormat::VideoCodec::H265;
- if (format == MFVideoFormat_VP80)
- return QMediaFormat::VideoCodec::VP8;
- if (format == MFVideoFormat_VP90)
- return QMediaFormat::VideoCodec::VP9;
- if (format == MFVideoFormat_AV1)
- return QMediaFormat::VideoCodec::AV1;
- if (format == MFVideoFormat_WMV1
- || format == MFVideoFormat_WMV2
- || format == MFVideoFormat_WMV3)
- return QMediaFormat::VideoCodec::WMV;
- if (format == MFVideoFormat_MJPG)
- return QMediaFormat::VideoCodec::MotionJPEG;
- return QMediaFormat::VideoCodec::Unspecified;
-}
-
-GUID QWindowsMultimediaUtils::audioFormatForCodec(QMediaFormat::AudioCodec codec)
-{
- switch (codec) {
- case QMediaFormat::AudioCodec::MP3:
- return MFAudioFormat_MP3;
- case QMediaFormat::AudioCodec::AAC:
- return MFAudioFormat_AAC;
- case QMediaFormat::AudioCodec::ALAC:
- return MFAudioFormat_ALAC;
- case QMediaFormat::AudioCodec::FLAC:
- return MFAudioFormat_FLAC;
- case QMediaFormat::AudioCodec::Vorbis:
- return MFAudioFormat_Vorbis;
- case QMediaFormat::AudioCodec::Wave:
- return MFAudioFormat_PCM;
- case QMediaFormat::AudioCodec::Opus:
- return MFAudioFormat_Opus;
- case QMediaFormat::AudioCodec::AC3:
- return MFAudioFormat_Dolby_AC3;
- case QMediaFormat::AudioCodec::EAC3:
- return MFAudioFormat_Dolby_DDPlus;
- case QMediaFormat::AudioCodec::WMA:
- return MFAudioFormat_WMAudioV9;
- default:
- return MFAudioFormat_AAC;
- }
-}
-
-QMediaFormat::AudioCodec QWindowsMultimediaUtils::codecForAudioFormat(GUID format)
-{
- if (format == MFAudioFormat_MP3)
- return QMediaFormat::AudioCodec::MP3;
- if (format == MFAudioFormat_AAC)
- return QMediaFormat::AudioCodec::AAC;
- if (format == MFAudioFormat_ALAC)
- return QMediaFormat::AudioCodec::ALAC;
- if (format == MFAudioFormat_FLAC)
- return QMediaFormat::AudioCodec::FLAC;
- if (format == MFAudioFormat_Vorbis)
- return QMediaFormat::AudioCodec::Vorbis;
- if (format == MFAudioFormat_PCM)
- return QMediaFormat::AudioCodec::Wave;
- if (format == MFAudioFormat_Opus)
- return QMediaFormat::AudioCodec::Opus;
- if (format == MFAudioFormat_Dolby_AC3)
- return QMediaFormat::AudioCodec::AC3;
- if (format == MFAudioFormat_Dolby_DDPlus)
- return QMediaFormat::AudioCodec::EAC3;
- if (format == MFAudioFormat_WMAudioV8
- || format == MFAudioFormat_WMAudioV9
- || format == MFAudioFormat_WMAudio_Lossless)
- return QMediaFormat::AudioCodec::WMA;
- return QMediaFormat::AudioCodec::Unspecified;
-}
-
-GUID QWindowsMultimediaUtils::containerForVideoFileFormat(QMediaFormat::FileFormat format)
-{
- switch (format) {
- case QMediaFormat::FileFormat::MPEG4:
- return MFTranscodeContainerType_MPEG4;
- case QMediaFormat::FileFormat::WMV:
- return MFTranscodeContainerType_ASF;
- case QMediaFormat::FileFormat::AVI:
- return MFTranscodeContainerType_AVI;
- default:
- return MFTranscodeContainerType_MPEG4;
- }
-}
-
-GUID QWindowsMultimediaUtils::containerForAudioFileFormat(QMediaFormat::FileFormat format)
-{
- switch (format) {
- case QMediaFormat::FileFormat::MP3:
- return MFTranscodeContainerType_MP3;
- case QMediaFormat::FileFormat::AAC:
- return MFTranscodeContainerType_ADTS;
- case QMediaFormat::FileFormat::Mpeg4Audio:
- return MFTranscodeContainerType_MPEG4;
- case QMediaFormat::FileFormat::WMA:
- return MFTranscodeContainerType_ASF;
- case QMediaFormat::FileFormat::FLAC:
- return MFTranscodeContainerType_FLAC;
- case QMediaFormat::FileFormat::Wave:
- return MFTranscodeContainerType_WAVE;
- default:
- return MFTranscodeContainerType_MPEG4;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/common/qwindowsmultimediautils_p.h b/src/multimedia/platform/windows/common/qwindowsmultimediautils_p.h
deleted file mode 100644
index 100059cf0..000000000
--- a/src/multimedia/platform/windows/common/qwindowsmultimediautils_p.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWINDOWSMULTIMEDIATUTILS_P_H
-#define QWINDOWSMULTIMEDIATUTILS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qtmultimediaglobal_p.h>
-#include <private/qplatformmediaformatinfo_p.h>
-#include <qvideoframeformat.h>
-#include <guiddef.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QWindowsMultimediaUtils {
-
- QVideoFrameFormat::PixelFormat pixelFormatFromMediaSubtype(const GUID &subtype);
-
- GUID videoFormatForCodec(QMediaFormat::VideoCodec codec);
-
- QMediaFormat::VideoCodec codecForVideoFormat(GUID format);
-
- GUID audioFormatForCodec(QMediaFormat::AudioCodec codec);
-
- QMediaFormat::AudioCodec codecForAudioFormat(GUID format);
-
- GUID containerForVideoFileFormat(QMediaFormat::FileFormat format);
-
- GUID containerForAudioFileFormat(QMediaFormat::FileFormat format);
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/windows/decoder/mfaudiodecodercontrol.cpp b/src/multimedia/platform/windows/decoder/mfaudiodecodercontrol.cpp
deleted file mode 100644
index de1311835..000000000
--- a/src/multimedia/platform/windows/decoder/mfaudiodecodercontrol.cpp
+++ /dev/null
@@ -1,454 +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_p.h"
-
-MFAudioDecoderControl::MFAudioDecoderControl(QAudioDecoder *parent)
- : QPlatformAudioDecoder(parent)
- , m_decoderSourceReader(new MFDecoderSourceReader)
- , m_sourceResolver(new SourceResolver)
- , m_resampler(0)
- , m_device(0)
- , m_mfInputStreamID(0)
- , m_mfOutputStreamID(0)
- , m_bufferReady(false)
- , m_duration(-1)
- , m_position(-1)
- , 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;
- 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();
-}
-
-QUrl MFAudioDecoderControl::source() const
-{
- return m_source;
-}
-
-void MFAudioDecoderControl::onSourceCleared()
-{
- bool positionDirty = false;
- bool durationDirty = false;
- if (m_position != -1) {
- m_position = -1;
- positionDirty = true;
- }
- if (m_duration != -1) {
- m_duration = -1;
- durationDirty = true;
- }
- if (positionDirty)
- positionChanged(m_position);
- if (durationDirty)
- durationChanged(m_duration);
-}
-
-void MFAudioDecoderControl::setSource(const QUrl &fileName)
-{
- if (!m_device && m_source == fileName)
- return;
- m_sourceReady = false;
- m_sourceResolver->cancel();
- m_decoderSourceReader->setSource(nullptr, m_audioFormat);
- m_device = 0;
- m_source = fileName;
- if (!m_source.isEmpty()) {
- m_sourceResolver->shutdown();
- m_sourceResolver->load(m_source, 0);
- m_loadingSource = true;
- } else {
- onSourceCleared();
- }
- sourceChanged();
-}
-
-QIODevice* MFAudioDecoderControl::sourceDevice() const
-{
- return m_device;
-}
-
-void MFAudioDecoderControl::setSourceDevice(QIODevice *device)
-{
- if (m_device == device && m_source.isEmpty())
- return;
- m_sourceReady = false;
- m_sourceResolver->cancel();
- m_decoderSourceReader->setSource(nullptr, m_audioFormat);
- m_source.clear();
- m_device = device;
- if (m_device) {
- m_sourceResolver->shutdown();
- m_sourceResolver->load(QUrl(), m_device);
- m_loadingSource = true;
- } else {
- onSourceCleared();
- }
- 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;
-
- 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));
- }
- UINT32 bitsPerSample = 0;
- mediaType->GetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, &bitsPerSample);
-
- GUID subType;
- if (SUCCEEDED(mediaType->GetGUID(MF_MT_SUBTYPE, &subType))) {
- if (subType == MFAudioFormat_Float) {
- m_sourceOutputFormat.setSampleFormat(QAudioFormat::Float);
- } else if (bitsPerSample == 8) {
- m_sourceOutputFormat.setSampleFormat(QAudioFormat::UInt8);
- } else if (bitsPerSample == 16) {
- m_sourceOutputFormat.setSampleFormat(QAudioFormat::Int16);
- } else if (bitsPerSample == 32){
- m_sourceOutputFormat.setSampleFormat(QAudioFormat::Int32);
- }
- }
-
- if (!m_audioFormat.isValid())
- setResamplerOutputFormat(m_sourceOutputFormat);
- else {
- setResamplerOutputFormat(m_audioFormat);
- }
- }
-
- 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);
- durationChanged(m_duration);
- }
- }
- if (isDecoding()) {
- activatePipeline();
- }
- } else if (isDecoding()) {
- setIsDecoding(false);
- }
-}
-
-void MFAudioDecoderControl::setResamplerOutputFormat(const QAudioFormat &format)
-{
- if (format.isValid()) {
- IMFMediaType *mediaType = 0;
- MFCreateMediaType(&mediaType);
- mediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
- if (format.sampleFormat() == 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(format.channelCount()));
- mediaType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, UINT32(format.sampleRate()));
- UINT32 alignmentBlock = UINT32(format.bytesPerFrame());
- mediaType->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, alignmentBlock);
- UINT32 avgBytesPerSec = UINT32(format.sampleRate() * format.bytesPerFrame());
- mediaType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, avgBytesPerSec);
- mediaType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, UINT32(format.bytesPerSample()*8));
- 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 && !isDecoding()) {
- updateResamplerOutputType();
- } else {
- m_resamplerDirty = true;
- }
-}
-
-void MFAudioDecoderControl::handleMediaSourceError(long hr)
-{
- Q_UNUSED(hr);
- m_loadingSource = false;
- m_decoderSourceReader->setSource(nullptr, m_audioFormat);
- setIsDecoding(false);
-}
-
-void MFAudioDecoderControl::activatePipeline()
-{
- Q_ASSERT(!m_bufferReady);
- setIsDecoding(true);
- connect(m_decoderSourceReader, SIGNAL(sampleAdded()), this, SLOT(handleSampleAdded()));
- if (m_resamplerDirty) {
- updateResamplerOutputType();
- }
- m_decoderSourceReader->reset();
- m_decoderSourceReader->readNextSample();
- if (m_position != -1) {
- m_position = -1;
- positionChanged(-1);
- }
-}
-
-void MFAudioDecoderControl::start()
-{
- if (isDecoding())
- return;
-
- if (m_loadingSource) {
- //deferred starting
- setIsDecoding(true);
- return;
- }
-
- if (!m_decoderSourceReader->mediaSource())
- return;
- activatePipeline();
-}
-
-void MFAudioDecoderControl::stop()
-{
- if (!isDecoding())
- return;
- disconnect(m_decoderSourceReader, SIGNAL(sampleAdded()), this, SLOT(handleSampleAdded()));
- if (m_bufferReady) {
- m_bufferReady = false;
- emit bufferAvailableChanged(m_bufferReady);
- }
- setIsDecoding(false);
-}
-
-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;
- QAudioFormat bufferFormat;
- if (!m_audioFormat.isValid()) {
- bufferFormat = m_sourceOutputFormat;
- //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 {
- bufferFormat = m_audioFormat;
- 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, bufferFormat, 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;
- m_audioFormat = format;
- setResamplerOutputFormat(format);
- 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/multimedia/platform/windows/decoder/mfaudiodecodercontrol_p.h b/src/multimedia/platform/windows/decoder/mfaudiodecodercontrol_p.h
deleted file mode 100644
index 6efdbb346..000000000
--- a/src/multimedia/platform/windows/decoder/mfaudiodecodercontrol_p.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 MFAUDIODECODERCONTROL_H
-#define MFAUDIODECODERCONTROL_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 "private/qplatformaudiodecoder_p.h"
-#include "mfdecodersourcereader_p.h"
-#include "private/sourceresolver_p.h"
-
-QT_USE_NAMESPACE
-
-class MFAudioDecoderControl : public QPlatformAudioDecoder
-{
- Q_OBJECT
-public:
- MFAudioDecoderControl(QAudioDecoder *parent);
- ~MFAudioDecoderControl();
-
- QUrl source() const;
- void setSource(const QUrl &fileName);
-
- QIODevice* sourceDevice() const;
- void setSourceDevice(QIODevice *device);
-
- void start();
- void stop();
-
- QAudioFormat audioFormat() const override;
- void setAudioFormat(const QAudioFormat &format) override;
-
- 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();
- void setResamplerOutputFormat(const QAudioFormat &format);
-
- MFDecoderSourceReader *m_decoderSourceReader;
- SourceResolver *m_sourceResolver;
- IMFTransform *m_resampler;
- QUrl m_source;
- 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/multimedia/platform/windows/decoder/mfdecodersourcereader.cpp b/src/multimedia/platform/windows/decoder/mfdecodersourcereader.cpp
deleted file mode 100644
index 381c60dc5..000000000
--- a/src/multimedia/platform/windows/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_p.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.sampleFormat() == 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/multimedia/platform/windows/decoder/mfdecodersourcereader_p.h b/src/multimedia/platform/windows/decoder/mfdecodersourcereader_p.h
deleted file mode 100644
index 7d63f5368..000000000
--- a/src/multimedia/platform/windows/decoder/mfdecodersourcereader_p.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 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
-
-//
-// 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 <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/multimedia/platform/windows/evr/evrcustompresenter.cpp b/src/multimedia/platform/windows/evr/evrcustompresenter.cpp
deleted file mode 100644
index 086fb57d4..000000000
--- a/src/multimedia/platform/windows/evr/evrcustompresenter.cpp
+++ /dev/null
@@ -1,2005 +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_p.h"
-
-#include "evrd3dpresentengine_p.h"
-#include "evrhelpers_p.h"
-#include <private/qwindowsmultimediautils_p.h>
-#include <private/qplatformvideosink_p.h>
-
-#include <QtGui/private/qrhi_p.h>
-
-#include <QtCore/qmutex.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qrect.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 QVideoFrameFormat::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(QVideoSink *sink)
- : 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_videoSink(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;
-
- setSink(sink);
-}
-
-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_videoSink) {
- if (m_presentEngine->supportsTextureRendering() && m_videoSink->rhi() && m_videoSink->rhi()->backend() == QRhi::OpenGLES2) {
- m_presentEngine->setHint(D3DPresentEngine::RenderToTexture, true);
- m_canRenderToSurface = true;
- } else {
- for (int f = 0; f < QVideoFrameFormat::NPixelFormats; ++f) {
- // ### set a better preference order
- QVideoFrameFormat::PixelFormat format = QVideoFrameFormat::PixelFormat(f);
- if (SUCCEEDED(m_presentEngine->checkFormat(qt_evr_D3DFormatFromPixelFormat(format)))) {
- m_canRenderToSurface = true;
- break;
- }
- }
- }
- }
-
- // TODO: if media type already set, renegotiate?
-}
-
-void EVRCustomPresenter::setSink(QVideoSink *sink)
-{
- m_mutex.lock();
- m_videoSink = sink;
- 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_videoSink) {
- // 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;
-
- QVideoFrameFormat::PixelFormat pixelFormat = pixelFormatFromMediaType(proposed);
- if (pixelFormat == QVideoFrameFormat::Format_Invalid)
- 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;
- }
-}
-
-void EVRCustomPresenter::stopSurface()
-{
- if (thread() != QThread::currentThread()) {
- QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StopSurface)));
- return;
- }
-}
-
-void EVRCustomPresenter::presentSample(IMFSample *sample)
-{
- if (thread() != QThread::currentThread()) {
- QCoreApplication::postEvent(this, new PresentSampleEvent(sample));
- return;
- }
-
- if (!m_videoSink || !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);
- }
-
- m_videoSink->platformVideoSink()->setVideoFrame(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 QVideoFrameFormat::PixelFormat pixelFormatFromMediaType(IMFMediaType *type)
-{
- GUID majorType;
- if (FAILED(type->GetMajorType(&majorType)))
- return QVideoFrameFormat::Format_Invalid;
- if (majorType != MFMediaType_Video)
- return QVideoFrameFormat::Format_Invalid;
-
- GUID subtype;
- if (FAILED(type->GetGUID(MF_MT_SUBTYPE, &subtype)))
- return QVideoFrameFormat::Format_Invalid;
-
- return QWindowsMultimediaUtils::pixelFormatFromMediaSubtype(subtype);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/evr/evrcustompresenter_p.h b/src/multimedia/platform/windows/evr/evrcustompresenter_p.h
deleted file mode 100644
index 9b34e449f..000000000
--- a/src/multimedia/platform/windows/evr/evrcustompresenter_p.h
+++ /dev/null
@@ -1,387 +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
-
-//
-// 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 <QObject>
-#include <qmutex.h>
-#include <qqueue.h>
-#include <qevent.h>
-#include <qvideoframeformat.h>
-#include <qvideosink.h>
-
-#include "evrdefs_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class EVRCustomPresenter;
-class D3DPresentEngine;
-
-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(QVideoSink *sink = 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 setSink(QVideoSink *sink);
-
- 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
-
- QVideoSink *m_videoSink;
- 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/multimedia/platform/windows/evr/evrd3dpresentengine.cpp b/src/multimedia/platform/windows/evr/evrd3dpresentengine.cpp
deleted file mode 100644
index 89c22d3ae..000000000
--- a/src/multimedia/platform/windows/evr/evrd3dpresentengine.cpp
+++ /dev/null
@@ -1,393 +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_p.h"
-
-#include "evrhelpers_p.h"
-
-#include <private/qabstractvideobuffer_p.h>
-#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, QVideoFrame::HandleType handleType)
- : QAbstractVideoBuffer(handleType)
- , m_sample(sample)
- , m_surface(0)
- , m_mapMode(QVideoFrame::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 != QVideoFrame::NotMapped)
- m_surface->UnlockRect();
- m_surface->Release();
- }
- if (m_sample)
- m_sample->Release();
- }
-
- QVideoFrame::MapMode mapMode() const override { return m_mapMode; }
- MapData map(QVideoFrame::MapMode mode) override;
- void unmap() override;
-
-private:
- IMFSample *m_sample;
- IDirect3DSurface9 *m_surface;
- QVideoFrame::MapMode m_mapMode;
-};
-
-IMFSampleVideoBuffer::MapData IMFSampleVideoBuffer::map(QVideoFrame::MapMode mode)
-{
- if (!m_surface || m_mapMode != QVideoFrame::NotMapped)
- return {};
-
- D3DSURFACE_DESC desc;
- if (FAILED(m_surface->GetDesc(&desc)))
- return {};
-
- D3DLOCKED_RECT rect;
- if (FAILED(m_surface->LockRect(&rect, NULL, mode == QVideoFrame::ReadOnly ? D3DLOCK_READONLY : 0)))
- return {};
-
- m_mapMode = mode;
-
- MapData mapData;
- mapData.nPlanes = 1;
- mapData.bytesPerLine[0] = (int)rect.Pitch;
- mapData.data[0] = reinterpret_cast<uchar *>(rect.pBits);
- mapData.size[0] = (int)(rect.Pitch * desc.Height);
- return mapData;
-}
-
-void IMFSampleVideoBuffer::unmap()
-{
- if (m_mapMode == QVideoFrame::NotMapped)
- return;
-
- m_mapMode = QVideoFrame::NotMapped;
- m_surface->UnlockRect();
-}
-
-D3DPresentEngine::D3DPresentEngine()
- : m_deviceResetToken(0)
- , m_D3D9(0)
- , m_device(0)
- , m_devices(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_devices);
- 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_devices);
-
- 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_devices)
- 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_devices->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 = QVideoFrameFormat();
-}
-
-HRESULT D3DPresentEngine::getService(REFGUID, REFIID riid, void** ppv)
-{
- HRESULT hr = S_OK;
-
- if (riid == __uuidof(IDirect3DDeviceManager9)) {
- if (m_devices == NULL) {
- hr = MF_E_UNSUPPORTED_SERVICE;
- } else {
- *ppv = m_devices;
- m_devices->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(&params);
- 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 = QVideoFrameFormat(QSize(width, height),
- m_useTextureRendering ? QVideoFrameFormat::Format_BGRX8888
- : qt_evr_pixelFormatFromD3DFormat(d3dFormat));
- } 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_useTextureRendering ? QVideoFrame::RhiTextureHandle : QVideoFrame::NoHandle)),
- m_surfaceFormat);
-
- // 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/multimedia/platform/windows/evr/evrd3dpresentengine_p.h b/src/multimedia/platform/windows/evr/evrd3dpresentengine_p.h
deleted file mode 100644
index 6b8353c53..000000000
--- a/src/multimedia/platform/windows/evr/evrd3dpresentengine_p.h
+++ /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$
-**
-****************************************************************************/
-
-#ifndef EVRD3DPRESENTENGINE_H
-#define EVRD3DPRESENTENGINE_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 <QMutex>
-#include <QVideoFrameFormat>
-
-#include <d3d9.h>
-
-struct IDirect3D9Ex;
-struct IDirect3DDevice9Ex;
-struct IDirect3DDeviceManager9;
-struct IDirect3DSurface9;
-struct IDirect3DTexture9;
-struct IMFSample;
-struct IMFMediaType;
-
-QT_BEGIN_NAMESPACE
-class QVideoFrame;
-QT_END_NAMESPACE
-
-// Randomly generated GUIDs
-static const GUID MFSamplePresenter_SampleCounter =
-{ 0xb0bb83cc, 0xf10f, 0x4e2e, { 0xaa, 0x2b, 0x29, 0xea, 0x5e, 0x92, 0xef, 0x85 } };
-
-QT_BEGIN_NAMESPACE
-
-#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);
- QVideoFrameFormat 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_devices;
-
- QVideoFrameFormat 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/multimedia/platform/windows/evr/evrdefs.cpp b/src/multimedia/platform/windows/evr/evrdefs.cpp
deleted file mode 100644
index 94370a14a..000000000
--- a/src/multimedia/platform/windows/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_p.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/multimedia/platform/windows/evr/evrdefs_p.h b/src/multimedia/platform/windows/evr/evrdefs_p.h
deleted file mode 100644
index f9df48387..000000000
--- a/src/multimedia/platform/windows/evr/evrdefs_p.h
+++ /dev/null
@@ -1,364 +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
-
-//
-// 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 <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/multimedia/platform/windows/evr/evrhelpers.cpp b/src/multimedia/platform/windows/evr/evrhelpers.cpp
deleted file mode 100644
index 3f2059585..000000000
--- a/src/multimedia/platform/windows/evr/evrhelpers.cpp
+++ /dev/null
@@ -1,174 +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_p.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;
-}
-
-QVideoFrameFormat::PixelFormat qt_evr_pixelFormatFromD3DFormat(DWORD format)
-{
- switch (format) {
- case D3DFMT_A8R8G8B8:
- return QVideoFrameFormat::Format_BGRA8888;
- case D3DFMT_X8R8G8B8:
- return QVideoFrameFormat::Format_BGRX8888;
- case D3DFMT_A8:
- return QVideoFrameFormat::Format_Y8;
- case D3DFMT_A8B8G8R8:
- return QVideoFrameFormat::Format_RGBA8888;
- case D3DFMT_X8B8G8R8:
- return QVideoFrameFormat::Format_RGBX8888;
- case D3DFMT_UYVY:
- return QVideoFrameFormat::Format_UYVY;
- case D3DFMT_YUY2:
- return QVideoFrameFormat::Format_YUYV;
- case D3DFMT_NV12:
- return QVideoFrameFormat::Format_NV12;
- case D3DFMT_YV12:
- return QVideoFrameFormat::Format_YV12;
- case D3DFMT_UNKNOWN:
- default:
- return QVideoFrameFormat::Format_Invalid;
- }
-}
-
-D3DFORMAT qt_evr_D3DFormatFromPixelFormat(QVideoFrameFormat::PixelFormat format)
-{
- switch (format) {
- case QVideoFrameFormat::Format_BGRA8888:
- return D3DFMT_A8R8G8B8;
- case QVideoFrameFormat::Format_BGRX8888:
- return D3DFMT_X8R8G8B8;
- case QVideoFrameFormat::Format_Y8:
- return D3DFMT_A8;
- case QVideoFrameFormat::Format_RGBA8888:
- return D3DFMT_A8B8G8R8;
- case QVideoFrameFormat::Format_RGBX8888:
- return D3DFMT_X8B8G8R8;
- case QVideoFrameFormat::Format_UYVY:
- return D3DFMT_UYVY;
- case QVideoFrameFormat::Format_YUYV:
- return D3DFMT_YUY2;
- case QVideoFrameFormat::Format_NV12:
- return D3DFMT_NV12;
- case QVideoFrameFormat::Format_YV12:
- return D3DFMT_YV12;
- case QVideoFrameFormat::Format_Invalid:
- default:
- return D3DFMT_UNKNOWN;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/evr/evrhelpers_p.h b/src/multimedia/platform/windows/evr/evrhelpers_p.h
deleted file mode 100644
index 340658571..000000000
--- a/src/multimedia/platform/windows/evr/evrhelpers_p.h
+++ /dev/null
@@ -1,112 +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
-
-//
-// 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 "evrdefs_p.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));
-}
-
-QVideoFrameFormat::PixelFormat qt_evr_pixelFormatFromD3DFormat(DWORD format);
-D3DFORMAT qt_evr_D3DFormatFromPixelFormat(QVideoFrameFormat::PixelFormat format);
-
-QT_END_NAMESPACE
-
-#endif // EVRHELPERS_H
-
diff --git a/src/multimedia/platform/windows/evr/evrvideowindowcontrol.cpp b/src/multimedia/platform/windows/evr/evrvideowindowcontrol.cpp
deleted file mode 100644
index 18f883289..000000000
--- a/src/multimedia/platform/windows/evr/evrvideowindowcontrol.cpp
+++ /dev/null
@@ -1,269 +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_p.h"
-
-EvrVideoWindowControl::EvrVideoWindowControl(QVideoSink *parent)
- : QPlatformVideoSink(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;
-}
-
-void EvrVideoWindowControl::setWinId(WId id)
-{
- m_windowId = id;
-
- if (m_displayControl)
- m_displayControl->SetVideoWindow(HWND(m_windowId));
-}
-
-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);
- }
- }
-}
-
-void EvrVideoWindowControl::setFullScreen(bool fullScreen)
-{
- if (m_fullScreen == fullScreen)
- return;
-}
-
-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;
-}
-
-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);
- }
-}
-
-void EvrVideoWindowControl::setBrightness(float brightness)
-{
- if (m_brightness == brightness)
- return;
-
- m_brightness = brightness;
-
- m_dirtyValues |= DXVA2_ProcAmp_Brightness;
-
- applyImageControls();
-}
-
-void EvrVideoWindowControl::setContrast(float contrast)
-{
- if (m_contrast == contrast)
- return;
-
- m_contrast = contrast;
-
- m_dirtyValues |= DXVA2_ProcAmp_Contrast;
-
- applyImageControls();
-}
-
-void EvrVideoWindowControl::setHue(float hue)
-{
- if (m_hue == hue)
- return;
-
- m_hue = hue;
-
- m_dirtyValues |= DXVA2_ProcAmp_Hue;
-
- applyImageControls();
-}
-
-void EvrVideoWindowControl::setSaturation(float saturation)
-{
- if (m_saturation == saturation)
- return;
-
- m_saturation = saturation;
-
- m_dirtyValues |= DXVA2_ProcAmp_Saturation;
-
- applyImageControls();
-}
-
-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, float 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));
- else if (value < 0)
- scaledValue -= float(value) * (DXVA2FixedToFloat(range.MinValue) - DXVA2FixedToFloat(range.DefaultValue));
- }
-
- return DXVA2FloatToFixed(scaledValue);
-}
diff --git a/src/multimedia/platform/windows/evr/evrvideowindowcontrol_p.h b/src/multimedia/platform/windows/evr/evrvideowindowcontrol_p.h
deleted file mode 100644
index b9fbc271c..000000000
--- a/src/multimedia/platform/windows/evr/evrvideowindowcontrol_p.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 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
-
-//
-// 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 "private/qplatformvideosink_p.h"
-
-#include "evrdefs_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class EvrVideoWindowControl : public QPlatformVideoSink
-{
- Q_OBJECT
-public:
- EvrVideoWindowControl(QVideoSink *parent = 0);
- ~EvrVideoWindowControl() override;
-
- bool setEvr(IUnknown *evr);
-
- void setWinId(WId id) override;
-
- void setDisplayRect(const QRect &rect) override;
-
- void setFullScreen(bool fullScreen) override;
-
- QSize nativeSize() const override;
-
- void setAspectRatioMode(Qt::AspectRatioMode mode) override;
-
- void setBrightness(float brightness) override;
- void setContrast(float contrast) override;
- void setHue(float hue) override;
- void setSaturation(float saturation) override;
-
- void applyImageControls();
-
-private:
- void clear();
- DXVA2_Fixed32 scaleProcAmpValue(DWORD prop, float value) const;
-
- WId m_windowId;
- COLORREF m_windowColor;
- DWORD m_dirtyValues;
- Qt::AspectRatioMode m_aspectRatioMode;
- QRect m_displayRect;
- float m_brightness;
- float m_contrast;
- float m_hue;
- float m_saturation;
- bool m_fullScreen;
-
- IMFVideoDisplayControl *m_displayControl;
- IMFVideoProcessor *m_processor;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowscamera.cpp b/src/multimedia/platform/windows/mediacapture/qwindowscamera.cpp
deleted file mode 100644
index 53e8650f7..000000000
--- a/src/multimedia/platform/windows/mediacapture/qwindowscamera.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwindowscamera_p.h"
-
-#include "qwindowsmediadevicesession_p.h"
-#include "qwindowsmediacapture_p.h"
-#include <qcameradevice.h>
-
-QT_BEGIN_NAMESPACE
-
-QWindowsCamera::QWindowsCamera(QCamera *camera)
- : QPlatformCamera(camera)
-{
-}
-
-QWindowsCamera::~QWindowsCamera() = default;
-
-bool QWindowsCamera::isActive() const
-{
- return m_active;
-}
-
-void QWindowsCamera::setActive(bool active)
-{
- if (m_active == active)
- return;
- if (m_cameraDevice.isNull() && active)
- return;
- m_active = active;
- if (m_mediaDeviceSession)
- m_mediaDeviceSession->setActive(active);
-
- emit activeChanged(m_active);
-}
-
-void QWindowsCamera::setCamera(const QCameraDevice &camera)
-{
- if (m_cameraDevice == camera)
- return;
- m_cameraDevice = camera;
- if (m_mediaDeviceSession)
- m_mediaDeviceSession->setActiveCamera(camera);
-}
-
-void QWindowsCamera::setCaptureSession(QPlatformMediaCaptureSession *session)
-{
- QWindowsMediaCaptureService *captureService = static_cast<QWindowsMediaCaptureService *>(session);
- if (m_captureService == captureService)
- return;
-
- if (m_mediaDeviceSession) {
- m_mediaDeviceSession->disconnect(this);
- m_mediaDeviceSession->setActive(false);
- m_mediaDeviceSession->setCameraFormat({});
- m_mediaDeviceSession->setActiveCamera({});
- }
-
- m_captureService = captureService;
- if (!m_captureService) {
- m_mediaDeviceSession = nullptr;
- return;
- }
-
- m_mediaDeviceSession = m_captureService->session();
- Q_ASSERT(m_mediaDeviceSession);
-
- m_mediaDeviceSession->setActive(false);
- m_mediaDeviceSession->setActiveCamera(m_cameraDevice);
- m_mediaDeviceSession->setCameraFormat(m_cameraFormat);
- m_mediaDeviceSession->setActive(m_active);
-
- connect(m_mediaDeviceSession, &QWindowsMediaDeviceSession::activeChanged,
- this, &QWindowsCamera::onActiveChanged);
-}
-
-bool QWindowsCamera::setCameraFormat(const QCameraFormat &format)
-{
- if (!format.isNull() && !m_cameraDevice.videoFormats().contains(format))
- return false;
-
- m_cameraFormat = format.isNull() ? findBestCameraFormat(m_cameraDevice) : format;
-
- if (m_mediaDeviceSession)
- m_mediaDeviceSession->setCameraFormat(m_cameraFormat);
- return true;
-}
-
-void QWindowsCamera::onActiveChanged(bool active)
-{
- if (m_active == active)
- return;
- if (m_cameraDevice.isNull() && active)
- return;
- m_active = active;
- emit activeChanged(m_active);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowscamera_p.h b/src/multimedia/platform/windows/mediacapture/qwindowscamera_p.h
deleted file mode 100644
index 379a2cba3..000000000
--- a/src/multimedia/platform/windows/mediacapture/qwindowscamera_p.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWINDOWSCAMERA_H
-#define QWINDOWSCAMERA_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 <private/qplatformcamera_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsMediaCaptureService;
-class QWindowsMediaDeviceSession;
-
-class QWindowsCamera : public QPlatformCamera
-{
- Q_OBJECT
-public:
- explicit QWindowsCamera(QCamera *camera);
- virtual ~QWindowsCamera();
-
- bool isActive() const override;
-
- void setCamera(const QCameraDevice &camera) override;
-
- void setCaptureSession(QPlatformMediaCaptureSession *) override;
-
- bool setCameraFormat(const QCameraFormat &format) override;
-
- void setActive(bool active) override;
-
-private Q_SLOTS:
- void onActiveChanged(bool active);
-
-private:
- QWindowsMediaCaptureService *m_captureService = nullptr;
- QWindowsMediaDeviceSession *m_mediaDeviceSession = nullptr;
- QCameraDevice m_cameraDevice;
- QCameraFormat m_cameraFormat;
- bool m_active = false;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSCAMERA_H
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowsimagecapture.cpp b/src/multimedia/platform/windows/mediacapture/qwindowsimagecapture.cpp
deleted file mode 100644
index d61cd6cde..000000000
--- a/src/multimedia/platform/windows/mediacapture/qwindowsimagecapture.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwindowsimagecapture_p.h"
-
-#include "qwindowsmediadevicesession_p.h"
-#include "qwindowsmediacapture_p.h"
-#include "qmediastoragelocation_p.h"
-
-#include <QtConcurrent/qtconcurrentrun.h>
-#include <QtGui/qimagewriter.h>
-
-QT_BEGIN_NAMESPACE
-
-QWindowsImageCapture::QWindowsImageCapture(QImageCapture *parent)
- : QPlatformImageCapture(parent)
-{
-}
-
-QWindowsImageCapture::~QWindowsImageCapture() = default;
-
-bool QWindowsImageCapture::isReadyForCapture() const
-{
- if (!m_mediaDeviceSession)
- return false;
- return !m_capturing && m_mediaDeviceSession->isActive() && !m_mediaDeviceSession->activeCamera().isNull();
-}
-
-int QWindowsImageCapture::capture(const QString &fileName)
-{
- auto ext = writerFormat(m_settings.format());
- auto path = QMediaStorageLocation::generateFileName(fileName, QStandardPaths::PicturesLocation, ext);
- return doCapture(path);
-}
-
-int QWindowsImageCapture::captureToBuffer()
-{
- return doCapture(QString());
-}
-
-int QWindowsImageCapture::doCapture(const QString &fileName)
-{
- if (!isReadyForCapture())
- return -1;
- m_fileName = fileName;
- m_capturing = true;
- return m_captureId;
-}
-
-QImageEncoderSettings QWindowsImageCapture::imageSettings() const
-{
- return m_settings;
-}
-
-void QWindowsImageCapture::setImageSettings(const QImageEncoderSettings &settings)
-{
- m_settings = settings;
-}
-
-void QWindowsImageCapture::setCaptureSession(QPlatformMediaCaptureSession *session)
-{
- QWindowsMediaCaptureService *captureService = static_cast<QWindowsMediaCaptureService *>(session);
- if (m_captureService == captureService)
- return;
-
- if (m_mediaDeviceSession)
- disconnect(m_mediaDeviceSession, nullptr, this, nullptr);
-
- m_captureService = captureService;
- if (!m_captureService) {
- m_mediaDeviceSession = nullptr;
- return;
- }
-
- m_mediaDeviceSession = m_captureService->session();
- Q_ASSERT(m_mediaDeviceSession);
-
- connect(m_mediaDeviceSession, SIGNAL(readyForCaptureChanged(bool)),
- this, SIGNAL(readyForCaptureChanged(bool)));
-
- connect(m_mediaDeviceSession, SIGNAL(videoFrameChanged(QVideoFrame)),
- this, SLOT(handleVideoFrameChanged(QVideoFrame)));
-}
-
-void QWindowsImageCapture::handleVideoFrameChanged(const QVideoFrame &frame)
-{
- if (m_capturing) {
-
- QImage image = frame.toImage();
-
- emit imageExposed(m_captureId);
- emit imageAvailable(m_captureId, frame);
- emit imageCaptured(m_captureId, image);
-
- QMediaMetaData metaData = this->metaData();
- metaData.insert(QMediaMetaData::Date, QDateTime::currentDateTime());
- metaData.insert(QMediaMetaData::Resolution, frame.size());
-
- emit imageMetadataAvailable(m_captureId, metaData);
-
- if (!m_fileName.isEmpty()) {
-
- (void)QtConcurrent::run(&QWindowsImageCapture::saveImage, this,
- m_captureId, m_fileName, image, metaData, m_settings);
- }
-
- ++m_captureId;
- m_capturing = false;
- }
-}
-
-void QWindowsImageCapture::saveImage(int captureId, const QString &fileName,
- const QImage &image, const QMediaMetaData &metaData,
- const QImageEncoderSettings &settings)
-{
- QImageWriter imageWriter;
- imageWriter.setFileName(fileName);
-
- QString format = writerFormat(settings.format());
- imageWriter.setFormat(format.toUtf8());
-
- int quality = writerQuality(format, settings.quality());
- if (quality > -1)
- imageWriter.setQuality(quality);
-
- for (auto key : metaData.keys())
- imageWriter.setText(QMediaMetaData::metaDataKeyToString(key),
- metaData.stringValue(key));
-
- imageWriter.write(image);
-
- QMetaObject::invokeMethod(this, "imageSaved", Qt::QueuedConnection,
- Q_ARG(int, captureId), Q_ARG(QString, fileName));
-}
-
-QString QWindowsImageCapture::writerFormat(QImageCapture::FileFormat reqFormat)
-{
- QString format;
-
- switch (reqFormat) {
- case QImageCapture::FileFormat::JPEG:
- format = QLatin1String("jpg");
- break;
- case QImageCapture::FileFormat::PNG:
- format = QLatin1String("png");
- break;
- case QImageCapture::FileFormat::WebP:
- format = QLatin1String("webp");
- break;
- case QImageCapture::FileFormat::Tiff:
- format = QLatin1String("tiff");
- break;
- default:
- format = QLatin1String("jpg");
- }
-
- auto supported = QImageWriter::supportedImageFormats();
- for (const auto &f : supported)
- if (format.compare(QString::fromUtf8(f), Qt::CaseInsensitive) == 0)
- return format;
-
- return QLatin1String("jpg");
-}
-
-int QWindowsImageCapture::writerQuality(const QString &writerFormat,
- QImageCapture::Quality quality)
-{
- if (writerFormat.compare(QLatin1String("jpg"), Qt::CaseInsensitive) == 0 ||
- writerFormat.compare(QLatin1String("jpeg"), Qt::CaseInsensitive) == 0) {
-
- switch (quality) {
- case QImageCapture::Quality::VeryLowQuality:
- return 10;
- case QImageCapture::Quality::LowQuality:
- return 30;
- case QImageCapture::Quality::NormalQuality:
- return 75;
- case QImageCapture::Quality::HighQuality:
- return 90;
- case QImageCapture::Quality::VeryHighQuality:
- return 98;
- default:
- return 75;
- }
- }
- return -1;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowsimagecapture_p.h b/src/multimedia/platform/windows/mediacapture/qwindowsimagecapture_p.h
deleted file mode 100644
index 6c3bc8107..000000000
--- a/src/multimedia/platform/windows/mediacapture/qwindowsimagecapture_p.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWindowsImageCapture_H
-#define QWindowsImageCapture_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 <private/qplatformimagecapture_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsMediaDeviceSession;
-class QWindowsMediaCaptureService;
-
-class QWindowsImageCapture : public QPlatformImageCapture
-{
- Q_OBJECT
-public:
- explicit QWindowsImageCapture(QImageCapture *parent);
- virtual ~QWindowsImageCapture();
-
- bool isReadyForCapture() const override;
-
- int capture(const QString &fileName) override;
- int captureToBuffer() override;
-
- QImageEncoderSettings imageSettings() const override;
- void setImageSettings(const QImageEncoderSettings &settings) override;
-
- void setCaptureSession(QPlatformMediaCaptureSession *session);
-
-private Q_SLOTS:
- void handleVideoFrameChanged(const QVideoFrame &frame);
-
-private:
- int doCapture(const QString &fileName);
- void saveImage(int captureId, const QString &fileName,
- const QImage &image, const QMediaMetaData &metaData,
- const QImageEncoderSettings &settings);
- QString writerFormat(QImageCapture::FileFormat reqFormat);
- int writerQuality(const QString &writerFormat,
- QImageCapture::Quality quality);
-
- QWindowsMediaCaptureService *m_captureService = nullptr;
- QWindowsMediaDeviceSession *m_mediaDeviceSession = nullptr;
- QImageEncoderSettings m_settings;
- int m_captureId = 0;
- bool m_capturing = false;
- QString m_fileName;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWindowsImageCapture_H
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowsmediacapture.cpp b/src/multimedia/platform/windows/mediacapture/qwindowsmediacapture.cpp
deleted file mode 100644
index a298039ee..000000000
--- a/src/multimedia/platform/windows/mediacapture/qwindowsmediacapture.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwindowsmediacapture_p.h"
-
-#include "qwindowsmediaencoder_p.h"
-#include "qwindowscamera_p.h"
-#include "qwindowsmediadevicesession_p.h"
-#include "qwindowsimagecapture_p.h"
-#include "qmediadevices.h"
-#include "qaudiodevice.h"
-#include "qplatformaudioinput_p.h"
-#include "qplatformaudiooutput_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QWindowsMediaCaptureService::QWindowsMediaCaptureService()
-{
- m_mediaDeviceSession = new QWindowsMediaDeviceSession(this);
-}
-
-QWindowsMediaCaptureService::~QWindowsMediaCaptureService()
-{
- delete m_mediaDeviceSession;
-}
-
-QPlatformCamera *QWindowsMediaCaptureService::camera()
-{
- return m_camera;
-}
-
-void QWindowsMediaCaptureService::setCamera(QPlatformCamera *camera)
-{
- QWindowsCamera *control = static_cast<QWindowsCamera*>(camera);
- if (m_camera == control)
- return;
-
- if (m_camera)
- m_camera->setCaptureSession(nullptr);
-
- m_camera = control;
- if (m_camera)
- m_camera->setCaptureSession(this);
- emit cameraChanged();
-}
-
-QPlatformImageCapture *QWindowsMediaCaptureService::imageCapture()
-{
- return m_imageCapture;
-}
-
-void QWindowsMediaCaptureService::setImageCapture(QPlatformImageCapture *imageCapture)
-{
- QWindowsImageCapture *control = static_cast<QWindowsImageCapture *>(imageCapture);
- if (m_imageCapture == control)
- return;
-
- if (m_imageCapture)
- m_imageCapture->setCaptureSession(nullptr);
-
- m_imageCapture = control;
- if (m_imageCapture)
- m_imageCapture->setCaptureSession(this);
- emit imageCaptureChanged();
-}
-
-QPlatformMediaEncoder *QWindowsMediaCaptureService::mediaEncoder()
-{
- return m_encoder;
-}
-
-void QWindowsMediaCaptureService::setMediaEncoder(QPlatformMediaEncoder *encoder)
-{
- QWindowsMediaEncoder *control = static_cast<QWindowsMediaEncoder *>(encoder);
- if (m_encoder == control)
- return;
-
- if (m_encoder)
- m_encoder->setCaptureSession(nullptr);
-
- m_encoder = control;
- if (m_encoder)
- m_encoder->setCaptureSession(this);
- emit encoderChanged();
-}
-
-void QWindowsMediaCaptureService::setAudioInput(QPlatformAudioInput *input)
-{
- m_mediaDeviceSession->setAudioInput(input ? input->q : nullptr);
-}
-
-void QWindowsMediaCaptureService::setAudioOutput(QPlatformAudioOutput *output)
-{
- m_mediaDeviceSession->setAudioOutput(output ? output->q : nullptr);
-}
-
-void QWindowsMediaCaptureService::setVideoPreview(QVideoSink *sink)
-{
- m_mediaDeviceSession->setVideoSink(sink);
-}
-
-QWindowsMediaDeviceSession *QWindowsMediaCaptureService::session() const
-{
- return m_mediaDeviceSession;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowsmediacapture_p.h b/src/multimedia/platform/windows/mediacapture/qwindowsmediacapture_p.h
deleted file mode 100644
index 147fb72ed..000000000
--- a/src/multimedia/platform/windows/mediacapture/qwindowsmediacapture_p.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWINDOWSMEDIACAPTURE_H
-#define QWINDOWSMEDIACAPTURE_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 <private/qplatformmediacapture_p.h>
-#include <private/qplatformmediaintegration_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsMediaEncoder;
-class QWindowsCamera;
-class QWindowsMediaDeviceSession;
-class QWindowsImageCapture;
-class QPlatformAudioInput;
-
-class QWindowsMediaCaptureService : public QPlatformMediaCaptureSession
-{
- Q_OBJECT
-
-public:
- QWindowsMediaCaptureService();
- virtual ~QWindowsMediaCaptureService();
-
- QPlatformCamera *camera() override;
- void setCamera(QPlatformCamera *camera) override;
-
- QPlatformImageCapture *imageCapture() override;
- void setImageCapture(QPlatformImageCapture *imageCapture) override;
-
- QPlatformMediaEncoder *mediaEncoder() override;
- void setMediaEncoder(QPlatformMediaEncoder *encoder) override;
-
- void setAudioInput(QPlatformAudioInput *) override;
-
- void setAudioOutput(QPlatformAudioOutput *output) override;
-
- void setVideoPreview(QVideoSink *sink) override;
-
- QWindowsMediaDeviceSession *session() const;
-
-private:
- QWindowsCamera *m_camera = nullptr;
- QWindowsMediaDeviceSession *m_mediaDeviceSession = nullptr;
- QWindowsImageCapture *m_imageCapture = nullptr;
- QWindowsMediaEncoder *m_encoder = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSMEDIAINTERFACE_H
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowsmediadevicereader.cpp b/src/multimedia/platform/windows/mediacapture/qwindowsmediadevicereader.cpp
deleted file mode 100644
index 2e338476e..000000000
--- a/src/multimedia/platform/windows/mediacapture/qwindowsmediadevicereader.cpp
+++ /dev/null
@@ -1,1054 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwindowsmediadevicereader_p.h"
-
-#include "qwindowsmultimediautils_p.h"
-#include <qvideosink.h>
-#include <qmediadevices.h>
-#include <qaudiodevice.h>
-#include <private/qmemoryvideobuffer_p.h>
-#include <QtCore/qdebug.h>
-
-#include <mmdeviceapi.h>
-
-QT_BEGIN_NAMESPACE
-
-enum { MEDIA_TYPE_INDEX_DEFAULT = 0xffffffff };
-
-QWindowsMediaDeviceReader::QWindowsMediaDeviceReader(QObject *parent)
- : QObject(parent)
-{
- m_durationTimer.setInterval(100);
- connect(&m_durationTimer, SIGNAL(timeout()), this, SLOT(updateDuration()));
-}
-
-QWindowsMediaDeviceReader::~QWindowsMediaDeviceReader()
-{
- stopRecording();
- deactivate();
-}
-
-// Creates a video or audio media source specified by deviceId (symbolic link)
-HRESULT QWindowsMediaDeviceReader::createSource(const QString &deviceId, bool video, IMFMediaSource **source)
-{
- if (!source)
- return E_INVALIDARG;
-
- *source = nullptr;
- IMFAttributes *sourceAttributes = nullptr;
-
- HRESULT hr = MFCreateAttributes(&sourceAttributes, 2);
- if (SUCCEEDED(hr)) {
-
- hr = sourceAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
- video ? MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
- : MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID);
- if (SUCCEEDED(hr)) {
-
- hr = sourceAttributes->SetString(video ? MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK
- : MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID,
- reinterpret_cast<LPCWSTR>(deviceId.utf16()));
- if (SUCCEEDED(hr)) {
-
- hr = MFCreateDeviceSource(sourceAttributes, source);
- }
- }
- sourceAttributes->Release();
- }
-
- return hr;
-}
-
-// Creates a source/reader aggregating two other sources (video/audio).
-// If one of the sources is null the result will be video-only or audio-only.
-HRESULT QWindowsMediaDeviceReader::createAggregateReader(IMFMediaSource *firstSource,
- IMFMediaSource *secondSource,
- IMFMediaSource **aggregateSource,
- IMFSourceReader **sourceReader)
-{
- if ((!firstSource && !secondSource) || !aggregateSource || !sourceReader)
- return E_INVALIDARG;
-
- *aggregateSource = nullptr;
- *sourceReader = nullptr;
-
- IMFCollection *sourceCollection = nullptr;
-
- HRESULT hr = MFCreateCollection(&sourceCollection);
- if (SUCCEEDED(hr)) {
-
- if (firstSource)
- sourceCollection->AddElement(firstSource);
-
- if (secondSource)
- sourceCollection->AddElement(secondSource);
-
- hr = MFCreateAggregateSource(sourceCollection, aggregateSource);
- if (SUCCEEDED(hr)) {
-
- IMFAttributes *readerAttributes = nullptr;
-
- hr = MFCreateAttributes(&readerAttributes, 1);
- if (SUCCEEDED(hr)) {
-
- // Set callback so OnReadSample() is called for each new video frame or audio sample.
- hr = readerAttributes->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK,
- static_cast<IMFSourceReaderCallback*>(this));
- if (SUCCEEDED(hr)) {
-
- hr = MFCreateSourceReaderFromMediaSource(*aggregateSource, readerAttributes, sourceReader);
- }
- readerAttributes->Release();
- }
- }
- sourceCollection->Release();
- }
- return hr;
-}
-
-// Selects the requested resolution/frame rate (if specified),
-// or chooses a high quality configuration otherwise.
-DWORD QWindowsMediaDeviceReader::findMediaTypeIndex(const QCameraFormat &reqFormat)
-{
- DWORD mediaIndex = MEDIA_TYPE_INDEX_DEFAULT;
-
- if (m_sourceReader && m_videoSource) {
-
- DWORD index = 0;
- IMFMediaType *mediaType = nullptr;
-
- UINT32 currArea = 0;
- float currFrameRate = 0.0f;
-
- while (SUCCEEDED(m_sourceReader->GetNativeMediaType(DWORD(MF_SOURCE_READER_FIRST_VIDEO_STREAM),
- index, &mediaType))) {
-
- GUID subtype = GUID_NULL;
- if (SUCCEEDED(mediaType->GetGUID(MF_MT_SUBTYPE, &subtype))) {
-
- auto pixelFormat = QWindowsMultimediaUtils::pixelFormatFromMediaSubtype(subtype);
- if (pixelFormat != QVideoFrameFormat::Format_Invalid) {
-
- UINT32 width, height;
- if (SUCCEEDED(MFGetAttributeSize(mediaType, MF_MT_FRAME_SIZE, &width, &height))) {
-
- UINT32 num, den;
- if (SUCCEEDED(MFGetAttributeRatio(mediaType, MF_MT_FRAME_RATE, &num, &den))) {
-
- UINT32 area = width * height;
- float frameRate = float(num) / den;
-
- if (!reqFormat.isNull()
- && reqFormat.resolution().width() == width
- && reqFormat.resolution().height() == height
- && qFuzzyCompare(reqFormat.maxFrameRate(), frameRate)
- && reqFormat.pixelFormat() == pixelFormat) {
- mediaType->Release();
- return index;
- }
-
- if ((currFrameRate < 29.9 && currFrameRate < frameRate) ||
- (currFrameRate == frameRate && currArea < area)) {
- currArea = area;
- currFrameRate = frameRate;
- mediaIndex = index;
- }
- }
- }
- }
- }
- mediaType->Release();
- ++index;
- }
- }
-
- return mediaIndex;
-}
-
-
-// Prepares the source video stream and gets some metadata.
-HRESULT QWindowsMediaDeviceReader::prepareVideoStream(DWORD mediaTypeIndex)
-{
- if (!m_sourceReader)
- return E_FAIL;
-
- if (!m_videoSource)
- return S_OK; // It may be audio-only
-
- HRESULT hr;
-
- if (mediaTypeIndex == MEDIA_TYPE_INDEX_DEFAULT) {
- hr = m_sourceReader->GetCurrentMediaType(DWORD(MF_SOURCE_READER_FIRST_VIDEO_STREAM),
- &m_videoMediaType);
- } else {
- hr = m_sourceReader->GetNativeMediaType(DWORD(MF_SOURCE_READER_FIRST_VIDEO_STREAM),
- mediaTypeIndex, &m_videoMediaType);
- if (SUCCEEDED(hr))
- hr = m_sourceReader->SetCurrentMediaType(DWORD(MF_SOURCE_READER_FIRST_VIDEO_STREAM),
- nullptr, m_videoMediaType);
- }
-
- if (SUCCEEDED(hr)) {
-
- GUID subtype = GUID_NULL;
- hr = m_videoMediaType->GetGUID(MF_MT_SUBTYPE, &subtype);
- if (SUCCEEDED(hr)) {
-
- m_pixelFormat = QWindowsMultimediaUtils::pixelFormatFromMediaSubtype(subtype);
-
- if (m_pixelFormat == QVideoFrameFormat::Format_Invalid) {
- hr = E_FAIL;
- } else {
-
- // get the frame dimensions
- hr = MFGetAttributeSize(m_videoMediaType, MF_MT_FRAME_SIZE, &m_frameWidth, &m_frameHeight);
- if (SUCCEEDED(hr)) {
-
- // and the stride, which we need to convert the frame later
- hr = MFGetStrideForBitmapInfoHeader(subtype.Data1, m_frameWidth, &m_stride);
- if (SUCCEEDED(hr)) {
-
- UINT32 frameRateNum, frameRateDen;
- hr = MFGetAttributeRatio(m_videoMediaType, MF_MT_FRAME_RATE, &frameRateNum, &frameRateDen);
- if (SUCCEEDED(hr)) {
-
- m_frameRate = qreal(frameRateNum) / frameRateDen;
-
- hr = m_sourceReader->SetStreamSelection(DWORD(MF_SOURCE_READER_FIRST_VIDEO_STREAM), TRUE);
- }
- }
- }
- }
- }
- }
-
- return hr;
-}
-
-HRESULT QWindowsMediaDeviceReader::initAudioType(IMFMediaType *mediaType, UINT32 channels, UINT32 samplesPerSec, bool flt)
-{
- if (!mediaType)
- return E_INVALIDARG;
-
- HRESULT hr = mediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
- if (SUCCEEDED(hr)) {
- hr = mediaType->SetGUID(MF_MT_SUBTYPE, flt ? MFAudioFormat_Float : MFAudioFormat_PCM);
- if (SUCCEEDED(hr)) {
- hr = mediaType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, channels);
- if (SUCCEEDED(hr)) {
- hr = mediaType->SetUINT32(MF_MT_AUDIO_CHANNEL_MASK,
- (channels == 1) ? SPEAKER_FRONT_CENTER : (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT ));
- if (SUCCEEDED(hr)) {
- hr = mediaType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, samplesPerSec);
- if (SUCCEEDED(hr)) {
- UINT32 bitsPerSample = flt ? 32 : 16;
- UINT32 bytesPerFrame = channels * bitsPerSample/8;
- hr = mediaType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, bitsPerSample);
- if (SUCCEEDED(hr)) {
- hr = mediaType->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, bytesPerFrame);
- if (SUCCEEDED(hr)) {
- hr = mediaType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, bytesPerFrame * samplesPerSec);
- }
- }
- }
- }
- }
- }
- }
-
- return hr;
-}
-
-// Prepares the source audio stream.
-HRESULT QWindowsMediaDeviceReader::prepareAudioStream()
-{
- if (!m_sourceReader)
- return E_FAIL;
-
- if (!m_audioSource)
- return S_OK; // It may be video-only
-
- HRESULT hr = m_sourceReader->GetCurrentMediaType(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM),
- &m_audioMediaType);
- if (SUCCEEDED(hr)) {
- hr = initAudioType(m_audioMediaType, 2, 48000, true);
- if (SUCCEEDED(hr)) {
- hr = m_sourceReader->SetCurrentMediaType(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM),
- nullptr, m_audioMediaType);
- if (SUCCEEDED(hr)) {
- hr = m_sourceReader->SetStreamSelection(DWORD(MF_SOURCE_READER_FIRST_AUDIO_STREAM), TRUE);
- }
- }
- }
- return hr;
-}
-
-// Retrieves the indexes for selected video/audio streams.
-HRESULT QWindowsMediaDeviceReader::initSourceIndexes()
-{
- if (!m_sourceReader)
- return E_FAIL;
-
- m_sourceVideoStreamIndex = MF_SOURCE_READER_INVALID_STREAM_INDEX;
- m_sourceAudioStreamIndex = MF_SOURCE_READER_INVALID_STREAM_INDEX;
-
- DWORD index = 0;
- BOOL selected = FALSE;
-
- while (m_sourceReader->GetStreamSelection(index, &selected) == S_OK) {
- if (selected) {
- IMFMediaType *mediaType = nullptr;
- if (SUCCEEDED(m_sourceReader->GetCurrentMediaType(index, &mediaType))) {
- GUID majorType = GUID_NULL;
- if (SUCCEEDED(mediaType->GetGUID(MF_MT_MAJOR_TYPE, &majorType))) {
- if (majorType == MFMediaType_Video)
- m_sourceVideoStreamIndex = index;
- else if (majorType == MFMediaType_Audio)
- m_sourceAudioStreamIndex = index;
- }
- mediaType->Release();
- }
- }
- ++index;
- }
- if ((m_videoSource && m_sourceVideoStreamIndex == MF_SOURCE_READER_INVALID_STREAM_INDEX) ||
- (m_audioSource && m_sourceAudioStreamIndex == MF_SOURCE_READER_INVALID_STREAM_INDEX))
- return E_FAIL;
- return S_OK;
-}
-
-bool QWindowsMediaDeviceReader::setAudioOutput(const QString &audioOutputId)
-{
- QMutexLocker locker(&m_mutex);
-
- stopMonitoring();
-
- m_audioOutputId = audioOutputId;
-
- if (!m_active || m_audioOutputId.isEmpty())
- return true;
-
- HRESULT hr = startMonitoring();
-
- return SUCCEEDED(hr);
-}
-
-HRESULT QWindowsMediaDeviceReader::startMonitoring()
-{
- if (m_audioOutputId.isEmpty())
- return E_FAIL;
-
- IMFAttributes *sinkAttributes = nullptr;
-
- HRESULT hr = MFCreateAttributes(&sinkAttributes, 1);
- if (SUCCEEDED(hr)) {
-
- hr = sinkAttributes->SetString(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID,
- reinterpret_cast<LPCWSTR>(m_audioOutputId.utf16()));
- if (SUCCEEDED(hr)) {
-
- IMFMediaSink *mediaSink = nullptr;
- hr = MFCreateAudioRenderer(sinkAttributes, &mediaSink);
- if (SUCCEEDED(hr)) {
-
- IMFStreamSink *streamSink = nullptr;
- hr = mediaSink->GetStreamSinkByIndex(0, &streamSink);
- if (SUCCEEDED(hr)) {
-
- IMFMediaTypeHandler *typeHandler = nullptr;
- hr = streamSink->GetMediaTypeHandler(&typeHandler);
- if (SUCCEEDED(hr)) {
-
- hr = typeHandler->IsMediaTypeSupported(m_audioMediaType, nullptr);
- if (SUCCEEDED(hr)) {
-
- hr = typeHandler->SetCurrentMediaType(m_audioMediaType);
- if (SUCCEEDED(hr)) {
-
- IMFAttributes *writerAttributes = nullptr;
-
- HRESULT hr = MFCreateAttributes(&writerAttributes, 1);
- if (SUCCEEDED(hr)) {
-
- hr = writerAttributes->SetUINT32(MF_SINK_WRITER_DISABLE_THROTTLING, TRUE);
- if (SUCCEEDED(hr)) {
-
- IMFSinkWriter *sinkWriter = nullptr;
- hr = MFCreateSinkWriterFromMediaSink(mediaSink, writerAttributes, &sinkWriter);
- if (SUCCEEDED(hr)) {
-
- hr = sinkWriter->SetInputMediaType(0, m_audioMediaType, nullptr);
- if (SUCCEEDED(hr)) {
-
- IMFSimpleAudioVolume *audioVolume = nullptr;
-
- if (SUCCEEDED(MFGetService(mediaSink, MR_POLICY_VOLUME_SERVICE, IID_PPV_ARGS(&audioVolume)))) {
- audioVolume->SetMasterVolume(float(m_outputVolume));
- audioVolume->SetMute(m_outputMuted);
- audioVolume->Release();
- }
-
- hr = sinkWriter->BeginWriting();
- if (SUCCEEDED(hr)) {
- m_monitorSink = mediaSink;
- m_monitorSink->AddRef();
- m_monitorWriter = sinkWriter;
- m_monitorWriter->AddRef();
- }
- }
- sinkWriter->Release();
- }
- }
- writerAttributes->Release();
- }
- }
- }
- typeHandler->Release();
- }
- streamSink->Release();
- }
- mediaSink->Release();
- }
- }
- sinkAttributes->Release();
- }
-
- return hr;
-}
-
-void QWindowsMediaDeviceReader::stopMonitoring()
-{
- if (m_monitorWriter) {
- m_monitorWriter->Release();
- m_monitorWriter = nullptr;
- }
- if (m_monitorSink) {
- m_monitorSink->Shutdown();
- m_monitorSink->Release();
- m_monitorSink = nullptr;
- }
-}
-
-// Activates the requested camera/microphone for streaming.
-// One of the IDs may be empty for video-only/audio-only.
-bool QWindowsMediaDeviceReader::activate(const QString &cameraId,
- const QCameraFormat &cameraFormat,
- const QString &microphoneId)
-{
- QMutexLocker locker(&m_mutex);
-
- if (cameraId.isEmpty() && microphoneId.isEmpty())
- return false;
-
- stopMonitoring();
- releaseResources();
-
- m_active = false;
- m_streaming = false;
-
- if (!cameraId.isEmpty()) {
- if (!SUCCEEDED(createSource(cameraId, true, &m_videoSource))) {
- releaseResources();
- return false;
- }
- }
-
- if (!microphoneId.isEmpty()) {
- if (!SUCCEEDED(createSource(microphoneId, false, &m_audioSource))) {
- releaseResources();
- return false;
- }
- }
-
- if (!SUCCEEDED(createAggregateReader(m_videoSource, m_audioSource, &m_aggregateSource, &m_sourceReader))) {
- releaseResources();
- return false;
- }
-
- DWORD mediaTypeIndex = findMediaTypeIndex(cameraFormat);
-
- if (!SUCCEEDED(prepareVideoStream(mediaTypeIndex))) {
- releaseResources();
- return false;
- }
-
- if (!SUCCEEDED(prepareAudioStream())) {
- releaseResources();
- return false;
- }
-
- if (!SUCCEEDED(initSourceIndexes())) {
- releaseResources();
- return false;
- }
-
- updateSinkInputMediaTypes();
- startMonitoring();
-
- // Request the first frame or audio sample.
- if (!SUCCEEDED(m_sourceReader->ReadSample(MF_SOURCE_READER_ANY_STREAM, 0, nullptr, nullptr, nullptr, nullptr))) {
- releaseResources();
- return false;
- }
-
- m_active = true;
- return true;
-}
-
-void QWindowsMediaDeviceReader::deactivate()
-{
- stopMonitoring();
- stopStreaming();
- m_active = false;
- m_streaming = false;
-}
-
-void QWindowsMediaDeviceReader::stopStreaming()
-{
- QMutexLocker locker(&m_mutex);
- releaseResources();
-}
-
-// Releases allocated streaming stuff.
-void QWindowsMediaDeviceReader::releaseResources()
-{
- if (m_videoMediaType) {
- m_videoMediaType->Release();
- m_videoMediaType = nullptr;
- }
- if (m_audioMediaType) {
- m_audioMediaType->Release();
- m_audioMediaType = nullptr;
- }
- if (m_sourceReader) {
- m_sourceReader->Release();
- m_sourceReader = nullptr;
- }
- if (m_aggregateSource) {
- m_aggregateSource->Release();
- m_aggregateSource = nullptr;
- }
- if (m_videoSource) {
- m_videoSource->Release();
- m_videoSource = nullptr;
- }
- if (m_audioSource) {
- m_audioSource->Release();
- m_audioSource = nullptr;
- }
-}
-
-HRESULT QWindowsMediaDeviceReader::createVideoMediaType(const GUID &format, UINT32 bitRate, UINT32 width,
- UINT32 height, qreal frameRate, IMFMediaType **mediaType)
-{
- if (!mediaType)
- return E_INVALIDARG;
-
- *mediaType = nullptr;
- IMFMediaType *targetMediaType = nullptr;
-
- if (SUCCEEDED(MFCreateMediaType(&targetMediaType))) {
-
- if (SUCCEEDED(targetMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video))) {
-
- if (SUCCEEDED(targetMediaType->SetGUID(MF_MT_SUBTYPE, format))) {
-
- if (SUCCEEDED(targetMediaType->SetUINT32(MF_MT_AVG_BITRATE, bitRate))) {
-
- if (SUCCEEDED(MFSetAttributeSize(targetMediaType, MF_MT_FRAME_SIZE, width, height))) {
-
- if (SUCCEEDED(MFSetAttributeRatio(targetMediaType, MF_MT_FRAME_RATE,
- UINT32(frameRate * 1000), 1000))) {
- UINT32 t1, t2;
- if (SUCCEEDED(MFGetAttributeRatio(m_videoMediaType, MF_MT_PIXEL_ASPECT_RATIO, &t1, &t2))) {
-
- if (SUCCEEDED(MFSetAttributeRatio(targetMediaType, MF_MT_PIXEL_ASPECT_RATIO, t1, t2))) {
-
- if (SUCCEEDED(m_videoMediaType->GetUINT32(MF_MT_INTERLACE_MODE, &t1))) {
-
- if (SUCCEEDED(targetMediaType->SetUINT32(MF_MT_INTERLACE_MODE, t1))) {
-
- *mediaType = targetMediaType;
- return S_OK;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- targetMediaType->Release();
- }
- return E_FAIL;
-}
-
-HRESULT QWindowsMediaDeviceReader::createAudioMediaType(const GUID &format, UINT32 bitRate, IMFMediaType **mediaType)
-{
- if (!mediaType)
- return E_INVALIDARG;
-
- *mediaType = nullptr;
- IMFMediaType *targetMediaType = nullptr;
-
- if (SUCCEEDED(MFCreateMediaType(&targetMediaType))) {
-
- if (SUCCEEDED(targetMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio))) {
-
- if (SUCCEEDED(targetMediaType->SetGUID(MF_MT_SUBTYPE, format))) {
-
- if (bitRate == 0 || SUCCEEDED(targetMediaType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, bitRate / 8))) {
-
- *mediaType = targetMediaType;
- return S_OK;
- }
- }
- }
- targetMediaType->Release();
- }
- return E_FAIL;
-}
-
-HRESULT QWindowsMediaDeviceReader::updateSinkInputMediaTypes()
-{
- HRESULT hr = S_OK;
- if (m_sinkWriter) {
- if (m_videoSource && m_videoMediaType && m_sinkVideoStreamIndex != MF_SINK_WRITER_INVALID_STREAM_INDEX) {
- hr = m_sinkWriter->SetInputMediaType(m_sinkVideoStreamIndex, m_videoMediaType, nullptr);
- }
- if (SUCCEEDED(hr)) {
- if (m_audioSource && m_audioMediaType && m_sinkAudioStreamIndex != MF_SINK_WRITER_INVALID_STREAM_INDEX) {
- hr = m_sinkWriter->SetInputMediaType(m_sinkAudioStreamIndex, m_audioMediaType, nullptr);
- }
- }
- }
- return hr;
-}
-
-bool QWindowsMediaDeviceReader::startRecording(const QString &fileName, const GUID &container,
- const GUID &videoFormat, UINT32 videoBitRate, UINT32 width,
- UINT32 height, qreal frameRate, const GUID &audioFormat,
- UINT32 audioBitRate)
-{
- QMutexLocker locker(&m_mutex);
-
- if (!m_active || m_recording || (videoFormat == GUID_NULL && audioFormat == GUID_NULL))
- return false;
-
- IMFAttributes *writerAttributes = nullptr;
-
- HRESULT hr = MFCreateAttributes(&writerAttributes, 2);
- if (SUCCEEDED(hr)) {
-
- // Set callback so OnFinalize() is called after video is saved.
- hr = writerAttributes->SetUnknown(MF_SINK_WRITER_ASYNC_CALLBACK,
- static_cast<IMFSinkWriterCallback*>(this));
- if (SUCCEEDED(hr)) {
-
- hr = writerAttributes->SetGUID(MF_TRANSCODE_CONTAINERTYPE, container);
- if (SUCCEEDED(hr)) {
-
- hr = MFCreateSinkWriterFromURL(reinterpret_cast<LPCWSTR>(fileName.utf16()),
- nullptr, writerAttributes, &m_sinkWriter);
- if (SUCCEEDED(hr)) {
-
- m_sinkVideoStreamIndex = MF_SINK_WRITER_INVALID_STREAM_INDEX;
- m_sinkAudioStreamIndex = MF_SINK_WRITER_INVALID_STREAM_INDEX;
-
- if (m_videoSource && videoFormat != GUID_NULL) {
- IMFMediaType *targetMediaType = nullptr;
-
- hr = createVideoMediaType(videoFormat, videoBitRate, width, height,
- frameRate, &targetMediaType);
- if (SUCCEEDED(hr)) {
-
- hr = m_sinkWriter->AddStream(targetMediaType, &m_sinkVideoStreamIndex);
- if (SUCCEEDED(hr)) {
-
- hr = m_sinkWriter->SetInputMediaType(m_sinkVideoStreamIndex,
- m_videoMediaType, nullptr);
- }
- targetMediaType->Release();
- }
- }
-
- if (SUCCEEDED(hr)) {
-
- if (m_audioSource && audioFormat != GUID_NULL) {
- IMFMediaType *targetMediaType = nullptr;
-
- hr = createAudioMediaType(audioFormat, audioBitRate, &targetMediaType);
- if (SUCCEEDED(hr)) {
-
- hr = m_sinkWriter->AddStream(targetMediaType, &m_sinkAudioStreamIndex);
- if (SUCCEEDED(hr)) {
-
- hr = m_sinkWriter->SetInputMediaType(m_sinkAudioStreamIndex,
- m_audioMediaType, nullptr);
- }
- targetMediaType->Release();
- }
- }
-
- if (SUCCEEDED(hr)) {
-
- hr = m_sinkWriter->BeginWriting();
- if (SUCCEEDED(hr)) {
- m_lastDuration = -1;
- m_currentDuration = 0;
- updateDuration();
- m_durationTimer.start();
- m_recording = true;
- m_firstFrame = true;
- m_paused = false;
- m_pauseChanging = false;
- }
- }
- }
- }
- }
- }
- writerAttributes->Release();
- }
- if (m_sinkWriter && !SUCCEEDED(hr)) {
- m_sinkWriter->Release();
- m_sinkWriter = nullptr;
- }
- return SUCCEEDED(hr);
-}
-
-void QWindowsMediaDeviceReader::stopRecording()
-{
- QMutexLocker locker(&m_mutex);
-
- if (m_sinkWriter && m_recording) {
-
- HRESULT hr = m_sinkWriter->Finalize();
-
- if (SUCCEEDED(hr)) {
- m_hasFinalized.wait(&m_mutex);
- } else {
- m_sinkWriter->Release();
- m_sinkWriter = nullptr;
-
- QMetaObject::invokeMethod(this, "recordingError",
- Qt::QueuedConnection, Q_ARG(int, hr));
- }
- }
-
- m_recording = false;
- m_paused = false;
- m_pauseChanging = false;
-
- m_durationTimer.stop();
- m_lastDuration = -1;
- m_currentDuration = -1;
-}
-
-bool QWindowsMediaDeviceReader::pauseRecording()
-{
- if (!m_recording || m_paused)
- return false;
- m_pauseTime = m_lastTimestamp;
- m_paused = true;
- m_pauseChanging = true;
- return true;
-}
-
-bool QWindowsMediaDeviceReader::resumeRecording()
-{
- if (!m_recording || !m_paused)
- return false;
- m_paused = false;
- m_pauseChanging = true;
- return true;
-}
-
-//from IUnknown
-STDMETHODIMP QWindowsMediaDeviceReader::QueryInterface(REFIID riid, LPVOID *ppvObject)
-{
- if (!ppvObject)
- return E_POINTER;
- if (riid == IID_IMFSourceReaderCallback) {
- *ppvObject = static_cast<IMFSourceReaderCallback*>(this);
- } else if (riid == IID_IMFSinkWriterCallback) {
- *ppvObject = static_cast<IMFSinkWriterCallback*>(this);
- } else if (riid == IID_IUnknown) {
- *ppvObject = static_cast<IUnknown*>(static_cast<IMFSourceReaderCallback*>(this));
- } else {
- *ppvObject = nullptr;
- return E_NOINTERFACE;
- }
- AddRef();
- return S_OK;
-}
-
-STDMETHODIMP_(ULONG) QWindowsMediaDeviceReader::AddRef(void)
-{
- return InterlockedIncrement(&m_cRef);
-}
-
-STDMETHODIMP_(ULONG) QWindowsMediaDeviceReader::Release(void)
-{
- LONG cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0) {
- this->deleteLater();
- }
- return cRef;
-}
-
-UINT32 QWindowsMediaDeviceReader::frameWidth() const
-{
- return m_frameWidth;
-}
-
-UINT32 QWindowsMediaDeviceReader::frameHeight() const
-{
- return m_frameHeight;
-}
-
-qreal QWindowsMediaDeviceReader::frameRate() const
-{
- return m_frameRate;
-}
-
-void QWindowsMediaDeviceReader::setInputMuted(bool muted)
-{
- m_inputMuted = muted;
-}
-
-void QWindowsMediaDeviceReader::setInputVolume(qreal volume)
-{
- m_inputVolume = qBound(0.0, volume, 1.0);
-}
-
-void QWindowsMediaDeviceReader::setOutputMuted(bool muted)
-{
- QMutexLocker locker(&m_mutex);
-
- m_outputMuted = muted;
-
- if (m_active && m_monitorSink) {
- IMFSimpleAudioVolume *audioVolume = nullptr;
- if (SUCCEEDED(MFGetService(m_monitorSink, MR_POLICY_VOLUME_SERVICE,
- IID_PPV_ARGS(&audioVolume)))) {
- audioVolume->SetMute(m_outputMuted);
- audioVolume->Release();
- }
- }
-}
-
-void QWindowsMediaDeviceReader::setOutputVolume(qreal volume)
-{
- QMutexLocker locker(&m_mutex);
-
- m_outputVolume = qBound(0.0, volume, 1.0);
-
- if (m_active && m_monitorSink) {
- IMFSimpleAudioVolume *audioVolume = nullptr;
- if (SUCCEEDED(MFGetService(m_monitorSink, MR_POLICY_VOLUME_SERVICE,
- IID_PPV_ARGS(&audioVolume)))) {
- audioVolume->SetMasterVolume(float(m_outputVolume));
- audioVolume->Release();
- }
- }
-}
-
-void QWindowsMediaDeviceReader::updateDuration()
-{
- if (m_currentDuration >= 0 && m_lastDuration != m_currentDuration) {
- m_lastDuration = m_currentDuration;
- emit durationChanged(m_currentDuration);
- }
-}
-
-//from IMFSourceReaderCallback
-STDMETHODIMP QWindowsMediaDeviceReader::OnReadSample(HRESULT hrStatus, DWORD dwStreamIndex,
- DWORD dwStreamFlags, LONGLONG llTimestamp,
- IMFSample *pSample)
-{
- QMutexLocker locker(&m_mutex);
-
- if (FAILED(hrStatus)) {
- emit streamingError(int(hrStatus));
- return hrStatus;
- }
-
- m_lastTimestamp = llTimestamp;
-
- if ((dwStreamFlags & MF_SOURCE_READERF_ENDOFSTREAM) == MF_SOURCE_READERF_ENDOFSTREAM) {
- m_streaming = false;
- emit streamingStopped();
- } else {
-
- if (!m_streaming) {
- m_streaming = true;
- emit streamingStarted();
- }
- if (pSample) {
-
- if (m_monitorWriter && dwStreamIndex == m_sourceAudioStreamIndex)
- m_monitorWriter->WriteSample(0, pSample);
-
- if (m_recording) {
-
- if (m_firstFrame) {
- m_timeOffset = llTimestamp;
- m_firstFrame = false;
- emit recordingStarted();
- }
-
- if (m_pauseChanging) {
- // Recording time should not pass while paused.
- if (m_paused)
- m_pauseTime = llTimestamp;
- else
- m_timeOffset += llTimestamp - m_pauseTime;
- m_pauseChanging = false;
- }
-
- // Send the video frame or audio sample to be encoded.
- if (m_sinkWriter && !m_paused) {
-
- pSample->SetSampleTime(llTimestamp - m_timeOffset);
-
- if (dwStreamIndex == m_sourceVideoStreamIndex) {
-
- m_sinkWriter->WriteSample(m_sinkVideoStreamIndex, pSample);
-
- } else if (dwStreamIndex == m_sourceAudioStreamIndex) {
-
- float volume = m_inputMuted ? 0.0f : float(m_inputVolume);
-
- // Change the volume of the audio sample, if needed.
- if (volume != 1.0f) {
- IMFMediaBuffer *mediaBuffer = nullptr;
- if (SUCCEEDED(pSample->ConvertToContiguousBuffer(&mediaBuffer))) {
-
- DWORD bufLen = 0;
- BYTE *buffer = nullptr;
-
- if (SUCCEEDED(mediaBuffer->Lock(&buffer, nullptr, &bufLen))) {
-
- float *floatBuffer = reinterpret_cast<float*>(buffer);
-
- for (DWORD i = 0; i < bufLen/4; ++i)
- floatBuffer[i] *= volume;
-
- mediaBuffer->Unlock();
- }
- mediaBuffer->Release();
- }
- }
-
- m_sinkWriter->WriteSample(m_sinkAudioStreamIndex, pSample);
- }
- m_currentDuration = (llTimestamp - m_timeOffset) / 10000;
- }
- }
-
- // Generate a new QVideoFrame from IMFSample.
- if (dwStreamIndex == m_sourceVideoStreamIndex) {
- IMFMediaBuffer *mediaBuffer = nullptr;
- if (SUCCEEDED(pSample->ConvertToContiguousBuffer(&mediaBuffer))) {
-
- DWORD bufLen = 0;
- BYTE *buffer = nullptr;
-
- if (SUCCEEDED(mediaBuffer->Lock(&buffer, nullptr, &bufLen))) {
- auto bytes = QByteArray(reinterpret_cast<char*>(buffer), bufLen);
-
- QVideoFrame frame(new QMemoryVideoBuffer(bytes, m_stride),
- QVideoFrameFormat(QSize(m_frameWidth, m_frameHeight), m_pixelFormat));
-
- // WMF uses 100-nanosecond units, Qt uses microseconds
- frame.setStartTime(llTimestamp * 0.1);
-
- LONGLONG duration = -1;
- if (SUCCEEDED(pSample->GetSampleDuration(&duration)))
- frame.setEndTime((llTimestamp + duration) * 0.1);
-
- emit videoFrameChanged(frame);
-
- mediaBuffer->Unlock();
- }
- mediaBuffer->Release();
- }
- }
- }
- // request the next video frame or sound sample
- if (m_sourceReader)
- m_sourceReader->ReadSample(MF_SOURCE_READER_ANY_STREAM,
- 0, nullptr, nullptr, nullptr, nullptr);
- }
-
- return S_OK;
-}
-
-STDMETHODIMP QWindowsMediaDeviceReader::OnFlush(DWORD)
-{
- return S_OK;
-}
-
-STDMETHODIMP QWindowsMediaDeviceReader::OnEvent(DWORD, IMFMediaEvent*)
-{
- return S_OK;
-}
-
-//from IMFSinkWriterCallback
-STDMETHODIMP QWindowsMediaDeviceReader::OnFinalize(HRESULT)
-{
- QMutexLocker locker(&m_mutex);
- if (m_sinkWriter) {
- m_sinkWriter->Release();
- m_sinkWriter = nullptr;
- }
- emit recordingStopped();
- m_hasFinalized.notify_one();
- return S_OK;
-}
-
-STDMETHODIMP QWindowsMediaDeviceReader::OnMarker(DWORD, LPVOID)
-{
- return S_OK;
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowsmediadevicereader_p.h b/src/multimedia/platform/windows/mediacapture/qwindowsmediadevicereader_p.h
deleted file mode 100644
index e7af22e5d..000000000
--- a/src/multimedia/platform/windows/mediacapture/qwindowsmediadevicereader_p.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWINDOWSMEDIADEVICEREADER_H
-#define QWINDOWSMEDIADEVICEREADER_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 <mfapi.h>
-#include <mfidl.h>
-#include <Mferror.h>
-#include <Mfreadwrite.h>
-
-#include <QtCore/qobject.h>
-#include <QtCore/qmutex.h>
-#include <QtCore/qwaitcondition.h>
-#include <QtCore/qtimer.h>
-#include <qvideoframe.h>
-#include <qcameradevice.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVideoSink;
-
-class QWindowsMediaDeviceReader : public QObject,
- public IMFSourceReaderCallback,
- public IMFSinkWriterCallback
-{
- Q_OBJECT
-public:
- explicit QWindowsMediaDeviceReader(QObject *parent = nullptr);
- ~QWindowsMediaDeviceReader();
-
- //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);
-
- //from IMFSinkWriterCallback
- STDMETHODIMP OnFinalize(HRESULT hrStatus);
- STDMETHODIMP OnMarker(DWORD dwStreamIndex, LPVOID pvContext);
-
- bool activate(const QString &cameraId,
- const QCameraFormat &cameraFormat,
- const QString &microphoneId);
- void deactivate();
-
- bool startRecording(const QString &fileName, const GUID &container,
- const GUID &videoFormat, UINT32 videoBitRate, UINT32 width,
- UINT32 height, qreal frameRate, const GUID &audioFormat,
- UINT32 audioBitRate);
- void stopRecording();
- bool pauseRecording();
- bool resumeRecording();
-
- UINT32 frameWidth() const;
- UINT32 frameHeight() const;
- qreal frameRate() const;
- void setInputMuted(bool muted);
- void setInputVolume(qreal volume);
- void setOutputMuted(bool muted);
- void setOutputVolume(qreal volume);
- bool setAudioOutput(const QString &audioOutputId);
-
-Q_SIGNALS:
- void streamingStarted();
- void streamingStopped();
- void streamingError(int errorCode);
- void recordingStarted();
- void recordingStopped();
- void recordingError(int errorCode);
- void durationChanged(qint64 duration);
- void videoFrameChanged(const QVideoFrame &frame);
-
-private slots:
- void updateDuration();
-
-private:
- HRESULT createSource(const QString &deviceId, bool video, IMFMediaSource **source);
- HRESULT createAggregateReader(IMFMediaSource *firstSource, IMFMediaSource *secondSource,
- IMFMediaSource **aggregateSource, IMFSourceReader **sourceReader);
- HRESULT createVideoMediaType(const GUID &format, UINT32 bitRate, UINT32 width, UINT32 height,
- qreal frameRate, IMFMediaType **mediaType);
- HRESULT createAudioMediaType(const GUID &format, UINT32 bitRate, IMFMediaType **mediaType);
- HRESULT initAudioType(IMFMediaType *mediaType, UINT32 channels, UINT32 samplesPerSec, bool flt);
- HRESULT prepareVideoStream(DWORD mediaTypeIndex);
- HRESULT prepareAudioStream();
- HRESULT initSourceIndexes();
- HRESULT updateSinkInputMediaTypes();
- HRESULT startMonitoring();
- void stopMonitoring();
- void releaseResources();
- void stopStreaming();
- DWORD findMediaTypeIndex(const QCameraFormat &reqFormat);
-
- long m_cRef = 1;
- QMutex m_mutex;
- QWaitCondition m_hasFinalized;
- IMFMediaSource *m_videoSource = nullptr;
- IMFMediaType *m_videoMediaType = nullptr;
- IMFMediaSource *m_audioSource = nullptr;
- IMFMediaType *m_audioMediaType = nullptr;
- IMFMediaSource *m_aggregateSource = nullptr;
- IMFSourceReader *m_sourceReader = nullptr;
- IMFSinkWriter *m_sinkWriter = nullptr;
- IMFMediaSink *m_monitorSink = nullptr;
- IMFSinkWriter *m_monitorWriter = nullptr;
- QString m_audioOutputId;
- DWORD m_sourceVideoStreamIndex = MF_SOURCE_READER_INVALID_STREAM_INDEX;
- DWORD m_sourceAudioStreamIndex = MF_SOURCE_READER_INVALID_STREAM_INDEX;
- DWORD m_sinkVideoStreamIndex = MF_SINK_WRITER_INVALID_STREAM_INDEX;
- DWORD m_sinkAudioStreamIndex = MF_SINK_WRITER_INVALID_STREAM_INDEX;
- UINT32 m_frameWidth = 0;
- UINT32 m_frameHeight = 0;
- qreal m_frameRate = 0.0;
- LONG m_stride = 0;
- bool m_active = false;
- bool m_streaming = false;
- bool m_recording = false;
- bool m_firstFrame = false;
- bool m_paused = false;
- bool m_pauseChanging = false;
- bool m_inputMuted = false;
- bool m_outputMuted = false;
- qreal m_inputVolume = 1.0;
- qreal m_outputVolume = 1.0;
- QVideoFrameFormat::PixelFormat m_pixelFormat = QVideoFrameFormat::Format_Invalid;
- LONGLONG m_timeOffset = 0;
- LONGLONG m_pauseTime = 0;
- LONGLONG m_lastTimestamp = 0;
- QTimer m_durationTimer;
- qint64 m_currentDuration = -1;
- qint64 m_lastDuration = -1;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSMEDIADEVICEREADER_H
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowsmediadevicesession.cpp b/src/multimedia/platform/windows/mediacapture/qwindowsmediadevicesession.cpp
deleted file mode 100644
index c43771d23..000000000
--- a/src/multimedia/platform/windows/mediacapture/qwindowsmediadevicesession.cpp
+++ /dev/null
@@ -1,399 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwindowsmediadevicesession_p.h"
-
-#include "qwindowsmediadevicereader_p.h"
-#include "qwindowsmultimediautils_p.h"
-#include "private/qplatformvideosink_p.h"
-#include <qvideosink.h>
-#include <QtCore/qdebug.h>
-#include <qaudioinput.h>
-#include <qaudiooutput.h>
-
-QT_BEGIN_NAMESPACE
-
-QWindowsMediaDeviceSession::QWindowsMediaDeviceSession(QObject *parent)
- : QObject(parent)
-{
- m_mediaDeviceReader = new QWindowsMediaDeviceReader(this);
- connect(m_mediaDeviceReader, SIGNAL(streamingStarted()), this, SLOT(handleStreamingStarted()));
- connect(m_mediaDeviceReader, SIGNAL(streamingStopped()), this, SLOT(handleStreamingStopped()));
- connect(m_mediaDeviceReader, SIGNAL(streamingError(int)), this, SLOT(handleStreamingError(int)));
- connect(m_mediaDeviceReader, SIGNAL(videoFrameChanged(QVideoFrame)), this, SLOT(handleVideoFrameChanged(QVideoFrame)));
- connect(m_mediaDeviceReader, SIGNAL(recordingStarted()), this, SIGNAL(recordingStarted()));
- connect(m_mediaDeviceReader, SIGNAL(recordingStopped()), this, SIGNAL(recordingStopped()));
- connect(m_mediaDeviceReader, SIGNAL(recordingError(int)), this, SIGNAL(recordingError(int)));
- connect(m_mediaDeviceReader, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64)));
-}
-
-QWindowsMediaDeviceSession::~QWindowsMediaDeviceSession()
-{
- delete m_mediaDeviceReader;
-}
-
-bool QWindowsMediaDeviceSession::isActive() const
-{
- return m_active;
-}
-
-bool QWindowsMediaDeviceSession::isActivating() const
-{
- return m_activating;
-}
-
-void QWindowsMediaDeviceSession::setActive(bool active)
-{
- if ((active && (m_active || m_activating)) || (!active && !m_active && !m_activating))
- return;
-
- if (active) {
- auto camId = QString::fromUtf8(m_activeCameraDevice.id());
- auto micId = m_audioInput ? QString::fromUtf8(m_audioInput->device().id()) : QString();
- if (!camId.isEmpty() || !micId.isEmpty()) {
- if (m_mediaDeviceReader->activate(camId, m_cameraFormat, micId)) {
- m_activating = true;
- } else {
- emit streamingError(MF_E_NOT_AVAILABLE);
- }
- } else {
- qWarning() << Q_FUNC_INFO << "Camera ID and Microphone ID both undefined.";
- }
- } else {
- m_mediaDeviceReader->deactivate();
- m_active = false;
- m_activating = false;
- emit activeChanged(m_active);
- emit readyForCaptureChanged(m_active);
- }
-}
-
-void QWindowsMediaDeviceSession::reactivate()
-{
- if (m_active || m_activating) {
- pauseRecording();
- setActive(false);
- setActive(true);
- resumeRecording();
- }
-}
-
-void QWindowsMediaDeviceSession::setActiveCamera(const QCameraDevice &camera)
-{
- m_activeCameraDevice = camera;
- reactivate();
-}
-
-QCameraDevice QWindowsMediaDeviceSession::activeCamera() const
-{
- return m_activeCameraDevice;
-}
-
-void QWindowsMediaDeviceSession::setCameraFormat(const QCameraFormat &cameraFormat)
-{
- m_cameraFormat = cameraFormat;
-}
-
-void QWindowsMediaDeviceSession::setVideoSink(QVideoSink *surface)
-{
- m_surface = surface;
-}
-
-void QWindowsMediaDeviceSession::handleStreamingStarted()
-{
- m_active = true;
- m_activating = false;
- emit activeChanged(m_active);
- emit readyForCaptureChanged(m_active);
-}
-
-void QWindowsMediaDeviceSession::handleStreamingStopped()
-{
- m_active = false;
- emit activeChanged(m_active);
- emit readyForCaptureChanged(m_active);
-}
-
-void QWindowsMediaDeviceSession::handleStreamingError(int errorCode)
-{
- if (m_surface)
- emit m_surface->platformVideoSink()->setVideoFrame(QVideoFrame());
- emit streamingError(errorCode);
-}
-
-void QWindowsMediaDeviceSession::handleVideoFrameChanged(const QVideoFrame &frame)
-{
- if (m_surface)
- emit m_surface->platformVideoSink()->setVideoFrame(frame);
- emit videoFrameChanged(frame);
-}
-
-void QWindowsMediaDeviceSession::setAudioInputMuted(bool muted)
-{
- m_mediaDeviceReader->setInputMuted(muted);
-}
-
-void QWindowsMediaDeviceSession::setAudioInputVolume(float volume)
-{
- m_mediaDeviceReader->setInputVolume(volume);
-}
-
-void QWindowsMediaDeviceSession::audioInputDeviceChanged()
-{
- reactivate();
-}
-
-void QWindowsMediaDeviceSession::setAudioOutputMuted(bool muted)
-{
- m_mediaDeviceReader->setOutputMuted(muted);
-}
-
-void QWindowsMediaDeviceSession::setAudioOutputVolume(float volume)
-{
- m_mediaDeviceReader->setOutputVolume(volume);
-}
-
-void QWindowsMediaDeviceSession::audioOutputDeviceChanged()
-{
- if (m_active || m_activating)
- m_mediaDeviceReader->setAudioOutput(QString::fromUtf8(m_audioOutput->device().id()));
-}
-
-void QWindowsMediaDeviceSession::setAudioInput(QAudioInput *input)
-{
- if (m_audioInput == input)
- return;
- if (m_audioInput)
- m_audioInput->disconnect(this);
- m_audioInput = input;
-
- audioInputDeviceChanged();
-
- if (!m_audioInput)
- return;
- connect(m_audioInput, &QAudioInput::mutedChanged, this, &QWindowsMediaDeviceSession::setAudioInputMuted);
- connect(m_audioInput, &QAudioInput::volumeChanged, this, &QWindowsMediaDeviceSession::setAudioInputVolume);
- connect(m_audioInput, &QAudioInput::deviceChanged, this, &QWindowsMediaDeviceSession::audioInputDeviceChanged);
-}
-
-void QWindowsMediaDeviceSession::setAudioOutput(QAudioOutput *output)
-{
- if (m_audioOutput == output)
- return;
- if (m_audioOutput)
- m_audioOutput->disconnect(this);
- m_audioOutput = output;
- if (!m_audioOutput) {
- m_mediaDeviceReader->setAudioOutput({});
- return;
- }
-
- m_mediaDeviceReader->setAudioOutput(QString::fromUtf8(m_audioOutput->device().id()));
-
- connect(m_audioOutput, &QAudioOutput::mutedChanged, this, &QWindowsMediaDeviceSession::setAudioOutputMuted);
- connect(m_audioOutput, &QAudioOutput::volumeChanged, this, &QWindowsMediaDeviceSession::setAudioOutputVolume);
- connect(m_audioOutput, &QAudioOutput::deviceChanged, this, &QWindowsMediaDeviceSession::audioOutputDeviceChanged);
-}
-
-bool QWindowsMediaDeviceSession::startRecording(QMediaEncoderSettings &settings, const QString &fileName, bool audioOnly)
-{
- GUID container = QWindowsMultimediaUtils::containerForVideoFileFormat(settings.mediaFormat().fileFormat());
- GUID videoFormat = QWindowsMultimediaUtils::videoFormatForCodec(settings.videoCodec());
- GUID audioFormat = QWindowsMultimediaUtils::audioFormatForCodec(settings.audioCodec());
-
- QSize res = settings.videoResolution();
- UINT32 width, height;
- if (res.width() > 0 && res.height() > 0) {
- width = UINT32(res.width());
- height = UINT32(res.height());
- } else {
- width = m_mediaDeviceReader->frameWidth();
- height = m_mediaDeviceReader->frameHeight();
- settings.setVideoResolution(QSize(int(width), int(height)));
- }
-
- qreal frameRate = settings.videoFrameRate();
- if (frameRate <= 0) {
- frameRate = m_mediaDeviceReader->frameRate();
- settings.setVideoFrameRate(frameRate);
- }
-
- auto quality = settings.quality();
-
- UINT32 videoBitRate = 0;
- if (settings.videoBitRate() > 0) {
- videoBitRate = UINT32(settings.videoBitRate());
- } else {
- videoBitRate = estimateVideoBitRate(videoFormat, width, height, frameRate, quality);
- settings.setVideoBitRate(int(videoBitRate));
- }
-
- UINT32 audioBitRate = 0;
- if (settings.audioBitRate() > 0) {
- audioBitRate = UINT32(settings.audioBitRate());
- } else {
- audioBitRate = estimateAudioBitRate(audioFormat, quality);
- settings.setAudioBitRate(int(audioBitRate));
- }
-
- return m_mediaDeviceReader->startRecording(fileName, container, audioOnly ? GUID_NULL : videoFormat,
- videoBitRate, width, height, frameRate,
- audioFormat, audioBitRate);
-}
-
-void QWindowsMediaDeviceSession::stopRecording()
-{
- m_mediaDeviceReader->stopRecording();
-}
-
-bool QWindowsMediaDeviceSession::pauseRecording()
-{
- return m_mediaDeviceReader->pauseRecording();
-}
-
-bool QWindowsMediaDeviceSession::resumeRecording()
-{
- return m_mediaDeviceReader->resumeRecording();
-}
-
-// empirical estimate of the required video bitrate (for H.264)
-quint32 QWindowsMediaDeviceSession::estimateVideoBitRate(const GUID &videoFormat, quint32 width, quint32 height,
- qreal frameRate, QMediaRecorder::Quality quality)
-{
- Q_UNUSED(videoFormat);
-
- qreal bitsPerPixel;
- switch (quality) {
- case QMediaRecorder::Quality::VeryLowQuality:
- bitsPerPixel = 0.08;
- break;
- case QMediaRecorder::Quality::LowQuality:
- bitsPerPixel = 0.2;
- break;
- case QMediaRecorder::Quality::NormalQuality:
- bitsPerPixel = 0.3;
- break;
- case QMediaRecorder::Quality::HighQuality:
- bitsPerPixel = 0.5;
- break;
- case QMediaRecorder::Quality::VeryHighQuality:
- bitsPerPixel = 0.8;
- break;
- default:
- bitsPerPixel = 0.3;
- }
-
- // Required bitrate is not linear on the number of pixels; small resolutions
- // require more BPP, thus the minimum values, to try to compensate it.
- quint32 pixelsPerSec = quint32(qMax(width, 320u) * qMax(height, 240u) * qMax(frameRate, 6.0));
- return pixelsPerSec * bitsPerPixel;
-}
-
-quint32 QWindowsMediaDeviceSession::estimateAudioBitRate(const GUID &audioFormat, QMediaRecorder::Quality quality)
-{
- if (audioFormat == MFAudioFormat_AAC) {
- // Bitrates supported by the AAC encoder are 96K, 128K, 160K, 192K.
- switch (quality) {
- case QMediaRecorder::Quality::VeryLowQuality:
- return 96000;
- case QMediaRecorder::Quality::LowQuality:
- return 96000;
- case QMediaRecorder::Quality::NormalQuality:
- return 128000;
- case QMediaRecorder::Quality::HighQuality:
- return 160000;
- case QMediaRecorder::Quality::VeryHighQuality:
- return 192000;
- default:
- return 128000;
- }
- } else if (audioFormat == MFAudioFormat_MP3) {
- // Bitrates supported by the MP3 encoder are
- // 32K, 40K, 48K, 56K, 64K, 80K, 96K, 112K, 128K, 160K, 192K, 224K, 256K, 320K.
- switch (quality) {
- case QMediaRecorder::Quality::VeryLowQuality:
- return 48000;
- case QMediaRecorder::Quality::LowQuality:
- return 96000;
- case QMediaRecorder::Quality::NormalQuality:
- return 128000;
- case QMediaRecorder::Quality::HighQuality:
- return 224000;
- case QMediaRecorder::Quality::VeryHighQuality:
- return 320000;
- default:
- return 128000;
- }
- } else if (audioFormat == MFAudioFormat_WMAudioV8) {
- // Bitrates supported by the Windows Media Audio 8 encoder
- switch (quality) {
- case QMediaRecorder::Quality::VeryLowQuality:
- return 32000;
- case QMediaRecorder::Quality::LowQuality:
- return 96000;
- case QMediaRecorder::Quality::NormalQuality:
- return 192000;
- case QMediaRecorder::Quality::HighQuality:
- return 256016;
- case QMediaRecorder::Quality::VeryHighQuality:
- return 320032;
- default:
- return 192000;
- }
- } else if (audioFormat == MFAudioFormat_WMAudioV9) {
- // Bitrates supported by the Windows Media Audio 9 encoder
- switch (quality) {
- case QMediaRecorder::Quality::VeryLowQuality:
- return 32000;
- case QMediaRecorder::Quality::LowQuality:
- return 96000;
- case QMediaRecorder::Quality::NormalQuality:
- return 192000;
- case QMediaRecorder::Quality::HighQuality:
- return 256016;
- case QMediaRecorder::Quality::VeryHighQuality:
- return 384000;
- default:
- return 192000;
- }
- }
- return 0; // Use default for format
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowsmediadevicesession_p.h b/src/multimedia/platform/windows/mediacapture/qwindowsmediadevicesession_p.h
deleted file mode 100644
index 4620bd6fb..000000000
--- a/src/multimedia/platform/windows/mediacapture/qwindowsmediadevicesession_p.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWINDOWSMEDIADEVICESESSION_H
-#define QWINDOWSMEDIADEVICESESSION_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 <private/qtmultimediaglobal_p.h>
-#include <qcamera.h>
-#include <qaudiodevice.h>
-#include <qwindowsmultimediautils_p.h>
-#include <qplatformmediaencoder_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QAudioInput;
-class QAudioOutput;
-class QVideoSink;
-class QWindowsMediaDeviceReader;
-
-class QWindowsMediaDeviceSession : public QObject
-{
- Q_OBJECT
-public:
- explicit QWindowsMediaDeviceSession(QObject *parent = nullptr);
- ~QWindowsMediaDeviceSession();
-
- bool isActive() const;
- void setActive(bool active);
-
- bool isActivating() const;
-
- void setActiveCamera(const QCameraDevice &camera);
- QCameraDevice activeCamera() const;
-
- void setCameraFormat(const QCameraFormat &cameraFormat);
-
- void setVideoSink(QVideoSink *surface);
-
-public Q_SLOTS:
- void setAudioInputMuted(bool muted);
- void setAudioInputVolume(float volume);
- void audioInputDeviceChanged();
- void setAudioOutputMuted(bool muted);
- void setAudioOutputVolume(float volume);
- void audioOutputDeviceChanged();
-
-public:
- void setAudioInput(QAudioInput *input);
- void setAudioOutput(QAudioOutput *output);
-
- bool startRecording(QMediaEncoderSettings &settings, const QString &fileName, bool audioOnly);
- void stopRecording();
- bool pauseRecording();
- bool resumeRecording();
-
-Q_SIGNALS:
- void activeChanged(bool);
- void readyForCaptureChanged(bool);
- void durationChanged(qint64 duration);
- void recordingStarted();
- void recordingStopped();
- void streamingError(int errorCode);
- void recordingError(int errorCode);
- void videoFrameChanged(const QVideoFrame &frame);
-
-private Q_SLOTS:
- void handleStreamingStarted();
- void handleStreamingStopped();
- void handleStreamingError(int errorCode);
- void handleVideoFrameChanged(const QVideoFrame &frame);
-
-private:
- void reactivate();
- quint32 estimateVideoBitRate(const GUID &videoFormat, quint32 width, quint32 height,
- qreal frameRate, QMediaRecorder::Quality quality);
- quint32 estimateAudioBitRate(const GUID &audioFormat, QMediaRecorder::Quality quality);
- bool m_active = false;
- bool m_activating = false;
- QCameraDevice m_activeCameraDevice;
- QCameraFormat m_cameraFormat;
- QWindowsMediaDeviceReader *m_mediaDeviceReader = nullptr;
- QAudioInput *m_audioInput = nullptr;
- QAudioOutput *m_audioOutput = nullptr;
- QVideoSink *m_surface = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSMEDIADEVICESESSION_H
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder.cpp b/src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder.cpp
deleted file mode 100644
index 555d5bbda..000000000
--- a/src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder.cpp
+++ /dev/null
@@ -1,253 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwindowsmediaencoder_p.h"
-
-#include "qwindowsmediadevicesession_p.h"
-#include "qwindowsmediacapture_p.h"
-#include "qmediastoragelocation_p.h"
-#include "mfmetadata_p.h"
-#include <QtCore/QUrl>
-#include <QtCore/QMimeType>
-#include <Mferror.h>
-#include <shobjidl.h>
-#include <private/qmediarecorder_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QWindowsMediaEncoder::QWindowsMediaEncoder(QMediaRecorder *parent)
- : QObject(parent),
- QPlatformMediaEncoder(parent)
-{
-}
-
-bool QWindowsMediaEncoder::isLocationWritable(const QUrl &location) const
-{
- return location.scheme() == QLatin1String("file") || location.scheme().isEmpty();
-}
-
-QMediaRecorder::RecorderState QWindowsMediaEncoder::state() const
-{
- return m_state;
-}
-
-qint64 QWindowsMediaEncoder::duration() const
-{
- return m_duration;
-}
-
-void QWindowsMediaEncoder::record(QMediaEncoderSettings &settings)
-{
- if (!m_captureService || !m_mediaDeviceSession) {
- qWarning() << Q_FUNC_INFO << "Encoder is not set to a capture session";
- return;
- }
- if (m_state != QMediaRecorder::StoppedState)
- return;
-
- m_mediaDeviceSession->setActive(true);
-
- if (!m_mediaDeviceSession->isActive() && !m_mediaDeviceSession->isActivating()) {
- error(QMediaRecorder::ResourceError,
- QMediaRecorderPrivate::msgFailedStartRecording());
- return;
- }
-
- const auto audioOnly = settings.videoCodec() == QMediaFormat::VideoCodec::Unspecified;
-
- const QString path = (outputLocation().scheme() == QLatin1String("file") ?
- outputLocation().path() : outputLocation().toString());
-
- m_fileName = QMediaStorageLocation::generateFileName(path, audioOnly
- ? QStandardPaths::MusicLocation
- : QStandardPaths::MoviesLocation,
- settings.mimeType().preferredSuffix());
-
- if (m_mediaDeviceSession->startRecording(settings, m_fileName, audioOnly)) {
-
- m_state = QMediaRecorder::RecordingState;
-
- actualLocationChanged(QUrl::fromLocalFile(m_fileName));
- stateChanged(m_state);
-
- } else {
- error(QMediaRecorder::FormatError,
- QMediaRecorderPrivate::msgFailedStartRecording());
- }
-}
-
-void QWindowsMediaEncoder::pause()
-{
- if (!m_mediaDeviceSession || m_state != QMediaRecorder::RecordingState)
- return;
-
- if (m_mediaDeviceSession->pauseRecording()) {
- m_state = QMediaRecorder::PausedState;
- stateChanged(m_state);
- } else {
- error(QMediaRecorder::FormatError, tr("Failed to pause recording"));
- }
-}
-
-void QWindowsMediaEncoder::resume()
-{
- if (!m_mediaDeviceSession || m_state != QMediaRecorder::PausedState)
- return;
-
- if (m_mediaDeviceSession->resumeRecording()) {
- m_state = QMediaRecorder::RecordingState;
- stateChanged(m_state);
- } else {
- error(QMediaRecorder::FormatError, tr("Failed to resume recording"));
- }
-}
-
-void QWindowsMediaEncoder::stop()
-{
- if (m_mediaDeviceSession && m_state != QMediaRecorder::StoppedState)
- m_mediaDeviceSession->stopRecording();
-}
-
-
-
-void QWindowsMediaEncoder::setCaptureSession(QPlatformMediaCaptureSession *session)
-{
- QWindowsMediaCaptureService *captureSession = static_cast<QWindowsMediaCaptureService *>(session);
- if (m_captureService == captureSession)
- return;
-
- if (m_captureService)
- stop();
-
- m_captureService = captureSession;
- if (!m_captureService) {
- m_mediaDeviceSession = nullptr;
- return;
- }
-
- m_mediaDeviceSession = m_captureService->session();
- Q_ASSERT(m_mediaDeviceSession);
-
- connect(m_mediaDeviceSession, &QWindowsMediaDeviceSession::recordingStarted, this, &QWindowsMediaEncoder::onRecordingStarted);
- connect(m_mediaDeviceSession, &QWindowsMediaDeviceSession::recordingStopped, this, &QWindowsMediaEncoder::onRecordingStopped);
- connect(m_mediaDeviceSession, &QWindowsMediaDeviceSession::streamingError, this, &QWindowsMediaEncoder::onStreamingError);
- connect(m_mediaDeviceSession, &QWindowsMediaDeviceSession::recordingError, this, &QWindowsMediaEncoder::onRecordingError);
- connect(m_mediaDeviceSession, &QWindowsMediaDeviceSession::durationChanged, this, &QWindowsMediaEncoder::onDurationChanged);
- connect(m_captureService, &QWindowsMediaCaptureService::cameraChanged, this, &QWindowsMediaEncoder::onCameraChanged);
- onCameraChanged();
-}
-
-void QWindowsMediaEncoder::setMetaData(const QMediaMetaData &metaData)
-{
- m_metaData = metaData;
-}
-
-QMediaMetaData QWindowsMediaEncoder::metaData() const
-{
- return m_metaData;
-}
-
-void QWindowsMediaEncoder::saveMetadata()
-{
- if (!m_metaData.isEmpty()) {
-
- const QString nativeFileName = QDir::toNativeSeparators(m_fileName);
-
- IPropertyStore *store = nullptr;
-
- if (SUCCEEDED(SHGetPropertyStoreFromParsingName(reinterpret_cast<LPCWSTR>(nativeFileName.utf16()),
- nullptr, GPS_READWRITE, IID_PPV_ARGS(&store)))) {
-
- MFMetaData::toNative(m_metaData, store);
-
- store->Commit();
- store->Release();
- }
- }
-}
-
-void QWindowsMediaEncoder::onDurationChanged(qint64 duration)
-{
- m_duration = duration;
- durationChanged(m_duration);
-}
-
-void QWindowsMediaEncoder::onStreamingError(int errorCode)
-{
- if (errorCode == MF_E_VIDEO_RECORDING_DEVICE_INVALIDATED)
- error(QMediaRecorder::ResourceError, tr("Camera is no longer present"));
- else if (errorCode == MF_E_AUDIO_RECORDING_DEVICE_INVALIDATED)
- error(QMediaRecorder::ResourceError, tr("Audio input is no longer present"));
- else
- error(QMediaRecorder::ResourceError, tr("Streaming error"));
-
- if (m_state != QMediaRecorder::StoppedState) {
- m_mediaDeviceSession->stopRecording();
- }
-}
-
-void QWindowsMediaEncoder::onRecordingError(int errorCode)
-{
- error(QMediaRecorder::ResourceError, tr("Recording error"));
-
- auto lastState = m_state;
- m_state = QMediaRecorder::StoppedState;
- if (m_state != lastState)
- stateChanged(m_state);
-}
-
-void QWindowsMediaEncoder::onCameraChanged()
-{
-}
-
-void QWindowsMediaEncoder::onRecordingStarted()
-{
-}
-
-void QWindowsMediaEncoder::onRecordingStopped()
-{
- saveMetadata();
-
- auto lastState = m_state;
- m_state = QMediaRecorder::StoppedState;
- if (m_state != lastState)
- stateChanged(m_state);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder_p.h b/src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder_p.h
deleted file mode 100644
index c7b9d8931..000000000
--- a/src/multimedia/platform/windows/mediacapture/qwindowsmediaencoder_p.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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$
-**
-****************************************************************************/
-
-//
-// 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.
-//
-
-#ifndef QWINDOWSMEDIAENCODER_H
-#define QWINDOWSMEDIAENCODER_H
-
-#include <private/qplatformmediaencoder_p.h>
-
-#include <QtCore/qglobal.h>
-#include <QtCore/qurl.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsMediaDeviceSession;
-class QPlatformMediaCaptureSession;
-class QWindowsMediaCaptureService;
-
-class QWindowsMediaEncoder : public QObject, public QPlatformMediaEncoder
-{
- Q_OBJECT
-public:
- explicit QWindowsMediaEncoder(QMediaRecorder *parent);
-
- bool isLocationWritable(const QUrl &location) const override;
- QMediaRecorder::RecorderState state() const override;
- qint64 duration() const override;
-
- void setMetaData(const QMediaMetaData &metaData) override;
- QMediaMetaData metaData() const override;
-
- void setCaptureSession(QPlatformMediaCaptureSession *session);
-
- void record(QMediaEncoderSettings &settings) override;
- void pause() override;
- void resume() override;
- void stop() override;
-
-private Q_SLOTS:
- void onCameraChanged();
- void onRecordingStarted();
- void onRecordingStopped();
- void onDurationChanged(qint64 duration);
- void onStreamingError(int errorCode);
- void onRecordingError(int errorCode);
-
-private:
- void saveMetadata();
-
- QWindowsMediaCaptureService *m_captureService = nullptr;
- QWindowsMediaDeviceSession *m_mediaDeviceSession = nullptr;
- QMediaRecorder::RecorderState m_state = QMediaRecorder::StoppedState;
- QString m_fileName;
- QMediaMetaData m_metaData;
- qint64 m_duration = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/windows/mfstream.cpp b/src/multimedia/platform/windows/mfstream.cpp
deleted file mode 100644
index b01dbb7b1..000000000
--- a/src/multimedia/platform/windows/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_p.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/multimedia/platform/windows/mfstream_p.h b/src/multimedia/platform/windows/mfstream_p.h
deleted file mode 100644
index 975d02c9d..000000000
--- a/src/multimedia/platform/windows/mfstream_p.h
+++ /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 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
-
-//
-// 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 <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/multimedia/platform/windows/player/mfactivate.cpp b/src/multimedia/platform/windows/player/mfactivate.cpp
deleted file mode 100644
index 05d9321be..000000000
--- a/src/multimedia/platform/windows/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_p.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/multimedia/platform/windows/player/mfactivate_p.h b/src/multimedia/platform/windows/player/mfactivate_p.h
deleted file mode 100644
index 86ef1c438..000000000
--- a/src/multimedia/platform/windows/player/mfactivate_p.h
+++ /dev/null
@@ -1,223 +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
-
-//
-// 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 <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/multimedia/platform/windows/player/mfevrvideowindowcontrol.cpp b/src/multimedia/platform/windows/player/mfevrvideowindowcontrol.cpp
deleted file mode 100644
index 105424253..000000000
--- a/src/multimedia/platform/windows/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_p.h"
-
-#include <qdebug.h>
-
-MFEvrVideoWindowControl::MFEvrVideoWindowControl(QVideoSink *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/multimedia/platform/windows/player/mfevrvideowindowcontrol_p.h b/src/multimedia/platform/windows/player/mfevrvideowindowcontrol_p.h
deleted file mode 100644
index 2f9d867d6..000000000
--- a/src/multimedia/platform/windows/player/mfevrvideowindowcontrol_p.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 MFEVRVIDEOWINDOWCONTROL_H
-#define MFEVRVIDEOWINDOWCONTROL_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 "private/evrvideowindowcontrol_p.h"
-
-QT_USE_NAMESPACE
-
-class MFEvrVideoWindowControl : public EvrVideoWindowControl
-{
-public:
- MFEvrVideoWindowControl(QVideoSink *parent = 0);
- ~MFEvrVideoWindowControl();
-
- IMFActivate* createActivate();
- void releaseActivate();
-
-private:
- void clear();
-
- IMFActivate *m_currentActivate;
- IMFMediaSink *m_evrSink;
-};
-
-#endif // MFEVRVIDEOWINDOWCONTROL_H
diff --git a/src/multimedia/platform/windows/player/mfplayercontrol.cpp b/src/multimedia/platform/windows/player/mfplayercontrol.cpp
deleted file mode 100644
index 47e74ab38..000000000
--- a/src/multimedia/platform/windows/player/mfplayercontrol.cpp
+++ /dev/null
@@ -1,328 +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_p.h"
-#include "mfplayersession_p.h"
-#include "mfvideorenderercontrol_p.h"
-#include <qdebug.h>
-
-//#define DEBUG_MEDIAFOUNDATION
-
-MFPlayerControl::MFPlayerControl(QMediaPlayer *player)
- : QPlatformMediaPlayer(player)
- , m_state(QMediaPlayer::StoppedState)
- , m_stateDirty(false)
- , m_videoAvailable(false)
- , m_audioAvailable(false)
- , m_duration(0)
- , m_seekable(false)
-{
- m_session = new MFPlayerSession(this);
-}
-
-MFPlayerControl::~MFPlayerControl()
-{
- m_session->close();
- m_session->Release();
-}
-
-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(0);
- handleSeekableUpdate(false);
- m_session->load(media, stream);
-}
-
-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::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();
-}
-
-QMediaMetaData MFPlayerControl::metaData() const
-{
- return m_session->metaData();
-}
-
-void MFPlayerControl::setAudioOutput(QPlatformAudioOutput *output)
-{
- m_session->setAudioOutput(output);
-}
-
-void MFPlayerControl::setVideoSink(QVideoSink *sink)
-{
- m_session->setVideoSink(sink);
-}
-
-void MFPlayerControl::changeState(QMediaPlayer::PlaybackState 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::handleTracksChanged()
-{
- tracksChanged();
-}
-
-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::PlaybackState 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);
-}
-
-float MFPlayerControl::bufferProgress() const
-{
- return m_session->bufferProgress() / 100.;
-}
-
-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);
-}
-
-void MFPlayerControl::setActiveTrack(TrackType type, int index)
-{
- m_session->setActiveTrack(type, index);
-}
-
-int MFPlayerControl::activeTrack(TrackType type)
-{
- return m_session->activeTrack(type);
-}
-
-int MFPlayerControl::trackCount(TrackType type)
-{
- return m_session->trackCount(type);
-}
-
-QMediaMetaData MFPlayerControl::trackMetaData(TrackType type, int trackNumber)
-{
- return m_session->trackMetaData(type, trackNumber);
-}
-
diff --git a/src/multimedia/platform/windows/player/mfplayercontrol_p.h b/src/multimedia/platform/windows/player/mfplayercontrol_p.h
deleted file mode 100644
index e8467ab8d..000000000
--- a/src/multimedia/platform/windows/player/mfplayercontrol_p.h
+++ /dev/null
@@ -1,139 +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
-
-//
-// 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 "QUrl.h"
-#include "qplatformmediaplayer_p.h"
-
-#include <QtCore/qcoreevent.h>
-
-QT_USE_NAMESPACE
-
-class MFPlayerSession;
-
-class MFPlayerControl : public QPlatformMediaPlayer
-{
-public:
- MFPlayerControl(QMediaPlayer *player);
- ~MFPlayerControl();
-
- QMediaPlayer::PlaybackState state() const override;
-
- QMediaPlayer::MediaStatus mediaStatus() const override;
-
- qint64 duration() const override;
-
- qint64 position() const override;
- void setPosition(qint64 position) override;
-
- float bufferProgress() 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;
-
- bool streamPlaybackSupported() const override { return true; }
-
- QMediaMetaData metaData() const override;
-
- void setAudioOutput(QPlatformAudioOutput *output) override;
-
- void setVideoSink(QVideoSink *sink) override;
-
- void setActiveTrack(TrackType type, int index) override;
- int activeTrack(TrackType type) override;
- int trackCount(TrackType type) override;
- QMediaMetaData trackMetaData(TrackType type, int trackNumber) override;
-
- void handleStatusChanged();
- void handleTracksChanged();
- 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::PlaybackState state);
- void resetAudioVideoAvailable();
- void refreshState();
-
- QMediaPlayer::PlaybackState 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/multimedia/platform/windows/player/mfplayersession.cpp b/src/multimedia/platform/windows/player/mfplayersession.cpp
deleted file mode 100644
index aeeb7c792..000000000
--- a/src/multimedia/platform/windows/player/mfplayersession.cpp
+++ /dev/null
@@ -1,2009 +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 "qplatformmediaplayer_p.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 "qplatformaudiooutput_p.h"
-#include "qaudiooutput.h"
-
-#include "mfplayercontrol_p.h"
-#include "mfevrvideowindowcontrol_p.h"
-#include "mfvideorenderercontrol_p.h"
-#include <private/mfmetadata_p.h>
-
-#include "mfplayersession_p.h"
-#include <mferror.h>
-#include <nserror.h>
-#include "private/sourceresolver_p.h"
-#include "samplegrabber_p.h"
-#include "mftvideo_p.h"
-#include <wmcodecdsp.h>
-
-#include <mmdeviceapi.h>
-#include <propvarutil.h>
-#include <Functiondiscoverykeys_devpkey.h>
-
-//#define DEBUG_MEDIAFOUNDATION
-
-MFPlayerSession::MFPlayerSession(MFPlayerControl *playerControl)
- : m_cRef(1)
- , m_playerControl(playerControl)
- , m_session(0)
- , m_presentationClock(0)
- , m_rateControl(0)
- , m_rateSupport(0)
- , m_volumeControl(0)
- , m_netsourceStatistics(0)
- , m_scrubbing(false)
- , m_restoreRate(1)
- , m_sourceResolver(0)
- , m_hCloseEvent(0)
- , m_closing(false)
- , m_mediaTypes(0)
- , m_pendingRate(1)
- , m_status(QMediaPlayer::NoMedia)
- , m_audioSampleGrabber(0)
- , m_audioSampleGrabberNode(0)
- , m_videoProbeMFT(0)
-
-{
- QObject::connect(this, SIGNAL(sessionEvent(IMFMediaEvent*)), this, SLOT(handleSessionEvent(IMFMediaEvent*)));
-
- m_signalPositionChangeTimer.setInterval(100);
- m_signalPositionChangeTimer.callOnTimeout([this](){
- positionChanged(position());
- });
-
- 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;
- m_videoRendererControl = new MFVideoRendererControl;
-}
-
-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;
- }
-
- m_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;
-}
-
-MFPlayerSession::~MFPlayerSession()
-{
- m_audioSampleGrabber->Release();
-}
-
-
-void MFPlayerSession::load(const QUrl &url, QIODevice *stream)
-{
-#ifdef DEBUG_MEDIAFOUNDATION
- qDebug() << "load";
-#endif
- clear();
-
- if (m_status == QMediaPlayer::LoadingMedia && m_sourceResolver)
- m_sourceResolver->cancel();
-
- if (url.isEmpty() && !stream) {
- close();
- changeStatus(QMediaPlayer::NoMedia);
- } else if (stream && (!stream->isReadable())) {
- close();
- 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_metaData = MFMetaData::fromNative(mediaSource);
- emit metaDataChanged();
- sourcePD->GetUINT64(MF_PD_DURATION, &m_duration);
- //convert from 100 nanosecond to milisecond
- emit durationUpdate(qint64(m_duration / 10000));
- setupPlaybackTopology(mediaSource, sourcePD);
- tracksChanged();
- sourcePD->Release();
- } else {
- changeStatus(QMediaPlayer::InvalidMedia);
- emit error(QMediaPlayer::ResourceError, tr("Cannot create presentation descriptor."), true);
- }
-}
-
-bool MFPlayerSession::getStreamInfo(IMFStreamDescriptor *stream,
- MFPlayerSession::MediaType *type,
- QString *name,
- QString *language) const
-{
- if (!stream || !type || !name || !language)
- return false;
-
- *type = Unknown;
- *name = QString();
- *language = QString();
-
- IMFMediaTypeHandler *typeHandler = nullptr;
-
- if (SUCCEEDED(stream->GetMediaTypeHandler(&typeHandler))) {
-
- UINT32 len = 0;
- if (SUCCEEDED(stream->GetStringLength(MF_SD_STREAM_NAME, &len)) && len > 0) {
- WCHAR *wstr = new WCHAR[len+1];
- if (SUCCEEDED(stream->GetString(MF_SD_STREAM_NAME, wstr, len+1, &len))) {
- *name = QString::fromUtf16(reinterpret_cast<const char16_t *>(wstr));
- }
- delete []wstr;
- }
- if (SUCCEEDED(stream->GetStringLength(MF_SD_LANGUAGE, &len)) && len > 0) {
- WCHAR *wstr = new WCHAR[len+1];
- if (SUCCEEDED(stream->GetString(MF_SD_LANGUAGE, wstr, len+1, &len))) {
- *language = QString::fromUtf16(reinterpret_cast<const char16_t *>(wstr));
- }
- delete []wstr;
- }
-
- GUID guidMajorType;
- if (SUCCEEDED(typeHandler->GetMajorType(&guidMajorType))) {
- if (guidMajorType == MFMediaType_Audio)
- *type = Audio;
- else if (guidMajorType == MFMediaType_Video)
- *type = Video;
- }
- typeHandler->Release();
- }
-
- return *type != 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::InvalidMedia);
- emit error(QMediaPlayer::ResourceError, tr("Failed to get stream count."), true);
- return;
- }
-
- IMFTopology *topology;
- hr = MFCreateTopology(&topology);
- if (FAILED(hr)) {
- changeStatus(QMediaPlayer::InvalidMedia);
- emit error(QMediaPlayer::ResourceError, tr("Failed to create topology."), true);
- return;
- }
-
- // For each stream, create the topology nodes and add them to the topology.
- DWORD succeededCount = 0;
- for (DWORD i = 0; i < cSourceStreams; i++) {
- BOOL selected = FALSE;
- bool streamAdded = false;
- IMFStreamDescriptor *streamDesc = NULL;
-
- HRESULT hr = sourcePD->GetStreamDescriptorByIndex(i, &selected, &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 = Unknown;
- QString streamName;
- QString streamLanguage;
-
- if (getStreamInfo(streamDesc, &mediaType, &streamName, &streamLanguage)) {
-
- QPlatformMediaPlayer::TrackType trackType = (mediaType == Audio) ?
- QPlatformMediaPlayer::AudioStream : QPlatformMediaPlayer::VideoStream;
-
- QLocale::Language lang = streamLanguage.isEmpty() ?
- QLocale::Language::AnyLanguage : QLocale(streamLanguage).language();
-
- QMediaMetaData metaData;
- metaData.insert(QMediaMetaData::Title, streamName);
- metaData.insert(QMediaMetaData::Language, lang);
-
- m_trackInfo[trackType].metaData.append(metaData);
- m_trackInfo[trackType].nativeIndexes.append(i);
-
- if (((m_mediaTypes & mediaType) == 0) && selected) { // Check if this type isn't already added
- 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);
- }
- sourceNode->GetTopoNodeID(&m_trackInfo[trackType].sourceNodeId);
- outputNode->GetTopoNodeID(&m_trackInfo[trackType].outputNodeId);
-
- if (!connected)
- hr = sourceNode->ConnectOutput(0, outputNode, 0);
-
- if (FAILED(hr)) {
- emit error(QMediaPlayer::FormatError, tr("Unable to play any stream."), false);
- } else {
- m_trackInfo[trackType].currentIndex = m_trackInfo[trackType].nativeIndexes.count() - 1;
- streamAdded = true;
- succeededCount++;
- m_mediaTypes |= mediaType;
- switch (mediaType) {
- case Audio:
- emit audioAvailable();
- break;
- case Video:
- emit videoAvailable();
- break;
- }
- }
- outputNode->Release();
- }
- sourceNode->Release();
- }
- }
- }
-
- if (selected && !streamAdded)
- sourcePD->DeselectStream(i);
-
- streamDesc->Release();
- }
- }
-
- if (succeededCount == 0) {
- changeStatus(QMediaPlayer::InvalidMedia);
- emit error(QMediaPlayer::ResourceError, tr("Unable to play."), true);
- } else {
- if (m_trackInfo[QPlatformMediaPlayer::VideoStream].outputNodeId != -1)
- topology = insertMFT(topology, m_trackInfo[QPlatformMediaPlayer::VideoStream].outputNodeId);
-
- hr = m_session->SetTopology(MFSESSION_SETTOPOLOGY_IMMEDIATE, topology);
- if (SUCCEEDED(hr)) {
- m_updatingTopology = true;
- } else {
- changeStatus(QMediaPlayer::InvalidMedia);
- 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) {
- if (m_audioOutput) {
- HRESULT hr = MFCreateAudioRendererActivate(&activate);
- if (FAILED(hr)) {
- qWarning() << "Failed to create audio renderer activate";
- node->Release();
- return NULL;
- }
-
- auto id = m_audioOutput->device.id();
- if (!id.isEmpty()) {
- QString s = QString::fromUtf8(id);
- hr = activate->SetString(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, (LPCWSTR)s.utf16());
- } 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" << m_audioOutput->device.description();
- activate->Release();
- node->Release();
- return NULL;
- }
- }
- } else if (mediaType == Video) {
- activate = m_videoRendererControl->createActivate();
- } 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;
- }
-
- if (activate && mediaType == Audio)
- activate->Release();
-
- 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);
- if (wfx->wBitsPerSample == 8)
- format.setSampleFormat(QAudioFormat::UInt8);
- else if (wfx->wBitsPerSample == 16)
- format.setSampleFormat(QAudioFormat::Int16);
- else if (wfx->wBitsPerSample == 32)
- format.setSampleFormat(QAudioFormat::Int32);
-
- 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_position = 0;
- }
- } else {
- emit error(QMediaPlayer::ResourceError, tr("Failed to stop."), true);
- }
- }
-}
-
-void MFPlayerSession::start()
-{
- if (m_status == QMediaPlayer::EndOfMedia)
- m_position = 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 (m_restorePosition >= 0) {
- m_position = m_restorePosition;
- if (!m_updatingTopology)
- m_restorePosition = -1;
- }
-
- PROPVARIANT varStart;
- InitPropVariantFromInt64(m_position, &varStart);
-
- if (SUCCEEDED(m_session->Start(&GUID_NULL, &varStart))) {
- m_state.setCommand(CmdStart);
- m_pendingState = CmdPending;
- } else {
- emit error(QMediaPlayer::ResourceError, tr("failed to start playback"), true);
- }
- PropVariantClear(&varStart);
- }
-}
-
-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::InvalidMedia);
- emit error(QMediaPlayer::ResourceError, tr("Unable to create mediasession."), true);
- }
-
- hr = m_session->BeginGetEvent(this, m_session);
-
- if (FAILED(hr)) {
- changeStatus(QMediaPlayer::InvalidMedia);
- emit error(QMediaPlayer::ResourceError, tr("Unable to pull session events."), false);
- }
-
- m_position = 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 m_position / 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_position = 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)))
- {
- PropVariantClear(&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);
- }
-}
-
-void MFPlayerSession::setVolume(float volume)
-{
- if (m_volume == volume)
- return;
- m_volume = volume;
-
- if (!m_muted)
- setVolumeInternal(volume);
-}
-
-void MFPlayerSession::setMuted(bool muted)
-{
- if (m_muted == muted)
- return;
- m_muted = muted;
-
- setVolumeInternal(muted ? 0 : m_volume);
-}
-
-void MFPlayerSession::setVolumeInternal(float volume)
-{
- if (m_volumeControl) {
- quint32 channelCount = 0;
- if (!SUCCEEDED(m_volumeControl->GetChannelCount(&channelCount))
- || channelCount == 0)
- return;
-
- for (quint32 i = 0; i < channelCount; ++i)
- m_volumeControl->SetChannelVolume(i, volume);
- }
-}
-
-float MFPlayerSession::bufferProgress()
-{
- 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() << "bufferProgress: progress = " << progress;
-#endif
-
- return progress/100.;
-}
-
-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::InvalidMedia);
- 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();
-// }
- m_signalPositionChangeTimer.start();
- break;
- case MESessionStopped:
- if (m_status != QMediaPlayer::EndOfMedia) {
- m_position = 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);
- m_signalPositionChangeTimer.stop();
- break;
- case MESessionPaused:
- m_position = position() * 10000;
- updatePendingCommands(CmdPause);
- m_signalPositionChangeTimer.stop();
- 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_position = 0;
-
- changeStatus(QMediaPlayer::LoadedMedia);
- }
- break;
- }
-
- if (FAILED(hrStatus)) {
- sessionEvent->Release();
- return;
- }
-
- switch (meType) {
- case MEBufferingStarted:
- changeStatus(QMediaPlayer::StalledMedia);
- emit bufferProgressChanged(bufferProgress());
- break;
- case MEBufferingStopped:
- changeStatus(QMediaPlayer::BufferedMedia);
- emit bufferProgressChanged(bufferProgress());
- break;
- case MESessionEnded:
- m_pendingState = NoPending;
- m_state.command = CmdStop;
- m_state.prevCmd = CmdNone;
- m_request.command = CmdNone;
- m_request.prevCmd = CmdNone;
-
- //keep reporting the final position after end of media
- m_position = qint64(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);
-
- m_updatingTopology = false;
- stop();
- }
- }
- }
- 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;
-
- for (int i = 0; i < QPlatformMediaPlayer::NTrackTypes; ++i) {
- m_trackInfo[i].metaData.clear();
- m_trackInfo[i].nativeIndexes.clear();
- m_trackInfo[i].currentIndex = -1;
- m_trackInfo[i].sourceNodeId = -1;
- m_trackInfo[i].outputNodeId = -1;
- }
-
- if (!m_metaData.isEmpty()) {
- m_metaData.clear();
- emit metaDataChanged();
- }
-
- 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;
- }
-}
-
-void MFPlayerSession::setAudioOutput(QPlatformAudioOutput *device)
-{
- if (m_audioOutput == device)
- return;
-
- if (m_audioOutput)
- m_audioOutput->q->disconnect(this);
-
- m_audioOutput = device;
- if (m_audioOutput) {
- setMuted(m_audioOutput->q->isMuted());
- setVolume(m_audioOutput->q->volume());
- updateOutputRouting();
- connect(m_audioOutput->q, &QAudioOutput::deviceChanged, this, &MFPlayerSession::updateOutputRouting);
- connect(m_audioOutput->q, &QAudioOutput::volumeChanged, this, &MFPlayerSession::setVolume);
- connect(m_audioOutput->q, &QAudioOutput::mutedChanged, this, &MFPlayerSession::setMuted);
- }
-}
-
-void MFPlayerSession::updateOutputRouting()
-{
- int currentAudioTrack = m_trackInfo[QPlatformMediaPlayer::AudioStream].currentIndex;
- if (currentAudioTrack > -1)
- setActiveTrack(QPlatformMediaPlayer::AudioStream, currentAudioTrack);
-}
-
-void MFPlayerSession::setVideoSink(QVideoSink *sink)
-{
- m_videoRendererControl->setSink(sink);
-}
-
-void MFPlayerSession::setActiveTrack(QPlatformMediaPlayer::TrackType type, int index)
-{
- if (!m_session)
- return;
-
- // Only audio track selection is currently supported.
- if (type != QPlatformMediaPlayer::AudioStream)
- return;
-
- const auto &nativeIndexes = m_trackInfo[type].nativeIndexes;
-
- if (index < -1 || index >= nativeIndexes.count())
- return;
-
- IMFTopology *topology = nullptr;
-
- if (SUCCEEDED(m_session->GetFullTopology(MFSESSION_GETFULLTOPOLOGY_CURRENT, 0, &topology))) {
-
- m_restorePosition = position() * 10000;
-
- if (m_state.command == CmdStart)
- stop();
-
- if (m_trackInfo[type].outputNodeId != -1) {
- IMFTopologyNode *node = nullptr;
- if (SUCCEEDED(topology->GetNodeByID(m_trackInfo[type].outputNodeId, &node))) {
- topology->RemoveNode(node);
- node->Release();
- m_trackInfo[type].outputNodeId = -1;
- }
- }
- if (m_trackInfo[type].sourceNodeId != -1) {
- IMFTopologyNode *node = nullptr;
- if (SUCCEEDED(topology->GetNodeByID(m_trackInfo[type].sourceNodeId, &node))) {
- topology->RemoveNode(node);
- node->Release();
- m_trackInfo[type].sourceNodeId = -1;
- }
- }
-
- IMFMediaSource *mediaSource = m_sourceResolver->mediaSource();
-
- IMFPresentationDescriptor *sourcePD = nullptr;
- if (SUCCEEDED(mediaSource->CreatePresentationDescriptor(&sourcePD))) {
-
- if (m_trackInfo[type].currentIndex >= 0 && m_trackInfo[type].currentIndex < nativeIndexes.count())
- sourcePD->DeselectStream(nativeIndexes.at(m_trackInfo[type].currentIndex));
-
- m_trackInfo[type].currentIndex = index;
-
- if (index == -1) {
- m_session->SetTopology(MFSESSION_SETTOPOLOGY_IMMEDIATE, topology);
- } else {
- int nativeIndex = nativeIndexes.at(index);
- sourcePD->SelectStream(nativeIndex);
-
- IMFStreamDescriptor *streamDesc = nullptr;
- BOOL selected = FALSE;
-
- if (SUCCEEDED(sourcePD->GetStreamDescriptorByIndex(nativeIndex, &selected, &streamDesc))) {
- IMFTopologyNode *sourceNode = addSourceNode(topology, mediaSource, sourcePD, streamDesc);
- if (sourceNode) {
- IMFTopologyNode *outputNode = addOutputNode(MFPlayerSession::Audio, topology, 0);
- if (outputNode) {
- if (SUCCEEDED(sourceNode->ConnectOutput(0, outputNode, 0))) {
- sourceNode->GetTopoNodeID(&m_trackInfo[type].sourceNodeId);
- outputNode->GetTopoNodeID(&m_trackInfo[type].outputNodeId);
- m_session->SetTopology(MFSESSION_SETTOPOLOGY_IMMEDIATE, topology);
- }
- outputNode->Release();
- }
- sourceNode->Release();
- }
- streamDesc->Release();
- }
- }
- m_updatingTopology = true;
- sourcePD->Release();
- }
- topology->Release();
- }
-}
-
-int MFPlayerSession::activeTrack(QPlatformMediaPlayer::TrackType type)
-{
- if (type < 0 || type >= QPlatformMediaPlayer::NTrackTypes)
- return -1;
- return m_trackInfo[type].currentIndex;
-}
-
-int MFPlayerSession::trackCount(QPlatformMediaPlayer::TrackType type)
-{
- if (type < 0 || type >= QPlatformMediaPlayer::NTrackTypes)
- return -1;
- return m_trackInfo[type].metaData.count();
-}
-
-QMediaMetaData MFPlayerSession::trackMetaData(QPlatformMediaPlayer::TrackType type, int trackNumber)
-{
- if (type < 0 || type >= QPlatformMediaPlayer::NTrackTypes)
- return {};
-
- if (trackNumber < 0 || trackNumber >= m_trackInfo[type].metaData.count())
- return {};
-
- return m_trackInfo[type].metaData.at(trackNumber);
-}
-
diff --git a/src/multimedia/platform/windows/player/mfplayersession_p.h b/src/multimedia/platform/windows/player/mfplayersession_p.h
deleted file mode 100644
index 3aafedb86..000000000
--- a/src/multimedia/platform/windows/player/mfplayersession_p.h
+++ /dev/null
@@ -1,275 +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
-
-//
-// 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 <mfapi.h>
-#include <mfidl.h>
-
-#include "qmediaplayer.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/qvideoframeformat.h>
-#include <qaudiodevice.h>
-#include <qtimer.h>
-#include "mfplayercontrol_p.h"
-
-QT_BEGIN_NAMESPACE
-class QUrl;
-QT_END_NAMESPACE
-
-QT_USE_NAMESPACE
-
-class SourceResolver;
-class MFVideoRendererControl;
-class MFPlayerControl;
-class MFPlayerService;
-class AudioSampleGrabberCallback;
-class MFTransform;
-
-class MFPlayerSession : public QObject, public IMFAsyncCallback
-{
- Q_OBJECT
- friend class SourceResolver;
-public:
- MFPlayerSession(MFPlayerControl *playerControl = 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);
- float bufferProgress();
- QMediaTimeRange availablePlaybackRanges();
-
- void changeStatus(QMediaPlayer::MediaStatus newStatus);
-
- void close();
-
- void setAudioOutput(QPlatformAudioOutput *device);
-
- QMediaMetaData metaData() const { return m_metaData; }
-
- void setVideoSink(QVideoSink *sink);
-
- void setActiveTrack(QPlatformMediaPlayer::TrackType type, int index);
- int activeTrack(QPlatformMediaPlayer::TrackType type);
- int trackCount(QPlatformMediaPlayer::TrackType);
- QMediaMetaData trackMetaData(QPlatformMediaPlayer::TrackType type, int trackNumber);
-
- void statusChanged() { if (m_playerControl) m_playerControl->handleStatusChanged(); }
- void tracksChanged() { if (m_playerControl) m_playerControl->handleTracksChanged(); }
- void audioAvailable() { if (m_playerControl) m_playerControl->handleAudioAvailable(); }
- void videoAvailable() { if (m_playerControl) m_playerControl->handleVideoAvailable(); }
- void durationUpdate(qint64 duration) { if (m_playerControl) m_playerControl->handleDurationUpdate(duration); }
- void seekableUpdate(bool seekable) { if (m_playerControl) m_playerControl->handleSeekableUpdate(seekable); }
- void error(QMediaPlayer::Error error, QString errorString, bool isFatal) { if (m_playerControl) m_playerControl->handleError(error, errorString, isFatal); }
- void playbackRateChanged(qreal rate) { if (m_playerControl) m_playerControl->playbackRateChanged(rate); }
- void bufferProgressChanged(float percentFilled) { if (m_playerControl) m_playerControl->bufferProgressChanged(percentFilled); }
- void metaDataChanged() { if (m_playerControl) m_playerControl->metaDataChanged(); }
- void positionChanged(qint64 position) { if (m_playerControl) m_playerControl->positionChanged(position); }
-
-public Q_SLOTS:
- void setVolume(float volume);
- void setMuted(bool muted);
-
-Q_SIGNALS:
- void sessionEvent(IMFMediaEvent *sessionEvent);
-
-private Q_SLOTS:
- void handleMediaSourceReady();
- void handleSessionEvent(IMFMediaEvent *sessionEvent);
- void handleSourceError(long hr);
- void updateOutputRouting();
-
-private:
- long m_cRef;
- MFPlayerControl *m_playerControl = nullptr;
- MFVideoRendererControl *m_videoRendererControl = nullptr;
- IMFMediaSession *m_session;
- IMFPresentationClock *m_presentationClock;
- IMFRateControl *m_rateControl;
- IMFRateSupport *m_rateSupport;
- IMFAudioStreamVolume *m_volumeControl;
- IPropertyStore *m_netsourceStatistics;
- qint64 m_position = 0;
- qint64 m_restorePosition = -1;
- UINT64 m_duration = 0;
- bool m_updatingTopology = false;
-
- 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);
-
- struct TrackInfo
- {
- QList<QMediaMetaData> metaData;
- QList<int> nativeIndexes;
- int currentIndex = -1;
- TOPOID sourceNodeId = -1;
- TOPOID outputNodeId = -1;
- };
- TrackInfo m_trackInfo[QPlatformMediaPlayer::NTrackTypes];
-
- QMediaPlayer::MediaStatus m_status;
- bool m_canScrub;
- float m_volume = 1.;
- bool m_muted = false;
-
- QPlatformAudioOutput *m_audioOutput = nullptr;
- QMediaMetaData m_metaData;
-
- void setVolumeInternal(float volume);
-
- void createSession();
- void setupPlaybackTopology(IMFMediaSource *source, IMFPresentationDescriptor *sourcePD);
- bool getStreamInfo(IMFStreamDescriptor *stream, MFPlayerSession::MediaType *type, QString *name, QString *language) 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;
- // ### Below can be used to monitor the audio channel. Currently unused.
- AudioSampleGrabberCallback *m_audioSampleGrabber;
- IMFTopologyNode *m_audioSampleGrabberNode;
-
- IMFTopology *insertMFT(IMFTopology *topology, TOPOID outputNodeId);
- bool insertResizer(IMFTopology *topology);
- void insertColorConverter(IMFTopology *topology, TOPOID outputNodeId);
- // ### Below can be used to monitor the video channel. Functionality currently unused.
- MFTransform *m_videoProbeMFT;
-
- QTimer m_signalPositionChangeTimer;
-};
-
-
-#endif
diff --git a/src/multimedia/platform/windows/player/mftvideo.cpp b/src/multimedia/platform/windows/player/mftvideo.cpp
deleted file mode 100644
index 5028bd053..000000000
--- a/src/multimedia/platform/windows/player/mftvideo.cpp
+++ /dev/null
@@ -1,725 +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_p.h"
-#include <private/qmemoryvideobuffer_p.h>
-#include <private/qwindowsmultimediautils_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;
-}
-
-QVideoFrameFormat MFTransform::videoFormatForMFMediaType(IMFMediaType *mediaType, int *bytesPerLine)
-{
- UINT32 stride;
- if (FAILED(mediaType->GetUINT32(MF_MT_DEFAULT_STRIDE, &stride))) {
- *bytesPerLine = 0;
- return QVideoFrameFormat();
- }
-
- *bytesPerLine = (int)stride;
-
- QSize size;
- UINT32 width, height;
- if (FAILED(MFGetAttributeSize(mediaType, MF_MT_FRAME_SIZE, &width, &height)))
- return QVideoFrameFormat();
-
- size.setWidth(width);
- size.setHeight(height);
-
- GUID subtype = GUID_NULL;
- if (FAILED(mediaType->GetGUID(MF_MT_SUBTYPE, &subtype)))
- return QVideoFrameFormat();
-
- QVideoFrameFormat::PixelFormat pixelFormat =
- QWindowsMultimediaUtils::pixelFormatFromMediaSubtype(subtype);
- QVideoFrameFormat format(size, pixelFormat);
-
- quint32 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);
-
- // 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/multimedia/platform/windows/player/mftvideo_p.h b/src/multimedia/platform/windows/player/mftvideo_p.h
deleted file mode 100644
index a8a0337cc..000000000
--- a/src/multimedia/platform/windows/player/mftvideo_p.h
+++ /dev/null
@@ -1,131 +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
-
-//
-// 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 <mfapi.h>
-#include <mfidl.h>
-#include <QtCore/qlist.h>
-#include <QtCore/qmutex.h>
-#include <QtMultimedia/qvideoframeformat.h>
-
-QT_USE_NAMESPACE
-
-class MFVideoProbeControl;
-
-QT_BEGIN_NAMESPACE
-class QVideoFrame;
-QT_END_NAMESPACE
-
-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 QVideoFrameFormat 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;
-
- QVideoFrameFormat m_format;
- int m_bytesPerLine;
-};
-
-#endif
diff --git a/src/multimedia/platform/windows/player/mfvideorenderercontrol.cpp b/src/multimedia/platform/windows/player/mfvideorenderercontrol.cpp
deleted file mode 100644
index a2a83d1cb..000000000
--- a/src/multimedia/platform/windows/player/mfvideorenderercontrol.cpp
+++ /dev/null
@@ -1,2318 +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_p.h"
-#include "mfactivate_p.h"
-
-#include "evrcustompresenter_p.h"
-
-#include <private/qplatformvideosink_p.h>
-#include <private/qabstractvideobuffer_p.h>
-#include <qvideosink.h>
-#include <qvideoframeformat.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(QVideoFrame::NoHandle)
- , m_buffer(buffer)
- , m_bytesPerLine(bytesPerLine)
- , m_mapMode(QVideoFrame::NotMapped)
- {
- buffer->AddRef();
- }
-
- ~MediaSampleVideoBuffer()
- {
- m_buffer->Release();
- }
-
- MapData map(QVideoFrame::MapMode mode) override
- {
- MapData mapData;
- if (m_mapMode == QVideoFrame::NotMapped && mode != QVideoFrame::NotMapped) {
- BYTE *bytes;
- DWORD length;
- HRESULT hr = m_buffer->Lock(&bytes, NULL, &length);
- if (SUCCEEDED(hr)) {
- mapData.nPlanes = 1;
- mapData.bytesPerLine[0] = m_bytesPerLine;
- mapData.data[0] = reinterpret_cast<uchar *>(bytes);
- mapData.size[0] = qsizetype(length);
- m_mapMode = mode;
- } else {
- qWarning("Faild to lock mf buffer!");
- }
- }
- return mapData;
- }
-
- void unmap() override
- {
- if (m_mapMode == QVideoFrame::NotMapped)
- return;
- m_mapMode = QVideoFrame::NotMapped;
- m_buffer->Unlock();
- }
-
- QVideoFrame::MapMode mapMode() const override
- {
- return m_mapMode;
- }
-
- private:
- IMFMediaBuffer *m_buffer;
- int m_bytesPerLine;
- QVideoFrame::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_videoSink(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));
- QVideoFrameFormat 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 setSink(QVideoSink *sink)
- {
- m_mutex.lock();
- m_videoSink = sink;
- 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_videoSink)
- return;
- for (int f = 0; f < QVideoFrameFormat::NPixelFormats; ++f) {
- QVideoFrameFormat::PixelFormat format = QVideoFrameFormat::PixelFormat(f);
- 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 QVideoFrameFormat::Format_BGRA8888:
- case QVideoFrameFormat::Format_BGRA8888_Premultiplied:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_ARGB32);
- break;
- case QVideoFrameFormat::Format_BGRX8888:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32);
- break;
- case QVideoFrameFormat::Format_AYUV:
- case QVideoFrameFormat::Format_AYUV_Premultiplied:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_AYUV);
- break;
- case QVideoFrameFormat::Format_YUV420P:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_I420);
- break;
- case QVideoFrameFormat::Format_UYVY:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_UYVY);
- break;
- case QVideoFrameFormat::Format_YV12:
- mediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YV12);
- break;
- case QVideoFrameFormat::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);
- frame.setStartTime(m_bufferStartTime * 0.1);
- frame.setEndTime((m_bufferStartTime + m_bufferDuration) * 0.1);
- m_videoSink->platformVideoSink()->setVideoFrame(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
- {
- 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:
- HRESULT m_startResult;
-
- private:
- 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<QVideoFrameFormat::PixelFormat> m_pixelFormats;
- int m_currentFormatIndex;
- int m_bytesPerLine;
- QVideoFrameFormat m_surfaceFormat;
- QVideoSink *m_videoSink;
- 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 QVideoFrameFormat &format)
- {
- switch (format.pixelFormat()) {
- // 32 bpp packed formats.
- case QVideoFrameFormat::Format_XBGR8888:
- case QVideoFrameFormat::Format_BGRX8888:
- case QVideoFrameFormat::Format_XRGB8888:
- case QVideoFrameFormat::Format_RGBX8888:
- case QVideoFrameFormat::Format_AYUV:
- return format.frameWidth() * 4;
- // 16 bpp packed formats.
- case QVideoFrameFormat::Format_YUYV:
- case QVideoFrameFormat::Format_UYVY:
- return PAD_TO_DWORD(format.frameWidth() * 2);
- // Planar formats.
- case QVideoFrameFormat::Format_IMC1:
- case QVideoFrameFormat::Format_IMC2:
- case QVideoFrameFormat::Format_IMC3:
- case QVideoFrameFormat::Format_IMC4:
- case QVideoFrameFormat::Format_YV12:
- case QVideoFrameFormat::Format_NV12:
- case QVideoFrameFormat::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);
- 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);
- 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, &currentTime, &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(QVideoSink *surface)
- {
- QMutexLocker locker(&m_mutex);
- if (m_shutdown)
- return;
- m_stream->setSink(surface);
- }
-
- 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_videoSink(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_videoSink)
- m_sink->setSurface(m_videoSink);
- }
- 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 setSink(QVideoSink *sink)
- {
- QMutexLocker locker(&m_mutex);
- if (m_videoSink == sink)
- return;
-
- m_videoSink = sink;
-
- if (!m_sink)
- return;
- m_sink->setSurface(m_videoSink);
- }
-
- 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;
- QVideoSink *m_videoSink;
- QMutex m_mutex;
- };
-}
-
-
-class EVRCustomPresenterActivate : public MFAbstractActivate
-{
-public:
- EVRCustomPresenterActivate();
- ~EVRCustomPresenterActivate()
- { }
-
- STDMETHODIMP ActivateObject(REFIID riid, void **ppv);
- STDMETHODIMP ShutdownObject();
- STDMETHODIMP DetachObject();
-
- void setSink(QVideoSink *sink);
-
-private:
- EVRCustomPresenter *m_presenter;
- QVideoSink *m_videoSink;
- QMutex m_mutex;
-};
-
-
-MFVideoRendererControl::MFVideoRendererControl(QObject *parent)
- : QObject(parent)
-{
-}
-
-MFVideoRendererControl::~MFVideoRendererControl()
-{
- clear();
-}
-
-void MFVideoRendererControl::clear()
-{
- if (m_sink)
- m_sink->platformVideoSink()->setVideoFrame(QVideoFrame());
-
- 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();
-}
-
-QVideoSink *MFVideoRendererControl::sink() const
-{
- return m_sink;
-}
-
-void MFVideoRendererControl::setSink(QVideoSink *sink)
-{
- m_sink = sink;
-
- if (m_presenterActivate)
- m_presenterActivate->setSink(m_sink);
- else if (m_currentActivate)
- static_cast<VideoRendererActivate*>(m_currentActivate)->setSink(m_sink);
-}
-
-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;
- }
- QObject::customEvent(event);
-}
-
-void MFVideoRendererControl::present()
-{
- if (m_presenterActivate)
- return;
-
- if (m_currentActivate)
- static_cast<VideoRendererActivate*>(m_currentActivate)->present();
-}
-
-IMFActivate* MFVideoRendererControl::createActivate()
-{
- clear();
-
- if (m_sink) {
- // 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);
- }
- }
-
- setSink(m_sink);
-
- return m_currentActivate;
-}
-
-
-EVRCustomPresenterActivate::EVRCustomPresenterActivate()
- : MFAbstractActivate()
- , m_presenter(0)
- , m_videoSink(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_videoSink)
- m_presenter->setSink(m_videoSink);
- }
- 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::setSink(QVideoSink *sink)
-{
- QMutexLocker locker(&m_mutex);
- if (m_videoSink == sink)
- return;
-
- m_videoSink = sink;
-
- if (m_presenter)
- m_presenter->setSink(sink);
-}
-
-#include "moc_mfvideorenderercontrol_p.cpp"
-#include "mfvideorenderercontrol.moc"
diff --git a/src/multimedia/platform/windows/player/mfvideorenderercontrol_p.h b/src/multimedia/platform/windows/player/mfvideorenderercontrol_p.h
deleted file mode 100644
index b4bb2d92d..000000000
--- a/src/multimedia/platform/windows/player/mfvideorenderercontrol_p.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 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
-
-//
-// 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 "qobject.h"
-#include <mfapi.h>
-#include <mfidl.h>
-
-QT_USE_NAMESPACE
-
-class EVRCustomPresenterActivate;
-
-QT_BEGIN_NAMESPACE
-class QVideoSink;
-QT_END_NAMESPACE
-
-class MFVideoRendererControl : public QObject
-{
- Q_OBJECT
-public:
- MFVideoRendererControl(QObject *parent = 0);
- ~MFVideoRendererControl();
-
- QVideoSink *sink() const;
- void setSink(QVideoSink *surface);
-
- IMFActivate* createActivate();
- void releaseActivate();
-
-protected:
- void customEvent(QEvent *event);
-
-private Q_SLOTS:
- void present();
-
-private:
- void clear();
-
- QVideoSink *m_sink = nullptr;
- IMFActivate *m_currentActivate = nullptr;
- IMFSampleGrabberSinkCallback *m_callback = nullptr;
-
- EVRCustomPresenterActivate *m_presenterActivate = nullptr;
-};
-
-#endif
diff --git a/src/multimedia/platform/windows/player/samplegrabber.cpp b/src/multimedia/platform/windows/player/samplegrabber.cpp
deleted file mode 100644
index ef039a902..000000000
--- a/src/multimedia/platform/windows/player/samplegrabber.cpp
+++ /dev/null
@@ -1,172 +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_p.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/multimedia/platform/windows/player/samplegrabber_p.h b/src/multimedia/platform/windows/player/samplegrabber_p.h
deleted file mode 100644
index 31e00987c..000000000
--- a/src/multimedia/platform/windows/player/samplegrabber_p.h
+++ /dev/null
@@ -1,103 +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
-
-//
-// 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 <QtCore/qmutex.h>
-#include <QtCore/qlist.h>
-#include <QtMultimedia/qaudioformat.h>
-#include <mfapi.h>
-#include <mfidl.h>
-
-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 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/multimedia/platform/windows/qwindowsformatinfo.cpp b/src/multimedia/platform/windows/qwindowsformatinfo.cpp
deleted file mode 100644
index 85c362b29..000000000
--- a/src/multimedia/platform/windows/qwindowsformatinfo.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwindowsformatinfo_p.h"
-
-
-QT_BEGIN_NAMESPACE
-
-QWindowsFormatInfo::QWindowsFormatInfo()
-{
- decoders = {
- { QMediaFormat::MPEG4,
- { QMediaFormat::AudioCodec::AAC, QMediaFormat::AudioCodec::MP3, QMediaFormat::AudioCodec::ALAC, QMediaFormat::AudioCodec::AC3, QMediaFormat::AudioCodec::EAC3, },
- { QMediaFormat::VideoCodec::H264, QMediaFormat::VideoCodec::H265, QMediaFormat::VideoCodec::MotionJPEG } },
- { QMediaFormat::QuickTime,
- { QMediaFormat::AudioCodec::AAC, QMediaFormat::AudioCodec::MP3, QMediaFormat::AudioCodec::ALAC, QMediaFormat::AudioCodec::AC3, QMediaFormat::AudioCodec::EAC3, },
- { QMediaFormat::VideoCodec::H264, QMediaFormat::VideoCodec::H265, QMediaFormat::VideoCodec::MotionJPEG } },
- { QMediaFormat::AAC,
- { QMediaFormat::AudioCodec::AAC },
- {} },
- { QMediaFormat::MP3,
- { QMediaFormat::AudioCodec::MP3 },
- {} },
- { QMediaFormat::FLAC,
- { QMediaFormat::AudioCodec::FLAC },
- {} },
- { QMediaFormat::Mpeg4Audio,
- { QMediaFormat::AudioCodec::AAC },
- {} },
- { QMediaFormat::WMA,
- { QMediaFormat::AudioCodec::WMA },
- {} },
- { QMediaFormat::WMV,
- { QMediaFormat::AudioCodec::WMA },
- { QMediaFormat::VideoCodec::WMV } }
- };
-
- encoders = {
- { QMediaFormat::MPEG4,
- { QMediaFormat::AudioCodec::AAC, QMediaFormat::AudioCodec::MP3 },
- { QMediaFormat::VideoCodec::H264 } },
- { QMediaFormat::AAC,
- { QMediaFormat::AudioCodec::AAC },
- {} },
- { QMediaFormat::MP3,
- { QMediaFormat::AudioCodec::MP3 },
- {} },
- { QMediaFormat::Mpeg4Audio,
- { QMediaFormat::AudioCodec::AAC },
- {} },
- { QMediaFormat::WMA,
- { QMediaFormat::AudioCodec::WMA },
- {} },
- { QMediaFormat::WMV,
- { QMediaFormat::AudioCodec::WMA },
- { QMediaFormat::VideoCodec::WMV } }
- };
-
- // ####
- imageFormats = { QImageCapture::JPEG, QImageCapture::PNG };
-
-}
-
-QWindowsFormatInfo::~QWindowsFormatInfo()
-{
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/qwindowsformatinfo_p.h b/src/multimedia/platform/windows/qwindowsformatinfo_p.h
deleted file mode 100644
index 355aea7d7..000000000
--- a/src/multimedia/platform/windows/qwindowsformatinfo_p.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWINDOWSFORMATSINFO_H
-#define QWINDOWSFORMATSINFO_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 <private/qplatformmediaformatinfo_p.h>
-#include <qhash.h>
-#include <qlist.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsFormatInfo : public QPlatformMediaFormatInfo
-{
-public:
- QWindowsFormatInfo();
- ~QWindowsFormatInfo();
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/windows/qwindowsintegration.cpp b/src/multimedia/platform/windows/qwindowsintegration.cpp
deleted file mode 100644
index b224a8937..000000000
--- a/src/multimedia/platform/windows/qwindowsintegration.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwindowsintegration_p.h"
-#include <private/qwindowsmediadevices_p.h>
-#include <private/qwindowsformatinfo_p.h>
-#include <private/qwindowsmediacapture_p.h>
-#include <private/qwindowsimagecapture_p.h>
-#include <private/qwindowscamera_p.h>
-#include <private/qwindowsmediaencoder_p.h>
-#include <private/mfplayercontrol_p.h>
-#include <private/mfaudiodecodercontrol_p.h>
-#include <private/mfevrvideowindowcontrol_p.h>
-
-QT_BEGIN_NAMESPACE
-
-static int g_refCount = 0;
-
-QWindowsMediaIntegration::QWindowsMediaIntegration()
-{
- g_refCount++;
- if (g_refCount == 1) {
- CoInitialize(NULL);
- MFStartup(MF_VERSION);
- }
-}
-
-QWindowsMediaIntegration::~QWindowsMediaIntegration()
-{
- delete m_devices;
- delete m_formatInfo;
-
- g_refCount--;
- if (g_refCount == 0) {
- // ### This currently crashes on exit
-// MFShutdown();
-// CoUninitialize();
- }
-}
-
-QPlatformMediaDevices *QWindowsMediaIntegration::devices()
-{
- if (!m_devices)
- m_devices = new QWindowsMediaDevices();
- return m_devices;
-}
-
-QPlatformMediaFormatInfo *QWindowsMediaIntegration::formatInfo()
-{
- if (!m_formatInfo)
- m_formatInfo = new QWindowsFormatInfo();
- return m_formatInfo;
-}
-
-QPlatformMediaCaptureSession *QWindowsMediaIntegration::createCaptureSession()
-{
- return new QWindowsMediaCaptureService();
-}
-
-QPlatformAudioDecoder *QWindowsMediaIntegration::createAudioDecoder(QAudioDecoder *decoder)
-{
- return new MFAudioDecoderControl(decoder);
-}
-
-QPlatformMediaPlayer *QWindowsMediaIntegration::createPlayer(QMediaPlayer *parent)
-{
- return new MFPlayerControl(parent);
-}
-
-QPlatformCamera *QWindowsMediaIntegration::createCamera(QCamera *camera)
-{
- return new QWindowsCamera(camera);
-}
-
-QPlatformMediaEncoder *QWindowsMediaIntegration::createEncoder(QMediaRecorder *encoder)
-{
- return new QWindowsMediaEncoder(encoder);
-}
-
-QPlatformImageCapture *QWindowsMediaIntegration::createImageCapture(QImageCapture *imageCapture)
-{
- return new QWindowsImageCapture(imageCapture);
-}
-
-QPlatformVideoSink *QWindowsMediaIntegration::createVideoSink(QVideoSink *sink)
-{
- return new MFEvrVideoWindowControl(sink);
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/qwindowsintegration_p.h b/src/multimedia/platform/windows/qwindowsintegration_p.h
deleted file mode 100644
index 835d502c1..000000000
--- a/src/multimedia/platform/windows/qwindowsintegration_p.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWINDOWSINTEGRATION_H
-#define QWINDOWSINTEGRATION_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 <private/qplatformmediaintegration_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsMediaDevices;
-class QWindowsFormatInfo;
-
-class QWindowsMediaIntegration : public QPlatformMediaIntegration
-{
-public:
- QWindowsMediaIntegration();
- ~QWindowsMediaIntegration();
-
- void addRefCount();
- void releaseRefCount();
-
- QPlatformMediaDevices *devices() override;
- QPlatformMediaFormatInfo *formatInfo() override;
-
- QPlatformMediaCaptureSession *createCaptureSession() override;
-
- QPlatformAudioDecoder *createAudioDecoder(QAudioDecoder *decoder) override;
- QPlatformMediaPlayer *createPlayer(QMediaPlayer *parent) override;
- QPlatformCamera *createCamera(QCamera *camera) override;
- QPlatformMediaEncoder *createEncoder(QMediaRecorder *encoder) override;
- QPlatformImageCapture *createImageCapture(QImageCapture *imageCapture) override;
-
- QPlatformVideoSink *createVideoSink(QVideoSink *sink) override;
-
- QWindowsMediaDevices *m_devices = nullptr;
- QWindowsFormatInfo *m_formatInfo = nullptr;
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/windows/qwindowsmediadevices.cpp b/src/multimedia/platform/windows/qwindowsmediadevices.cpp
deleted file mode 100644
index 2b1a74a44..000000000
--- a/src/multimedia/platform/windows/qwindowsmediadevices.cpp
+++ /dev/null
@@ -1,532 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 "qwindowsmediadevices_p.h"
-#include "qmediadevices.h"
-#include "qcameradevice_p.h"
-#include "qvarlengtharray.h"
-
-#include "private/qwindowsaudiosource_p.h"
-#include "private/qwindowsaudiosink_p.h"
-#include "private/qwindowsaudiodevice_p.h"
-#include "private/qwindowsmultimediautils_p.h"
-
-#include <private/mftvideo_p.h>
-
-#include <Dbt.h>
-#include <ks.h>
-
-#include <mmsystem.h>
-#include <mmddk.h>
-#include <mfapi.h>
-#include <mfobjects.h>
-#include <mfidl.h>
-#include <mfreadwrite.h>
-#include <Mferror.h>
-#include <mmdeviceapi.h>
-#include <Functiondiscoverykeys_devpkey.h>
-#include "private/qwindowsaudioutils_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class CMMNotificationClient : public IMMNotificationClient
-{
- LONG m_cRef;
- QWindowsIUPointer<IMMDeviceEnumerator> m_enumerator;
- QWindowsMediaDevices *m_windowsMediaDevices;
- QMap<QString, DWORD> m_deviceState;
-
-public:
- CMMNotificationClient(QWindowsMediaDevices *windowsMediaDevices,
- QWindowsIUPointer<IMMDeviceEnumerator> enumerator,
- QMap<QString, DWORD> &&deviceState) :
- m_cRef(1),
- m_enumerator(enumerator),
- m_windowsMediaDevices(windowsMediaDevices),
- m_deviceState(deviceState)
- {}
-
- virtual ~CMMNotificationClient() {}
-
- // IUnknown methods -- AddRef, Release, and QueryInterface
- ULONG STDMETHODCALLTYPE AddRef()
- {
- return InterlockedIncrement(&m_cRef);
- }
-
- ULONG STDMETHODCALLTYPE Release()
- {
- ULONG ulRef = InterlockedDecrement(&m_cRef);
- if (0 == ulRef) {
- delete this;
- }
- return ulRef;
- }
-
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID **ppvInterface)
- {
- if (IID_IUnknown == riid) {
- AddRef();
- *ppvInterface = (IUnknown*)this;
- } else if (__uuidof(IMMNotificationClient) == riid) {
- AddRef();
- *ppvInterface = (IMMNotificationClient*)this;
- } else {
- *ppvInterface = NULL;
- return E_NOINTERFACE;
- }
- return S_OK;
- }
-
- HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR)
- {
- if (role == ERole::eMultimedia)
- emitAudioDevicesChanged(flow);
-
- return S_OK;
- }
-
- HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR deviceID)
- {
- auto it = m_deviceState.find(QString::fromWCharArray(deviceID));
- if (it == std::end(m_deviceState)) {
- m_deviceState.insert(QString::fromWCharArray(deviceID), DEVICE_STATE_ACTIVE);
- emitAudioDevicesChanged(deviceID);
- }
-
- return S_OK;
- };
-
- HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR deviceID)
- {
- auto key = QString::fromWCharArray(deviceID);
- auto it = m_deviceState.find(key);
- if (it != std::end(m_deviceState)) {
- if (it.value() == DEVICE_STATE_ACTIVE)
- emitAudioDevicesChanged(deviceID);
- m_deviceState.remove(key);
- }
-
- return S_OK;
- }
-
- HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR deviceID, DWORD newState)
- {
- if (auto it = m_deviceState.find(QString::fromWCharArray(deviceID)); it != std::end(m_deviceState)) {
- // If either the old state or the new state is active emit device change
- if ((it.value() == DEVICE_STATE_ACTIVE) != (newState == DEVICE_STATE_ACTIVE)) {
- emitAudioDevicesChanged(deviceID);
- }
- it.value() = newState;
- }
-
- return S_OK;
- }
-
- HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(LPCWSTR, const PROPERTYKEY)
- {
- return S_OK;
- }
-
- void emitAudioDevicesChanged(EDataFlow flow)
- {
- // windowsMediaDevice may be deleted as we are executing the callback
- if (flow == EDataFlow::eCapture) {
- m_windowsMediaDevices->audioInputsChanged();
- } else if (flow == EDataFlow::eRender) {
- m_windowsMediaDevices->audioOutputsChanged();
- }
- }
-
- void emitAudioDevicesChanged(LPCWSTR deviceID)
- {
- QWindowsIUPointer<IMMDevice> device;
- QWindowsIUPointer<IMMEndpoint> endpoint;
- EDataFlow flow;
-
- if (SUCCEEDED(m_enumerator->GetDevice(deviceID, device.address()))
- && SUCCEEDED(device->QueryInterface(__uuidof(IMMEndpoint), (void**)endpoint.address()))
- && SUCCEEDED(endpoint->GetDataFlow(&flow)))
- {
- emitAudioDevicesChanged(flow);
- }
- }
-};
-
-LRESULT deviceNotificationWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- if (message == WM_DEVICECHANGE) {
- auto b = (PDEV_BROADCAST_HDR)lParam;
- if (b && b->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
- auto wmd = reinterpret_cast<QWindowsMediaDevices *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
-
- if (wmd) {
- if (wParam == DBT_DEVICEARRIVAL) {
- wmd->videoInputsChanged();
- } else if (wParam == DBT_DEVICEREMOVECOMPLETE) {
- wmd->videoInputsChanged();
- }
- }
- }
- }
-
- return 1;
-}
-
-static const auto windowClassName = TEXT("QWindowsMediaDevicesMessageWindow");
-
-HWND createMessageOnlyWindow()
-{
- WNDCLASSEX wx = {};
- wx.cbSize = sizeof(WNDCLASSEX);
- wx.lpfnWndProc = deviceNotificationWndProc;
- wx.hInstance = GetModuleHandle(nullptr);
- wx.lpszClassName = windowClassName;
-
- if (!RegisterClassEx(&wx))
- return nullptr;
-
- auto hwnd = CreateWindowEx(0, windowClassName, TEXT("Message"),
- 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, nullptr);
- if (!hwnd) {
- UnregisterClass(windowClassName, GetModuleHandle(nullptr));
- return nullptr;
- }
-
- return hwnd;
-}
-
-QWindowsMediaDevices::QWindowsMediaDevices()
- : QPlatformMediaDevices(),
- m_videoDeviceMsgWindow(nullptr),
- m_videoDeviceNotification(nullptr)
-
-{
- CoInitialize(nullptr);
-
- auto hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr,
- CLSCTX_INPROC_SERVER,__uuidof(IMMDeviceEnumerator),
- (void**)&m_deviceEnumerator);
-
- if (SUCCEEDED(hr)) {
- QMap<QString, DWORD> devState;
- QWindowsIUPointer<IMMDeviceCollection> devColl;
- UINT count = 0;
-
- if (SUCCEEDED(m_deviceEnumerator->EnumAudioEndpoints(EDataFlow::eAll, DEVICE_STATEMASK_ALL, devColl.address()))
- && SUCCEEDED(devColl->GetCount(&count)))
- {
- for (UINT i = 0; i < count; i++) {
- QWindowsIUPointer<IMMDevice> device;
- DWORD state = 0;
- LPWSTR id = nullptr;
-
- if (SUCCEEDED(devColl->Item(i, device.address()))
- && SUCCEEDED(device->GetState(&state))
- && SUCCEEDED(device->GetId(&id)))
- {
- devState.insert(QString::fromWCharArray(id), state);
- CoTaskMemFree(id);
- }
- }
- }
-
-
- m_notificationClient.reset(new CMMNotificationClient(this, m_deviceEnumerator, std::move(devState)));
- m_deviceEnumerator->RegisterEndpointNotificationCallback(m_notificationClient);
-
- } else {
- qWarning() << "Audio device change notification disabled";
- }
-
- m_videoDeviceMsgWindow = createMessageOnlyWindow();
- if (m_videoDeviceMsgWindow) {
- SetWindowLongPtr(m_videoDeviceMsgWindow, GWLP_USERDATA, (LONG_PTR)this);
-
- DEV_BROADCAST_DEVICEINTERFACE di = { 0 };
- di.dbcc_size = sizeof(di);
- di.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
- di.dbcc_classguid = KSCATEGORY_VIDEO_CAMERA;
-
- m_videoDeviceNotification =
- RegisterDeviceNotification(m_videoDeviceMsgWindow, &di, DEVICE_NOTIFY_WINDOW_HANDLE);
- if (!m_videoDeviceNotification) {
- DestroyWindow(m_videoDeviceMsgWindow);
- m_videoDeviceMsgWindow = nullptr;
-
- UnregisterClass(windowClassName, GetModuleHandle(nullptr));
- }
- }
-
- if (!m_videoDeviceNotification) {
- qWarning() << "Video device change notification disabled";
- }
-}
-
-QWindowsMediaDevices::~QWindowsMediaDevices()
-{
- if (m_deviceEnumerator) {
- m_deviceEnumerator->UnregisterEndpointNotificationCallback(m_notificationClient);
- }
-
- m_deviceEnumerator.reset();
- m_notificationClient.reset();
-
- if (m_videoDeviceNotification) {
- UnregisterDeviceNotification(m_videoDeviceNotification);
- }
-
- if (m_videoDeviceMsgWindow) {
- DestroyWindow(m_videoDeviceMsgWindow);
- UnregisterClass(windowClassName, GetModuleHandle(nullptr));
- }
-
- CoUninitialize();
-}
-
-QList<QAudioDevice> QWindowsMediaDevices::availableDevices(QAudioDevice::Mode mode) const
-{
- const auto audioOut = mode == QAudioDevice::Output;
-
- const auto defaultAudioDeviceID = [this, audioOut]{
- const auto dataFlow = audioOut ? EDataFlow::eRender : EDataFlow::eCapture;
- QWindowsIUPointer<IMMDevice> dev;
- LPWSTR id = nullptr;
- QString sid;
-
- if (SUCCEEDED(m_deviceEnumerator->GetDefaultAudioEndpoint(dataFlow, ERole::eMultimedia, dev.address()))
- && SUCCEEDED(dev->GetId(&id))) {
- sid = QString::fromWCharArray(id);
- CoTaskMemFree(id);
- }
- return sid.toUtf8();
- }();
-
- QList<QAudioDevice> devices;
-
- auto waveDevices = audioOut ? waveOutGetNumDevs() : waveInGetNumDevs();
-
- for (auto waveID = 0u; waveID < waveDevices; waveID++) {
- auto wave = IntToPtr(waveID);
- auto waveMessage = [wave, audioOut](UINT msg, auto p0, auto p1) {
- return audioOut ? waveOutMessage((HWAVEOUT)wave, msg, (DWORD_PTR)p0, (DWORD_PTR)p1)
- : waveInMessage((HWAVEIN)wave, msg, (DWORD_PTR)p0, (DWORD_PTR)p1);
- };
-
- size_t len = 0;
- if (waveMessage(DRV_QUERYFUNCTIONINSTANCEIDSIZE, &len, 0) != MMSYSERR_NOERROR)
- continue;
-
- QVarLengthArray<WCHAR> id(len);
- if (waveMessage(DRV_QUERYFUNCTIONINSTANCEID, id.data(), len) != MMSYSERR_NOERROR)
- continue;
-
- QWindowsIUPointer<IMMDevice> device;
- QWindowsIUPointer<IPropertyStore> props;
- if (FAILED(m_deviceEnumerator->GetDevice(id.data(), device.address()))
- || FAILED(device->OpenPropertyStore(STGM_READ, props.address()))) {
- continue;
- }
-
- PROPVARIANT varName;
- PropVariantInit(&varName);
-
- if (SUCCEEDED(props->GetValue(PKEY_Device_FriendlyName, &varName))) {
- auto description = QString::fromWCharArray(varName.pwszVal);
- auto strID = QString::fromWCharArray(id.data()).toUtf8();
-
- auto dev = new QWindowsAudioDeviceInfo(strID, waveID, description, mode);
- dev->isDefault = strID == defaultAudioDeviceID;
-
- devices.append(dev->create());
- }
- PropVariantClear(&varName);
- }
-
- return devices;
-}
-
-QList<QAudioDevice> QWindowsMediaDevices::audioInputs() const
-{
- return availableDevices(QAudioDevice::Input);
-}
-
-QList<QAudioDevice> QWindowsMediaDevices::audioOutputs() const
-{
- return availableDevices(QAudioDevice::Output);
-}
-
-QList<QCameraDevice> QWindowsMediaDevices::videoInputs() const
-{
- QList<QCameraDevice> cameras;
-
- IMFAttributes *pAttributes = NULL;
- IMFActivate **ppDevices = NULL;
-
- // Create an attribute store to specify the enumeration parameters.
- HRESULT hr = MFCreateAttributes(&pAttributes, 1);
- if (SUCCEEDED(hr)) {
- // Source type: video capture devices
- hr = pAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
- MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
-
- if (SUCCEEDED(hr)) {
- // Enumerate devices.
- UINT32 count;
- hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
- if (SUCCEEDED(hr)) {
- // Iterate through devices.
- for (int index = 0; index < int(count); index++) {
- QCameraDevicePrivate *info = new QCameraDevicePrivate;
-
- IMFMediaSource *pSource = NULL;
- IMFSourceReader *reader = NULL;
-
- WCHAR *deviceName = NULL;
- UINT32 deviceNameLength = 0;
- UINT32 deviceIdLength = 0;
- WCHAR *deviceId = NULL;
-
- hr = ppDevices[index]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,
- &deviceName, &deviceNameLength);
- if (SUCCEEDED(hr))
- info->description = QString::fromWCharArray(deviceName);
- CoTaskMemFree(deviceName);
-
- hr = ppDevices[index]->GetAllocatedString(
- MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &deviceId,
- &deviceIdLength);
- if (SUCCEEDED(hr))
- info->id = QString::fromWCharArray(deviceId).toUtf8();
- CoTaskMemFree(deviceId);
-
- // Create the media source object.
- hr = ppDevices[index]->ActivateObject(
- IID_PPV_ARGS(&pSource));
- // Create the media source reader.
- hr = MFCreateSourceReaderFromMediaSource(pSource, NULL, &reader);
- if (SUCCEEDED(hr)) {
- QList<QSize> photoResolutions;
- QList<QCameraFormat> videoFormats;
-
- DWORD dwMediaTypeIndex = 0;
- IMFMediaType *mediaFormat = NULL;
- GUID subtype = GUID_NULL;
- HRESULT mediaFormatResult = S_OK;
-
- UINT32 frameRateMin = 0u;
- UINT32 frameRateMax = 0u;
- UINT32 denominator = 0u;
- DWORD index = 0u;
- UINT32 width = 0u;
- UINT32 height = 0u;
-
- while (SUCCEEDED(mediaFormatResult)) {
- // Loop through the supported formats for the video device
- mediaFormatResult = reader->GetNativeMediaType(
- (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, dwMediaTypeIndex,
- &mediaFormat);
- if (mediaFormatResult == MF_E_NO_MORE_TYPES)
- break;
- else if (SUCCEEDED(mediaFormatResult)) {
- QVideoFrameFormat::PixelFormat pixelFormat = QVideoFrameFormat::Format_Invalid;
- QSize resolution;
- float minFr = .0;
- float maxFr = .0;
-
- if (SUCCEEDED(mediaFormat->GetGUID(MF_MT_SUBTYPE, &subtype)))
- pixelFormat = QWindowsMultimediaUtils::pixelFormatFromMediaSubtype(subtype);
-
- if (SUCCEEDED(MFGetAttributeSize(mediaFormat, MF_MT_FRAME_SIZE, &width,
- &height))) {
- resolution.rheight() = (int)height;
- resolution.rwidth() = (int)width;
- photoResolutions << resolution;
- }
-
- if (SUCCEEDED(MFGetAttributeRatio(mediaFormat, MF_MT_FRAME_RATE_RANGE_MIN,
- &frameRateMin, &denominator)))
- minFr = qreal(frameRateMin) / denominator;
- if (SUCCEEDED(MFGetAttributeRatio(mediaFormat, MF_MT_FRAME_RATE_RANGE_MAX,
- &frameRateMax, &denominator)))
- maxFr = qreal(frameRateMax) / denominator;
-
- auto *f = new QCameraFormatPrivate { QSharedData(), pixelFormat,
- resolution, minFr, maxFr };
- videoFormats << f->create();
- }
- ++dwMediaTypeIndex;
- }
- if (mediaFormat)
- mediaFormat->Release();
-
- info->videoFormats = videoFormats;
- info->photoResolutions = photoResolutions;
- }
- if (reader)
- reader->Release();
- cameras.append(info->create());
- }
- }
- for (DWORD i = 0; i < count; i++) {
- if (ppDevices[i])
- ppDevices[i]->Release();
- }
- CoTaskMemFree(ppDevices);
- }
- }
- if (pAttributes)
- pAttributes->Release();
-
- return cameras;
-}
-
-QPlatformAudioSource *QWindowsMediaDevices::createAudioSource(const QAudioDevice &deviceInfo)
-{
- const auto *devInfo = static_cast<const QWindowsAudioDeviceInfo *>(deviceInfo.handle());
- return new QWindowsAudioSource(devInfo->waveId());
-}
-
-QPlatformAudioSink *QWindowsMediaDevices::createAudioSink(const QAudioDevice &deviceInfo)
-{
- const auto *devInfo = static_cast<const QWindowsAudioDeviceInfo *>(deviceInfo.handle());
- return new QWindowsAudioSink(devInfo->waveId());
-}
-
-QT_END_NAMESPACE
diff --git a/src/multimedia/platform/windows/qwindowsmediadevices_p.h b/src/multimedia/platform/windows/qwindowsmediadevices_p.h
deleted file mode 100644
index 29e214d79..000000000
--- a/src/multimedia/platform/windows/qwindowsmediadevices_p.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 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 QWINDOWSMEDIADEVICES_H
-#define QWINDOWSMEDIADEVICES_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 <private/qplatformmediadevices_p.h>
-#include <private/qwindowsiupointer_p.h>
-#include <qset.h>
-#include <qaudio.h>
-#include <qaudiodevice.h>
-#include <windows.h>
-
-struct IMMDeviceEnumerator;
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsEngine;
-class CMMNotificationClient;
-
-LRESULT deviceNotificationWndProc(HWND, UINT, WPARAM, LPARAM);
-
-class QWindowsMediaDevices : public QPlatformMediaDevices
-{
-public:
- QWindowsMediaDevices();
- virtual ~QWindowsMediaDevices();
-
- QList<QAudioDevice> audioInputs() const override;
- QList<QAudioDevice> audioOutputs() const override;
- QList<QCameraDevice> videoInputs() const override;
- QPlatformAudioSource *createAudioSource(const QAudioDevice &deviceInfo) override;
- QPlatformAudioSink *createAudioSink(const QAudioDevice &deviceInfo) override;
-
-private:
- QList<QAudioDevice> availableDevices(QAudioDevice::Mode mode) const;
-
- QWindowsIUPointer<IMMDeviceEnumerator> m_deviceEnumerator;
- QWindowsIUPointer<CMMNotificationClient> m_notificationClient;
- HWND m_videoDeviceMsgWindow;
- HDEVNOTIFY m_videoDeviceNotification;
-
- friend CMMNotificationClient;
- friend LRESULT deviceNotificationWndProc(HWND, UINT, WPARAM, LPARAM);
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/multimedia/platform/windows/sourceresolver.cpp b/src/multimedia/platform/windows/sourceresolver.cpp
deleted file mode 100644
index 93af15a74..000000000
--- a/src/multimedia/platform/windows/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_p.h"
-#include "sourceresolver_p.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/multimedia/platform/windows/sourceresolver_p.h b/src/multimedia/platform/windows/sourceresolver_p.h
deleted file mode 100644
index 07da1d8bd..000000000
--- a/src/multimedia/platform/windows/sourceresolver_p.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 SOURCERESOLVER_H
-#define SOURCERESOLVER_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 "mfstream_p.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