summaryrefslogtreecommitdiffstats
path: root/src/plugins/symbian
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/symbian')
-rw-r--r--src/plugins/symbian/ecam/camera_s60.pri157
-rw-r--r--src/plugins/symbian/ecam/ecam.pro40
-rw-r--r--src/plugins/symbian/ecam/s60audioencodercontrol.cpp159
-rw-r--r--src/plugins/symbian/ecam/s60audioencodercontrol.h90
-rw-r--r--src/plugins/symbian/ecam/s60cameraconstants.h257
-rw-r--r--src/plugins/symbian/ecam/s60cameracontrol.cpp983
-rw-r--r--src/plugins/symbian/ecam/s60cameracontrol.h178
-rw-r--r--src/plugins/symbian/ecam/s60cameraengine.cpp824
-rw-r--r--src/plugins/symbian/ecam/s60cameraengine.h407
-rw-r--r--src/plugins/symbian/ecam/s60cameraengineobserver.h178
-rw-r--r--src/plugins/symbian/ecam/s60cameraexposurecontrol.cpp584
-rw-r--r--src/plugins/symbian/ecam/s60cameraexposurecontrol.h138
-rw-r--r--src/plugins/symbian/ecam/s60cameraflashcontrol.cpp109
-rw-r--r--src/plugins/symbian/ecam/s60cameraflashcontrol.h93
-rw-r--r--src/plugins/symbian/ecam/s60camerafocuscontrol.cpp193
-rw-r--r--src/plugins/symbian/ecam/s60camerafocuscontrol.h112
-rw-r--r--src/plugins/symbian/ecam/s60cameraimagecapturecontrol.cpp124
-rw-r--r--src/plugins/symbian/ecam/s60cameraimagecapturecontrol.h99
-rw-r--r--src/plugins/symbian/ecam/s60cameraimageprocessingcontrol.cpp254
-rw-r--r--src/plugins/symbian/ecam/s60cameraimageprocessingcontrol.h118
-rw-r--r--src/plugins/symbian/ecam/s60cameralockscontrol.cpp263
-rw-r--r--src/plugins/symbian/ecam/s60cameralockscontrol.h115
-rw-r--r--src/plugins/symbian/ecam/s60cameraservice.cpp259
-rw-r--r--src/plugins/symbian/ecam/s60cameraservice.h111
-rw-r--r--src/plugins/symbian/ecam/s60cameraserviceplugin.cpp115
-rw-r--r--src/plugins/symbian/ecam/s60cameraserviceplugin.h81
-rw-r--r--src/plugins/symbian/ecam/s60camerasettings.cpp986
-rw-r--r--src/plugins/symbian/ecam/s60camerasettings.h177
-rw-r--r--src/plugins/symbian/ecam/s60cameraviewfinderengine.cpp789
-rw-r--r--src/plugins/symbian/ecam/s60cameraviewfinderengine.h182
-rw-r--r--src/plugins/symbian/ecam/s60imagecapturesession.cpp1884
-rw-r--r--src/plugins/symbian/ecam/s60imagecapturesession.h359
-rw-r--r--src/plugins/symbian/ecam/s60imageencodercontrol.cpp128
-rw-r--r--src/plugins/symbian/ecam/s60imageencodercontrol.h84
-rw-r--r--src/plugins/symbian/ecam/s60mediacontainercontrol.cpp97
-rw-r--r--src/plugins/symbian/ecam/s60mediacontainercontrol.h82
-rw-r--r--src/plugins/symbian/ecam/s60mediarecordercontrol.cpp187
-rw-r--r--src/plugins/symbian/ecam/s60mediarecordercontrol.h118
-rw-r--r--src/plugins/symbian/ecam/s60videocapturesession.cpp2995
-rw-r--r--src/plugins/symbian/ecam/s60videocapturesession.h414
-rw-r--r--src/plugins/symbian/ecam/s60videodevicecontrol.cpp108
-rw-r--r--src/plugins/symbian/ecam/s60videodevicecontrol.h95
-rw-r--r--src/plugins/symbian/ecam/s60videoencodercontrol.cpp204
-rw-r--r--src/plugins/symbian/ecam/s60videoencodercontrol.h94
-rw-r--r--src/plugins/symbian/ecam/s60videorenderercontrol.cpp78
-rw-r--r--src/plugins/symbian/ecam/s60videorenderercontrol.h76
-rw-r--r--src/plugins/symbian/mmf/audiosource/audiosource_s60.pri31
-rw-r--r--src/plugins/symbian/mmf/audiosource/s60audiocaptureservice.cpp98
-rw-r--r--src/plugins/symbian/mmf/audiosource/s60audiocaptureservice.h75
-rw-r--r--src/plugins/symbian/mmf/audiosource/s60audiocapturesession.cpp937
-rw-r--r--src/plugins/symbian/mmf/audiosource/s60audiocapturesession.h193
-rw-r--r--src/plugins/symbian/mmf/audiosource/s60audiocontainercontrol.cpp96
-rw-r--r--src/plugins/symbian/mmf/audiosource/s60audiocontainercontrol.h70
-rw-r--r--src/plugins/symbian/mmf/audiosource/s60audioencodercontrol.cpp235
-rw-r--r--src/plugins/symbian/mmf/audiosource/s60audioencodercontrol.h82
-rw-r--r--src/plugins/symbian/mmf/audiosource/s60audioendpointselector.cpp100
-rw-r--r--src/plugins/symbian/mmf/audiosource/s60audioendpointselector.h76
-rw-r--r--src/plugins/symbian/mmf/audiosource/s60audiomediarecordercontrol.cpp180
-rw-r--r--src/plugins/symbian/mmf/audiosource/s60audiomediarecordercontrol.h92
-rw-r--r--src/plugins/symbian/mmf/inc/DebugMacros.h66
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/mediaplayer_s60.pri92
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/ms60mediaplayerresolver.h54
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60audioplayersession.cpp577
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60audioplayersession.h136
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60mediametadataprovider.cpp146
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60mediametadataprovider.h72
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60medianetworkaccesscontrol.cpp144
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60medianetworkaccesscontrol.h89
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60mediaplayeraudioendpointselector.cpp182
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60mediaplayeraudioendpointselector.h77
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60mediaplayercontrol.cpp518
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60mediaplayercontrol.h148
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60mediaplayerservice.cpp326
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60mediaplayerservice.h97
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60mediaplayersession.cpp1054
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60mediaplayersession.h187
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60mediarecognizer.cpp167
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60mediarecognizer.h79
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60mediastreamcontrol.cpp201
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60mediastreamcontrol.h79
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60videooutputinterface.h62
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60videoplayersession.cpp1124
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60videoplayersession.h218
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60videorenderer.cpp95
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60videorenderer.h66
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60videosurface.cpp372
-rw-r--r--src/plugins/symbian/mmf/mediaplayer/s60videosurface.h106
-rw-r--r--src/plugins/symbian/mmf/mmf.pro58
-rw-r--r--src/plugins/symbian/mmf/radio/radio.pri24
-rw-r--r--src/plugins/symbian/mmf/radio/s60radiotunercontrol_31.cpp603
-rw-r--r--src/plugins/symbian/mmf/radio/s60radiotunercontrol_31.h161
-rw-r--r--src/plugins/symbian/mmf/radio/s60radiotunercontrol_since32.cpp685
-rw-r--r--src/plugins/symbian/mmf/radio/s60radiotunercontrol_since32.h296
-rw-r--r--src/plugins/symbian/mmf/radio/s60radiotunerservice.cpp83
-rw-r--r--src/plugins/symbian/mmf/radio/s60radiotunerservice.h71
-rw-r--r--src/plugins/symbian/mmf/s60formatsupported.cpp121
-rw-r--r--src/plugins/symbian/mmf/s60formatsupported.h65
-rw-r--r--src/plugins/symbian/mmf/s60mediaserviceplugin.cpp115
-rw-r--r--src/plugins/symbian/mmf/s60mediaserviceplugin.h69
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/mediaplayer.pri36
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxamediaplayercontrol.cpp288
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxamediaplayercontrol.h99
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxamediastreamscontrol.cpp98
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxamediastreamscontrol.h77
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxametadatacontrol.cpp131
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxametadatacontrol.h78
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxaplaymediaservice.cpp117
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxaplaymediaservice.h74
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxaplaysession.cpp610
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxaplaysession.h192
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxavideowidgetcontrol.cpp182
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxavideowidgetcontrol.h93
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxavideowindowcontrol.cpp222
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxavideowindowcontrol.h105
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxawidget.cpp64
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/qxawidget.h63
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/xaplaysessioncommon.h58
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/xaplaysessionimpl.cpp1259
-rw-r--r--src/plugins/symbian/openmaxal/mediaplayer/xaplaysessionimpl.h210
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/mediarecorder.pri24
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/qxaaudioencodercontrol.cpp111
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/qxaaudioencodercontrol.h79
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/qxaaudioendpointselector.cpp98
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/qxaaudioendpointselector.h77
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/qxamediacontainercontrol.cpp81
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/qxamediacontainercontrol.h71
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/qxamediarecordercontrol.cpp122
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/qxamediarecordercontrol.h83
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/qxarecordmediaservice.cpp86
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/qxarecordmediaservice.h78
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/qxarecordsession.cpp766
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/qxarecordsession.h144
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/xarecordsessioncommon.h67
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/xarecordsessionimpl.cpp1378
-rw-r--r--src/plugins/symbian/openmaxal/mediarecorder/xarecordsessionimpl.h179
-rw-r--r--src/plugins/symbian/openmaxal/openmaxal.pro58
-rw-r--r--src/plugins/symbian/openmaxal/qxacommon.h203
-rw-r--r--src/plugins/symbian/openmaxal/qxamediaserviceproviderplugin.cpp87
-rw-r--r--src/plugins/symbian/openmaxal/qxamediaserviceproviderplugin.h60
-rw-r--r--src/plugins/symbian/openmaxal/radiotuner/qxaradiocontrol.cpp202
-rw-r--r--src/plugins/symbian/openmaxal/radiotuner/qxaradiocontrol.h95
-rw-r--r--src/plugins/symbian/openmaxal/radiotuner/qxaradiomediaservice.cpp72
-rw-r--r--src/plugins/symbian/openmaxal/radiotuner/qxaradiomediaservice.h66
-rw-r--r--src/plugins/symbian/openmaxal/radiotuner/qxaradiosession.cpp323
-rw-r--r--src/plugins/symbian/openmaxal/radiotuner/qxaradiosession.h118
-rw-r--r--src/plugins/symbian/openmaxal/radiotuner/radiotuner.pri18
-rw-r--r--src/plugins/symbian/openmaxal/radiotuner/xaradiosessionimpl.cpp715
-rw-r--r--src/plugins/symbian/openmaxal/radiotuner/xaradiosessionimpl.h128
-rw-r--r--src/plugins/symbian/openmaxal/radiotuner/xaradiosessionimplobserver.h64
-rw-r--r--src/plugins/symbian/openmaxal/xacommon.h79
-rw-r--r--src/plugins/symbian/symbian.pro23
-rw-r--r--src/plugins/symbian/videooutput/s60videodisplay.cpp179
-rw-r--r--src/plugins/symbian/videooutput/s60videodisplay.h188
-rw-r--r--src/plugins/symbian/videooutput/s60videooutpututils.cpp119
-rw-r--r--src/plugins/symbian/videooutput/s60videooutpututils.h71
-rw-r--r--src/plugins/symbian/videooutput/s60videowidget.cpp237
-rw-r--r--src/plugins/symbian/videooutput/s60videowidget.h97
-rw-r--r--src/plugins/symbian/videooutput/s60videowidgetcontrol.cpp171
-rw-r--r--src/plugins/symbian/videooutput/s60videowidgetcontrol.h131
-rw-r--r--src/plugins/symbian/videooutput/s60videowidgetdisplay.cpp174
-rw-r--r--src/plugins/symbian/videooutput/s60videowidgetdisplay.h85
-rw-r--r--src/plugins/symbian/videooutput/s60videowindowcontrol.cpp178
-rw-r--r--src/plugins/symbian/videooutput/s60videowindowcontrol.h102
-rw-r--r--src/plugins/symbian/videooutput/s60videowindowdisplay.cpp140
-rw-r--r--src/plugins/symbian/videooutput/s60videowindowdisplay.h73
-rw-r--r--src/plugins/symbian/videooutput/videooutput.pri37
166 files changed, 38121 insertions, 0 deletions
diff --git a/src/plugins/symbian/ecam/camera_s60.pri b/src/plugins/symbian/ecam/camera_s60.pri
new file mode 100644
index 000000000..beb44db8d
--- /dev/null
+++ b/src/plugins/symbian/ecam/camera_s60.pri
@@ -0,0 +1,157 @@
+INCLUDEPATH += $$PWD
+
+include (../videooutput/videooutput.pri)
+
+# Camera Service
+DEFINES += QMEDIA_SYMBIAN_CAMERA
+
+# S60 3.1 platform
+contains(S60_VERSION, 3.1) {
+ DEFINES += S60_31_PLATFORM
+ DEFINES *= S60_3X_PLATFORM
+}
+
+# S60 3.2 platform
+contains(S60_VERSION, 3.2) {
+ DEFINES += S60_32_PLATFORM
+ DEFINES *= S60_3X_PLATFORM
+}
+
+# S60 5.0 platform
+!contains(DEFINES, S60_31_PLATFORM) {
+ !contains(DEFINES, S60_32_PLATFORM) {
+ !contains(DEFINES, SYMBIAN_3_PLATFORM) {
+ DEFINES += S60_50_PLATFORM
+ }
+ }
+}
+
+# Symbian 3 platform
+contains(DEFINES, VIDEOOUTPUT_GRAPHICS_SURFACES) {
+ DEFINES += SYMBIAN_3_PLATFORM
+}
+
+# AutoFocusing (CamAutoFocus) from ForumNokia example
+contains(symbian_camera_camautofocus_enabled, yes) {
+ exists($${EPOCROOT}epoc32\\include\\CCamAutoFocus.h) {
+ message ("CameraBE: Using S60 3.1 autofocusing")
+ MMP_RULES += \
+ "$${LITERAL_HASH}ifdef WINSCW" \
+ "LIBRARY camautofocus.lib" \
+ "$${LITERAL_HASH}else" \
+ "STATICLIBRARY camautofocus_s.lib" \
+ "$${LITERAL_HASH}endif // WINS" \
+ "MACRO S60_CAM_AUTOFOCUS_SUPPORT"
+ }
+}
+
+# ECam AdvancedSettings
+contains(symbian_camera_ecamadvsettings_enabled, yes) {
+ exists($${EPOCROOT}epoc32\\include\\ecamadvancedsettings.h) {
+ MMP_RULES += \
+ "$${LITERAL_HASH}ifndef WINSCW" \
+ "LIBRARY ecamadvsettings.lib" \
+ "MACRO USE_S60_32_ECAM_ADVANCED_SETTINGS_HEADER" \
+ "$${LITERAL_HASH}endif"
+ message("CameraBE: Using from S60 3.2 CCameraAdvancedSettings header")
+ }
+ exists($${EPOCROOT}epoc32\\include\\ecamadvsettings.h) {
+ symbian:LIBS += -lecamadvsettings
+ DEFINES += USE_S60_50_ECAM_ADVANCED_SETTINGS_HEADER
+ message("CameraBE: Using CCameraAdvancedSettings header from S60 5.0 or later")
+ }
+}
+
+# DevVideo API Check (Requires both, DevVideoPlay and DevVideoRecord plugins):
+# DevVideoConstants has been problematic since not being included in SDK plugins
+# For S60 5.0 this has changed with plugin extension 1.1
+# But for S60 3.2 this is still a problem
+contains(symbian_camera_devvideorecord_enabled, yes) {
+ exists($${EPOCROOT}epoc32\\include\\mmf\\devvideo\\devvideorecord.h) {
+ exists($${EPOCROOT}epoc32\\include\\mmf\\devvideo\\devvideobase.h) {
+ exists($${EPOCROOT}epoc32\\include\\mmf\\devvideo\\devvideoconstants.h) {
+ symbian:LIBS += -ldevvideo
+ DEFINES += S60_DEVVIDEO_RECORDING_SUPPORTED
+ message("CameraBE: Devvideo API supported")
+ }
+ }
+ }
+}
+
+# ECam Snapshot API:
+contains(symbian_camera_snapshot_enabled, yes) {
+ exists($${EPOCROOT}epoc32\\include\\platform\\ecam\\camerasnapshot.h) {
+ DEFINES += ECAM_PREVIEW_API
+ message("CameraBE: Using CCameraSnapshot API")
+ symbian:LIBS += -lecamsnapshot
+ } else {
+ message("CameraBE: Using custom snapshot proving methods")
+ }
+} else {
+ message("CameraBE: Using custom snapshot proving methods")
+}
+
+# Libraries:
+symbian:LIBS += -lfbscli \
+ -lmediaclientvideo \
+ -lecam \
+ -lbafl \
+ -lPlatformEnv \
+ -lcharconv \
+ -lconvnames \
+ -lgb2312_shared \
+ -ljisx0201 \
+ -ljisx0208 \
+ -lmmfcontrollerframework \
+ -lfbscli \
+ -lefsrv \
+ -lcone \
+ -lws32 \
+ -limageconversion
+
+# Source:
+HEADERS += $$PWD/s60cameraconstants.h \
+ $$PWD/s60cameralockscontrol.h \
+ $$PWD/s60camerafocuscontrol.h \
+ $$PWD/s60cameraexposurecontrol.h \
+ $$PWD/s60cameraflashcontrol.h \
+ $$PWD/s60cameracontrol.h \
+ $$PWD/s60mediarecordercontrol.h \
+ $$PWD/s60videocapturesession.h \
+ $$PWD/s60imagecapturesession.h \
+ $$PWD/s60mediacontainercontrol.h \
+ $$PWD/s60videoencodercontrol.h \
+ $$PWD/s60audioencodercontrol.h \
+ $$PWD/s60cameraservice.h \
+ $$PWD/s60cameraimageprocessingcontrol.h \
+ $$PWD/s60cameraimagecapturecontrol.h \
+ $$PWD/s60videodevicecontrol.h \
+ $$PWD/s60imageencodercontrol.h \
+ $$PWD/s60camerasettings.h \
+ $$PWD/s60cameraengine.h \
+ $$PWD/s60cameraviewfinderengine.h \
+ $$PWD/s60cameraengineobserver.h \
+ $$PWD/s60videorenderercontrol.h
+
+SOURCES += $$PWD/s60cameralockscontrol.cpp \
+ $$PWD/s60camerafocuscontrol.cpp \
+ $$PWD/s60cameraexposurecontrol.cpp \
+ $$PWD/s60cameraflashcontrol.cpp \
+ $$PWD/s60cameracontrol.cpp \
+ $$PWD/s60mediarecordercontrol.cpp \
+ $$PWD/s60videocapturesession.cpp \
+ $$PWD/s60imagecapturesession.cpp \
+ $$PWD/s60mediacontainercontrol.cpp \
+ $$PWD/s60videoencodercontrol.cpp \
+ $$PWD/s60audioencodercontrol.cpp \
+ $$PWD/s60cameraservice.cpp \
+ $$PWD/s60cameraimageprocessingcontrol.cpp \
+ $$PWD/s60cameraimagecapturecontrol.cpp \
+ $$PWD/s60videodevicecontrol.cpp \
+ $$PWD/s60imageencodercontrol.cpp \
+ $$PWD/s60camerasettings.cpp \
+ $$PWD/s60cameraengine.cpp \
+ $$PWD/s60cameraviewfinderengine.cpp \
+ $$PWD/s60videorenderercontrol.cpp
+
+# End of file
diff --git a/src/plugins/symbian/ecam/ecam.pro b/src/plugins/symbian/ecam/ecam.pro
new file mode 100644
index 000000000..31f30b61c
--- /dev/null
+++ b/src/plugins/symbian/ecam/ecam.pro
@@ -0,0 +1,40 @@
+######################################################################
+#
+# Mobility API project - Symbian Camera backend
+#
+######################################################################
+
+TEMPLATE = lib
+CONFIG += plugin
+
+TARGET = $$qtLibraryTarget(qtmultimediakit_ecamengine)
+PLUGIN_TYPE = mediaservice
+include (../../../../common.pri)
+
+CONFIG += mobility
+MOBILITY += multimedia
+
+# Include here so that all defines are added here also
+include(camera_s60.pri)
+
+DEPENDPATH += .
+
+INCLUDEPATH += . \
+ $${SOURCE_DIR}/include \
+ $${SOURCE_DIR}/src/multimedia \
+ $${SOURCE_DIR}/src/multimedia/audio \
+ $${SOURCE_DIR}/src/multimedia/video \
+ $${SOURCE_DIR}
+
+HEADERS += s60cameraserviceplugin.h
+SOURCES += s60cameraserviceplugin.cpp
+
+load(data_caging_paths)
+TARGET.EPOCALLOWDLLDATA = 1
+TARGET.UID3 = 0x2002BFC2
+TARGET.CAPABILITY = ALL -TCB
+
+# Make a sis package from plugin + api + stub (plugin)
+pluginDep.sources = $${TARGET}.dll
+pluginDep.path = $${QT_PLUGINS_BASE_DIR}/$${PLUGIN_TYPE}
+DEPLOYMENT += pluginDep
diff --git a/src/plugins/symbian/ecam/s60audioencodercontrol.cpp b/src/plugins/symbian/ecam/s60audioencodercontrol.cpp
new file mode 100644
index 000000000..bd8f0147d
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60audioencodercontrol.cpp
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "s60audioencodercontrol.h"
+#include "s60videocapturesession.h"
+
+S60AudioEncoderControl::S60AudioEncoderControl(QObject *parent) :
+ QAudioEncoderControl(parent)
+{
+}
+
+S60AudioEncoderControl::S60AudioEncoderControl(S60VideoCaptureSession *session, QObject *parent) :
+ QAudioEncoderControl(parent)
+{
+ m_session = session;
+}
+
+S60AudioEncoderControl::~S60AudioEncoderControl()
+{
+}
+
+QStringList S60AudioEncoderControl::supportedAudioCodecs() const
+{
+ return m_session->supportedAudioCaptureCodecs();
+}
+
+QString S60AudioEncoderControl::codecDescription(const QString &codecName) const
+{
+ // According to ForumNokia MMF camcorder plugin supports AAC, AMR and QCELP
+ // QCELP is speech codec and can be discarded
+ if (qstrcmp(codecName.toLocal8Bit().constData(), "audio/aac") == 0)
+ return QLatin1String("Advanced Audio Coding");
+ else if (qstrcmp(codecName.toLocal8Bit().constData(), "audio/amr") == 0)
+ return QLatin1String("Adaptive Multi-Rate Audio Codec");
+
+ return QString();
+}
+
+QStringList S60AudioEncoderControl::supportedEncodingOptions(const QString &codec) const
+{
+ // Possible settings: EncodingMode, Codec, BitRate, ChannelCount, SampleRate, Quality
+ // Possible (codec specific) Options: None
+ Q_UNUSED(codec);
+ return QStringList();
+}
+
+QVariant S60AudioEncoderControl::encodingOption(const QString &codec, const QString &name) const
+{
+ // Possible settings: EncodingMode, Codec, BitRate, ChannelCount, SampleRate, Quality
+ // Possible (codec specific) Options: None
+ Q_UNUSED(codec);
+ Q_UNUSED(name);
+ return QVariant();
+}
+
+void S60AudioEncoderControl::setEncodingOption(
+ const QString &codec, const QString &name, const QVariant &value)
+{
+ m_session->setError(KErrNotSupported, tr("Audio encoding option is not supported"));
+
+ // The audio settings can currently be set only using setAudioSettings() function
+ Q_UNUSED(value)
+ Q_UNUSED(codec)
+ Q_UNUSED(name)
+}
+
+QList<int> S60AudioEncoderControl::supportedSampleRates(
+ const QAudioEncoderSettings &settings, bool *continuous) const
+{
+ return m_session->supportedSampleRates(settings, continuous);
+}
+
+QAudioEncoderSettings S60AudioEncoderControl::audioSettings() const
+{
+ QAudioEncoderSettings settings;
+ m_session->audioEncoderSettings(settings);
+
+ return settings;
+}
+
+void S60AudioEncoderControl::setAudioSettings(const QAudioEncoderSettings &settings)
+{
+ // Notify that settings have been implicitly set and there's no need to
+ // initialize them in case camera is changed
+ m_session->notifySettingsSet();
+
+ // Quality defines SampleRate/BitRate combination if either or both are missing
+ if (settings.codec().isEmpty()) { // Empty settings
+ m_session->setAudioCaptureQuality(settings.quality(), S60VideoCaptureSession::EOnlyAudioQuality);
+
+ } else if (settings.bitRate() == -1 && settings.sampleRate() != -1) { // Only SampleRate set
+ m_session->setAudioCaptureCodec(settings.codec());
+ m_session->setAudioChannelCount(settings.channelCount());
+ m_session->setAudioSampleRate(settings.sampleRate());
+ m_session->setAudioEncodingMode(settings.encodingMode());
+ m_session->setAudioCaptureQuality(settings.quality(), S60VideoCaptureSession::EAudioQualityAndSampleRate);
+
+ } else if (settings.bitRate() != -1 && settings.sampleRate() == -1) { // Only BitRate set
+ m_session->setAudioCaptureCodec(settings.codec());
+ m_session->setAudioChannelCount(settings.channelCount());
+ m_session->setAudioBitRate(settings.bitRate());
+ m_session->setAudioEncodingMode(settings.encodingMode());
+ m_session->setAudioCaptureQuality(settings.quality(), S60VideoCaptureSession::EAudioQualityAndBitRate);
+
+ } else if (settings.bitRate() == -1 && settings.sampleRate() == -1) { // No BitRate or SampleRate set
+ m_session->setAudioCaptureCodec(settings.codec());
+ m_session->setAudioChannelCount(settings.channelCount());
+ m_session->setAudioEncodingMode(settings.encodingMode());
+ m_session->setAudioCaptureQuality(settings.quality(), S60VideoCaptureSession::EOnlyAudioQuality);
+
+ } else { // Both SampleRate and BitRate set
+ m_session->setAudioCaptureCodec(settings.codec());
+ m_session->setAudioChannelCount(settings.channelCount());
+ m_session->setAudioSampleRate(settings.sampleRate());
+ m_session->setAudioBitRate(settings.bitRate());
+ m_session->setAudioEncodingMode(settings.encodingMode());
+ m_session->setAudioCaptureQuality(settings.quality(), S60VideoCaptureSession::ENoAudioQuality);
+ }
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60audioencodercontrol.h b/src/plugins/symbian/ecam/s60audioencodercontrol.h
new file mode 100644
index 000000000..db6ada5d1
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60audioencodercontrol.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60AUDIOENCODERCONTROL_H
+#define S60AUDIOENCODERCONTROL_H
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/qmap.h>
+
+#include <qaudioencodercontrol.h>
+
+QT_USE_NAMESPACE
+
+class S60VideoCaptureSession;
+
+/*
+ * Control for audio settings when recording video using QMediaRecorder.
+ */
+class S60AudioEncoderControl : public QAudioEncoderControl
+{
+ Q_OBJECT
+
+public: // Constructor & Destructor
+
+ S60AudioEncoderControl(QObject *parent = 0);
+ S60AudioEncoderControl(S60VideoCaptureSession *session, QObject *parent = 0);
+ virtual ~S60AudioEncoderControl();
+
+public: // QAudioEncoderControl
+
+ // Audio Codec
+ QStringList supportedAudioCodecs() const;
+ QString codecDescription(const QString &codecName) const;
+
+ // Sample Rate
+ QList<int> supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous = 0) const;
+
+ // Audio Settings
+ QAudioEncoderSettings audioSettings() const;
+ void setAudioSettings(const QAudioEncoderSettings &settings);
+
+ // Encoding Option
+ QStringList supportedEncodingOptions(const QString &codec) const;
+ QVariant encodingOption(const QString &codec, const QString &name) const;
+ void setEncodingOption(const QString &codec, const QString &name, const QVariant &value);
+
+private: // Data
+
+ S60VideoCaptureSession* m_session;
+};
+
+#endif // S60AUDIOENCODERCONTROL_H
diff --git a/src/plugins/symbian/ecam/s60cameraconstants.h b/src/plugins/symbian/ecam/s60cameraconstants.h
new file mode 100644
index 000000000..4b415c3e8
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraconstants.h
@@ -0,0 +1,257 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60CAMERACONSTANTS_H
+#define S60CAMERACONSTANTS_H
+
+//=============================================================================
+
+// GENERAL SETTINGS
+
+#define KDefaultCameraDevice 0
+#define KECamCameraPriority 0
+#define KInactivityTimerTimeout 30000 // msec
+#define KSymbianFineResolutionFactor 100.0
+#define KDefaultOpticalZoom 1.0
+#define KDefaultDigitalZoom 1.0
+#define KSmoothZoomStep 1
+#define KDefaultFocusMode QCameraFocus::AutoFocus
+
+#define KDefaultViewfinderSize QSize(320,240)
+#define KDefaultSizePreview_Normal TSize(640,480)
+#define KDefaultSizePreview_Wide TSize(640,360)
+#define KDefaultSizePreview_CIF TSize(352,288)
+#define KDefaultSizePreview_PAL TSize(640,512)
+#define KDefaultSizePreview_NTSC TSize(640,426)
+#define KDefaultFormatPreview CCamera::EFormatFbsBitmapColor16MU
+#define KViewfinderFrameRate 30
+#define KMaxVFErrorsSignalled 3
+
+//=============================================================================
+
+// IMAGE SETTINGS
+
+#define KDefaultImagePath QLatin1String("c:\\Data\\Images")
+#define KDefaultImageFileName QLatin1String("image.jpg")
+#define KDefaultImageCodec QLatin1String("image/jpeg")
+#define KDefaultImageFormatPrimaryCam CCamera::EFormatExif
+#ifdef SYMBIAN_3_PLATFORM
+#define KDefaultImageFormatSecondaryCam CCamera::EFormatExif
+#define KDefaultImageResolution QSize(3264, 2448)
+#else // Pre-Symbian3 Platforms
+#define KDefaultImageFormatSecondaryCam CCamera::EFormatFbsBitmapColor64K
+#define KDefaultImageResolution QSize(2048, 1536)
+#endif // SYMBIAN_3_PLATFORM
+#define KSymbianImageQualityCoefficient 25
+// This must be divisible by 4 and creater or equal to 8
+#define KSnapshotDownScaleFactor 8
+#define KSnapshotMinWidth 640
+#define KSnapshotMinHeight 360
+#define KJpegQualityVeryLow 40
+#define KJpegQualityLow 50
+#define KJpegQualityNormal 75
+#define KJpegQualityHigh 85
+#define KJpegQualityVeryHigh 95
+#define KDefaultImageQuality KJpegQualityHigh
+
+//=============================================================================
+
+// VIDEO SETTINGS
+
+// ================
+// General settings
+// ================
+
+// Dummy file name to execute CVideoRecorderUtility::OpenFileL() without
+// knowing the actual outputLocation. This is needed to be able to query/set
+// supported video settings.
+_LIT(KDummyVideoFile, "c:\\data\\temp");
+
+// Default container MIME type
+#define KMimeTypeDefaultContainer QLatin1String("video/mp4")
+#define KDefaultVideoPath QLatin1String("c:\\Data\\Videos")
+#define KDefaultVideoFileName QLatin1String("video.mp4")
+#define KDurationChangedInterval 1000 // 1 second
+
+// ==============
+// Audio Settings
+// ==============
+
+// Default audio codec MIME type
+#define KMimeTypeDefaultAudioCodec QLatin1String("audio/aac")
+
+// Default audio settings for video recording
+#define KDefaultChannelCount -1 // Not Supported on Symbian
+#define KDefaultBitRate 32000 // 32kbps
+#define KDefaultSampleRate -1 // Not Supported on Symbian
+
+// ==============
+// Video Settings
+// ==============
+
+// Default video codec MIME type
+#ifdef SYMBIAN_3_PLATFORM
+ // H.264: BaselineProfile Level 3.1, Max resolution: 1280x720
+ #define KMimeTypeDefaultVideoCodec QLatin1String("video/H264; profile-level-id=42801F")
+#else
+ // MPEG-4: Simple Profile, Level 4, Max resolution: 640x480
+ #define KMimeTypeDefaultVideoCodec QLatin1String("video/mp4v-es; profile-level-id=4")
+#endif
+
+// Maximum resolutions for encoder MIME Types
+// H.263
+#define KResH263 QSize(176,144);
+#define KResH263_Profile0 QSize(176,144);
+#define KResH263_Profile0_Level10 QSize(176,144);
+#define KResH263_Profile0_Level20 QSize(352,288);
+#define KResH263_Profile0_Level30 QSize(352,288);
+#define KResH263_Profile0_Level40 QSize(352,288);
+#define KResH263_Profile0_Level45 QSize(176,144);
+#define KResH263_Profile0_Level50 QSize(352,288);
+#define KResH263_Profile3 QSize(176,144);
+// MPEG-4
+#define KResMPEG4 QSize(176,144);
+#define KResMPEG4_PLID_1 QSize(176,144);
+#define KResMPEG4_PLID_2 QSize(352,288);
+#define KResMPEG4_PLID_3 QSize(352,288);
+#define KResMPEG4_PLID_4 QSize(640,480);
+#define KResMPEG4_PLID_5 QSize(720,576);
+#define KResMPEG4_PLID_6 QSize(1280,720);
+#define KResMPEG4_PLID_8 QSize(176,144);
+#define KResMPEG4_PLID_9 QSize(176,144);
+// H.264 (Baseline Profile, same resolutions apply to Main and High Profile)
+#define KResH264 QSize(176,144);
+#define KResH264_PLID_42800A QSize(176,144);
+#define KResH264_PLID_42900B QSize(176,144);
+#define KResH264_PLID_42800B QSize(352,288);
+#define KResH264_PLID_42800C QSize(352,288);
+#define KResH264_PLID_42800D QSize(352,288);
+#define KResH264_PLID_428014 QSize(352,288);
+#define KResH264_PLID_428015 QSize(352,288);
+#define KResH264_PLID_428016 QSize(640,480);
+#define KResH264_PLID_42801E QSize(640,480);
+#define KResH264_PLID_42801F QSize(1280,720);
+#define KResH264_PLID_428020 QSize(1280,720);
+#define KResH264_PLID_428028 QSize(1920,1080);
+
+// Maximum framerates for encoder MIME Types
+// H.263
+#define KFrR_H263 qreal(15);
+#define KFrR_H263_Profile0 qreal(15);
+#define KFrR_H263_Profile0_Level10 qreal(15);
+#define KFrR_H263_Profile0_Level20 qreal(15);
+#define KFrR_H263_Profile0_Level30 qreal(30);
+#define KFrR_H263_Profile0_Level40 qreal(30);
+#define KFrR_H263_Profile0_Level45 qreal(15);
+#define KFrR_H263_Profile0_Level50 qreal(15);
+#define KFrR_H263_Profile3 qreal(15);
+// MPEG-4
+#define KFrR_MPEG4 qreal(15);
+#define KFrR_MPEG4_PLID_1 qreal(15);
+#define KFrR_MPEG4_PLID_2 qreal(15);
+#define KFrR_MPEG4_PLID_3 qreal(30);
+// This is a workaround for a known platform bug
+#if (defined(S60_31_PLATFORM) | defined(S60_32_PLATFORM))
+#define KFrR_MPEG4_PLID_4 qreal(15);
+#else // All other platforms
+#define KFrR_MPEG4_PLID_4 qreal(30);
+#endif // S60 3.1 or 3.2
+#define KFrR_MPEG4_PLID_5 qreal(30);
+#define KFrR_MPEG4_PLID_6 qreal(30);
+#define KFrR_MPEG4_PLID_8 qreal(15);
+#define KFrR_MPEG4_PLID_9 qreal(15);
+// H.264 (Baseline Profile, same framerates apply to Main and High Profile)
+#define KFrR_H264 qreal(15);
+#define KFrR_H264_PLID_42800A qreal(15);
+#define KFrR_H264_PLID_42900B qreal(15);
+#define KFrR_H264_PLID_42800B qreal(7.5);
+#define KFrR_H264_PLID_42800C qreal(15);
+#define KFrR_H264_PLID_42800D qreal(30);
+#define KFrR_H264_PLID_428014 qreal(30);
+#define KFrR_H264_PLID_428015 qreal(50);
+#define KFrR_H264_PLID_428016 qreal(16.9);
+#define KFrR_H264_PLID_42801E qreal(33.8);
+#define KFrR_H264_PLID_42801F qreal(30);
+#define KFrR_H264_PLID_428020 qreal(60);
+#define KFrR_H264_PLID_428028 qreal(30);
+
+// Maximum bitrates for encoder MIME Types
+// H.263
+#define KBiR_H263 int(64000);
+#define KBiR_H263_Profile0 int(64000);
+#define KBiR_H263_Profile0_Level10 int(64000);
+#define KBiR_H263_Profile0_Level20 int(128000);
+#define KBiR_H263_Profile0_Level30 int(384000);
+#define KBiR_H263_Profile0_Level40 int(2048000);
+#define KBiR_H263_Profile0_Level45 int(128000);
+#define KBiR_H263_Profile0_Level50 int(4096000);
+#define KBiR_H263_Profile3 int(64000);
+// MPEG-4
+#define KBiR_MPEG4 int(64000);
+#define KBiR_MPEG4_PLID_1 int(64000);
+#define KBiR_MPEG4_PLID_2 int(128000);
+#define KBiR_MPEG4_PLID_3 int(384000);
+// This is a workaround for a known platform bug
+#if (defined(S60_31_PLATFORM) | defined(S60_32_PLATFORM))
+#define KBiR_MPEG4_PLID_4 int(2000000);
+#else // All other platforms
+#define KBiR_MPEG4_PLID_4 int(4000000);
+#endif // S60 3.1 or 3.2
+#define KBiR_MPEG4_PLID_5 int(8000000);
+#define KBiR_MPEG4_PLID_6 int(12000000);
+#define KBiR_MPEG4_PLID_8 int(64000);
+#define KBiR_MPEG4_PLID_9 int(128000);
+// H.264 (Baseline Profile, same bitrates apply to Main and High Profile)
+#define KBiR_H264 int(64000);
+#define KBiR_H264_PLID_42800A int(64000);
+#define KBiR_H264_PLID_42900B int(128000);
+#define KBiR_H264_PLID_42800B int(192000);
+#define KBiR_H264_PLID_42800C int(384000);
+#define KBiR_H264_PLID_42800D int(768000);
+#define KBiR_H264_PLID_428014 int(2000000);
+#define KBiR_H264_PLID_428015 int(4000000);
+#define KBiR_H264_PLID_428016 int(4000000);
+#define KBiR_H264_PLID_42801E int(10000000);
+#define KBiR_H264_PLID_42801F int(14000000);
+#define KBiR_H264_PLID_428020 int(20000000);
+#define KBiR_H264_PLID_428028 int(20000000);
+
+#endif // S60CAMERACONSTANTS_H
diff --git a/src/plugins/symbian/ecam/s60cameracontrol.cpp b/src/plugins/symbian/ecam/s60cameracontrol.cpp
new file mode 100644
index 000000000..64a3ff37e
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameracontrol.cpp
@@ -0,0 +1,983 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+#include <QTimer>
+
+#include "s60cameraservice.h"
+#include "s60cameraengine.h"
+#include "s60cameracontrol.h"
+#include "s60imagecapturesession.h"
+#include "s60videowidgetcontrol.h"
+#include "s60cameraviewfinderengine.h"
+#include "s60cameraconstants.h"
+
+S60CameraControl::S60CameraControl(QObject *parent) :
+ QCameraControl(parent)
+{
+}
+
+S60CameraControl::S60CameraControl(S60VideoCaptureSession *videosession,
+ S60ImageCaptureSession *imagesession,
+ QObject *parent):
+ QCameraControl(parent),
+ m_cameraEngine(0),
+ m_viewfinderEngine(0),
+ m_imageSession(0),
+ m_videoSession(0),
+ m_advancedSettings(0),
+ m_videoOutput(0),
+ m_inactivityTimer(0),
+ m_captureMode(QCamera::CaptureStillImage), // Default CaptureMode
+ m_requestedCaptureMode(QCamera::CaptureStillImage),
+ m_settingCaptureModeInternally(false),
+ m_internalState(QCamera::UnloadedStatus), // Default Status
+ m_requestedState(QCamera::UnloadedState), // Default State
+ m_deviceIndex(KDefaultCameraDevice),
+ m_error(KErrNone),
+ m_changeCaptureModeWhenReady(false),
+ m_rotateCameraWhenReady(false),
+ m_videoCaptureState(S60VideoCaptureSession::ENotInitialized)
+{
+ m_videoSession = videosession;
+ m_imageSession = imagesession;
+
+ m_inactivityTimer = new QTimer;
+ if (m_inactivityTimer)
+ m_inactivityTimer->setSingleShot(true);
+
+ TRAPD(err, m_cameraEngine = CCameraEngine::NewL(m_deviceIndex, KECamCameraPriority, this));
+ if (err) {
+ m_error = err;
+ if (err == KErrPermissionDenied)
+ qWarning("Failed to create camera. Possibly missing capabilities.");
+ else
+ qWarning("Failed to create camera.");
+ return;
+ }
+
+ m_viewfinderEngine = new S60CameraViewfinderEngine(this, m_cameraEngine, this);
+ if (m_viewfinderEngine == 0) {
+ m_error = KErrNoMemory;
+ qWarning("Failed to create viewfinder engine.");
+ return;
+ }
+
+ // Connect signals
+ connect(m_inactivityTimer, SIGNAL(timeout()), this, SLOT(toStandByStatus()));
+ connect(this, SIGNAL(statusChanged(QCamera::Status)),
+ m_imageSession, SLOT(cameraStatusChanged(QCamera::Status)));
+ connect(this, SIGNAL(statusChanged(QCamera::Status)),
+ m_videoSession, SLOT(cameraStatusChanged(QCamera::Status)));
+ connect(m_videoSession, SIGNAL(stateChanged(S60VideoCaptureSession::TVideoCaptureState)),
+ this, SLOT(videoStateChanged(S60VideoCaptureSession::TVideoCaptureState)));
+ connect(m_imageSession, SIGNAL(advancedSettingChanged()), this, SLOT(advancedSettingsCreated()));
+ connect(this, SIGNAL(cameraReadyChanged(bool)), m_imageSession, SIGNAL(readyForCaptureChanged(bool)));
+ connect(m_viewfinderEngine, SIGNAL(error(int, const QString&)), this, SIGNAL(error(int,const QString&)));
+ connect(m_imageSession, SIGNAL(cameraError(int, const QString&)), this, SIGNAL(error(int, const QString&)));
+ connect(m_imageSession, SIGNAL(captureSizeChanged(const QSize&)),
+ m_viewfinderEngine, SLOT(handleContentAspectRatioChange(const QSize&)));
+ connect(m_videoSession, SIGNAL(captureSizeChanged(const QSize&)),
+ m_viewfinderEngine, SLOT(handleContentAspectRatioChange(const QSize&)));
+
+ setCameraHandles();
+}
+
+S60CameraControl::~S60CameraControl()
+{
+ unloadCamera();
+
+ if (m_viewfinderEngine) {
+ delete m_viewfinderEngine;
+ m_viewfinderEngine = 0;
+ }
+
+ // Make sure AdvancedSettings are destructed
+ m_imageSession->deleteAdvancedSettings();
+
+ if (m_cameraEngine) {
+ delete m_cameraEngine;
+ m_cameraEngine = 0;
+ }
+
+ if (m_inactivityTimer) {
+ delete m_inactivityTimer;
+ m_inactivityTimer = 0;
+ }
+}
+
+void S60CameraControl::setState(QCamera::State state)
+{
+ if (m_error) { // Most probably failure in contructor
+ setError(m_error, tr("Unexpected camera error."));
+ return;
+ }
+
+ if (m_requestedState == state)
+ return;
+
+ if (m_inactivityTimer->isActive())
+ m_inactivityTimer->stop();
+
+ // Save the target state
+ m_requestedState = state;
+ emit stateChanged(m_requestedState);
+
+ switch (state) {
+ case QCamera::UnloadedState: // To UnloadedState - Release resources
+ switch (m_internalState) {
+ case QCamera::UnloadedStatus:
+ // Do nothing
+ break;
+ case QCamera::LoadingStatus:
+ case QCamera::StartingStatus:
+ // Release resources when ready (setting state handles this)
+ return;
+ case QCamera::LoadedStatus:
+ case QCamera::StandbyStatus:
+ // Unload
+ unloadCamera();
+ break;
+ case QCamera::ActiveStatus:
+ // Stop and Unload
+ stopCamera();
+ unloadCamera();
+ break;
+
+ default:
+ // Unrecognized internal state (Status)
+ setError(KErrGeneral, tr("Unexpected camera error."));
+ return;
+ }
+ break;
+
+ case QCamera::LoadedState: // To LoadedState - Reserve resources OR Stop ViewFinder and Cancel Capture
+ switch (m_internalState) {
+ case QCamera::UnloadedStatus:
+ case QCamera::StandbyStatus:
+ // Load
+ loadCamera();
+ break;
+ case QCamera::LoadingStatus:
+ // Discard, already moving to LoadedStatus
+ return;
+ case QCamera::StartingStatus:
+ // Stop when ready (setting state handles this)
+ return;
+ case QCamera::LoadedStatus:
+ m_inactivityTimer->start(KInactivityTimerTimeout);
+ break;
+ case QCamera::ActiveStatus:
+ // Stop
+ stopCamera();
+ break;
+
+ default:
+ // Unregocnized internal state (Status)
+ setError(KErrGeneral, tr("Unexpected camera error."));
+ return;
+ }
+ break;
+
+ case QCamera::ActiveState: // To ActiveState - (Reserve Resources and) Start ViewFinder
+ switch (m_internalState) {
+ case QCamera::UnloadedStatus:
+ case QCamera::StandbyStatus:
+ // Load and Start (setting state handles starting)
+ loadCamera();
+ break;
+ case QCamera::LoadingStatus:
+ // Start when loaded (setting state handles this)
+ break;
+ case QCamera::StartingStatus:
+ // Discard, already moving to ActiveStatus
+ return;
+ case QCamera::LoadedStatus:
+ // Start
+ startCamera();
+ break;
+ case QCamera::ActiveStatus:
+ // Do nothing
+ break;
+
+ default:
+ // Unregocnized internal state (Status)
+ setError(KErrGeneral, tr("Unexpected camera error."));
+ return;
+ }
+ break;
+
+ default:
+ setError(KErrNotSupported, tr("Requested state is not supported."));
+ return;
+ }
+}
+
+QCamera::State S60CameraControl::state() const
+{
+ return m_requestedState;
+}
+
+QCamera::Status S60CameraControl::status() const
+{
+ return m_internalState;
+}
+
+QCamera::CaptureMode S60CameraControl::captureMode() const
+{
+ return m_captureMode;
+}
+
+void S60CameraControl::setCaptureMode(QCamera::CaptureMode mode)
+{
+ if (m_error) { // Most probably failure in contructor
+ setError(m_error, tr("Unexpected camera error."));
+ return;
+ }
+
+ if (m_captureMode == mode)
+ return;
+
+ // Setting CaptureMode Internally or Externally (Client)
+ if (!m_settingCaptureModeInternally) {
+ // Save the requested mode
+ m_requestedCaptureMode = mode;
+
+ // CaptureMode change pending (backend busy), wait
+ if (m_changeCaptureModeWhenReady)
+ return;
+ } else {
+ m_changeCaptureModeWhenReady = false; // Reset
+ }
+ m_settingCaptureModeInternally = false; // Reset
+
+ if (!isCaptureModeSupported(mode)) {
+ setError(KErrNotSupported, tr("Requested capture mode is not supported."));
+ return;
+ }
+
+ if (m_inactivityTimer->isActive())
+ m_inactivityTimer->stop();
+
+ switch (m_internalState) {
+ case QCamera::UnloadedStatus:
+ case QCamera::LoadedStatus:
+ case QCamera::StandbyStatus:
+ switch (mode) {
+ case QCamera::CaptureStillImage:
+ m_videoSession->releaseVideoRecording();
+ m_captureMode = QCamera::CaptureStillImage;
+ if (m_internalState == QCamera::LoadedStatus)
+ m_inactivityTimer->start(KInactivityTimerTimeout);
+ else if (m_internalState == QCamera::StandbyStatus)
+ loadCamera();
+ break;
+ case QCamera::CaptureVideo:
+ m_imageSession->releaseImageCapture();
+ m_captureMode = QCamera::CaptureVideo;
+ if (m_internalState == QCamera::LoadedStatus) {
+ // Revet InternalState as we need to wait for the video
+ // side initialization to complete
+ m_internalState = QCamera::LoadingStatus;
+ emit statusChanged(m_internalState);
+ int prepareSuccess = m_videoSession->initializeVideoRecording();
+ setError(prepareSuccess, tr("Loading video capture failed."));
+ } else if (m_internalState == QCamera::StandbyStatus)
+ loadCamera();
+ break;
+ }
+ break;
+ case QCamera::LoadingStatus:
+ case QCamera::StartingStatus:
+ m_changeCaptureModeWhenReady = true;
+ return;
+ case QCamera::ActiveStatus:
+ // Stop, Change Mode and Start again
+ stopCamera();
+ switch (mode) {
+ case QCamera::CaptureStillImage:
+ m_videoSession->releaseVideoRecording();
+ m_captureMode = QCamera::CaptureStillImage;
+ startCamera();
+ break;
+ case QCamera::CaptureVideo:
+ m_imageSession->releaseImageCapture();
+ m_captureMode = QCamera::CaptureVideo;
+ // Revet InternalState as we need to wait for the video
+ // side initialization to complete
+ m_internalState = QCamera::LoadingStatus;
+ emit statusChanged(m_internalState);
+ int prepareSuccess = m_videoSession->initializeVideoRecording();
+ setError(prepareSuccess, tr("Loading video recorder failed."));
+ break;
+ }
+ break;
+
+ default:
+ // Unregocnized internal state (Status)
+ setError(KErrNotSupported, tr("Requested capture mode is not supported."));
+ break;
+ }
+
+ emit captureModeChanged(mode);
+}
+
+bool S60CameraControl::isCaptureModeSupported(QCamera::CaptureMode mode) const
+{
+ switch (mode) {
+ case QCamera::CaptureStillImage:
+ return true;
+ case QCamera::CaptureVideo:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool S60CameraControl::canChangeProperty(QCameraControl::PropertyChangeType changeType, QCamera::Status status) const
+{
+ Q_UNUSED(status);
+
+ bool returnValue = false;
+
+ switch (changeType) {
+ case QCameraControl::CaptureMode:
+ case QCameraControl::VideoEncodingSettings:
+ case QCameraControl::ImageEncodingSettings:
+ returnValue = true;
+ break;
+
+ case QCameraControl::Viewfinder:
+ returnValue = false;
+ break;
+
+ default:
+ // Safer to revert state before the unknown operation
+ returnValue = false;
+ break;
+ }
+
+ return returnValue;
+}
+
+void S60CameraControl::setVideoOutput(QObject *output,
+ S60CameraViewfinderEngine::ViewfinderOutputType type)
+{
+ if (!m_viewfinderEngine) {
+ setError(KErrGeneral, tr("Failed to set viewfinder"));
+ return;
+ }
+
+ switch (type) {
+ case S60CameraViewfinderEngine::OutputTypeVideoWidget:
+ m_viewfinderEngine->setVideoWidgetControl(output);
+ break;
+ case S60CameraViewfinderEngine::OutputTypeRenderer:
+ m_viewfinderEngine->setVideoRendererControl(output);
+ break;
+ case S60CameraViewfinderEngine::OutputTypeVideoWindow:
+ m_viewfinderEngine->setVideoWindowControl(output);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void S60CameraControl::releaseVideoOutput(const S60CameraViewfinderEngine::ViewfinderOutputType type)
+{
+ m_viewfinderEngine->releaseControl(type);
+}
+
+void S60CameraControl::loadCamera()
+{
+ if (m_internalState < QCamera::LoadingStatus) {
+ m_internalState = QCamera::LoadingStatus;
+ emit statusChanged(m_internalState);
+ } else if (m_internalState == QCamera::LoadedStatus
+ || m_internalState >= QCamera::StartingStatus) {
+ // Nothing to load (already loaded)
+ return;
+ }
+ // Status = Loading or Standby
+
+ m_cameraEngine->ReserveAndPowerOn();
+
+ // Completion notified in MceoCameraReady()
+}
+
+void S60CameraControl::unloadCamera()
+{
+ if (m_internalState > QCamera::LoadingStatus) {
+ m_internalState = QCamera::LoadingStatus;
+ emit statusChanged(m_internalState);
+ } else if (m_internalState < QCamera::LoadingStatus) {
+ // Nothing to unload
+ return;
+ }
+ // Status = Loading
+
+ if (m_inactivityTimer->isActive())
+ m_inactivityTimer->stop();
+
+ m_cameraEngine->ReleaseAndPowerOff();
+
+ m_internalState = QCamera::UnloadedStatus;
+ emit statusChanged(m_internalState);
+}
+
+void S60CameraControl::startCamera()
+{
+ if (m_internalState < QCamera::StartingStatus) {
+ m_internalState = QCamera::StartingStatus;
+ emit statusChanged(m_internalState);
+ } else if (m_internalState > QCamera::StartingStatus) {
+ // Nothing to start (already started)
+ return;
+ }
+ // Status = Starting
+
+ if (m_inactivityTimer->isActive())
+ m_inactivityTimer->stop();
+
+ if (m_viewfinderEngine)
+ m_viewfinderEngine->startViewfinder();
+ else
+ setError(KErrGeneral, tr("Failed to start viewfinder."));
+
+ m_internalState = QCamera::ActiveStatus;
+ emit statusChanged(m_internalState);
+
+ emit cameraReadyChanged(true);
+
+#ifdef Q_CC_NOKIAX86 // Emulator
+ MceoCameraReady(); // Signal that we are ready
+#endif
+}
+
+void S60CameraControl::stopCamera()
+{
+ if (m_internalState > QCamera::StartingStatus) {
+ m_internalState = QCamera::StartingStatus;
+ emit statusChanged(m_internalState);
+ } else if (m_internalState < QCamera::StartingStatus) {
+ // Nothing to stop
+ return;
+ }
+ // Status = Starting
+
+ // Cancel ongoing operations if any
+ m_imageSession->cancelCapture();
+ m_videoSession->stopRecording();
+
+ emit cameraReadyChanged(false);
+ if (m_viewfinderEngine)
+ m_viewfinderEngine->stopViewfinder();
+ else
+ setError(KErrGeneral, tr("Failed to stop viewfinder."));
+
+ m_internalState = QCamera::LoadedStatus;
+ emit statusChanged(m_internalState);
+
+ m_inactivityTimer->start(KInactivityTimerTimeout);
+}
+
+void S60CameraControl::videoStateChanged(const S60VideoCaptureSession::TVideoCaptureState state)
+{
+ // Save video state
+ m_videoCaptureState = state;
+
+ if (m_rotateCameraWhenReady) {
+ if (m_videoCaptureState != S60VideoCaptureSession::ERecording &&
+ m_videoCaptureState != S60VideoCaptureSession::EPaused)
+ resetCameraOrientation();
+ }
+
+ // If video recording was stopped, video state reverts back to
+ // Initializing. In that case revert also Camera status to notify that
+ // video initialization needs to be completed.
+ if (state == S60VideoCaptureSession::EInitializing) {
+ if (m_internalState > QCamera::LoadingStatus) {
+ m_internalState = QCamera::LoadingStatus;
+ emit statusChanged(m_internalState);
+ }
+
+ // Handle video initialization completion
+ } else if (state == S60VideoCaptureSession::EInitialized) {
+
+ // Make sure state is not downgraded
+ if (m_internalState == QCamera::LoadedStatus
+ || m_internalState == QCamera::ActiveStatus) {
+ // Do nothing (already in target state)
+ } else if (m_internalState == QCamera::StartingStatus) {
+ m_internalState = QCamera::ActiveStatus;
+ emit statusChanged(m_internalState);
+ } else {
+ m_internalState = QCamera::LoadedStatus;
+ emit statusChanged(m_internalState);
+ }
+
+ switch (m_requestedState) {
+ case QCamera::UnloadedState:
+ stopCamera();
+ unloadCamera();
+ if (m_changeCaptureModeWhenReady) {
+ m_settingCaptureModeInternally = true;
+ setCaptureMode(m_requestedCaptureMode);
+ }
+ break;
+ case QCamera::LoadedState:
+ stopCamera();
+ if (m_changeCaptureModeWhenReady) {
+ m_settingCaptureModeInternally = true;
+ setCaptureMode(m_requestedCaptureMode);
+ }
+ m_inactivityTimer->start(KInactivityTimerTimeout);
+ break;
+ case QCamera::ActiveState:
+ if (m_changeCaptureModeWhenReady) {
+ m_settingCaptureModeInternally = true;
+ setCaptureMode(m_requestedCaptureMode);
+ }
+ startCamera();
+ break;
+
+ default:
+ setError(KErrGeneral, tr("Unexpected camera error."));
+ return;
+ }
+ }
+}
+
+void S60CameraControl::imageCaptured(const int imageId, const QImage& preview)
+{
+ Q_UNUSED(imageId);
+ Q_UNUSED(preview);
+
+ // Unsubscribe the readyForCaptureChanged notification
+ disconnect(m_imageSession, SIGNAL(imageCaptured(const int, const QImage&)),
+ this, SLOT(imageCaptured(const int, const QImage&)));
+
+ if (m_rotateCameraWhenReady)
+ resetCameraOrientation();
+}
+
+void S60CameraControl::advancedSettingsCreated()
+{
+ m_advancedSettings = m_imageSession->advancedSettings();
+
+ if (m_advancedSettings)
+ connect(m_advancedSettings, SIGNAL(error(int, const QString&)), this, SIGNAL(error(int, const QString&)));
+}
+
+void S60CameraControl::MceoCameraReady()
+{
+ // Rotate camera if requested
+ if (m_rotateCameraWhenReady) {
+ resetCameraOrientation();
+ return;
+ }
+
+ if (m_internalState != QCamera::LoadedStatus) {
+
+ switch (m_requestedState) {
+ case QCamera::UnloadedState:
+ m_internalState = QCamera::LoadedStatus;
+ emit statusChanged(QCamera::LoadedStatus);
+
+ stopCamera();
+ unloadCamera();
+
+ if (m_changeCaptureModeWhenReady) {
+ m_settingCaptureModeInternally = true;
+ setCaptureMode(m_requestedCaptureMode);
+ }
+ break;
+
+ case QCamera::LoadedState:
+ if (m_captureMode == QCamera::CaptureVideo) {
+ int prepareSuccess = m_videoSession->initializeVideoRecording();
+ setError(prepareSuccess, tr("Loading video capture failed."));
+
+ // State change signalled when reservation is complete (in videoStateChanged())
+ return;
+ }
+ m_internalState = QCamera::LoadedStatus;
+ emit statusChanged(QCamera::LoadedStatus);
+
+ if (m_changeCaptureModeWhenReady) {
+ setCaptureMode(m_requestedCaptureMode);
+ m_changeCaptureModeWhenReady = false; // Reset
+ }
+
+ if (m_requestedState == QCamera::LoadedStatus &&
+ m_internalState == QCamera::LoadedStatus)
+ m_inactivityTimer->start(KInactivityTimerTimeout);
+ break;
+
+ case QCamera::ActiveState:
+ if (m_captureMode == QCamera::CaptureVideo) {
+ int prepareSuccess = m_videoSession->initializeVideoRecording();
+ setError(prepareSuccess, tr("Loading video capture failed."));
+
+ // State change signalled when reservation is complete (in videoStateChanged())
+ return;
+ }
+
+ m_internalState = QCamera::LoadedStatus;
+ emit statusChanged(QCamera::LoadedStatus);
+
+ if (m_changeCaptureModeWhenReady) {
+ setCaptureMode(m_requestedCaptureMode);
+ m_changeCaptureModeWhenReady = false; // Reset
+ }
+ startCamera();
+ break;
+
+ default:
+ setError(KErrGeneral, tr("Unexpected camera error."));
+ return;
+ }
+ }
+}
+
+void S60CameraControl::MceoHandleError(TCameraEngineError aErrorType, TInt aError)
+{
+ Q_UNUSED(aErrorType);
+
+ if (aError == KErrAccessDenied) {
+ setError(KErrGeneral, tr("Access to camera device was rejected."));
+ } else if (aError == KErrHardwareNotAvailable) {
+ setError(aError, tr("Camera resources were lost."));
+ toStandByStatus();
+ }
+ else
+ setError(aError, tr("Unexpected camera error."));
+}
+
+void S60CameraControl::setError(const TInt error, const QString &description)
+{
+ if (error == KErrNone)
+ return;
+
+ m_error = error;
+ QCamera::Error cameraError = fromSymbianErrorToQtMultimediaError(m_error);
+
+ emit this->error(int(cameraError), description);
+
+ // Reset everything, if other than not supported error or resource loss
+ if (error != KErrNotSupported && error != KErrHardwareNotAvailable)
+ resetCamera(true); // Try to recover from error
+ else
+ m_error = KErrNone; // Reset error
+}
+
+QCamera::Error S60CameraControl::fromSymbianErrorToQtMultimediaError(int aError)
+{
+ switch(aError) {
+ case KErrNone:
+ return QCamera::NoError; // No errors have occurred
+
+ case KErrNotSupported:
+ return QCamera::NotSupportedFeatureError; // The feature is not supported
+ case KErrNotFound:
+ case KErrBadHandle:
+ return QCamera::ServiceMissingError; // No camera service available
+ case KErrArgument:
+ case KErrNotReady:
+ return QCamera::InvalidRequestError; // Invalid parameter or state
+
+ default:
+ return QCamera::CameraError; // An error has occurred (i.e. General Error)
+ }
+}
+
+// For S60CameraVideoDeviceControl
+int S60CameraControl::deviceCount()
+{
+#ifdef Q_CC_NOKIAX86 // Emulator
+ return 1;
+#endif
+
+ return CCameraEngine::CamerasAvailable();
+}
+
+int S60CameraControl::defaultDevice() const
+{
+ return KDefaultCameraDevice;
+}
+
+int S60CameraControl::selectedDevice() const
+{
+ return m_deviceIndex;
+}
+
+void S60CameraControl::setSelectedDevice(const int index)
+{
+ if (m_deviceIndex != index) {
+ if (index >= 0 && index < deviceCount()) {
+ m_deviceIndex = index;
+ resetCamera();
+ } else {
+ setError(KErrNotSupported, tr("Requested camera is not available."));
+ }
+ }
+}
+
+QString S60CameraControl::name(const int index)
+{
+ QString cameraName;
+ switch (index) {
+ case 0:
+ cameraName = tr("Primary camera");
+ break;
+ case 1:
+ cameraName = tr("Secondary camera");
+ break;
+ case 2:
+ cameraName = tr("Tertiary camera");
+ break;
+
+ default:
+ cameraName = tr("Unidentified Camera");
+ break;
+ }
+
+ return cameraName;
+}
+
+QString S60CameraControl::description(const int index)
+{
+ QString cameraDesc;
+ switch (index) {
+ case 0:
+ cameraDesc = tr("Device primary camera");
+ break;
+ case 1:
+ cameraDesc = tr("Device secondary camera");
+ break;
+ case 2:
+ cameraDesc = tr("Device tertiary camera");
+ break;
+
+ default:
+ cameraDesc = tr("Unidentified Camera");
+ break;
+ }
+
+ return cameraDesc;
+}
+
+void S60CameraControl::resetCamera(bool errorHandling)
+{
+ if (m_inactivityTimer->isActive())
+ m_inactivityTimer->stop();
+
+ // Cancel ongoing activity
+ m_imageSession->cancelCapture();
+ m_videoSession->stopRecording(false); // Don't re-initialize video
+
+ // Advanced settings must be destructed before the camera
+ m_imageSession->deleteAdvancedSettings();
+
+ // Release resources
+ stopCamera();
+ unloadCamera();
+
+ disconnect(m_viewfinderEngine, SIGNAL(error(int, const QString&)), this, SIGNAL(error(int,const QString&)));
+ if (m_viewfinderEngine) {
+ delete m_viewfinderEngine;
+ m_viewfinderEngine = 0;
+ }
+
+ if (m_cameraEngine) {
+ delete m_cameraEngine;
+ m_cameraEngine = 0;
+ }
+
+ TRAPD(err, m_cameraEngine = CCameraEngine::NewL(m_deviceIndex, 0, this));
+ if (err) {
+ m_cameraEngine = 0;
+ if (errorHandling) {
+ qWarning("Failed to recover from error.");
+ if (err == KErrPermissionDenied)
+ emit error(int(QCamera::ServiceMissingError), tr("Recovering from error failed. Possibly missing capabilities."));
+ else
+ emit error(int(QCamera::CameraError), tr("Recovering from error failed."));
+ } else {
+ if (err == KErrPermissionDenied)
+ setError(err, tr("Camera device creation failed. Possibly missing capabilities."));
+ else
+ setError(err, tr("Camera device creation failed."));
+ }
+ return;
+ }
+
+ // Notify list of available camera devices has been updated
+ emit devicesChanged();
+
+ m_viewfinderEngine = new S60CameraViewfinderEngine(this, m_cameraEngine, this);
+ if (m_viewfinderEngine == 0)
+ setError(KErrNoMemory, tr("Viewfinder device creation failed."));
+ connect(m_viewfinderEngine, SIGNAL(error(int, const QString&)), this, SIGNAL(error(int,const QString&)));
+
+ setCameraHandles();
+
+ // Reset state
+ //setState(QCamera::UnloadedState);
+ if (m_internalState != QCamera::UnloadedStatus) {
+ m_internalState = QCamera::UnloadedStatus;
+ emit statusChanged(m_internalState);
+ }
+ if (m_requestedState != QCamera::UnloadedState) {
+ m_requestedState = QCamera::UnloadedState;
+ emit stateChanged(m_requestedState);
+ }
+
+ // Reset error
+ m_error = KErrNone;
+}
+
+/*
+ * Reset everything else than viewfinder engine and errors.
+ */
+void S60CameraControl::resetCameraOrientation()
+{
+ // If camera has not been created, it will be created automatically to correct orientation
+ if (!m_cameraEngine)
+ return;
+
+ // Check Image/VideoCapture allow rotation
+ if ((!m_cameraEngine->IsCameraReady() && m_internalState != QCamera::UnloadedStatus) ||
+ m_videoCaptureState == S60VideoCaptureSession::ERecording ||
+ m_videoCaptureState == S60VideoCaptureSession::EPaused) {
+
+ // If image capture is ongoing, request notification about the
+ // completion (imageCaptured() is used because that comes asynchronously
+ // after the image is captured)
+ // Obs! If preview creation is changed to be synchnonously done during
+ // the image capture this implementation needs to be changed)
+ if (m_videoCaptureState != S60VideoCaptureSession::ERecording &&
+ m_videoCaptureState != S60VideoCaptureSession::EPaused &&
+ m_internalState == QCamera::ActiveStatus)
+ connect(m_imageSession, SIGNAL(imageCaptured(const int, const QImage&)),
+ this, SLOT(imageCaptured(const int, const QImage&)));
+
+ m_rotateCameraWhenReady = true;
+ return;
+ }
+
+ m_rotateCameraWhenReady = false; // Reset
+
+ QCamera::State originalState = m_requestedState;
+
+ // Cancel ongoing activity
+ m_imageSession->cancelCapture();
+ m_videoSession->stopRecording(false); // Don't re-initialize video
+
+ // Advanced settings must be destructed before the camera
+ m_imageSession->deleteAdvancedSettings();
+
+ // Release resources
+ stopCamera();
+ unloadCamera();
+
+ // Unset CameraEngine to ViewfinderEngine
+ m_viewfinderEngine->setNewCameraEngine(0);
+ if (m_cameraEngine) {
+ delete m_cameraEngine;
+ m_cameraEngine = 0;
+ }
+
+ TRAPD(err, m_cameraEngine = CCameraEngine::NewL(m_deviceIndex, 0, this));
+ if (err) {
+ setError(err, tr("Camera device creation failed."));
+ return;
+ }
+ // Reset CameraEngine to ViewfinderEngine
+ m_viewfinderEngine->setNewCameraEngine(m_cameraEngine);
+
+ // Notify list of available camera devices has been updated
+ emit devicesChanged();
+
+ setCameraHandles();
+
+ // Reset state
+ if (m_internalState != QCamera::UnloadedStatus) {
+ m_internalState = QCamera::UnloadedStatus;
+ emit statusChanged(m_internalState);
+ }
+ if (m_requestedState != QCamera::UnloadedState) {
+ m_requestedState = QCamera::UnloadedState;
+ emit stateChanged(m_requestedState);
+ }
+
+ setState(originalState);
+}
+
+void S60CameraControl::setCameraHandles()
+{
+ m_imageSession->setCurrentDevice(m_deviceIndex);
+ m_imageSession->setCameraHandle(m_cameraEngine);
+ m_cameraEngine->SetImageCaptureObserver(m_imageSession);
+ m_videoSession->setCameraHandle(m_cameraEngine);
+}
+
+void S60CameraControl::toStandByStatus()
+{
+ // Cancel ongoing operations if any
+ m_imageSession->cancelCapture();
+ m_videoSession->stopRecording(false); // Don't re-initialize video
+
+ emit cameraReadyChanged(false);
+ if (m_viewfinderEngine)
+ m_viewfinderEngine->stopViewfinder();
+ else
+ setError(KErrGeneral, tr("Failed to stop viewfinder."));
+
+ m_cameraEngine->ReleaseAndPowerOff();
+
+ m_internalState = QCamera::StandbyStatus;
+ emit statusChanged(m_internalState);
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60cameracontrol.h b/src/plugins/symbian/ecam/s60cameracontrol.h
new file mode 100644
index 000000000..95c31fb34
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameracontrol.h
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60CAMERACONTROL_H
+#define S60CAMERACONTROL_H
+
+#include <qcameracontrol.h>
+
+#include "s60cameraengineobserver.h" // MCameraEngineObserver
+#include "s60videocapturesession.h" // TVideoCaptureState
+#include "s60cameraviewfinderengine.h" // ViewfinderOutputType
+
+#include <e32base.h>
+#include <fbs.h>
+
+QT_USE_NAMESPACE
+
+class S60CameraService;
+class S60ImageCaptureSession;
+class S60VideoCaptureSession;
+class S60CameraSettings;
+class CCameraEngine;
+class S60CameraViewfinderEngine;
+class QTimer;
+
+/*
+ * Control for controlling camera base operations (e.g. start/stop and capture
+ * mode).
+ */
+class S60CameraControl : public QCameraControl, public MCameraEngineObserver
+{
+ Q_OBJECT
+
+public: // Constructors & Destructor
+
+ S60CameraControl(QObject *parent = 0);
+ S60CameraControl(S60VideoCaptureSession *videosession,
+ S60ImageCaptureSession *imagesession,
+ QObject *parent = 0);
+ ~S60CameraControl();
+
+public: // QCameraControl
+
+ // State
+ QCamera::State state() const;
+ void setState(QCamera::State state);
+
+ // Status
+ QCamera::Status status() const;
+
+ // Capture Mode
+ QCamera::CaptureMode captureMode() const;
+ void setCaptureMode(QCamera::CaptureMode);
+ bool isCaptureModeSupported(QCamera::CaptureMode mode) const;
+
+ // Property Setting
+ bool canChangeProperty(QCameraControl::PropertyChangeType changeType, QCamera::Status status) const;
+
+/*
+Q_SIGNALS:
+ void stateChanged(QCamera::State);
+ void statusChanged(QCamera::Status);
+ void error(int error, const QString &errorString);
+ void captureModeChanged(QCamera::CaptureMode);
+*/
+
+public: // Internal
+
+ void setError(const TInt error, const QString &description);
+ void resetCameraOrientation();
+
+ // To provide QVideoDeviceControl info
+ static int deviceCount();
+ static QString name(const int index);
+ static QString description(const int index);
+ int defaultDevice() const;
+ int selectedDevice() const;
+ void setSelectedDevice(const int index);
+
+ void setVideoOutput(QObject *output,
+ const S60CameraViewfinderEngine::ViewfinderOutputType type);
+ void releaseVideoOutput(const S60CameraViewfinderEngine::ViewfinderOutputType type);
+
+private slots: // Internal Slots
+
+ void videoStateChanged(const S60VideoCaptureSession::TVideoCaptureState state);
+ // Needed to detect image capture completion when trying to rotate the camera
+ void imageCaptured(const int imageId, const QImage& preview);
+ /*
+ * This method moves the camera to the StandBy status:
+ * - If camera access was lost
+ * - If camera has been inactive in LoadedStatus for a long time
+ */
+ void toStandByStatus();
+ void advancedSettingsCreated();
+
+protected: // MCameraEngineObserver
+
+ void MceoCameraReady();
+ void MceoHandleError(TCameraEngineError aErrorType, TInt aError);
+
+private: // Internal
+
+ QCamera::Error fromSymbianErrorToQtMultimediaError(int aError);
+
+ void loadCamera();
+ void unloadCamera();
+ void startCamera();
+ void stopCamera();
+
+ void resetCamera(bool errorHandling = false);
+ void setCameraHandles();
+
+signals: // Internal Signals
+
+ void cameraReadyChanged(bool);
+ void devicesChanged();
+
+private: // Data
+
+ CCameraEngine *m_cameraEngine;
+ S60CameraViewfinderEngine *m_viewfinderEngine;
+ S60ImageCaptureSession *m_imageSession;
+ S60VideoCaptureSession *m_videoSession;
+ S60CameraSettings *m_advancedSettings;
+ QObject *m_videoOutput;
+ QTimer *m_inactivityTimer;
+ QCamera::CaptureMode m_captureMode;
+ QCamera::CaptureMode m_requestedCaptureMode;
+ bool m_settingCaptureModeInternally;
+ QCamera::Status m_internalState;
+ QCamera::State m_requestedState;
+ int m_deviceIndex;
+ mutable int m_error;
+ bool m_changeCaptureModeWhenReady;
+ bool m_rotateCameraWhenReady;
+ S60VideoCaptureSession::TVideoCaptureState m_videoCaptureState;
+};
+
+#endif // S60CAMERACONTROL_H
diff --git a/src/plugins/symbian/ecam/s60cameraengine.cpp b/src/plugins/symbian/ecam/s60cameraengine.cpp
new file mode 100644
index 000000000..dbd5fb33e
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraengine.cpp
@@ -0,0 +1,824 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the Qt Mobility Components.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** No Commercial Usage
+ ** This file contains pre-release code and may not be distributed.
+ ** You may use this file in accordance with the terms and conditions
+ ** contained in the Technology Preview License Agreement accompanying
+ ** this package.
+ **
+ ** GNU Lesser General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU Lesser
+ ** General Public License version 2.1 as published by the Free Software
+ ** Foundation and appearing in the file LICENSE.LGPL included in the
+ ** packaging of this file. Please review the following information to
+ ** ensure the GNU Lesser General Public License version 2.1 requirements
+ ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** If you have questions regarding the use of this file, please contact
+ ** Nokia at qt-info@nokia.com.
+ **
+ **
+ **
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#include "s60cameraengine.h"
+#include "s60cameraengineobserver.h"
+#include "s60cameraconstants.h"
+#include <QtCore/qglobal.h>
+#include <fbs.h> // CFbsBitmap
+#ifdef ECAM_PREVIEW_API
+ #include <platform/ecam/camerasnapshot.h>
+#endif // ECAM_PREVIEW_API
+
+CCameraEngine::CCameraEngine()
+{
+}
+
+CCameraEngine::CCameraEngine(TInt aCameraHandle,
+ TInt aPriority,
+ MCameraEngineObserver* aObserver) :
+ // CBase initializes member variables to NULL
+ iObserver(aObserver),
+ iCameraIndex(aCameraHandle),
+ iPriority(aPriority),
+ iEngineState(EEngineNotReady),
+ iCaptureResolution(TSize(0,0)),
+ iNew2LImplementation(false),
+ iLatestImageBufferIndex(1) // Thus we start from index 0
+{
+ // Observer is mandatory
+ ASSERT(aObserver != NULL);
+}
+
+CCameraEngine::~CCameraEngine()
+{
+ StopViewFinder();
+ ReleaseViewFinderBuffer(); // Releases iViewFinderBuffer
+ ReleaseImageBuffer(); // Releases iImageBuffer + iImageBitmap
+
+ iAdvancedSettingsObserver = NULL;
+ iImageCaptureObserver = NULL;
+ iViewfinderObserver = NULL;
+
+#ifdef S60_CAM_AUTOFOCUS_SUPPORT
+ delete iAutoFocus;
+#endif // S60_CAM_AUTOFOCUS_SUPPORT
+
+ if (iCamera) {
+ iCamera->Release();
+ delete iCamera;
+ iCamera = NULL;
+ }
+}
+
+TInt CCameraEngine::CamerasAvailable()
+{
+ return CCamera::CamerasAvailable();
+}
+
+CCameraEngine* CCameraEngine::NewL(TInt aCameraHandle,
+ TInt aPriority,
+ MCameraEngineObserver* aObserver)
+{
+ CCameraEngine* self = new (ELeave) CCameraEngine(aCameraHandle, aPriority, aObserver);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+}
+
+void CCameraEngine::ConstructL()
+{
+ if (!CCamera::CamerasAvailable())
+ User::Leave(KErrHardwareNotAvailable);
+
+#ifndef Q_CC_NOKIAX86 // Not Emulator
+ TInt err(KErrNone);
+#else // Emulator
+ TInt err(KErrNotFound);
+#endif // !(Q_CC_NOKIAX86)
+
+#ifdef S60_31_PLATFORM
+ // Construct CCamera object for S60 3.1 (NewL)
+ iNew2LImplementation = false;
+ TRAP(err, iCamera = CCamera::NewL(*this, iCameraIndex));
+ if (err)
+ User::Leave(err);
+#else // For S60 3.2 onwards - use this constructor (New2L)
+ iNew2LImplementation = true;
+ TRAP(err, iCamera = CCamera::New2L(*this, iCameraIndex, iPriority));
+ if (err)
+ User::Leave(err);
+#endif // S60_31_PLATFORM
+
+#ifdef S60_CAM_AUTOFOCUS_SUPPORT
+ // Might not be supported for secondary camera, discard errors
+ TRAP(err, iAutoFocus = CCamAutoFocus::NewL(iCamera));
+#endif // S60_CAM_AUTOFOCUS_SUPPORT
+
+ if (iCamera == NULL)
+ User::Leave(KErrNoMemory);
+
+ iCamera->CameraInfo(iCameraInfo);
+}
+
+void CCameraEngine::SetAdvancedObserver(MAdvancedSettingsObserver* aAdvancedSettingsObserver)
+{
+ iAdvancedSettingsObserver = aAdvancedSettingsObserver;
+}
+
+void CCameraEngine::SetImageCaptureObserver(MCameraEngineImageCaptureObserver* aImageCaptureObserver)
+{
+ iImageCaptureObserver = aImageCaptureObserver;
+}
+
+void CCameraEngine::SetViewfinderObserver(MCameraViewfinderObserver* aViewfinderObserver)
+{
+ iViewfinderObserver = aViewfinderObserver;
+}
+
+void CCameraEngine::ReserveAndPowerOn()
+{
+ if (!iCamera || iEngineState > EEngineNotReady) {
+ iObserver->MceoHandleError(EErrReserve, KErrNotReady);
+ return;
+ }
+
+ iCamera->Reserve();
+}
+
+void CCameraEngine::ReleaseAndPowerOff()
+{
+ if (iEngineState >= EEngineIdle) {
+ CancelCapture();
+ StopViewFinder();
+ FocusCancel();
+ iCamera->PowerOff();
+ iCamera->Release();
+ }
+ iEngineState = EEngineNotReady;
+}
+
+void CCameraEngine::StartViewFinderL(TSize& aSize)
+{
+ if (iEngineState < EEngineIdle)
+ User::Leave(KErrNotReady);
+
+ if (0 == (iCameraInfo.iOptionsSupported & TCameraInfo::EViewFinderBitmapsSupported))
+ User::Leave(KErrNotSupported);
+
+ if (!iCamera->ViewFinderActive()) {
+ if (iCameraIndex != 0)
+ iCamera->SetViewFinderMirrorL(true);
+ iCamera->StartViewFinderBitmapsL(aSize);
+ }
+}
+
+void CCameraEngine::StopViewFinder()
+{
+ if (iCamera && iCamera->ViewFinderActive())
+ iCamera->StopViewFinder();
+}
+
+void CCameraEngine::StartDirectViewFinderL(RWsSession& aSession,
+ CWsScreenDevice& aScreenDevice,
+ RWindowBase& aWindow,
+ TRect& aScreenRect,
+ TRect& aClipRect)
+{
+ if (iEngineState < EEngineIdle)
+ User::Leave(KErrNotReady);
+
+ if (0 == (iCameraInfo.iOptionsSupported & TCameraInfo::EViewFinderDirectSupported))
+ User::Leave(KErrNotSupported);
+
+ if (!iCamera->ViewFinderActive()) {
+ // Viewfinder extent needs to be clipped according to the clip rect.
+ // This is because the native camera framework does not support
+ // clipping and starting viewfinder with bigger than the display(S60
+ // 5.0 and older)/window(Symbian^3 and later) would cause viewfinder
+ // starting to fail entirely. This causes shrinking effect in some
+ // cases, but is better than not having the viewfinder at all.
+ if (aScreenRect.Intersects(aClipRect))
+ aScreenRect.Intersection(aClipRect);
+
+ if (iCameraIndex != 0)
+ iCamera->SetViewFinderMirrorL(true);
+ if (aScreenRect.Width() > 0 && aScreenRect.Height() > 0) {
+ iCamera->StartViewFinderDirectL(aSession, aScreenDevice, aWindow, aScreenRect);
+ } else {
+ if (iObserver)
+ iObserver->MceoHandleError(EErrViewFinderReady, KErrArgument);
+ }
+ }
+}
+
+void CCameraEngine::PrepareL(TSize& aCaptureSize, CCamera::TFormat aFormat)
+{
+ iImageCaptureFormat = aFormat;
+
+ TInt closestVar = KMaxTInt, selected = 0;
+ TSize size;
+
+ // Scan through supported capture sizes and select the closest match
+ for (TInt index = 0; index < iCameraInfo.iNumImageSizesSupported; index++) {
+
+ iCamera->EnumerateCaptureSizes(size, index, aFormat);
+ if (size == aCaptureSize) {
+ selected = index;
+ break;
+ }
+
+ TSize varSz = size - aCaptureSize;
+ TInt variation = varSz.iWidth * varSz.iHeight;
+ if (variation < closestVar) {
+ closestVar = variation;
+ selected = index;
+ }
+ }
+
+ iCamera->EnumerateCaptureSizes(aCaptureSize, selected, aFormat);
+ iCaptureResolution = aCaptureSize;
+ iCamera->PrepareImageCaptureL(aFormat, selected);
+}
+
+void CCameraEngine::CaptureL()
+{
+ if (iEngineState < EEngineIdle)
+ User::Leave(KErrNotReady);
+
+ iCamera->CaptureImage();
+ iEngineState = EEngineCapturing;
+}
+
+void CCameraEngine::CancelCapture()
+{
+ if (iEngineState == EEngineCapturing) {
+ iCamera->CancelCaptureImage();
+ iEngineState = EEngineIdle;
+ }
+}
+
+void CCameraEngine::HandleEvent(const TECAMEvent &aEvent)
+{
+ if (aEvent.iEventType == KUidECamEventReserveComplete) {
+ ReserveComplete(aEvent.iErrorCode);
+ return;
+ }
+
+ if (aEvent.iEventType == KUidECamEventPowerOnComplete) {
+ PowerOnComplete(aEvent.iErrorCode);
+ return;
+ }
+
+ if (aEvent.iEventType == KUidECamEventCameraNoLongerReserved) {
+ // All camera related operations need to be stopped
+ iObserver->MceoHandleError(EErrReserve, KErrHardwareNotAvailable);
+ return;
+ }
+
+#ifdef ECAM_PREVIEW_API
+ if (aEvent.iEventType == KUidECamEventCameraSnapshot) {
+ HandlePreview();
+ return;
+ }
+#endif // ECAM_PREVIEW_API
+
+#if !defined(Q_CC_NOKIAX86) // Not Emulator
+ // Other events; Exposure, Zoom, etc. (See ecamadvancedsettings.h)
+ if (iAdvancedSettingsObserver)
+ iAdvancedSettingsObserver->HandleAdvancedEvent(aEvent);
+
+ if (iImageCaptureObserver)
+ iImageCaptureObserver->MceoHandleOtherEvent(aEvent);
+#endif // !Q_CC_NOKIAX86
+}
+
+void CCameraEngine::ReserveComplete(TInt aError)
+{
+ if (aError == KErrNone) {
+ iCamera->PowerOn();
+#ifdef S60_31_PLATFORM
+ } else if (aError == KErrAlreadyExists) { // Known Issue on some S60 3.1 devices
+ User::After(500000); // Wait for 0,5 second and try again
+ iCamera->Reserve();
+#endif // S60_31_PLATFORM
+ } else {
+ iObserver->MceoHandleError(EErrReserve, aError);
+ }
+}
+
+void CCameraEngine::PowerOnComplete(TInt aError)
+{
+ if (aError) {
+ iObserver->MceoHandleError(EErrPowerOn, aError);
+ iEngineState = EEngineNotReady;
+ return;
+ }
+
+ // Init AutoFocus
+#ifndef Q_CC_NOKIAX86 // Not Emulator
+#ifdef S60_CAM_AUTOFOCUS_SUPPORT // S60 3.1
+ if( iAutoFocus ) {
+ TRAPD(afErr, iAutoFocus->InitL( *this ));
+ if (afErr) {
+ delete iAutoFocus;
+ iAutoFocus = 0;
+ }
+ }
+#endif // S60_CAM_AUTOFOCUS_SUPPORT
+#endif // !Q_CC_NOKIAX86
+
+ iEngineState = EEngineIdle;
+ iObserver->MceoCameraReady();
+}
+
+#ifdef ECAM_PREVIEW_API
+/**
+ * This method creates the CCameraPreview object and requests the previews to
+ * be provided during the image or video capture
+ */
+void CCameraEngine::EnablePreviewProvider(MCameraPreviewObserver *aPreviewObserver)
+{
+ // Delete old one if exists
+ if (iCameraSnapshot)
+ delete iCameraSnapshot;
+
+ iPreviewObserver = aPreviewObserver;
+
+ TInt error = KErrNone;
+
+ if (iCamera) {
+ TRAP(error, iCameraSnapshot = CCamera::CCameraSnapshot::NewL(*iCamera));
+ if (error) {
+ if (iObserver)
+ iObserver->MceoHandleError(EErrPreview, error);
+ return;
+ }
+
+ TRAP(error, iCameraSnapshot->PrepareSnapshotL(KDefaultFormatPreview, SelectPreviewResolution(), EFalse));
+ if (error) {
+ if (iObserver)
+ iObserver->MceoHandleError(EErrPreview, error);
+ return;
+ }
+
+ iCameraSnapshot->StartSnapshot();
+ } else {
+ if (iObserver)
+ iObserver->MceoHandleError(EErrPreview, KErrNotReady);
+ }
+}
+
+/**
+ * This method disables and destroys the CCameraPreview object. Thus previews
+ * will not be provided during the image or video capture.
+ */
+void CCameraEngine::DisablePreviewProvider()
+{
+ if (!iCameraSnapshot)
+ return;
+
+ iCameraSnapshot->StopSnapshot();
+
+ delete iCameraSnapshot;
+ iCameraSnapshot = 0;
+
+ iPreviewObserver = 0;
+}
+#endif // ECAM_PREVIEW_API
+
+/*
+ * MCameraObserver2:
+ * New viewfinder frame available
+ */
+void CCameraEngine::ViewFinderReady(MCameraBuffer &aCameraBuffer, TInt aError)
+{
+ iViewFinderBuffer = &aCameraBuffer;
+
+ if (aError == KErrNone) {
+ if (iViewfinderObserver) {
+ TRAPD(err, iViewfinderObserver->MceoViewFinderFrameReady(aCameraBuffer.BitmapL(0)));
+ if (err)
+ iObserver->MceoHandleError(EErrViewFinderReady, err);
+ } else {
+ iObserver->MceoHandleError(EErrViewFinderReady, KErrNotReady);
+ }
+ }
+ else {
+ iObserver->MceoHandleError(EErrViewFinderReady, aError);
+ }
+}
+
+/*
+ * MCameraObserver:
+ * New viewfinder frame available
+ */
+void CCameraEngine::ViewFinderFrameReady(CFbsBitmap& aFrame)
+{
+ if (iViewfinderObserver)
+ iViewfinderObserver->MceoViewFinderFrameReady(aFrame);
+ else
+ iObserver->MceoHandleError(EErrViewFinderReady, KErrNotReady);
+}
+
+void CCameraEngine::ReleaseViewFinderBuffer()
+{
+ if (iNew2LImplementation) { // NewL Implementation does not use MCameraBuffer
+ if (iViewFinderBuffer) {
+ iViewFinderBuffer->Release();
+ iViewFinderBuffer = NULL;
+ }
+ }
+}
+
+void CCameraEngine::ReleaseImageBuffer()
+{
+ // Reset Bitmap
+ if (iLatestImageBufferIndex == 1 || iImageBitmap2 == NULL) {
+ if (iImageBitmap1) {
+ if (!iNew2LImplementation) { // NewL - Ownership transferred
+ iImageBitmap1->Reset(); // Reset/Delete Bitmap
+ delete iImageBitmap1;
+ }
+ iImageBitmap1 = NULL;
+ }
+ } else {
+ if (iImageBitmap2) {
+ if (!iNew2LImplementation) { // NewL - Ownership transferred
+ iImageBitmap2->Reset(); // Reset/Delete Bitmap
+ delete iImageBitmap2;
+ }
+ iImageBitmap2 = NULL;
+ }
+ }
+
+ // Reset Data pointers
+ if (iLatestImageBufferIndex == 1 || iImageData2 == NULL) {
+ if (!iNew2LImplementation) // NewL - Ownership transfers with buffer
+ delete iImageData1;
+ iImageData1 = NULL;
+ } else {
+ if (!iNew2LImplementation) // NewL - Ownership transfers with buffer
+ delete iImageData2;
+ iImageData2 = NULL;
+ }
+
+ // Reset ImageBuffer - New2L Implementation only
+ if (iLatestImageBufferIndex == 1 || iImageBuffer2 == NULL) {
+ if (iImageBuffer1) {
+ iImageBuffer1->Release();
+ iImageBuffer1 = NULL;
+ }
+ } else {
+ if (iImageBuffer2) {
+ iImageBuffer2->Release();
+ iImageBuffer2 = NULL;
+ }
+ }
+}
+
+/*
+ * MCameraObserver2
+ * Captured image is ready (New2L version)
+ */
+void CCameraEngine::ImageBufferReady(MCameraBuffer &aCameraBuffer, TInt aError)
+{
+ // Use the buffer that is available
+ if (!iImageBuffer1) {
+ iLatestImageBufferIndex = 0;
+ iImageBuffer1 = &aCameraBuffer;
+ } else {
+ iLatestImageBufferIndex = 1;
+ iImageBuffer2 = &aCameraBuffer;
+ }
+
+ bool isBitmap = true;
+ TInt err = KErrNone;
+
+ switch (iImageCaptureFormat) {
+ case CCamera::EFormatFbsBitmapColor4K:
+ case CCamera::EFormatFbsBitmapColor64K:
+ case CCamera::EFormatFbsBitmapColor16M:
+ case CCamera::EFormatFbsBitmapColor16MU:
+ if (iLatestImageBufferIndex == 0) {
+ TRAP(err, iImageBitmap1 = &iImageBuffer1->BitmapL(0));
+ if (err) {
+ if (iImageCaptureObserver)
+ iImageCaptureObserver->MceoHandleError(EErrImageReady, err);
+ }
+ } else {
+ TRAP(err, iImageBitmap2 = &iImageBuffer2->BitmapL(0));
+ if (err) {
+ if (iImageCaptureObserver)
+ iImageCaptureObserver->MceoHandleError(EErrImageReady, err);
+ }
+ }
+ isBitmap = true;
+ break;
+ case CCamera::EFormatExif:
+ if (iLatestImageBufferIndex == 0) {
+ TRAP(err, iImageData1 = iImageBuffer1->DataL(0));
+ if (err) {
+ if (iImageCaptureObserver)
+ iImageCaptureObserver->MceoHandleError(EErrImageReady, err);
+ }
+ } else {
+ TRAP(err, iImageData2 = iImageBuffer2->DataL(0));
+ if (err) {
+ if (iImageCaptureObserver)
+ iImageCaptureObserver->MceoHandleError(EErrImageReady, err);
+ }
+ }
+ isBitmap = false;
+ break;
+
+ default:
+ if (iImageCaptureObserver)
+ iImageCaptureObserver->MceoHandleError(EErrImageReady, KErrNotSupported);
+ return;
+ }
+
+ // Handle captured image
+ HandleImageReady(aError, isBitmap);
+}
+
+/*
+ * MCameraObserver
+ * Captured image is ready (NewL version)
+ */
+void CCameraEngine::ImageReady(CFbsBitmap* aBitmap, HBufC8* aData, TInt aError)
+{
+ bool isBitmap = true;
+
+ // Toggle between the 2 buffers
+ if (iLatestImageBufferIndex == 1) {
+ iLatestImageBufferIndex = 0;
+ } else {
+ iLatestImageBufferIndex = 1;
+ }
+
+ switch (iImageCaptureFormat) {
+ case CCamera::EFormatFbsBitmapColor4K:
+ case CCamera::EFormatFbsBitmapColor64K:
+ case CCamera::EFormatFbsBitmapColor16M:
+ case CCamera::EFormatFbsBitmapColor16MU:
+ if (iLatestImageBufferIndex == 0)
+ iImageBitmap1 = aBitmap;
+ else
+ iImageBitmap2 = aBitmap;
+ isBitmap = true;
+ break;
+ case CCamera::EFormatExif:
+ if (iLatestImageBufferIndex == 0)
+ iImageData1 = aData;
+ else
+ iImageData2 = aData;
+ isBitmap = false;
+ break;
+
+ default:
+ if (iImageCaptureObserver)
+ iImageCaptureObserver->MceoHandleError(EErrImageReady, KErrNotSupported);
+ return;
+ }
+
+ // Handle captured image
+ HandleImageReady(aError, isBitmap);
+}
+
+void CCameraEngine::HandleImageReady(const TInt aError, const bool isBitmap)
+{
+ iEngineState = EEngineIdle;
+
+ if (aError == KErrNone) {
+ if (isBitmap)
+ if (iImageCaptureObserver) {
+ if (iLatestImageBufferIndex == 0)
+ iImageCaptureObserver->MceoCapturedBitmapReady(iImageBitmap1);
+ else
+ iImageCaptureObserver->MceoCapturedBitmapReady(iImageBitmap2);
+ }
+ else
+ ReleaseImageBuffer();
+ else {
+ if (iImageCaptureObserver) {
+ if (iLatestImageBufferIndex == 0)
+ iImageCaptureObserver->MceoCapturedDataReady(iImageData1);
+ else
+ iImageCaptureObserver->MceoCapturedDataReady(iImageData2);
+ }
+ else
+ ReleaseImageBuffer();
+ }
+ } else {
+ if (iImageCaptureObserver)
+ iImageCaptureObserver->MceoHandleError(EErrImageReady, aError);
+ }
+}
+
+#ifdef ECAM_PREVIEW_API
+void CCameraEngine::HandlePreview()
+{
+ if (!iCameraSnapshot) {
+ if (iObserver)
+ iObserver->MceoHandleError(EErrPreview, KErrGeneral);
+ return;
+ }
+
+ RArray<TInt> previewIndices;
+ CleanupClosePushL(previewIndices);
+
+ MCameraBuffer &newPreview = iCameraSnapshot->SnapshotDataL(previewIndices);
+
+ for (TInt i = 0; i < previewIndices.Count(); ++i)
+ iPreviewObserver->MceoPreviewReady(newPreview.BitmapL(0));
+
+ CleanupStack::PopAndDestroy(); // RArray<TInt> previewIndices
+}
+
+TSize CCameraEngine::SelectPreviewResolution()
+{
+ TSize currentResolution(iCaptureResolution);
+
+ TSize previewResolution(0, 0);
+ if (currentResolution == TSize(4000,2248) ||
+ currentResolution == TSize(3264,1832) ||
+ currentResolution == TSize(2592,1456) ||
+ currentResolution == TSize(1920,1080) ||
+ currentResolution == TSize(1280,720)) {
+ previewResolution = KDefaultSizePreview_Wide;
+ } else if (currentResolution == TSize(352,288) ||
+ currentResolution == TSize(176,144)) {
+ previewResolution = KDefaultSizePreview_CIF;
+ } else if (currentResolution == TSize(720,576)) {
+ previewResolution = KDefaultSizePreview_PAL;
+ } else if (currentResolution == TSize(720,480)) {
+ previewResolution = KDefaultSizePreview_NTSC;
+ } else {
+ previewResolution = KDefaultSizePreview_Normal;
+ }
+
+ return previewResolution;
+}
+#endif // ECAM_PREVIEW_API
+
+//=============================================================================
+// S60 3.1 - AutoFocus support (Other platforms, see S60CameraSettings class)
+//=============================================================================
+
+void CCameraEngine::InitComplete(TInt aError)
+{
+ if (aError) {
+ if (iImageCaptureObserver)
+ iImageCaptureObserver->MceoHandleError(EErrAutoFocusInit, aError);
+ }
+}
+
+void CCameraEngine::OptimisedFocusComplete(TInt aError)
+{
+ iEngineState = EEngineIdle;
+
+ if (aError == KErrNone)
+ if (iImageCaptureObserver)
+ iImageCaptureObserver->MceoFocusComplete();
+ else {
+ if (iImageCaptureObserver)
+ iImageCaptureObserver->MceoHandleError(EErrOptimisedFocusComplete, aError);
+ }
+}
+
+TBool CCameraEngine::IsCameraReady() const
+{
+ // If reserved and powered on, but not focusing or capturing
+ if (iEngineState == EEngineIdle)
+ return ETrue;
+
+ return EFalse;
+}
+
+TBool CCameraEngine::IsDirectViewFinderSupported() const
+{
+ if (iCameraInfo.iOptionsSupported & TCameraInfo::EViewFinderDirectSupported)
+ return true;
+ else
+ return false;
+}
+
+TCameraInfo *CCameraEngine::CameraInfo()
+{
+ return &iCameraInfo;
+}
+
+TBool CCameraEngine::IsAutoFocusSupported() const
+{
+#ifndef Q_CC_NOKIAX86 // Not Emulator
+
+#ifdef S60_CAM_AUTOFOCUS_SUPPORT // S60 3.1
+ return (iAutoFocus) ? ETrue : EFalse;
+#else // !S60_CAM_AUTOFOCUS_SUPPORT
+ return EFalse;
+#endif // S60_CAM_AUTOFOCUS_SUPPORT
+
+#else // Q_CC_NOKIAX86 - Emulator
+ return EFalse;
+#endif // !Q_CC_NOKIAX86
+}
+
+/*
+ * This function is used for focusing in S60 3.1 platform. Platforms from S60
+ * 3.2 onwards should use the focusing provided by the S60CameraSettings class.
+ */
+void CCameraEngine::StartFocusL()
+{
+ if (iEngineState != EEngineIdle)
+ return;
+
+#ifndef Q_CC_NOKIAX86 // Not Emulator
+#ifdef S60_CAM_AUTOFOCUS_SUPPORT // S60 3.1
+ if (iAutoFocus) {
+ if (!iAFRange) {
+ iAFRange = CCamAutoFocus::ERangeNormal;
+ iAutoFocus->SetFocusRangeL(iAFRange);
+ }
+
+ iAutoFocus->AttemptOptimisedFocusL();
+ iEngineState = EEngineFocusing;
+ }
+#endif // S60_CAM_AUTOFOCUS_SUPPORT
+#endif // !Q_CC_NOKIAX86
+}
+
+/*
+ * This function is used for cancelling focusing in S60 3.1 platform. Platforms
+ * from S60 3.2 onwards should use the focusing provided by the
+ * S60CameraSettings class.
+ */
+void CCameraEngine::FocusCancel()
+{
+#ifndef Q_CC_NOKIAX86 // Not Emulator
+#ifdef S60_CAM_AUTOFOCUS_SUPPORT
+ if (iAutoFocus) {
+ iAutoFocus->Cancel();
+ iEngineState = EEngineIdle;
+ }
+#endif // S60_CAM_AUTOFOCUS_SUPPORT
+#endif // !Q_CC_NOKIAX86
+}
+
+void CCameraEngine::SupportedFocusRanges(TInt& aSupportedRanges) const
+{
+ aSupportedRanges = 0;
+
+#ifndef Q_CC_NOKIAX86 // Not Emulator
+#ifdef S60_CAM_AUTOFOCUS_SUPPORT
+ if (iAutoFocus) {
+ // CCamAutoFocus doesn't provide a method for getting supported ranges!
+ // Assume everything is supported (rather optimistic)
+ aSupportedRanges = CCamAutoFocus::ERangeMacro |
+ CCamAutoFocus::ERangePortrait |
+ CCamAutoFocus::ERangeNormal |
+ CCamAutoFocus::ERangeInfinite;
+ }
+#endif // S60_CAM_AUTOFOCUS_SUPPORT
+#endif // !Q_CC_NOKIAX86
+}
+
+void CCameraEngine::SetFocusRange(TInt aFocusRange)
+{
+#if !defined(Q_CC_NOKIAX86) // Not Emulator
+
+#ifdef S60_CAM_AUTOFOCUS_SUPPORT
+ if (iAutoFocus) {
+ TRAPD(focusErr, iAutoFocus->SetFocusRangeL((CCamAutoFocus::TAutoFocusRange)aFocusRange));
+ if (focusErr)
+ iObserver->MceoHandleError(EErrAutoFocusRange, focusErr);
+ }
+#endif // S60_CAM_AUTOFOCUS_SUPPORT
+
+#else // Q_CC_NOKIAX86 // Emulator
+ Q_UNUSED(aFocusRange);
+ if (iImageCaptureObserver)
+ iImageCaptureObserver->MceoHandleError(EErrAutoFocusRange, KErrNotSupported);
+#endif // !Q_CC_NOKIAX86
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60cameraengine.h b/src/plugins/symbian/ecam/s60cameraengine.h
new file mode 100644
index 000000000..7a925c0ba
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraengine.h
@@ -0,0 +1,407 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the Qt Mobility Components.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** No Commercial Usage
+ ** This file contains pre-release code and may not be distributed.
+ ** You may use this file in accordance with the terms and conditions
+ ** contained in the Technology Preview License Agreement accompanying
+ ** this package.
+ **
+ ** GNU Lesser General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU Lesser
+ ** General Public License version 2.1 as published by the Free Software
+ ** Foundation and appearing in the file LICENSE.LGPL included in the
+ ** packaging of this file. Please review the following information to
+ ** ensure the GNU Lesser General Public License version 2.1 requirements
+ ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** If you have questions regarding the use of this file, please contact
+ ** Nokia at qt-info@nokia.com.
+ **
+ **
+ **
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+#ifndef S60CCAMERAENGINE_H
+#define S60CCAMERAENGINE_H
+
+// INCLUDES
+#include <e32base.h>
+#include <ecam.h> // for MCameraObserver(2)
+#ifdef S60_CAM_AUTOFOCUS_SUPPORT
+#include <ccamautofocus.h> // for CCamAutoFocus, MCamAutoFocusObserver
+#endif
+
+// FORWARD DECLARATIONS
+class MCameraEngineObserver;
+class MCameraEngineImageCaptureObserver;
+class MAdvancedSettingsObserver;
+class MCameraViewfinderObserver;
+class MCameraPreviewObserver;
+
+/*
+ * CameraEngine handling ECam operations needed.
+ */
+NONSHARABLE_CLASS( CCameraEngine ) : public CBase,
+ public MCameraObserver,
+ public MCameraObserver2
+#ifdef S60_CAM_AUTOFOCUS_SUPPORT
+ ,public MCamAutoFocusObserver
+#endif
+
+{
+public: // Enums
+
+ enum TCameraEngineState
+ {
+ EEngineNotReady = 0, // 0 - No resources reserved
+ EEngineInitializing, // 1 - Reserving and Powering On
+ EEngineIdle, // 2 - Reseved and Powered On
+ EEngineCapturing, // 3 - Capturing Still Image
+ EEngineFocusing // 4 - Focusing
+ };
+
+public: // Constructor & Destructor
+
+ static CCameraEngine* NewL( TInt aCameraHandle,
+ TInt aPriority,
+ MCameraEngineObserver* aObserver );
+ ~CCameraEngine();
+
+public:
+
+ /**
+ * External Advanced Settings callback observer.
+ */
+ void SetAdvancedObserver(MAdvancedSettingsObserver *aAdvancedSettingsObserver);
+
+ /**
+ * External Image Capture callback observer.
+ */
+ void SetImageCaptureObserver(MCameraEngineImageCaptureObserver *aImageCaptureObserver);
+
+ /**
+ * External Viewfinder callback observer.
+ */
+ void SetViewfinderObserver(MCameraViewfinderObserver *aViewfinderObserver);
+
+ /**
+ * Static function that returns the number of cameras on the device.
+ */
+ static TInt CamerasAvailable();
+
+ /**
+ * Returns the index of the currently active camera device
+ */
+ TInt CurrentCameraIndex() const { return iCameraIndex; }
+
+ /**
+ * Returns the current state (TCameraEngineState)
+ * of the camera engine.
+ */
+ TCameraEngineState State() const { return iEngineState; }
+
+ /**
+ * Returns true if the camera has been reserved and
+ * powered on, and not recording or capturing image
+ */
+ TBool IsCameraReady() const;
+
+ /**
+ * Returns whether DirectScreen ViewFinder is supported by the platform
+ */
+ TBool IsDirectViewFinderSupported() const;
+
+ /**
+ * Returns true if the camera supports AutoFocus.
+ */
+ TBool IsAutoFocusSupported() const;
+
+ /**
+ * Returns camera info
+ */
+ TCameraInfo *CameraInfo();
+
+ /**
+ * Captures an image. When complete, observer will receive
+ * MceoCapturedDataReady() or MceoCapturedBitmapReady() callback,
+ * depending on which image format was used in PrepareL().
+ * @leave May leave with KErrNotReady if camera is not
+ * reserved or prepared for capture.
+ */
+ void CaptureL();
+
+ /**
+ * Cancels ongoing image capture
+ */
+ void CancelCapture();
+
+ /**
+ * Reserves and powers on the camera. When complete,
+ * observer will receive MceoCameraReady() callback
+ *
+ */
+ void ReserveAndPowerOn();
+
+ /**
+ * Releases and powers off the camera
+ *
+ */
+ void ReleaseAndPowerOff();
+
+ /**
+ * Prepares for image capture.
+ * @param aCaptureSize requested capture size. On return,
+ * contains the selected size (closest match)
+ * @param aFormat Image format to use. Default is JPEG with
+ * EXIF information as provided by the camera module
+ * @leave KErrNotSupported, KErrNoMemory, KErrNotReady
+ */
+ void PrepareL( TSize& aCaptureSize,
+ CCamera::TFormat aFormat = CCamera::EFormatExif );
+
+ /**
+ * Starts the viewfinder. Observer will receive
+ * MceoViewFinderFrameReady() callbacks periodically.
+ * @param aSize requested viewfinder size. On return,
+ * contains the selected size.
+ *
+ * @leave KErrNotSupported is viewfinding with bitmaps is not
+ * supported, KErrNotReady
+ */
+ void StartViewFinderL( TSize& aSize );
+
+ /**
+ * Stops the viewfinder if active.
+ */
+ void StopViewFinder();
+
+ void StartDirectViewFinderL(RWsSession& aSession,
+ CWsScreenDevice& aScreenDevice,
+ RWindowBase& aWindow,
+ TRect& aScreenRect,
+ TRect& aClipRect);
+
+ /**
+ * Releases memory for the last received viewfinder frame.
+ * Client must call this in response to MceoViewFinderFrameReady()
+ * callback, after drawing the viewfinder frame is complete.
+ */
+ void ReleaseViewFinderBuffer();
+
+ /**
+ * Releases memory for the last captured image.
+ * Client must call this in response to MceoCapturedDataReady()
+ * or MceoCapturedBitmapReady()callback, after processing the
+ * data/bitmap is complete.
+ */
+ void ReleaseImageBuffer();
+
+ /**
+ * Starts focusing. Does nothing if AutoFocus is not supported.
+ * When complete, observer will receive MceoFocusComplete()
+ * callback.
+ * @leave KErrInUse, KErrNotReady
+ */
+ void StartFocusL();
+
+ /**
+ * Cancels the ongoing focusing operation.
+ */
+ void FocusCancel();
+
+ /**
+ * Gets a bitfield of supported focus ranges.
+ * @param aSupportedRanges a bitfield of either TAutoFocusRange
+ * (S60 3.0/3.1 devices) or TFocusRange (S60 3.2 and onwards) values
+ */
+ void SupportedFocusRanges( TInt& aSupportedRanges ) const;
+
+ /**
+ * Sets the focus range
+ * @param aFocusRange one of the values returned by
+ * SupportedFocusRanges().
+ */
+ void SetFocusRange( TInt aFocusRange );
+
+ /**
+ * Returns a pointer to CCamera object used by the engine.
+ * Allows getting access to additional functionality
+ * from CCamera - do not use for functionality already provided
+ * by CCameraEngine methods.
+ */
+ CCamera* Camera() { return iCamera; }
+
+#ifdef ECAM_PREVIEW_API
+ /**
+ * This enables the preview creation during the capture (image or video).
+ */
+ void EnablePreviewProvider(MCameraPreviewObserver *aPreviewObserver);
+
+ /**
+ * This disabled the preview creation during the capture (image or video)
+ */
+ void DisablePreviewProvider();
+#endif // ECAM_PREVIEW_API
+
+protected: // Protected constructors
+
+ CCameraEngine();
+ CCameraEngine( TInt aCameraHandle,
+ TInt aPriority,
+ MCameraEngineObserver* aObserver );
+ void ConstructL();
+
+protected: // MCameraObserver
+
+ /**
+ * From MCameraObserver
+ * Gets called when CCamera::Reserve() is completed.
+ * (V2: Called internally from HandleEvent)
+ */
+ virtual void ReserveComplete(TInt aError);
+
+ /**
+ * From MCameraObserver.
+ * Gets called when CCamera::PowerOn() is completed.
+ * (V2: Called internally from HandleEvent)
+ */
+ virtual void PowerOnComplete(TInt aError);
+
+ /**
+ * From MCameraObserver.
+ * Gets called when CCamera::StartViewFinderBitmapsL() is completed.
+ * (V2: Called internally from ViewFinderReady)
+ */
+ virtual void ViewFinderFrameReady( CFbsBitmap& aFrame );
+
+ /**
+ * From MCameraObserver.
+ * Gets called when CCamera::CaptureImage() is completed.
+ */
+ virtual void ImageReady( CFbsBitmap* aBitmap, HBufC8* aData, TInt aError );
+
+ /**
+ * From MCameraObserver.
+ * Video capture not implemented.
+ */
+ virtual void FrameBufferReady( MFrameBuffer* /*aFrameBuffer*/, TInt /*aError*/ ) {}
+
+protected: // MCameraObserver2
+
+ /**
+ * From MCameraObserver2
+ * Camera event handler
+ */
+ virtual void HandleEvent(const TECAMEvent &aEvent);
+
+ /**
+ * From MCameraObserver2
+ * Notifies the client of new viewfinder data
+ */
+ virtual void ViewFinderReady(MCameraBuffer &aCameraBuffer, TInt aError);
+
+ /**
+ * From MCameraObserver2
+ * Notifies the client of a new captured image
+ */
+ virtual void ImageBufferReady(MCameraBuffer &aCameraBuffer, TInt aError);
+
+ /**
+ * From MCameraObserver2
+ * Video capture not implemented.
+ */
+ virtual void VideoBufferReady(MCameraBuffer& /*aCameraBuffer*/, TInt /*aError*/) {}
+
+protected: // MCamAutoFocusObserver
+
+ /**
+ * From MCamAutoFocusObserver.
+ * Delivers notification of completion of auto focus initialisation to
+ * an interested party.
+ * @param aError Reason for completion of focus request.
+ */
+ virtual void InitComplete( TInt aError );
+
+ /**
+ * From MCamAutoFocusObserver.
+ * Gets called when CCamAutoFocus::AttemptOptimisedFocusL() is
+ * completed.
+ * (V2: Called internally from HandleEvent)
+ */
+ virtual void OptimisedFocusComplete( TInt aError );
+
+private: // Internal functions
+
+ /**
+ * Internal function to handle ImageReady callbacks from
+ * both observer (V1 & V2) interfaces
+ */
+ void HandleImageReady(const TInt aError, const bool isBitmap);
+
+#ifdef ECAM_PREVIEW_API
+ /**
+ * Handle preview. Retrieve preview data and notify observer about the
+ * preview availability.
+ */
+ void HandlePreview();
+
+ /**
+ * Calculate proper resolution for the SnapShot (Preview) image.
+ */
+ TSize SelectPreviewResolution();
+#endif // ECAM_PREVIEW_API
+
+private: // Data
+
+ CCamera *iCamera;
+ MCameraEngineObserver *iObserver;
+ MCameraEngineImageCaptureObserver *iImageCaptureObserver;
+ MAdvancedSettingsObserver *iAdvancedSettingsObserver;
+ MCameraViewfinderObserver *iViewfinderObserver;
+ MCameraPreviewObserver *iPreviewObserver;
+ MCameraBuffer *iViewFinderBuffer;
+ /*
+ * Following pointers are for the image buffers:
+ * * Makes buffering of 2 concurrent image buffers possible
+ */
+ MCameraBuffer *iImageBuffer1;
+ MCameraBuffer *iImageBuffer2;
+ TDesC8 *iImageData1;
+ TDesC8 *iImageData2;
+ CFbsBitmap *iImageBitmap1;
+ CFbsBitmap *iImageBitmap2;
+ TInt iCameraIndex;
+ TInt iPriority;
+ TCameraEngineState iEngineState;
+ TCameraInfo iCameraInfo;
+ CCamera::TFormat iImageCaptureFormat;
+ TSize iCaptureResolution;
+ bool iNew2LImplementation;
+ int iLatestImageBufferIndex; // 0 = Buffer1, 1 = Buffer2
+#ifdef ECAM_PREVIEW_API
+ CCamera::CCameraSnapshot *iCameraSnapshot;
+#endif // ECAM_PREVIEW_API
+#ifdef S60_CAM_AUTOFOCUS_SUPPORT
+ CCamAutoFocus* iAutoFocus;
+ CCamAutoFocus::TAutoFocusRange iAFRange;
+#endif // S60_CAM_AUTOFOCUS_SUPPORT
+};
+
+#endif // S60CCAMERAENGINE_H
diff --git a/src/plugins/symbian/ecam/s60cameraengineobserver.h b/src/plugins/symbian/ecam/s60cameraengineobserver.h
new file mode 100644
index 000000000..b1e669d70
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraengineobserver.h
@@ -0,0 +1,178 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the Qt Mobility Components.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** No Commercial Usage
+ ** This file contains pre-release code and may not be distributed.
+ ** You may use this file in accordance with the terms and conditions
+ ** contained in the Technology Preview License Agreement accompanying
+ ** this package.
+ **
+ ** GNU Lesser General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU Lesser
+ ** General Public License version 2.1 as published by the Free Software
+ ** Foundation and appearing in the file LICENSE.LGPL included in the
+ ** packaging of this file. Please review the following information to
+ ** ensure the GNU Lesser General Public License version 2.1 requirements
+ ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** If you have questions regarding the use of this file, please contact
+ ** Nokia at qt-info@nokia.com.
+ **
+ **
+ **
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+#ifndef S60CCAMERAENGINEOBSERVER_H
+#define S60CCAMERAENGINEOBSERVER_H
+
+// FORWARD DECLARATIONS
+class CFbsBitmap;
+class TECAMEvent;
+
+enum TCameraEngineError
+{
+ EErrReserve,
+ EErrPowerOn,
+ EErrViewFinderReady,
+ EErrImageReady,
+ EErrPreview,
+ EErrAutoFocusInit,
+ EErrAutoFocusMode,
+ EErrAutoFocusArea,
+ EErrAutoFocusRange,
+ EErrAutoFocusType,
+ EErrOptimisedFocusComplete,
+};
+
+/*
+ * CameraEngine Observer class towards Camera AdvancedSettings
+ */
+class MAdvancedSettingsObserver
+{
+public:
+
+ virtual void HandleAdvancedEvent( const TECAMEvent &aEvent ) = 0;
+
+};
+
+//=============================================================================
+
+/*
+ * CameraEngine Observer class towards Camera Control
+ */
+class MCameraEngineObserver
+{
+public:
+
+ /**
+ * Camera is ready to use for capturing images.
+ */
+ virtual void MceoCameraReady() = 0;
+
+ /**
+ * Notifies clients about errors in camera engine
+ * @param aErrorType type of error (see TCameraEngineError)
+ * @param aError Symbian system-wide error code
+ */
+ virtual void MceoHandleError( TCameraEngineError aErrorType, TInt aError ) = 0;
+
+};
+
+//=============================================================================
+
+/*
+ * CameraEngine Observer class towards Camera ImageCaptureSession
+ */
+class MCameraEngineImageCaptureObserver
+{
+public:
+
+ /**
+ * Camera AF lens has attained optimal focus
+ */
+ virtual void MceoFocusComplete() = 0;
+
+ /**
+ * Captured data is ready - call CCameraEngine::ReleaseImageBuffer()
+ * after processing/saving the data (typically, JPG-encoded image)
+ * @param aData Pointer to a descriptor containing a frame of camera data.
+ */
+ virtual void MceoCapturedDataReady( TDesC8* aData ) = 0;
+
+ /**
+ * Captured bitmap is ready.
+ * after processing/saving the image, call
+ * CCameraEngine::ReleaseImageBuffer() to free the bitmap.
+ * @param aBitmap Pointer to an FBS bitmap containing a captured image.
+ */
+ virtual void MceoCapturedBitmapReady( CFbsBitmap* aBitmap ) = 0;
+
+ /**
+ * Notifies clients about errors in camera engine
+ * @param aErrorType type of error (see TCameraEngineError)
+ * @param aError Symbian system-wide error code
+ */
+ virtual void MceoHandleError( TCameraEngineError aErrorType, TInt aError ) = 0;
+
+ /**
+ * Notifies client about other events not recognized by camera engine.
+ * The default implementation is empty.
+ * @param aEvent camera event (see MCameraObserver2::HandleEvent())
+ */
+ virtual void MceoHandleOtherEvent( const TECAMEvent& /*aEvent*/ ) {}
+};
+
+//=============================================================================
+
+/*
+ * CameraEngine Observer class towards Camera ViewFinderEngine
+ */
+class MCameraViewfinderObserver
+{
+public:
+ /**
+ * A new viewfinder frame is ready.
+ * after displaying the frame, call
+ * CCameraEngine::ReleaseViewFinderBuffer()
+ * to free the bitmap.
+ * @param aFrame Pointer to an FBS bitmap containing a viewfinder frame.
+ */
+ virtual void MceoViewFinderFrameReady( CFbsBitmap& aFrame ) = 0;
+};
+
+//=============================================================================
+
+#ifdef ECAM_PREVIEW_API
+/*
+ * CameraEngine Observer class towards Camera ViewFinderEngine
+ */
+class MCameraPreviewObserver
+{
+public:
+ /**
+ * A new preview is available.
+ * @param aPreview Pointer to an FBS bitmap containing a preview.
+ */
+ virtual void MceoPreviewReady( CFbsBitmap& aPreview ) = 0;
+};
+#endif // ECAM_PREVIEW_API
+
+#endif // CCAMERAENGINEOBSERVER_H
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60cameraexposurecontrol.cpp b/src/plugins/symbian/ecam/s60cameraexposurecontrol.cpp
new file mode 100644
index 000000000..9ebdd2c6e
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraexposurecontrol.cpp
@@ -0,0 +1,584 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+
+#include "s60cameraexposurecontrol.h"
+#include "s60cameraservice.h"
+#include "s60imagecapturesession.h"
+
+S60CameraExposureControl::S60CameraExposureControl(QObject *parent) :
+ QCameraExposureControl(parent)
+{
+}
+
+S60CameraExposureControl::S60CameraExposureControl(S60ImageCaptureSession *session, QObject *parent) :
+ QCameraExposureControl(parent),
+ m_session(0),
+ m_service(0),
+ m_advancedSettings(0),
+ m_exposureMode(QCameraExposure::ExposureAuto),
+ m_meteringMode(QCameraExposure::MeteringMatrix)
+{
+ m_session = session;
+
+ connect(m_session, SIGNAL(advancedSettingChanged()), this, SLOT(resetAdvancedSetting()));
+ m_advancedSettings = m_session->advancedSettings();
+
+ if (m_advancedSettings) {
+ connect(m_advancedSettings, SIGNAL(apertureChanged()), this, SLOT(apertureChanged()));
+ connect(m_advancedSettings, SIGNAL(apertureRangeChanged()), this, SLOT(apertureRangeChanged()));
+ connect(m_advancedSettings, SIGNAL(shutterSpeedChanged()), this, SLOT(shutterSpeedChanged()));
+ connect(m_advancedSettings, SIGNAL(isoSensitivityChanged()), this, SLOT(isoSensitivityChanged()));
+ connect(m_advancedSettings, SIGNAL(evChanged()), this, SLOT(evChanged()));
+ }
+}
+
+S60CameraExposureControl::~S60CameraExposureControl()
+{
+ m_advancedSettings = 0;
+}
+
+void S60CameraExposureControl::resetAdvancedSetting()
+{
+ m_advancedSettings = m_session->advancedSettings();
+ if (m_advancedSettings) {
+ connect(m_advancedSettings, SIGNAL(apertureChanged()), this, SLOT(apertureChanged()));
+ connect(m_advancedSettings, SIGNAL(apertureRangeChanged()), this, SLOT(apertureRangeChanged()));
+ connect(m_advancedSettings, SIGNAL(shutterSpeedChanged()), this, SLOT(shutterSpeedChanged()));
+ connect(m_advancedSettings, SIGNAL(isoSensitivityChanged()), this, SLOT(isoSensitivityChanged()));
+ connect(m_advancedSettings, SIGNAL(evChanged()), this, SLOT(evChanged()));
+ }
+}
+
+void S60CameraExposureControl::apertureChanged()
+{
+ emit exposureParameterChanged(QCameraExposureControl::Aperture);
+}
+
+void S60CameraExposureControl::apertureRangeChanged()
+{
+ emit exposureParameterRangeChanged(QCameraExposureControl::Aperture);
+}
+
+void S60CameraExposureControl::shutterSpeedChanged()
+{
+ emit exposureParameterChanged(QCameraExposureControl::ShutterSpeed);
+}
+
+void S60CameraExposureControl::isoSensitivityChanged()
+{
+ emit exposureParameterChanged(QCameraExposureControl::ISO);
+}
+
+void S60CameraExposureControl::evChanged()
+{
+ emit exposureParameterChanged(QCameraExposureControl::ExposureCompensation);
+}
+
+QCameraExposure::ExposureMode S60CameraExposureControl::exposureMode() const
+{
+ return m_session->exposureMode();
+}
+
+void S60CameraExposureControl::setExposureMode(QCameraExposure::ExposureMode mode)
+{
+ if (isExposureModeSupported(mode)) {
+ m_exposureMode = mode;
+ m_session->setExposureMode(m_exposureMode);
+ return;
+ }
+
+ m_session->setError(KErrNotSupported, tr("Requested exposure mode is not supported."));
+}
+
+bool S60CameraExposureControl::isExposureModeSupported(QCameraExposure::ExposureMode mode) const
+{
+ if (m_session->isExposureModeSupported(mode))
+ return true;
+
+ return false;
+}
+
+QCameraExposure::MeteringMode S60CameraExposureControl::meteringMode() const
+{
+ if (m_advancedSettings)
+ return m_advancedSettings->meteringMode();
+
+ return QCameraExposure::MeteringMode();
+}
+
+void S60CameraExposureControl::setMeteringMode(QCameraExposure::MeteringMode mode)
+{
+ if (m_advancedSettings) {
+ if (isMeteringModeSupported(mode)) {
+ m_meteringMode = mode;
+ m_advancedSettings->setMeteringMode(mode);
+ return;
+ }
+ }
+
+ m_session->setError(KErrNotSupported, tr("Requested metering mode is not supported."));
+}
+
+bool S60CameraExposureControl::isMeteringModeSupported(QCameraExposure::MeteringMode mode) const
+{
+ if (m_advancedSettings)
+ return m_advancedSettings->isMeteringModeSupported(mode);
+
+ return false;
+}
+
+bool S60CameraExposureControl::isParameterSupported(ExposureParameter parameter) const
+{
+ // Settings supported only if advanced settings available
+ if (m_advancedSettings) {
+ switch (parameter) {
+ case QCameraExposureControl::ISO:
+ if (m_advancedSettings->supportedIsoSensitivities().count() > 0)
+ return true;
+ else
+ return false;
+ case QCameraExposureControl::Aperture:
+ if (m_advancedSettings->supportedApertures().count() > 0)
+ return true;
+ else
+ return false;
+ case QCameraExposureControl::ShutterSpeed:
+ if (m_advancedSettings->supportedShutterSpeeds().count() > 0)
+ return true;
+ else
+ return false;
+ case QCameraExposureControl::ExposureCompensation:
+ if (m_advancedSettings->supportedExposureCompensationValues().count() > 0)
+ return true;
+ else
+ return false;
+ case QCameraExposureControl::FlashPower:
+ case QCameraExposureControl::FlashCompensation:
+ return false;
+
+ default:
+ return false;
+ }
+ }
+
+ return false;
+}
+
+QVariant S60CameraExposureControl::exposureParameter(ExposureParameter parameter) const
+{
+ switch (parameter) {
+ case QCameraExposureControl::ISO:
+ return QVariant(isoSensitivity());
+ case QCameraExposureControl::Aperture:
+ return QVariant(aperture());
+ case QCameraExposureControl::ShutterSpeed:
+ return QVariant(shutterSpeed());
+ case QCameraExposureControl::ExposureCompensation:
+ return QVariant(exposureCompensation());
+ case QCameraExposureControl::FlashPower:
+ case QCameraExposureControl::FlashCompensation:
+ // Not supported in Symbian
+ return QVariant();
+
+ default:
+ // Not supported in Symbian
+ return QVariant();
+ }
+}
+
+QCameraExposureControl::ParameterFlags S60CameraExposureControl::exposureParameterFlags(ExposureParameter parameter) const
+{
+ QCameraExposureControl::ParameterFlags flags;
+
+ /*
+ * ISO, ExposureCompensation:
+ * - Automatic/Manual
+ * - Read/Write
+ * - Discrete range
+ *
+ * Aperture, ShutterSpeed, FlashPower, FlashCompensation:
+ * - Not supported
+ */
+ switch (parameter) {
+ case QCameraExposureControl::ISO:
+ case QCameraExposureControl::ExposureCompensation:
+ flags |= QCameraExposureControl::AutomaticValue;
+ break;
+ case QCameraExposureControl::Aperture:
+ case QCameraExposureControl::ShutterSpeed:
+ case QCameraExposureControl::FlashPower:
+ case QCameraExposureControl::FlashCompensation:
+ // Do nothing - no flags
+ break;
+
+ default:
+ // Do nothing - no flags
+ break;
+ }
+
+ return flags;
+}
+
+QVariantList S60CameraExposureControl::supportedParameterRange(ExposureParameter parameter) const
+{
+ QVariantList valueList;
+
+ if (m_advancedSettings) {
+ switch (parameter) {
+ case QCameraExposureControl::ISO: {
+ foreach (int iso, m_advancedSettings->supportedIsoSensitivities())
+ valueList << QVariant(iso);
+ break;
+ }
+ case QCameraExposureControl::Aperture: {
+ foreach (qreal aperture, m_advancedSettings->supportedApertures())
+ valueList << QVariant(aperture);
+ break;
+ }
+ case QCameraExposureControl::ShutterSpeed: {
+ foreach (qreal shutterSpeed, m_advancedSettings->supportedShutterSpeeds())
+ valueList << QVariant(shutterSpeed);
+ break;
+ }
+ case QCameraExposureControl::ExposureCompensation: {
+ foreach (qreal ev, m_advancedSettings->supportedExposureCompensationValues())
+ valueList << QVariant(ev);
+ break;
+ }
+ case QCameraExposureControl::FlashPower:
+ case QCameraExposureControl::FlashCompensation:
+ // Not supported in Symbian
+ break;
+
+ default:
+ // Not supported in Symbian
+ break;
+ }
+ }
+
+ return valueList;
+}
+
+bool S60CameraExposureControl::setExposureParameter(ExposureParameter parameter, const QVariant& value)
+{
+ bool useDefaultValue = false;
+
+ if (value.isNull())
+ useDefaultValue = true;
+
+ switch (parameter) {
+ case QCameraExposureControl::ISO:
+ if (useDefaultValue) {
+ setAutoIsoSensitivity();
+ return false;
+ }
+ else
+ return setManualIsoSensitivity(value.toInt());
+
+ case QCameraExposureControl::Aperture:
+ if (useDefaultValue) {
+ setAutoAperture();
+ return false;
+ }
+ else
+ return setManualAperture(value.toFloat());
+
+ case QCameraExposureControl::ShutterSpeed:
+ if (useDefaultValue) {
+ setAutoShutterSpeed();
+ return false;
+ }
+ else
+ return setManualShutterSpeed(value.toFloat());
+
+ case QCameraExposureControl::ExposureCompensation:
+ if (useDefaultValue) {
+ setAutoExposureCompensation();
+ return false;
+ }
+ else
+ return setManualExposureCompensation(value.toFloat());
+
+ case QCameraExposureControl::FlashPower:
+ return false;
+ case QCameraExposureControl::FlashCompensation:
+ return false;
+
+ default:
+ // Not supported in Symbian
+ return false;
+ }
+}
+
+QString S60CameraExposureControl::extendedParameterName(ExposureParameter parameter)
+{
+ switch (parameter) {
+ case QCameraExposureControl::ISO:
+ return QLatin1String("ISO Sensitivity");
+ case QCameraExposureControl::Aperture:
+ return QLatin1String("Aperture");
+ case QCameraExposureControl::ShutterSpeed:
+ return QLatin1String("Shutter Speed");
+ case QCameraExposureControl::ExposureCompensation:
+ return QLatin1String("Exposure Compensation");
+ case QCameraExposureControl::FlashPower:
+ return QLatin1String("Flash Power");
+ case QCameraExposureControl::FlashCompensation:
+ return QLatin1String("Flash Compensation");
+
+ default:
+ return QString();
+ }
+}
+
+int S60CameraExposureControl::isoSensitivity() const
+{
+ if (m_advancedSettings)
+ return m_advancedSettings->isoSensitivity();
+ return 0;
+}
+
+bool S60CameraExposureControl::isIsoSensitivitySupported(const int iso) const
+{
+ if (m_advancedSettings &&
+ m_advancedSettings->supportedIsoSensitivities().contains(iso))
+ return true;
+ else
+ return false;
+}
+
+bool S60CameraExposureControl::setManualIsoSensitivity(int iso)
+{
+ if (m_advancedSettings) {
+ if (isIsoSensitivitySupported(iso)) {
+ m_advancedSettings->setManualIsoSensitivity(iso);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void S60CameraExposureControl::setAutoIsoSensitivity()
+{
+ if (m_advancedSettings)
+ m_advancedSettings->setAutoIsoSensitivity();
+}
+
+qreal S60CameraExposureControl::aperture() const
+{
+ if (m_advancedSettings)
+ return m_advancedSettings->aperture();
+ return 0.0;
+}
+
+bool S60CameraExposureControl::isApertureSupported(const qreal aperture) const
+{
+ if (m_advancedSettings) {
+ QList<qreal> supportedValues = m_advancedSettings->supportedApertures();
+ if(supportedValues.indexOf(aperture) != -1)
+ return true;
+ }
+
+ return false;
+}
+
+bool S60CameraExposureControl::setManualAperture(qreal aperture)
+{
+ if (m_advancedSettings) {
+ if (isApertureSupported(aperture)) {
+ m_advancedSettings->setManualAperture(aperture);
+ return true;
+ } else {
+ QList<qreal> supportedApertureValues = m_advancedSettings->supportedApertures();
+ int minAperture = supportedApertureValues.first();
+ int maxAperture = supportedApertureValues.last();
+
+ if (aperture < minAperture) { // Smaller than minimum
+ aperture = minAperture;
+ } else if (aperture > maxAperture) { // Bigger than maximum
+ aperture = maxAperture;
+ } else { // Find closest
+ int indexOfClosest = 0;
+ int smallestDiff = 100000000; // Sensible max diff
+ for(int i = 0; i < supportedApertureValues.count(); ++i) {
+ if((abs((aperture*100) - (supportedApertureValues[i]*100))) < smallestDiff) {
+ smallestDiff = abs((aperture*100) - (supportedApertureValues[i]*100));
+ indexOfClosest = i;
+ }
+ }
+ aperture = supportedApertureValues[indexOfClosest];
+ }
+ m_advancedSettings->setManualAperture(aperture);
+ }
+ }
+
+ return false;
+}
+
+void S60CameraExposureControl::setAutoAperture()
+{
+ // Not supported in Symbian
+}
+
+qreal S60CameraExposureControl::shutterSpeed() const
+{
+ if (m_advancedSettings)
+ return m_advancedSettings->shutterSpeed();
+ return 0.0;
+}
+
+bool S60CameraExposureControl::isShutterSpeedSupported(const qreal seconds) const
+{
+ if (m_advancedSettings) {
+ QList<qreal> supportedValues = m_advancedSettings->supportedShutterSpeeds();
+ if(supportedValues.indexOf(seconds) != -1)
+ return true;
+ }
+
+ return false;
+}
+
+bool S60CameraExposureControl::setManualShutterSpeed(qreal seconds)
+{
+ if (m_advancedSettings) {
+ if (isShutterSpeedSupported(seconds)) {
+ m_advancedSettings->setManualShutterSpeed(seconds);
+ return true;
+ } else {
+ QList<qreal> supportedShutterSpeeds = m_advancedSettings->supportedShutterSpeeds();
+
+ if (supportedShutterSpeeds.count() == 0)
+ return false;
+
+ int minShutterSpeed = supportedShutterSpeeds.first();
+ int maxShutterSpeed = supportedShutterSpeeds.last();
+
+ if (seconds < minShutterSpeed) { // Smaller than minimum
+ seconds = minShutterSpeed;
+ } else if (seconds > maxShutterSpeed) { // Bigger than maximum
+ seconds = maxShutterSpeed;
+ } else { // Find closest
+ int indexOfClosest = 0;
+ int smallestDiff = 100000000; // Sensible max diff
+ for(int i = 0; i < supportedShutterSpeeds.count(); ++i) {
+ if((abs((seconds*100) - (supportedShutterSpeeds[i]*100))) < smallestDiff) {
+ smallestDiff = abs((seconds*100) - (supportedShutterSpeeds[i]*100));
+ indexOfClosest = i;
+ }
+ }
+ seconds = supportedShutterSpeeds[indexOfClosest];
+ }
+ m_advancedSettings->setManualShutterSpeed(seconds);
+ }
+ }
+
+ return false;
+}
+
+void S60CameraExposureControl::setAutoShutterSpeed()
+{
+ // Not supported in Symbian
+}
+
+qreal S60CameraExposureControl::exposureCompensation() const
+{
+ if (m_advancedSettings)
+ return m_advancedSettings->exposureCompensation();
+ return 0.0;
+}
+
+bool S60CameraExposureControl::isExposureCompensationSupported(const qreal ev) const
+{
+ if (m_advancedSettings) {
+ QList<qreal> supportedValues = m_advancedSettings->supportedExposureCompensationValues();
+ if(supportedValues.indexOf(ev) != -1)
+ return true;
+ }
+
+ return false;
+}
+
+bool S60CameraExposureControl::setManualExposureCompensation(qreal ev)
+{
+ if (m_advancedSettings) {
+ if (isExposureCompensationSupported(ev)) {
+ m_advancedSettings->setExposureCompensation(ev);
+ return true;
+ } else {
+ QList<qreal> supportedEVs = m_advancedSettings->supportedExposureCompensationValues();
+
+ if (supportedEVs.count() == 0)
+ return false;
+
+ int minEV = supportedEVs.first();
+ int maxEV = supportedEVs.last();
+
+ if (ev < minEV) { // Smaller than minimum
+ ev = minEV;
+ } else if (ev > maxEV) { // Bigger than maximum
+ ev = maxEV;
+ } else { // Find closest
+ int indexOfClosest = 0;
+ int smallestDiff = 100000000; // Sensible max diff
+ for(int i = 0; i < supportedEVs.count(); ++i) {
+ if((abs((ev*100) - (supportedEVs[i]*100))) < smallestDiff) {
+ smallestDiff = abs((ev*100) - (supportedEVs[i]*100));
+ indexOfClosest = i;
+ }
+ }
+ ev = supportedEVs[indexOfClosest];
+ }
+ m_advancedSettings->setExposureCompensation(ev);
+ }
+ }
+
+ return false;
+}
+
+void S60CameraExposureControl::setAutoExposureCompensation()
+{
+ // Not supported in Symbian
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60cameraexposurecontrol.h b/src/plugins/symbian/ecam/s60cameraexposurecontrol.h
new file mode 100644
index 000000000..1c623c774
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraexposurecontrol.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60CAMERAEXPOSURECONTROL_H
+#define S60CAMERAEXPOSURECONTROL_H
+
+#include <qcameraexposurecontrol.h>
+
+#include "s60camerasettings.h"
+
+QT_USE_NAMESPACE
+
+class S60CameraService;
+class S60ImageCaptureSession;
+
+/*
+ * Control for exposure related camera operation.
+ */
+class S60CameraExposureControl : public QCameraExposureControl
+{
+ Q_OBJECT
+
+public: // Constructors & Destructor
+
+ S60CameraExposureControl(QObject *parent = 0);
+ S60CameraExposureControl(S60ImageCaptureSession *session, QObject *parent = 0);
+ ~S60CameraExposureControl();
+
+public: // QCameraExposureControl
+
+ // Exposure Mode
+ QCameraExposure::ExposureMode exposureMode() const;
+ void setExposureMode(QCameraExposure::ExposureMode mode);
+ bool isExposureModeSupported(QCameraExposure::ExposureMode mode) const;
+
+ // Metering Mode
+ QCameraExposure::MeteringMode meteringMode() const;
+ void setMeteringMode(QCameraExposure::MeteringMode mode);
+ bool isMeteringModeSupported(QCameraExposure::MeteringMode mode) const;
+
+ // Exposure Parameter
+ bool isParameterSupported(ExposureParameter parameter) const;
+ QVariant exposureParameter(ExposureParameter parameter) const;
+ QCameraExposureControl::ParameterFlags exposureParameterFlags(ExposureParameter parameter) const;
+ QVariantList supportedParameterRange(ExposureParameter parameter) const;
+ bool setExposureParameter(ExposureParameter parameter, const QVariant& value);
+
+ QString extendedParameterName(ExposureParameter parameter);
+
+/*
+Q_SIGNALS: // QCameraExposureControl
+ void exposureParameterChanged(int parameter);
+ void exposureParameterRangeChanged(int parameter);
+*/
+
+private slots: // Internal Slots
+
+ void resetAdvancedSetting();
+ void apertureChanged();
+ void apertureRangeChanged();
+ void shutterSpeedChanged();
+ void isoSensitivityChanged();
+ void evChanged();
+
+private: // Internal - Implementing ExposureParameter
+
+ // ISO Sensitivity
+ int isoSensitivity() const;
+ bool setManualIsoSensitivity(int iso);
+ void setAutoIsoSensitivity();
+ bool isIsoSensitivitySupported(const int iso) const;
+
+ // Aperture
+ qreal aperture() const;
+ bool setManualAperture(qreal aperture);
+ void setAutoAperture();
+ bool isApertureSupported(const qreal aperture) const;
+
+ // Shutter Speed
+ qreal shutterSpeed() const;
+ bool setManualShutterSpeed(qreal seconds);
+ void setAutoShutterSpeed();
+ bool isShutterSpeedSupported(const qreal seconds) const;
+
+ // Exposure Compensation
+ qreal exposureCompensation() const;
+ bool setManualExposureCompensation(qreal ev);
+ void setAutoExposureCompensation();
+ bool isExposureCompensationSupported(const qreal ev) const;
+
+private: // Data
+
+ S60ImageCaptureSession *m_session;
+ S60CameraService *m_service;
+ S60CameraSettings *m_advancedSettings;
+ QCameraExposure::ExposureMode m_exposureMode;
+ QCameraExposure::MeteringMode m_meteringMode;
+};
+
+#endif // S60CAMERAEXPOSURECONTROL_H
diff --git a/src/plugins/symbian/ecam/s60cameraflashcontrol.cpp b/src/plugins/symbian/ecam/s60cameraflashcontrol.cpp
new file mode 100644
index 000000000..a18c57a03
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraflashcontrol.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+
+#include "s60cameraflashcontrol.h"
+#include "s60cameraservice.h"
+#include "s60imagecapturesession.h"
+
+S60CameraFlashControl::S60CameraFlashControl(QObject *parent) :
+ QCameraFlashControl(parent)
+{
+}
+
+S60CameraFlashControl::S60CameraFlashControl(S60ImageCaptureSession *session, QObject *parent) :
+ QCameraFlashControl(parent),
+ m_session(0),
+ m_service(0),
+ m_advancedSettings(0),
+ m_flashMode(QCameraExposure::FlashOff)
+{
+ m_session = session;
+
+ connect(m_session, SIGNAL(advancedSettingChanged()), this, SLOT(resetAdvancedSetting()));
+ m_advancedSettings = m_session->advancedSettings();
+
+ if (m_advancedSettings)
+ connect(m_advancedSettings, SIGNAL(flashReady(bool)), this, SIGNAL(flashReady(bool)));
+}
+
+S60CameraFlashControl::~S60CameraFlashControl()
+{
+ m_advancedSettings = 0;
+}
+
+void S60CameraFlashControl::resetAdvancedSetting()
+{
+ m_advancedSettings = m_session->advancedSettings();
+ if (m_advancedSettings)
+ connect(m_advancedSettings, SIGNAL(flashReady(bool)), this, SIGNAL(flashReady(bool)));
+}
+
+QCameraExposure::FlashModes S60CameraFlashControl::flashMode() const
+{
+ return m_session->flashMode();
+}
+
+void S60CameraFlashControl::setFlashMode(QCameraExposure::FlashModes mode)
+{
+ if (isFlashModeSupported(mode)) {
+ m_flashMode = mode;
+ m_session->setFlashMode(m_flashMode);
+ }
+ else
+ m_session->setError(KErrNotSupported, tr("Requested flash mode is not supported."));
+}
+
+bool S60CameraFlashControl::isFlashModeSupported(QCameraExposure::FlashModes mode) const
+{
+ return m_session->supportedFlashModes() & mode;
+}
+
+bool S60CameraFlashControl::isFlashReady() const
+{
+ if (m_advancedSettings)
+ return m_advancedSettings->isFlashReady();
+
+ return false;
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60cameraflashcontrol.h b/src/plugins/symbian/ecam/s60cameraflashcontrol.h
new file mode 100644
index 000000000..50dbc41dc
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraflashcontrol.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60CAMERAFLASHCONTROL_H
+#define S60CAMERAFLASHCONTROL_H
+
+#include <qcameraflashcontrol.h>
+
+#include "s60camerasettings.h"
+
+QT_USE_NAMESPACE
+
+class S60CameraService;
+class S60ImageCaptureSession;
+
+/*
+ * Control to setup Flash related camera settings.
+ */
+class S60CameraFlashControl : public QCameraFlashControl
+{
+ Q_OBJECT
+
+public: // Constructors & Destructor
+
+ S60CameraFlashControl(QObject *parent = 0);
+ S60CameraFlashControl(S60ImageCaptureSession *session, QObject *parent = 0);
+ ~S60CameraFlashControl();
+
+public: // QCameraExposureControl
+
+ // Flash Mode
+ QCameraExposure::FlashModes flashMode() const;
+ void setFlashMode(QCameraExposure::FlashModes mode);
+ bool isFlashModeSupported(QCameraExposure::FlashModes mode) const;
+
+ bool isFlashReady() const;
+
+/*
+Q_SIGNALS: // QCameraExposureControl
+ void flashReady(bool);
+*/
+
+private slots: // Internal Slots
+
+ void resetAdvancedSetting();
+
+private: // Data
+
+ S60ImageCaptureSession *m_session;
+ S60CameraService *m_service;
+ S60CameraSettings *m_advancedSettings;
+ QCameraExposure::FlashModes m_flashMode;
+};
+
+#endif // S60CAMERAFLASHCONTROL_H
diff --git a/src/plugins/symbian/ecam/s60camerafocuscontrol.cpp b/src/plugins/symbian/ecam/s60camerafocuscontrol.cpp
new file mode 100644
index 000000000..a7941ce20
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60camerafocuscontrol.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+
+#include "s60camerafocuscontrol.h"
+#include "s60cameraservice.h"
+#include "s60imagecapturesession.h"
+#include "s60cameraconstants.h"
+
+S60CameraFocusControl::S60CameraFocusControl(QObject *parent) :
+ QCameraFocusControl(parent)
+{
+}
+
+S60CameraFocusControl::S60CameraFocusControl(S60ImageCaptureSession *session, QObject *parent) :
+ QCameraFocusControl(parent),
+ m_session(0),
+ m_service(0),
+ m_advancedSettings(0),
+ m_isFocusLocked(false),
+ m_opticalZoomValue(KDefaultOpticalZoom),
+ m_digitalZoomValue(KDefaultDigitalZoom),
+ m_focusMode(KDefaultFocusMode)
+{
+ m_session = session;
+
+ connect(m_session, SIGNAL(advancedSettingChanged()), this, SLOT(resetAdvancedSetting()));
+ m_advancedSettings = m_session->advancedSettings();
+
+ TRAPD(err, m_session->doSetZoomFactorL(m_opticalZoomValue, m_digitalZoomValue));
+ if (err)
+ m_session->setError(KErrNotSupported, tr("Setting default zoom factors failed."));
+}
+
+S60CameraFocusControl::~S60CameraFocusControl()
+{
+}
+
+QCameraFocus::FocusMode S60CameraFocusControl::focusMode() const
+{
+ return m_focusMode;
+}
+
+void S60CameraFocusControl::setFocusMode(QCameraFocus::FocusMode mode)
+{
+ if (isFocusModeSupported(mode)) {
+ // FocusMode and FocusRange are set. Focusing is triggered by setting
+ // the corresponding FocusType active by calling searchAndLock in LocksControl.
+ m_focusMode = mode;
+ if (m_advancedSettings)
+ m_advancedSettings->setFocusMode(m_focusMode);
+ else
+ m_session->setError(KErrGeneral, tr("Unable to set focus mode before camera is started."));
+ } else {
+ m_session->setError(KErrNotSupported, tr("Requested focus mode is not supported."));
+ }
+}
+
+bool S60CameraFocusControl::isFocusModeSupported(QCameraFocus::FocusMode mode) const
+{
+ if (m_advancedSettings) {
+ return m_advancedSettings->supportedFocusModes() & mode;
+ } else {
+ if (mode == QCameraFocus::AutoFocus)
+ return m_session->isFocusSupported();
+ }
+
+ return false;
+}
+
+qreal S60CameraFocusControl::maximumOpticalZoom() const
+{
+ return m_session->maximumZoom();
+}
+
+qreal S60CameraFocusControl::maximumDigitalZoom() const
+{
+ return m_session->maxDigitalZoom();
+}
+
+qreal S60CameraFocusControl::opticalZoom() const
+{
+ return m_session->opticalZoomFactor();
+}
+
+qreal S60CameraFocusControl::digitalZoom() const
+{
+ return m_session->digitalZoomFactor();
+}
+
+void S60CameraFocusControl::zoomTo(qreal optical, qreal digital)
+{
+ TRAPD(err, m_session->doSetZoomFactorL(optical, digital));
+ if (err)
+ m_session->setError(KErrNotSupported, tr("Requested zoom factor is not supported."));
+
+ // Query new values
+ if (m_opticalZoomValue != m_session->opticalZoomFactor()) {
+ m_opticalZoomValue = m_session->opticalZoomFactor();
+ emit opticalZoomChanged(m_opticalZoomValue);
+ }
+ if (m_digitalZoomValue != m_session->digitalZoomFactor()) {
+ m_digitalZoomValue = m_session->digitalZoomFactor();
+ emit digitalZoomChanged(m_digitalZoomValue);
+ }
+}
+
+void S60CameraFocusControl::resetAdvancedSetting()
+{
+ m_advancedSettings = m_session->advancedSettings();
+}
+
+QCameraFocus::FocusPointMode S60CameraFocusControl::focusPointMode() const
+{
+ // Not supported in Symbian
+ return QCameraFocus::FocusPointAuto;
+}
+
+void S60CameraFocusControl::setFocusPointMode(QCameraFocus::FocusPointMode mode)
+{
+ if (mode != QCameraFocus::FocusPointAuto)
+ m_session->setError(KErrNotSupported, tr("Requested focus point mode is not supported."));
+}
+
+bool S60CameraFocusControl::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const
+{
+ // Not supported in Symbian
+ if (mode == QCameraFocus::FocusPointAuto)
+ return true;
+ else
+ return false;
+}
+
+QPointF S60CameraFocusControl::customFocusPoint() const
+{
+ // Not supported in Symbian, return image center
+ return QPointF(0.5, 0.5);
+}
+
+void S60CameraFocusControl::setCustomFocusPoint(const QPointF &point)
+{
+ // Not supported in Symbian
+ Q_UNUSED(point);
+ m_session->setError(KErrNotSupported, tr("Setting custom focus point is not supported."));
+}
+
+QCameraFocusZoneList S60CameraFocusControl::focusZones() const
+{
+ // Not supported in Symbian
+ return QCameraFocusZoneList(); // Return empty list
+}
+
+// End of file
+
diff --git a/src/plugins/symbian/ecam/s60camerafocuscontrol.h b/src/plugins/symbian/ecam/s60camerafocuscontrol.h
new file mode 100644
index 000000000..28c83ed70
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60camerafocuscontrol.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60CAMERAFOCUSCONTROL_H
+#define S60CAMERAFOCUSCONTROL_H
+
+#include <qcamerafocuscontrol.h>
+
+#include "s60camerasettings.h"
+
+QT_USE_NAMESPACE
+
+class S60CameraService;
+class S60ImageCaptureSession;
+
+/*
+ * Control for focusing related operations (inc. zooming)
+ */
+class S60CameraFocusControl : public QCameraFocusControl
+{
+ Q_OBJECT
+
+public: // Constructors & Destructor
+
+ S60CameraFocusControl(QObject *parent = 0);
+ S60CameraFocusControl(S60ImageCaptureSession *session, QObject *parent = 0);
+ ~S60CameraFocusControl();
+
+public: // QCameraFocusControl
+
+ // Focus Mode
+ QCameraFocus::FocusMode focusMode() const;
+ void setFocusMode(QCameraFocus::FocusMode mode);
+ bool isFocusModeSupported(QCameraFocus::FocusMode) const;
+
+ // Zoom
+ qreal maximumOpticalZoom() const;
+ qreal maximumDigitalZoom() const;
+ qreal opticalZoom() const;
+ qreal digitalZoom() const;
+
+ void zoomTo(qreal optical, qreal digital);
+
+ // Focus Point
+ QCameraFocus::FocusPointMode focusPointMode() const;
+ void setFocusPointMode(QCameraFocus::FocusPointMode mode);
+ bool isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const;
+ QPointF customFocusPoint() const;
+ void setCustomFocusPoint(const QPointF &point);
+
+ QCameraFocusZoneList focusZones() const;
+
+/*
+Q_SIGNALS: // QCameraFocusControl
+ void opticalZoomChanged(qreal opticalZoom);
+ void digitalZoomChanged(qreal digitalZoom);
+ void focusZonesChanged();
+*/
+
+private slots: // Internal Slots
+
+ void resetAdvancedSetting();
+
+private: // Data
+ S60ImageCaptureSession *m_session;
+ S60CameraService *m_service;
+ S60CameraSettings *m_advancedSettings;
+ bool m_isFocusLocked;
+ qreal m_opticalZoomValue;
+ qreal m_digitalZoomValue;
+ QCameraFocus::FocusMode m_focusMode;
+};
+
+#endif // S60CAMERAFOCUSCONTROL_H
diff --git a/src/plugins/symbian/ecam/s60cameraimagecapturecontrol.cpp b/src/plugins/symbian/ecam/s60cameraimagecapturecontrol.cpp
new file mode 100644
index 000000000..427a3bd97
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraimagecapturecontrol.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+
+#include "s60cameraimagecapturecontrol.h"
+#include "s60cameraservice.h"
+#include "s60imagecapturesession.h"
+#include "s60cameracontrol.h"
+
+S60CameraImageCaptureControl::S60CameraImageCaptureControl(QObject *parent) :
+ QCameraImageCaptureControl(parent)
+{
+}
+
+S60CameraImageCaptureControl::S60CameraImageCaptureControl(S60CameraService *service,
+ S60ImageCaptureSession *session,
+ QObject *parent) :
+ QCameraImageCaptureControl(parent),
+ m_driveMode(QCameraImageCapture::SingleImageCapture) // Default DriveMode
+{
+ m_session = session;
+ m_service = service;
+ m_cameraControl = qobject_cast<S60CameraControl *>(m_service->requestControl(QCameraControl_iid));
+
+ if (!m_cameraControl)
+ m_session->setError(KErrGeneral, tr("Unexpected camera error."));
+
+ // Chain these signals from session class
+ connect(m_session, SIGNAL(imageCaptured(const int, QImage)),
+ this, SIGNAL(imageCaptured(const int, QImage)));
+ connect(m_session, SIGNAL(readyForCaptureChanged(bool)),
+ this, SIGNAL(readyForCaptureChanged(bool)), Qt::QueuedConnection);
+ connect(m_session, SIGNAL(imageSaved(const int, const QString&)),
+ this, SIGNAL(imageSaved(const int, const QString&)));
+ connect(m_session, SIGNAL(imageExposed(int)),
+ this, SIGNAL(imageExposed(int)));
+ connect(m_session, SIGNAL(captureError(int, int, const QString&)),
+ this, SIGNAL(error(int, int, const QString&)));
+}
+
+S60CameraImageCaptureControl::~S60CameraImageCaptureControl()
+{
+}
+
+bool S60CameraImageCaptureControl::isReadyForCapture() const
+{
+ if (m_cameraControl && m_cameraControl->captureMode() != QCamera::CaptureStillImage)
+ return false;
+
+ return m_session->isDeviceReady();
+}
+
+QCameraImageCapture::DriveMode S60CameraImageCaptureControl::driveMode() const
+{
+ return m_driveMode;
+}
+
+void S60CameraImageCaptureControl::setDriveMode(QCameraImageCapture::DriveMode mode)
+{
+ if (mode != QCameraImageCapture::SingleImageCapture) {
+ emit error((m_session->currentImageId() + 1), QCamera::NotSupportedFeatureError, tr("DriveMode not supported."));
+ return;
+ }
+
+ m_driveMode = mode;
+}
+
+int S60CameraImageCaptureControl::capture(const QString &fileName)
+{
+ if (m_cameraControl && m_cameraControl->captureMode() != QCamera::CaptureStillImage) {
+ emit error((m_session->currentImageId() + 1), QCameraImageCapture::NotReadyError, tr("Incorrect CaptureMode."));
+ return 0;
+ }
+
+ int imageId = m_session->capture(fileName);
+
+ return imageId;
+}
+
+void S60CameraImageCaptureControl::cancelCapture()
+{
+ m_session->cancelCapture();
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60cameraimagecapturecontrol.h b/src/plugins/symbian/ecam/s60cameraimagecapturecontrol.h
new file mode 100644
index 000000000..4c369e807
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraimagecapturecontrol.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60CAMERAIMAGECAPTURECONTROL_H
+#define S60CAMERAIMAGECAPTURECONTROL_H
+
+#include "qcameraimagecapturecontrol.h"
+
+QT_USE_NAMESPACE
+
+class S60CameraService;
+class S60ImageCaptureSession;
+class S60CameraControl;
+
+/*
+ * Control for image capture operations.
+ */
+class S60CameraImageCaptureControl : public QCameraImageCaptureControl
+{
+ Q_OBJECT
+
+public: // Contructors & Destrcutor
+
+ S60CameraImageCaptureControl(QObject *parent = 0);
+ S60CameraImageCaptureControl(S60CameraService *service,
+ S60ImageCaptureSession *session,
+ QObject *parent = 0);
+ ~S60CameraImageCaptureControl();
+
+public: // QCameraImageCaptureControl
+
+ bool isReadyForCapture() const;
+
+ // Drive Mode
+ QCameraImageCapture::DriveMode driveMode() const;
+ void setDriveMode(QCameraImageCapture::DriveMode mode);
+
+ // Capture
+ int capture(const QString &fileName);
+ void cancelCapture();
+
+/*
+Q_SIGNALS: // QCameraImageCaptureControl
+ void readyForCaptureChanged(bool);
+
+ void imageExposed(int id);
+ void imageCaptured(int id, const QImage &preview);
+ void imageSaved(int id, const QString &fileName);
+
+ void error(int id, int error, const QString &errorString);
+*/
+
+private: // Data
+
+ S60ImageCaptureSession *m_session;
+ S60CameraService *m_service;
+ S60CameraControl *m_cameraControl;
+ QCameraImageCapture::DriveMode m_driveMode;
+};
+
+#endif // S60CAMERAIMAGECAPTURECONTROL_H
diff --git a/src/plugins/symbian/ecam/s60cameraimageprocessingcontrol.cpp b/src/plugins/symbian/ecam/s60cameraimageprocessingcontrol.cpp
new file mode 100644
index 000000000..ae2c4535a
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraimageprocessingcontrol.cpp
@@ -0,0 +1,254 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+
+#include "s60cameraimageprocessingcontrol.h"
+#include "s60cameraservice.h"
+#include "s60imagecapturesession.h"
+
+S60CameraImageProcessingControl::S60CameraImageProcessingControl(QObject *parent) :
+ QCameraImageProcessingControl(parent)
+{
+}
+
+S60CameraImageProcessingControl::S60CameraImageProcessingControl(S60ImageCaptureSession *session, QObject *parent) :
+ QCameraImageProcessingControl(parent),
+ m_session(0),
+ m_advancedSettings(0)
+{
+ m_session = session;
+ m_advancedSettings = m_session->advancedSettings();
+}
+
+S60CameraImageProcessingControl::~S60CameraImageProcessingControl()
+{
+ m_advancedSettings = 0;
+}
+
+void S60CameraImageProcessingControl::resetAdvancedSetting()
+{
+ m_advancedSettings = m_session->advancedSettings();
+}
+
+QCameraImageProcessing::WhiteBalanceMode S60CameraImageProcessingControl::whiteBalanceMode() const
+{
+ return m_session->whiteBalanceMode();
+}
+
+void S60CameraImageProcessingControl::setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode)
+{
+ if (isWhiteBalanceModeSupported(mode))
+ m_session->setWhiteBalanceMode(mode);
+ else
+ m_session->setError(KErrNotSupported, tr("Requested white balance mode is not supported."));
+}
+
+bool S60CameraImageProcessingControl::isWhiteBalanceModeSupported(
+ QCameraImageProcessing::WhiteBalanceMode mode) const
+{
+ return m_session->isWhiteBalanceModeSupported(mode);
+}
+
+int S60CameraImageProcessingControl::manualWhiteBalance() const
+{
+ return 0;
+}
+
+void S60CameraImageProcessingControl::setManualWhiteBalance(int colorTemperature)
+{
+ m_session->setError(KErrNotSupported, tr("Setting manual white balance is not supported."));
+ Q_UNUSED(colorTemperature)
+}
+
+bool S60CameraImageProcessingControl::isProcessingParameterSupported(ProcessingParameter parameter) const
+{
+ // First check settings requiring Adv. Settings
+ if (m_advancedSettings) {
+ switch (parameter) {
+ case QCameraImageProcessingControl::Saturation:
+ return true;
+ case QCameraImageProcessingControl::Sharpening:
+ return isSharpeningSupported();
+ case QCameraImageProcessingControl::Denoising:
+ return isDenoisingSupported();
+ case QCameraImageProcessingControl::ColorTemperature:
+ return false;
+ }
+ }
+
+ // Then the rest
+ switch (parameter) {
+ case QCameraImageProcessingControl::Contrast:
+ case QCameraImageProcessingControl::Brightness:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+QVariant S60CameraImageProcessingControl::processingParameter(
+ QCameraImageProcessingControl::ProcessingParameter parameter) const
+{
+ switch (parameter) {
+ case QCameraImageProcessingControl::Contrast:
+ return QVariant(contrast());
+ case QCameraImageProcessingControl::Saturation:
+ return QVariant(saturation());
+ case QCameraImageProcessingControl::Brightness:
+ return QVariant(brightness());
+ case QCameraImageProcessingControl::Sharpening:
+ return QVariant(sharpeningLevel());
+ case QCameraImageProcessingControl::Denoising:
+ return QVariant(denoisingLevel());
+ case QCameraImageProcessingControl::ColorTemperature:
+ return QVariant(manualWhiteBalance());
+
+ default:
+ return QVariant();
+ }
+}
+
+void S60CameraImageProcessingControl::setProcessingParameter(
+ QCameraImageProcessingControl::ProcessingParameter parameter, QVariant value)
+{
+ switch (parameter) {
+ case QCameraImageProcessingControl::Contrast:
+ setContrast(value.toInt());
+ break;
+ case QCameraImageProcessingControl::Saturation:
+ setSaturation(value.toInt());
+ break;
+ case QCameraImageProcessingControl::Brightness:
+ setBrightness(value.toInt());
+ break;
+ case QCameraImageProcessingControl::Sharpening:
+ if (isSharpeningSupported())
+ setSharpeningLevel(value.toInt());
+ break;
+ case QCameraImageProcessingControl::Denoising:
+ if (isDenoisingSupported())
+ setDenoisingLevel(value.toInt());
+ break;
+ case QCameraImageProcessingControl::ColorTemperature:
+ setManualWhiteBalance(value.toInt());
+ break;
+
+ default:
+ break;
+ }
+}
+
+void S60CameraImageProcessingControl::setContrast(int value)
+{
+ m_session->setContrast(value);
+}
+
+int S60CameraImageProcessingControl::contrast() const
+{
+ return m_session->contrast();
+}
+
+void S60CameraImageProcessingControl::setBrightness(int value)
+{
+ m_session->setBrightness(value);
+}
+
+int S60CameraImageProcessingControl::brightness() const
+{
+ return m_session->brightness();
+}
+
+void S60CameraImageProcessingControl::setSaturation(int value)
+{
+ if (m_advancedSettings)
+ m_advancedSettings->setSaturation(value);
+ else
+ m_session->setError(KErrNotSupported, tr("Setting saturation is not supported."));
+}
+
+int S60CameraImageProcessingControl::saturation() const
+{
+ if (m_advancedSettings)
+ return m_advancedSettings->saturation();
+ return 0;
+}
+
+void S60CameraImageProcessingControl::setDenoisingLevel(int value)
+{
+ m_session->setError(KErrNotSupported, tr("Setting denoising level is not supported."));
+ Q_UNUSED(value); // Not supported for Symbian
+}
+
+bool S60CameraImageProcessingControl::isDenoisingSupported() const
+{
+ return false; // Not supported for Symbian
+}
+
+int S60CameraImageProcessingControl::denoisingLevel() const
+{
+ return 0; // Not supported for Symbian
+}
+
+void S60CameraImageProcessingControl::setSharpeningLevel(int value)
+{
+ if (m_advancedSettings)
+ m_advancedSettings->setSharpeningLevel(value);
+ else
+ m_session->setError(KErrNotSupported, tr("Setting sharpening level is not supported."));
+}
+
+bool S60CameraImageProcessingControl::isSharpeningSupported() const
+{
+ if (m_advancedSettings)
+ return m_advancedSettings->isSharpeningSupported();
+ return false;
+}
+
+int S60CameraImageProcessingControl::sharpeningLevel() const
+{
+ if (m_advancedSettings)
+ return m_advancedSettings->sharpeningLevel();
+ return 0;
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60cameraimageprocessingcontrol.h b/src/plugins/symbian/ecam/s60cameraimageprocessingcontrol.h
new file mode 100644
index 000000000..7fc6b8900
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraimageprocessingcontrol.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60CAMERAIMAGEPROCESSINGCONTROL_H
+#define S60CAMERAIMAGEPROCESSINGCONTROL_H
+
+#include <qcameraimageprocessing.h>
+#include <qcameraimageprocessingcontrol.h>
+
+#include "s60camerasettings.h"
+
+QT_USE_NAMESPACE
+
+class S60CameraService;
+class S60ImageCaptureSession;
+
+/*
+ * Control for image processing related camera operations (inc. white balance).
+ */
+class S60CameraImageProcessingControl : public QCameraImageProcessingControl
+{
+ Q_OBJECT
+
+public: // Constructors & Destructor
+
+ S60CameraImageProcessingControl(QObject *parent = 0);
+ S60CameraImageProcessingControl(S60ImageCaptureSession *session, QObject *parent = 0);
+ ~S60CameraImageProcessingControl();
+
+public: // QCameraImageProcessingControl
+
+ // White Balance
+ QCameraImageProcessing::WhiteBalanceMode whiteBalanceMode() const;
+ void setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode);
+ bool isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const;
+
+ // Processing Parameter
+ bool isProcessingParameterSupported(ProcessingParameter parameter) const;
+ QVariant processingParameter(QCameraImageProcessingControl::ProcessingParameter parameter) const;
+ void setProcessingParameter(QCameraImageProcessingControl::ProcessingParameter parameter, QVariant value);
+
+private slots: // Internal Slots
+
+ void resetAdvancedSetting();
+
+private: // Internal operations - Implementing ProcessingParameter
+
+ // Manual White Balance (Color Temperature)
+ int manualWhiteBalance() const;
+ void setManualWhiteBalance(int colorTemperature);
+
+ // Contrast
+ int contrast() const;
+ void setContrast(int value);
+
+ // Brightness
+ int brightness() const;
+ void setBrightness(int value);
+
+ // Saturation
+ int saturation() const;
+ void setSaturation(int value);
+
+ // Sharpening
+ bool isSharpeningSupported() const;
+ int sharpeningLevel() const;
+ void setSharpeningLevel(int value);
+
+ // Denoising
+ bool isDenoisingSupported() const;
+ int denoisingLevel() const;
+ void setDenoisingLevel(int value);
+
+private: // Data
+
+ S60ImageCaptureSession *m_session;
+ S60CameraSettings *m_advancedSettings;
+};
+
+#endif // S60CAMERAIMAGEPROCESSINGCONTROL_H
diff --git a/src/plugins/symbian/ecam/s60cameralockscontrol.cpp b/src/plugins/symbian/ecam/s60cameralockscontrol.cpp
new file mode 100644
index 000000000..cce030f22
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameralockscontrol.cpp
@@ -0,0 +1,263 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+#include <qcamerafocus.h> // FocusMode
+
+#include "s60cameralockscontrol.h"
+#include "s60cameraservice.h"
+#include "s60imagecapturesession.h"
+#include "s60camerasettings.h"
+#include "s60camerafocuscontrol.h"
+
+S60CameraLocksControl::S60CameraLocksControl(QObject *parent) :
+ QCameraLocksControl(parent)
+{
+}
+
+S60CameraLocksControl::S60CameraLocksControl(S60CameraService *service,
+ S60ImageCaptureSession *session,
+ QObject *parent) :
+ QCameraLocksControl(parent),
+ m_session(0),
+ m_service(0),
+ m_advancedSettings(0),
+ m_focusControl(0),
+ m_focusStatus(QCamera::Unlocked),
+ m_exposureStatus(QCamera::Unlocked),
+ m_whiteBalanceStatus(QCamera::Unlocked)
+{
+ m_session = session;
+ m_service = service;
+ m_focusControl = qobject_cast<S60CameraFocusControl *>(m_service->requestControl(QCameraFocusControl_iid));
+
+ connect(m_session, SIGNAL(advancedSettingChanged()), this, SLOT(resetAdvancedSetting()));
+ m_advancedSettings = m_session->advancedSettings();
+
+ // Exposure Lock Signals
+ if (m_advancedSettings)
+ connect(m_advancedSettings, SIGNAL(exposureStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)),
+ this, SLOT(exposureStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)));
+
+ // Focus Lock Signal
+ // * S60 3.2 and later (through Adv. Settings)
+ if (m_advancedSettings)
+ connect(m_advancedSettings, SIGNAL(focusStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)),
+ this, SLOT(focusStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)));
+ // * S60 3.1 (through ImageSession)
+ connect(m_session, SIGNAL(focusStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)),
+ this, SLOT(focusStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)));
+}
+
+S60CameraLocksControl::~S60CameraLocksControl()
+{
+ m_advancedSettings = 0;
+}
+
+QCamera::LockTypes S60CameraLocksControl::supportedLocks() const
+{
+ QCamera::LockTypes supportedLocks = 0;
+
+#ifdef S60_CAM_AUTOFOCUS_SUPPORT // S60 3.1
+ if (m_session)
+ if (m_session->isFocusSupported())
+ supportedLocks |= QCamera::LockFocus;
+#else // S60 3.2 and later
+ if (m_advancedSettings) {
+ QCameraFocus::FocusModes supportedFocusModes = m_advancedSettings->supportedFocusModes();
+ if (supportedFocusModes & QCameraFocus::AutoFocus)
+ supportedLocks |= QCamera::LockFocus;
+
+ // Exposure/WhiteBalance Locking not implemented in Symbian
+ // supportedLocks |= QCamera::LockExposure;
+ // supportedLocks |= QCamera::LockWhiteBalance;
+ }
+#endif // S60_CAM_AUTOFOCUS_SUPPORT
+
+ return supportedLocks;
+}
+
+QCamera::LockStatus S60CameraLocksControl::lockStatus(QCamera::LockType lock) const
+{
+ switch (lock) {
+ case QCamera::LockExposure:
+ return m_exposureStatus;
+ case QCamera::LockWhiteBalance:
+ return m_whiteBalanceStatus;
+ case QCamera::LockFocus:
+ return m_focusStatus;
+
+ default:
+ // Unsupported lock
+ return QCamera::Unlocked;
+ }
+}
+
+void S60CameraLocksControl::searchAndLock(QCamera::LockTypes locks)
+{
+ if (locks & QCamera::LockExposure) {
+ // Not implemented in Symbian
+ //startExposureLocking();
+ }
+ if (locks & QCamera::LockWhiteBalance) {
+ // Not implemented in Symbian
+ }
+ if (locks & QCamera::LockFocus)
+ startFocusing();
+}
+
+void S60CameraLocksControl::unlock(QCamera::LockTypes locks)
+{
+ if (locks & QCamera::LockExposure) {
+ // Not implemented in Symbian
+ //cancelExposureLocking();
+ }
+
+ if (locks & QCamera::LockFocus)
+ cancelFocusing();
+}
+
+void S60CameraLocksControl::resetAdvancedSetting()
+{
+ m_advancedSettings = m_session->advancedSettings();
+
+ // Reconnect Lock Signals
+ if (m_advancedSettings) {
+ connect(m_advancedSettings, SIGNAL(exposureStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)),
+ this, SLOT(exposureStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)));
+ connect(m_advancedSettings, SIGNAL(focusStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)),
+ this, SLOT(focusStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason)));
+ }
+}
+
+void S60CameraLocksControl::exposureStatusChanged(QCamera::LockStatus status,
+ QCamera::LockChangeReason reason)
+{
+ if(status != m_exposureStatus) {
+ m_exposureStatus = status;
+ emit lockStatusChanged(QCamera::LockExposure, status, reason);
+ }
+}
+
+void S60CameraLocksControl::focusStatusChanged(QCamera::LockStatus status,
+ QCamera::LockChangeReason reason)
+{
+ if(status != m_focusStatus) {
+ m_focusStatus = status;
+ emit lockStatusChanged(QCamera::LockFocus, status, reason);
+ }
+}
+
+void S60CameraLocksControl::startFocusing()
+{
+#ifndef S60_CAM_AUTOFOCUS_SUPPORT // S60 3.2 or later
+ // Focusing is triggered on Symbian by setting the FocusType corresponding
+ // to the FocusMode set to FocusControl
+ if (m_focusControl) {
+ if (m_advancedSettings) {
+ m_advancedSettings->startFocusing();
+ m_focusStatus = QCamera::Searching;
+ emit lockStatusChanged(QCamera::LockFocus, QCamera::Searching, QCamera::UserRequest);
+ }
+ else
+ emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::LockFailed);
+ }
+ else
+ emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::LockFailed);
+
+#else // S60 3.1
+ if (m_focusControl && m_focusControl->focusMode() == QCameraFocus::AutoFocus) {
+ m_session->startFocus();
+ m_focusStatus = QCamera::Searching;
+ emit lockStatusChanged(QCamera::LockFocus, QCamera::Searching, QCamera::UserRequest);
+ }
+ else
+ emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::LockFailed);
+#endif // S60_CAM_AUTOFOCUS_SUPPORT
+}
+
+void S60CameraLocksControl::cancelFocusing()
+{
+ if (m_focusStatus == QCamera::Unlocked)
+ return;
+
+#ifndef S60_CAM_AUTOFOCUS_SUPPORT // S60 3.2 or later
+ if (m_advancedSettings) {
+ m_advancedSettings->cancelFocusing();
+ m_focusStatus = QCamera::Unlocked;
+ emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::UserRequest);
+ }
+ else
+ emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::LockFailed);
+
+#else // S60 3.1
+ m_session->cancelFocus();
+ m_focusStatus = QCamera::Unlocked;
+ emit lockStatusChanged(QCamera::LockFocus, QCamera::Unlocked, QCamera::UserRequest);
+#endif // S60_CAM_AUTOFOCUS_SUPPORT
+}
+
+void S60CameraLocksControl::startExposureLocking()
+{
+ if (m_advancedSettings) {
+ m_advancedSettings->lockExposure(true);
+ m_exposureStatus = QCamera::Searching;
+ emit lockStatusChanged(QCamera::LockExposure, QCamera::Searching, QCamera::UserRequest);
+ }
+ else
+ emit lockStatusChanged(QCamera::LockExposure, QCamera::Unlocked, QCamera::LockFailed);
+}
+
+void S60CameraLocksControl::cancelExposureLocking()
+{
+ if (m_exposureStatus == QCamera::Unlocked)
+ return;
+
+ if (m_advancedSettings) {
+ m_advancedSettings->lockExposure(false);
+ m_exposureStatus = QCamera::Unlocked;
+ emit lockStatusChanged(QCamera::LockExposure, QCamera::Unlocked, QCamera::UserRequest);
+ }
+ else
+ emit lockStatusChanged(QCamera::LockExposure, QCamera::Unlocked, QCamera::LockFailed);
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60cameralockscontrol.h b/src/plugins/symbian/ecam/s60cameralockscontrol.h
new file mode 100644
index 000000000..3b49cbaba
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameralockscontrol.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60CAMERALOCKSCONTROL_H
+#define S60CAMERALOCKSCONTROL_H
+
+#include <QtCore/qobject.h>
+#include "qcameralockscontrol.h"
+
+QT_USE_NAMESPACE
+
+class S60CameraService;
+class S60ImageCaptureSession;
+class S60CameraSettings;
+class S60CameraFocusControl;
+
+/*
+ * Control for searching and locking 3A algorithms (AutoFocus, AutoExposure
+ * and AutoWhitebalance).
+ */
+class S60CameraLocksControl : public QCameraLocksControl
+{
+ Q_OBJECT
+
+public: // Contructors & Destrcutor
+
+ S60CameraLocksControl(QObject *parent = 0);
+ S60CameraLocksControl(S60CameraService *service,
+ S60ImageCaptureSession *session,
+ QObject *parent = 0);
+ ~S60CameraLocksControl();
+
+public: // QCameraLocksControl
+
+ QCamera::LockTypes supportedLocks() const;
+
+ QCamera::LockStatus lockStatus(QCamera::LockType lock) const;
+
+ void searchAndLock(QCamera::LockTypes locks);
+ void unlock(QCamera::LockTypes locks);
+
+/*
+Q_SIGNALS: // QCameraLocksControl
+
+ void lockStatusChanged(QCamera::LockType type,
+ QCamera::LockStatus status,
+ QCamera::LockChangeReason reason);
+*/
+
+private slots: // Internal Slots
+
+ void exposureStatusChanged(QCamera::LockStatus status, QCamera::LockChangeReason reason);
+ void focusStatusChanged(QCamera::LockStatus status, QCamera::LockChangeReason reason);
+ void resetAdvancedSetting();
+
+private: // Internal
+
+ // Focus
+ void startFocusing();
+ void cancelFocusing();
+
+ // Exposure
+ void startExposureLocking();
+ void cancelExposureLocking();
+
+private: // Data
+
+ S60ImageCaptureSession *m_session;
+ S60CameraService *m_service;
+ S60CameraSettings *m_advancedSettings;
+ S60CameraFocusControl *m_focusControl;
+ QCamera::LockStatus m_focusStatus;
+ QCamera::LockStatus m_exposureStatus;
+ QCamera::LockStatus m_whiteBalanceStatus;
+};
+
+#endif // S60CAMERALOCKSCONTROL_H
diff --git a/src/plugins/symbian/ecam/s60cameraservice.cpp b/src/plugins/symbian/ecam/s60cameraservice.cpp
new file mode 100644
index 000000000..5cc4485c1
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraservice.cpp
@@ -0,0 +1,259 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qvariant.h>
+#include <QtGui/qwidget.h>
+#include <QtCore/qlist.h>
+
+#include "s60cameraservice.h"
+#include "s60cameracontrol.h"
+#include "s60videodevicecontrol.h"
+#include "s60camerafocuscontrol.h"
+#include "s60cameraexposurecontrol.h"
+#include "s60cameraflashcontrol.h"
+#include "s60cameraimageprocessingcontrol.h"
+#include "s60cameraimagecapturecontrol.h"
+#include "s60mediarecordercontrol.h"
+#include "s60videocapturesession.h"
+#include "s60imagecapturesession.h"
+#include "s60videowidgetcontrol.h"
+#include "s60mediacontainercontrol.h"
+#include "s60videoencodercontrol.h"
+#include "s60audioencodercontrol.h"
+#include "s60imageencodercontrol.h"
+#include "s60cameralockscontrol.h"
+#include "s60videorenderercontrol.h"
+#include "s60videowindowcontrol.h"
+
+#include "s60cameraviewfinderengine.h" // ViewfinderOutputType
+
+S60CameraService::S60CameraService(QObject *parent) :
+ QMediaService(parent)
+{
+ // Session classes for video and image capturing
+ m_imagesession = new S60ImageCaptureSession(this);
+ m_videosession = new S60VideoCaptureSession(this);
+
+ if (m_imagesession && m_videosession) {
+ // Different control classes implementing the Camera API
+ m_control = new S60CameraControl(m_videosession, m_imagesession, this);
+ m_videoDeviceControl = new S60VideoDeviceControl(m_control, this);
+ m_focusControl = new S60CameraFocusControl(m_imagesession, this);
+ m_exposureControl = new S60CameraExposureControl(m_imagesession, this);
+ m_flashControl = new S60CameraFlashControl(m_imagesession, this);
+ m_imageProcessingControl = new S60CameraImageProcessingControl(m_imagesession, this);
+ m_imageCaptureControl = new S60CameraImageCaptureControl(this, m_imagesession, this);
+ m_media = new S60MediaRecorderControl(this, m_videosession, this);
+ m_mediaFormat = new S60MediaContainerControl(m_videosession, this);
+ m_videoEncoder = new S60VideoEncoderControl(m_videosession, this);
+ m_audioEncoder = new S60AudioEncoderControl(m_videosession, this);
+ m_viewFinderWidget = new S60VideoWidgetControl(this);
+ m_imageEncoderControl = new S60ImageEncoderControl(m_imagesession, this);
+ m_locksControl = new S60CameraLocksControl(this, m_imagesession, this);
+ m_rendererControl = new S60VideoRendererControl(this);
+ m_windowControl = new S60VideoWindowControl(this);
+ }
+}
+
+S60CameraService::~S60CameraService()
+{
+ // Delete controls
+ if (m_videoDeviceControl)
+ delete m_videoDeviceControl;
+ if (m_focusControl)
+ delete m_focusControl;
+ if (m_exposureControl)
+ delete m_exposureControl;
+ if (m_flashControl)
+ delete m_flashControl;
+ if (m_imageProcessingControl)
+ delete m_imageProcessingControl;
+ if (m_imageCaptureControl)
+ delete m_imageCaptureControl;
+ if (m_media)
+ delete m_media;
+ if (m_mediaFormat)
+ delete m_mediaFormat;
+ if (m_videoEncoder)
+ delete m_videoEncoder;
+ if (m_audioEncoder)
+ delete m_audioEncoder;
+ if (m_imageEncoderControl)
+ delete m_imageEncoderControl;
+ if (m_locksControl)
+ delete m_locksControl;
+
+ // CameraControl destroys:
+ // * ViewfinderEngine
+ // * CameraEngine
+ if (m_control)
+ delete m_control;
+
+ // Delete viewfinder controls after CameraControl to be sure that
+ // ViewFinder gets stopped before widget (and window) is destroyed
+ if (m_viewFinderWidget)
+ delete m_viewFinderWidget;
+ if (m_rendererControl)
+ delete m_rendererControl;
+ if (m_windowControl)
+ delete m_windowControl;
+
+ // Delete sessions
+ if (m_videosession)
+ delete m_videosession;
+ if (m_imagesession)
+ delete m_imagesession;
+}
+
+QMediaControl *S60CameraService::requestControl(const char *name)
+{
+ if (qstrcmp(name, QMediaRecorderControl_iid) == 0)
+ return m_media;
+
+ if (qstrcmp(name, QCameraControl_iid) == 0)
+ return m_control;
+
+ if (qstrcmp(name, QVideoEncoderControl_iid) == 0)
+ return m_videoEncoder;
+
+ if (qstrcmp(name, QAudioEncoderControl_iid) == 0)
+ return m_audioEncoder;
+
+ if (qstrcmp(name, QMediaContainerControl_iid) == 0)
+ return m_mediaFormat;
+
+ if (qstrcmp(name, QCameraExposureControl_iid) == 0)
+ return m_exposureControl;
+
+ if (qstrcmp(name, QCameraFlashControl_iid) == 0)
+ return m_flashControl;
+
+ if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
+ if (m_viewFinderWidget) {
+ m_control->setVideoOutput(m_viewFinderWidget,
+ S60CameraViewfinderEngine::OutputTypeVideoWidget);
+ return m_viewFinderWidget;
+ }
+ else
+ return 0;
+ }
+
+ if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
+ if (m_rendererControl) {
+ m_control->setVideoOutput(m_rendererControl,
+ S60CameraViewfinderEngine::OutputTypeRenderer);
+ return m_rendererControl;
+ }
+ else
+ return 0;
+ }
+
+ if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
+ if (m_windowControl) {
+ m_control->setVideoOutput(m_windowControl,
+ S60CameraViewfinderEngine::OutputTypeVideoWindow);
+ return m_windowControl;
+ }
+ else
+ return 0;
+ }
+
+
+ if (qstrcmp(name, QCameraFocusControl_iid) == 0)
+ return m_focusControl;
+
+ if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0)
+ return m_imageProcessingControl;
+
+ if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0)
+ return m_imageCaptureControl;
+
+ if (qstrcmp(name, QVideoDeviceControl_iid) == 0)
+ return m_videoDeviceControl;
+
+ if (qstrcmp(name, QImageEncoderControl_iid) == 0)
+ return m_imageEncoderControl;
+
+ if (qstrcmp(name, QCameraLocksControl_iid) == 0)
+ return m_locksControl;
+
+ return 0;
+}
+
+void S60CameraService::releaseControl(QMediaControl *control)
+{
+ if (control == 0)
+ return;
+
+ // Release viewfinder output
+ if (control == m_viewFinderWidget) {
+ if (m_viewFinderWidget)
+ m_control->releaseVideoOutput(S60CameraViewfinderEngine::OutputTypeVideoWidget);
+ }
+
+ if (control == m_rendererControl) {
+ if (m_rendererControl)
+ m_control->releaseVideoOutput(S60CameraViewfinderEngine::OutputTypeRenderer);
+ }
+
+ if (control == m_windowControl) {
+ if (m_windowControl)
+ m_control->releaseVideoOutput(S60CameraViewfinderEngine::OutputTypeVideoWindow);
+ }
+}
+
+int S60CameraService::deviceCount()
+{
+ return S60CameraControl::deviceCount();
+}
+
+QString S60CameraService::deviceDescription(const int index)
+{
+ return S60CameraControl::description(index);
+}
+
+QString S60CameraService::deviceName(const int index)
+{
+ return S60CameraControl::name(index);
+}
+
+// End of file
+
diff --git a/src/plugins/symbian/ecam/s60cameraservice.h b/src/plugins/symbian/ecam/s60cameraservice.h
new file mode 100644
index 000000000..a2744c1fa
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraservice.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60CAMERASERVICE_H
+#define S60CAMERASERVICE_H
+
+#include <QtCore/qobject.h>
+#include <qmediaservice.h>
+
+QT_USE_NAMESPACE
+
+class S60MediaContainerControl;
+class S60VideoEncoderControl;
+class S60AudioEncoderControl;
+class S60CameraControl;
+class S60VideoDeviceControl;
+class S60MediaRecorderControl;
+class S60ImageCaptureSession;
+class S60VideoCaptureSession;
+class S60CameraFocusControl;
+class S60CameraExposureControl;
+class S60CameraFlashControl;
+class S60CameraImageProcessingControl;
+class S60CameraImageCaptureControl;
+class S60VideoWidgetControl;
+class S60ImageEncoderControl;
+class S60CameraLocksControl;
+class S60VideoRendererControl;
+class S60VideoWindowControl;
+
+class S60CameraService : public QMediaService
+{
+ Q_OBJECT
+
+public: // Contructor & Destructor
+
+ S60CameraService(QObject *parent = 0);
+ ~S60CameraService();
+
+public: // QMediaService
+
+ QMediaControl *requestControl(const char *name);
+ void releaseControl(QMediaControl *control);
+
+public: // Static Device Info
+
+ static int deviceCount();
+ static QString deviceName(const int index);
+ static QString deviceDescription(const int index);
+
+private: // Data
+
+ S60ImageCaptureSession *m_imagesession;
+ S60VideoCaptureSession *m_videosession;
+ S60MediaContainerControl *m_mediaFormat;
+ S60VideoEncoderControl *m_videoEncoder;
+ S60AudioEncoderControl *m_audioEncoder;
+ S60CameraControl *m_control;
+ S60VideoDeviceControl *m_videoDeviceControl;
+ S60CameraFocusControl *m_focusControl;
+ S60CameraExposureControl *m_exposureControl;
+ S60CameraFlashControl *m_flashControl;
+ S60CameraImageProcessingControl *m_imageProcessingControl;
+ S60CameraImageCaptureControl *m_imageCaptureControl;
+ S60MediaRecorderControl *m_media;
+ S60VideoWidgetControl *m_viewFinderWidget;
+ S60ImageEncoderControl *m_imageEncoderControl;
+ S60CameraLocksControl *m_locksControl;
+ S60VideoRendererControl *m_rendererControl;
+ S60VideoWindowControl *m_windowControl;
+};
+
+#endif // S60CAMERASERVICE_H
diff --git a/src/plugins/symbian/ecam/s60cameraserviceplugin.cpp b/src/plugins/symbian/ecam/s60cameraserviceplugin.cpp
new file mode 100644
index 000000000..8f22fd205
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraserviceplugin.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+
+#include "s60cameraserviceplugin.h"
+#ifdef QMEDIA_SYMBIAN_CAMERA
+#include "s60cameraservice.h"
+#endif
+
+QStringList S60CameraServicePlugin::keys() const
+{
+ QStringList list;
+#ifdef QMEDIA_SYMBIAN_CAMERA
+ list << QLatin1String(Q_MEDIASERVICE_CAMERA);
+#endif
+ return list;
+}
+
+QMediaService* S60CameraServicePlugin::create(QString const& key)
+{
+#ifdef QMEDIA_SYMBIAN_CAMERA
+ if (key == QLatin1String(Q_MEDIASERVICE_CAMERA))
+ return new S60CameraService;
+#endif
+ return 0;
+}
+
+void S60CameraServicePlugin::release(QMediaService *service)
+{
+ delete service;
+}
+
+QList<QByteArray> S60CameraServicePlugin::devices(const QByteArray &service) const
+{
+#ifdef QMEDIA_SYMBIAN_CAMERA
+ if (service == Q_MEDIASERVICE_CAMERA) {
+ if (m_cameraDevices.isEmpty())
+ updateDevices();
+
+ return m_cameraDevices;
+ }
+#endif
+ return QList<QByteArray>();
+}
+
+QString S60CameraServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
+{
+#ifdef QMEDIA_SYMBIAN_CAMERA
+ if (service == Q_MEDIASERVICE_CAMERA) {
+ if (m_cameraDevices.isEmpty())
+ updateDevices();
+
+ for (int i=0; i<m_cameraDevices.count(); i++)
+ if (m_cameraDevices[i] == device)
+ return m_cameraDescriptions[i];
+ }
+#endif
+ return QString();
+}
+
+void S60CameraServicePlugin::updateDevices() const
+{
+#ifdef QMEDIA_SYMBIAN_CAMERA
+ m_cameraDevices.clear();
+ m_cameraDescriptions.clear();
+ for (int i=0; i < S60CameraService::deviceCount(); i ++) {
+ m_cameraDevices.append(S60CameraService::deviceName(i).toUtf8());
+ m_cameraDescriptions.append(S60CameraService::deviceDescription(i));
+ }
+#endif
+}
+
+Q_EXPORT_PLUGIN2(qtmultimedia_ecamngine, S60CameraServicePlugin);
+
+// End of file
+
diff --git a/src/plugins/symbian/ecam/s60cameraserviceplugin.h b/src/plugins/symbian/ecam/s60cameraserviceplugin.h
new file mode 100644
index 000000000..c56b054c6
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraserviceplugin.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef S60CAMERASERVICEPLUGIN_H
+#define S60CAMERASERVICEPLUGIN_H
+
+#include <qmediaservice.h>
+#include <qmediaserviceproviderplugin.h>
+
+QT_USE_NAMESPACE
+
+/*
+ * Plugin implementation for the Camera Service
+ */
+class S60CameraServicePlugin : public QMediaServiceProviderPlugin,
+ public QMediaServiceSupportedDevicesInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
+
+public: // QMediaServiceProviderPlugin
+
+ QStringList keys() const;
+ QMediaService* create(QString const& key);
+ void release(QMediaService *service);
+
+public: // QMediaServiceSupportedDevicesInterface
+
+ QList<QByteArray> devices(const QByteArray &service) const;
+ QString deviceDescription(const QByteArray &service, const QByteArray &device);
+
+private: // Internal
+
+ void updateDevices() const;
+
+private: // Data
+
+ mutable QList<QByteArray> m_cameraDevices;
+ mutable QStringList m_cameraDescriptions;
+};
+
+#endif // S60CAMERASERVICEPLUGIN_H
diff --git a/src/plugins/symbian/ecam/s60camerasettings.cpp b/src/plugins/symbian/ecam/s60camerasettings.cpp
new file mode 100644
index 000000000..a5918078f
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60camerasettings.cpp
@@ -0,0 +1,986 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "s60camerasettings.h"
+#include "s60cameraconstants.h"
+
+// S60 3.2 Platform
+#ifdef USE_S60_32_ECAM_ADVANCED_SETTINGS_HEADER
+#define POST_31_PLATFORM
+#include <ecamadvancedsettings.h> // CCameraAdvancedSettings (inc. TValueInfo)
+#endif // S60 3.2
+
+// S60 5.0 or later
+#ifdef USE_S60_50_ECAM_ADVANCED_SETTINGS_HEADER
+#define POST_31_PLATFORM
+#include <ecamadvsettings.h> // CCameraAdvancedSettings
+#include <ecam/ecamconstants.h> // TValueInfo
+#endif // S60 5.0 or later
+
+S60CameraSettings::S60CameraSettings(QObject *parent, CCameraEngine *engine) :
+ QObject(parent),
+#ifndef S60_31_PLATFORM // Post S60 3.1 Platforms
+ m_advancedSettings(0),
+ m_imageProcessingSettings(0),
+#endif // S60_31_PLATFORM
+ m_cameraEngine(engine),
+ m_continuousFocusing(false)
+{
+}
+
+S60CameraSettings::~S60CameraSettings()
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ delete m_advancedSettings;
+ m_advancedSettings = 0;
+ }
+
+ if (m_imageProcessingSettings) {
+ delete m_imageProcessingSettings;
+ m_imageProcessingSettings = 0;
+ }
+#endif // POST_31_PLATFORM
+}
+
+/*
+ * This is Symbian NewL kind of consructor, but unlike Symbian version this
+ * constructor will not leave, but instead it will return possible errors in
+ * the error variable. This is to be able to write the class without deriving
+ * it form CBase. Also CleanupStack is cleaned here if the ConstructL leaves.
+ */
+S60CameraSettings* S60CameraSettings::New(int &error, QObject *parent, CCameraEngine *engine)
+{
+ S60CameraSettings* self = new S60CameraSettings(parent, engine);
+ if (!self) {
+ error = KErrNoMemory;
+ return 0;
+ }
+
+ TRAPD(err, self->ConstructL());
+ if (err) {
+ // Clean created object
+ delete self;
+ self = 0;
+ error = err;
+ return 0;
+ }
+
+ error = KErrNone;
+ return self;
+}
+
+void S60CameraSettings::ConstructL()
+{
+#ifdef POST_31_PLATFORM
+ if (!m_cameraEngine)
+ User::Leave(KErrGeneral);
+ // From now on it is safe to assume engine exists
+
+ // If no AdvancedSettings is available, there's no benefit of S60CameraSettings
+ // Leave if creation fails
+ m_advancedSettings = CCamera::CCameraAdvancedSettings::NewL(*m_cameraEngine->Camera());
+ CleanupStack::PushL(m_advancedSettings);
+
+ // ImageProcessing module may not be supported, don't Leave
+ TRAPD(err, m_imageProcessingSettings = CCamera::CCameraImageProcessing::NewL(*m_cameraEngine->Camera()));
+ if (err == KErrNone && m_imageProcessingSettings) {
+ CleanupStack::PushL(m_imageProcessingSettings);
+ } else {
+ if (err == KErrNotSupported)
+ m_imageProcessingSettings = 0;
+ else {
+ // Leave with error
+ if (!m_imageProcessingSettings)
+ User::Leave(KErrNoMemory);
+ else
+ User::Leave(err);
+ }
+ }
+
+ if (m_advancedSettings) {
+ RArray<TInt> digitalZoomFactors;
+ CleanupClosePushL(digitalZoomFactors);
+
+ TValueInfo info = ENotActive;
+ m_advancedSettings->GetDigitalZoomStepsL(digitalZoomFactors, info);
+
+ for (int i = 0; i < digitalZoomFactors.Count(); ++i)
+ m_supportedSymbianDigitalZoomFactors << digitalZoomFactors[i];
+
+ CleanupStack::PopAndDestroy(); // RArray<TInt> digitalZoomFactors
+ }
+
+ // Pop objects from CleanupStack
+ if (m_imageProcessingSettings)
+ CleanupStack::Pop(m_imageProcessingSettings);
+ CleanupStack::Pop(m_advancedSettings);
+
+#else // S60 3.1
+ // AdvancedSettings are not suppoted on S60 3.1 (There's no use for S60CameraSettings)
+ User::Leave(KErrNotSupported);
+#endif // POST_31_PLATFORM
+}
+
+void S60CameraSettings::setFocusMode(QCameraFocus::FocusMode mode)
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ switch (mode) {
+ case QCameraFocus::ManualFocus: // Manual focus mode
+ m_advancedSettings->SetFocusMode(CCamera::CCameraAdvancedSettings::EFocusModeManual);
+ m_continuousFocusing = false;
+ break;
+ case QCameraFocus::AutoFocus: // Single-shot AutoFocus mode
+ m_advancedSettings->SetFocusMode(CCamera::CCameraAdvancedSettings::EFocusModeAuto);
+ m_advancedSettings->SetFocusRange(CCamera::CCameraAdvancedSettings::EFocusRangeAuto);
+ m_continuousFocusing = false;
+ break;
+ case QCameraFocus::HyperfocalFocus:
+ m_advancedSettings->SetFocusMode(CCamera::CCameraAdvancedSettings::EFocusModeAuto);
+ m_advancedSettings->SetFocusRange(CCamera::CCameraAdvancedSettings::EFocusRangeHyperfocal);
+ m_continuousFocusing = false;
+ break;
+ case QCameraFocus::InfinityFocus:
+ m_advancedSettings->SetFocusMode(CCamera::CCameraAdvancedSettings::EFocusModeAuto);
+ m_advancedSettings->SetFocusRange(CCamera::CCameraAdvancedSettings::EFocusRangeInfinite);
+ m_continuousFocusing = false;
+ break;
+ case QCameraFocus::ContinuousFocus:
+ m_advancedSettings->SetFocusMode(CCamera::CCameraAdvancedSettings::EFocusModeAuto);
+ m_advancedSettings->SetFocusRange(CCamera::CCameraAdvancedSettings::EFocusRangeAuto);
+ m_continuousFocusing = true;
+ break;
+ case QCameraFocus::MacroFocus:
+ m_advancedSettings->SetFocusMode(CCamera::CCameraAdvancedSettings::EFocusModeAuto);
+ m_advancedSettings->SetFocusRange(CCamera::CCameraAdvancedSettings::EFocusRangeMacro);
+ m_continuousFocusing = false;
+ break;
+
+ default:
+ emit error(QCamera::NotSupportedFeatureError, tr("Requested focus mode is not supported."));
+ break;
+ }
+ } else {
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ }
+#else // S60 3.1
+ Q_UNUSED(mode);
+ emit error(QCamera::NotSupportedFeatureError, tr("Settings focus mode is not supported."));
+#endif // POST_31_PLATFORM
+}
+
+void S60CameraSettings::startFocusing()
+{
+#ifdef POST_31_PLATFORM
+ // Setting AutoFocusType triggers the focusing on Symbian
+ if (m_advancedSettings) {
+ if (m_continuousFocusing)
+ m_advancedSettings->SetAutoFocusType(CCamera::CCameraAdvancedSettings::EAutoFocusTypeContinuous);
+ else
+ m_advancedSettings->SetAutoFocusType(CCamera::CCameraAdvancedSettings::EAutoFocusTypeSingle);
+ } else {
+ emit error(QCamera::CameraError, tr("Unable to focus."));
+ }
+#endif // POST_31_PLATFORM
+}
+
+void S60CameraSettings::cancelFocusing()
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings)
+ m_advancedSettings->SetAutoFocusType(CCamera::CCameraAdvancedSettings::EAutoFocusTypeOff);
+ else
+ emit error(QCamera::CameraError, tr("Unable to cancel focusing."));
+#endif // POST_31_PLATFORM
+}
+
+QCameraFocus::FocusMode S60CameraSettings::focusMode()
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ // First request needed info
+ CCamera::CCameraAdvancedSettings::TFocusMode mode = m_advancedSettings->FocusMode();
+ CCamera::CCameraAdvancedSettings::TFocusRange range = m_advancedSettings->FocusRange();
+ CCamera::CCameraAdvancedSettings::TAutoFocusType autoType = m_advancedSettings->AutoFocusType();
+
+ switch (mode) {
+ case CCamera::CCameraAdvancedSettings::EFocusModeManual:
+ case CCamera::CCameraAdvancedSettings::EFocusModeFixed:
+ return QCameraFocus::ManualFocus;
+
+ case CCamera::CCameraAdvancedSettings::EFocusModeAuto:
+ if (autoType == CCamera::CCameraAdvancedSettings::EAutoFocusTypeContinuous) {
+ return QCameraFocus::ContinuousFocus;
+ } else {
+ // Single-shot focusing
+ switch (range) {
+ case CCamera::CCameraAdvancedSettings::EFocusRangeMacro:
+ case CCamera::CCameraAdvancedSettings::EFocusRangeSuperMacro:
+ return QCameraFocus::MacroFocus;
+ case CCamera::CCameraAdvancedSettings::EFocusRangeHyperfocal:
+ return QCameraFocus::HyperfocalFocus;
+ case CCamera::CCameraAdvancedSettings::EFocusRangeInfinite:
+ return QCameraFocus::InfinityFocus;
+ case CCamera::CCameraAdvancedSettings::EFocusRangeAuto:
+ case CCamera::CCameraAdvancedSettings::EFocusRangeNormal:
+ return QCameraFocus::AutoFocus;
+
+ default:
+ return QCameraFocus::AutoFocus;
+ }
+ }
+ default:
+ return QCameraFocus::AutoFocus; // Return automatic focusing
+ }
+ } else {
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ }
+#endif // POST_31_PLATFORM
+ return QCameraFocus::AutoFocus; // Return automatic focusing
+}
+
+QCameraFocus::FocusModes S60CameraSettings::supportedFocusModes()
+{
+ QCameraFocus::FocusModes modes = 0;
+
+#ifdef POST_31_PLATFORM
+ TInt supportedModes = 0;
+ TInt autoFocusTypes = 0;
+ TInt supportedRanges = 0;
+
+ if (m_advancedSettings) {
+ supportedModes = m_advancedSettings->SupportedFocusModes();
+ autoFocusTypes = m_advancedSettings->SupportedAutoFocusTypes();
+ supportedRanges = m_advancedSettings->SupportedFocusRanges();
+
+ if (supportedModes == 0 || autoFocusTypes == 0 || supportedRanges == 0)
+ return modes;
+
+ // EFocusModeAuto is the only supported on Symbian
+ if (supportedModes & CCamera::CCameraAdvancedSettings::EFocusModeAuto) {
+ // Check supported types (Single-shot Auto vs. Continuous)
+ if (autoFocusTypes & CCamera::CCameraAdvancedSettings::EAutoFocusTypeSingle)
+ modes |= QCameraFocus::AutoFocus;
+ if (autoFocusTypes & CCamera::CCameraAdvancedSettings::EAutoFocusTypeContinuous)
+ modes |= QCameraFocus::ContinuousFocus;
+
+ // Check supported ranges (Note! Some are actually fixed focuses
+ // even though the mode is Auto on Symbian)
+ if (supportedRanges & CCamera::CCameraAdvancedSettings::EFocusRangeMacro)
+ modes |= QCameraFocus::MacroFocus;
+ if (supportedRanges & CCamera::CCameraAdvancedSettings::EFocusRangeHyperfocal)
+ modes |= QCameraFocus::HyperfocalFocus;
+ if (supportedRanges & CCamera::CCameraAdvancedSettings::EFocusRangeInfinite)
+ modes |= QCameraFocus::InfinityFocus;
+ }
+ } else {
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ }
+#endif // POST_31_PLATFORM
+
+ return modes;
+}
+
+qreal S60CameraSettings::opticalZoomFactorL() const
+{
+ // Not supported on Symbian
+ return 1.0;
+}
+
+void S60CameraSettings::setOpticalZoomFactorL(const qreal zoomFactor)
+{
+ // Not supported on Symbian
+ Q_UNUSED(zoomFactor);
+}
+
+QList<qreal> S60CameraSettings::supportedDigitalZoomFactors() const
+{
+ QList<qreal> zoomFactors;
+ foreach (int factor, m_supportedSymbianDigitalZoomFactors)
+ zoomFactors << qreal(factor) / KSymbianFineResolutionFactor;
+
+ return zoomFactors;
+}
+
+qreal S60CameraSettings::digitalZoomFactorL() const
+{
+ qreal factor = 1.0;
+
+#ifdef POST_31_PLATFORM
+ int symbianFactor = 0;
+ if (m_advancedSettings)
+ symbianFactor = m_advancedSettings->DigitalZoom();
+ else
+ User::Leave(KErrNotSupported);
+
+ if (symbianFactor != 0)
+ factor = qreal(symbianFactor) / KSymbianFineResolutionFactor;
+#endif // POST_31_PLATFORM
+
+ return factor;
+}
+
+void S60CameraSettings::setDigitalZoomFactorL(const qreal zoomFactor)
+{
+#ifdef POST_31_PLATFORM
+ int symbianFactor = zoomFactor * KSymbianFineResolutionFactor;
+
+ // Find closest supported Symbian ZoomFactor if needed
+ if (!m_supportedSymbianDigitalZoomFactors.contains(symbianFactor)) {
+ int closestIndex = -1;
+ int closestDiff = 1000000; // Sensible maximum
+ for (int i = 0; i < m_supportedSymbianDigitalZoomFactors.count(); ++i) {
+ int diff = abs(m_supportedSymbianDigitalZoomFactors.at(i) - symbianFactor);
+ if (diff < closestDiff) {
+ closestDiff = diff;
+ closestIndex = i;
+ }
+ }
+ if (closestIndex != -1)
+ symbianFactor = m_supportedSymbianDigitalZoomFactors.at(closestIndex);
+ else
+ User::Leave(KErrGeneral);
+ }
+ if (m_advancedSettings)
+ m_advancedSettings->SetDigitalZoom(symbianFactor);
+ else
+ User::Leave(KErrNotSupported);
+#else // S60 3.1 Platform
+ Q_UNUSED(zoomFactor);
+ emit error(QCamera::NotSupportedFeatureError, tr("Settings digital zoom factor is not supported."));
+#endif // POST_31_PLATFORM
+}
+
+// MCameraObserver2
+void S60CameraSettings::HandleAdvancedEvent(const TECAMEvent& aEvent)
+{
+#ifdef POST_31_PLATFORM
+
+ if (aEvent.iErrorCode != KErrNone) {
+ switch (aEvent.iErrorCode) {
+ case KErrECamCameraDisabled:
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ return;
+ case KErrECamSettingDisabled:
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ return;
+ case KErrECamParameterNotInRange:
+ emit error(QCamera::NotSupportedFeatureError, tr("Requested value is not in supported range."));
+ return;
+ case KErrECamSettingNotSupported:
+ emit error(QCamera::NotSupportedFeatureError, tr("Requested setting is not supported."));
+ return;
+ case KErrECamNotOptimalFocus:
+ if (m_continuousFocusing)
+ emit focusStatusChanged(QCamera::Searching, QCamera::LockTemporaryLost);
+ else
+ emit focusStatusChanged(QCamera::Unlocked, QCamera::LockFailed);
+ return;
+ }
+
+ if (aEvent.iEventType == KUidECamEventCameraSettingFocusRange ||
+ aEvent.iEventType == KUidECamEventCameraSettingAutoFocusType2) {
+ emit focusStatusChanged(QCamera::Unlocked, QCamera::LockFailed);
+ return;
+ } else if (aEvent.iEventType == KUidECamEventCameraSettingIsoRate) {
+ if (aEvent.iErrorCode == KErrNotSupported)
+ emit error(QCamera::NotSupportedFeatureError, tr("Requested ISO value is not supported."));
+ else
+ emit error(QCamera::CameraError, tr("Setting ISO value failed."));
+ return;
+ } else if (aEvent.iEventType == KUidECamEventCameraSettingAperture) {
+ if (aEvent.iErrorCode == KErrNotSupported)
+ emit error(QCamera::NotSupportedFeatureError, tr("Requested aperture value is not supported."));
+ else
+ emit error(QCamera::CameraError, tr("Setting aperture value failed."));
+ return;
+ } else if (aEvent.iEventType == KUidECamEventCameraSettingExposureCompensation) {
+ if (aEvent.iErrorCode == KErrNotSupported)
+ emit error(QCamera::NotSupportedFeatureError, tr("Requested exposure compensation is not supported."));
+ else
+ emit error(QCamera::CameraError, tr("Setting exposure compensation failed."));
+ return;
+ } else if (aEvent.iEventType == KUidECamEventCameraSettingOpticalZoom ||
+ aEvent.iEventType == KUidECamEventCameraSettingDigitalZoom) {
+ if (aEvent.iErrorCode == KErrNotSupported)
+ return; // Discard
+ else {
+ emit error(QCamera::CameraError, tr("Setting zoom factor failed."));
+ return;
+ }
+ } else if (aEvent.iEventType == KUidECamEventCameraSettingFocusMode) {
+ if (aEvent.iErrorCode == KErrNotSupported)
+ if (m_cameraEngine && m_cameraEngine->CurrentCameraIndex() != 0)
+ emit error(QCamera::NotSupportedFeatureError, tr("Focusing is not supported with this camera."));
+ else
+ emit error(QCamera::NotSupportedFeatureError, tr("Requested focus mode is not supported."));
+ else
+ emit error(QCamera::CameraError, tr("Setting focus mode failed."));
+ return;
+ } else {
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ return;
+ }
+ }
+
+ if (aEvent.iEventType == KUidECamEventCameraSettingExposureLock) {
+ if (m_advancedSettings) {
+ if (m_advancedSettings->ExposureLockOn())
+ emit exposureStatusChanged(QCamera::Locked, QCamera::LockAcquired);
+ else
+ emit exposureStatusChanged(QCamera::Unlocked, QCamera::LockLost);
+ }
+ else
+ emit exposureStatusChanged(QCamera::Unlocked, QCamera::LockLost);
+ }
+ else if (aEvent.iEventType == KUidECamEventCameraSettingAperture)
+ emit apertureChanged();
+
+ else if (aEvent.iEventType == KUidECamEventCameraSettingApertureRange)
+ emit apertureRangeChanged();
+
+ else if (aEvent.iEventType == KUidECamEventCameraSettingIsoRateType)
+ emit isoSensitivityChanged();
+
+ else if (aEvent.iEventType == KUidECamEventCameraSettingShutterSpeed)
+ emit shutterSpeedChanged();
+
+ else if (aEvent.iEventType == KUidECamEventCameraSettingExposureCompensationStep)
+ emit evChanged();
+
+ else if (aEvent.iEventType == KUidECamEventFlashReady)
+ emit flashReady(true);
+
+ else if (aEvent.iEventType == KUidECamEventFlashNotReady)
+ emit flashReady(false);
+
+ else if (aEvent.iEventType.iUid == KUidECamEventCameraSettingsOptimalFocusUidValue)
+ emit focusStatusChanged(QCamera::Locked, QCamera::LockAcquired);
+
+#else // S60 3.1 Platform
+ Q_UNUSED(aEvent);
+#endif // POST_31_PLATFORM
+}
+
+bool S60CameraSettings::isFlashReady()
+{
+ TBool isReady = false;
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ int flashErr = m_advancedSettings->IsFlashReady(isReady);
+ if(flashErr != KErrNone) {
+ if (flashErr != KErrNotSupported)
+ emit error(QCamera::CameraError, tr("Unexpected error with flash."));
+ return false;
+ }
+ }
+ else
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+#endif
+ return isReady;
+}
+
+QCameraExposure::MeteringMode S60CameraSettings::meteringMode()
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ CCamera::CCameraAdvancedSettings::TMeteringMode mode = m_advancedSettings->MeteringMode();
+ switch (mode) {
+ case CCamera::CCameraAdvancedSettings::EMeteringModeCenterWeighted:
+ return QCameraExposure::MeteringAverage;
+ case CCamera::CCameraAdvancedSettings::EMeteringModeEvaluative:
+ return QCameraExposure::MeteringMatrix;
+ case CCamera::CCameraAdvancedSettings::EMeteringModeSpot:
+ return QCameraExposure::MeteringSpot;
+
+ default:
+ return QCameraExposure::MeteringAverage;
+ }
+ }else {
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ return QCameraExposure::MeteringAverage;
+ }
+#else // S60 3.1 Platform
+ return QCameraExposure::MeteringAverage;
+#endif // POST_31_PLATFORM
+}
+
+void S60CameraSettings::setMeteringMode(QCameraExposure::MeteringMode mode)
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ switch(mode) {
+ case QCameraExposure::MeteringAverage:
+ m_advancedSettings->SetMeteringMode(CCamera::CCameraAdvancedSettings::EMeteringModeCenterWeighted);
+ break;
+ case QCameraExposure::MeteringMatrix:
+ m_advancedSettings->SetMeteringMode(CCamera::CCameraAdvancedSettings::EMeteringModeEvaluative);
+ break;
+ case QCameraExposure::MeteringSpot:
+ m_advancedSettings->SetMeteringMode(CCamera::CCameraAdvancedSettings::EMeteringModeSpot);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+#else // S60 3.1
+ Q_UNUSED(mode);
+ emit error(QCamera::NotSupportedFeatureError, tr("Setting metering mode is not supported."));
+#endif // POST_31_PLATFORM
+}
+
+bool S60CameraSettings::isMeteringModeSupported(QCameraExposure::MeteringMode mode)
+{
+#ifdef POST_31_PLATFORM
+ TInt supportedModes = 0;
+
+ if (m_advancedSettings) {
+ supportedModes = m_advancedSettings->SupportedMeteringModes();
+ if (supportedModes == 0)
+ return false;
+
+ switch (mode) {
+ case QCameraExposure::MeteringMatrix:
+ if (supportedModes & CCamera::CCameraAdvancedSettings::EMeteringModeEvaluative)
+ return true;
+ else
+ return false;
+ case QCameraExposure::MeteringAverage:
+ if (supportedModes & CCamera::CCameraAdvancedSettings::EMeteringModeCenterWeighted)
+ return true;
+ else
+ return false;
+ case QCameraExposure::MeteringSpot:
+ if (supportedModes & CCamera::CCameraAdvancedSettings::EMeteringModeSpot)
+ return true;
+ else
+ return false;
+
+ default:
+ return false;
+ }
+ }
+ else
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+#else // S60 3.1
+ Q_UNUSED(mode);
+#endif // POST_31_PLATFORM
+
+ return false;
+}
+
+int S60CameraSettings::isoSensitivity()
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ CCamera::CCameraAdvancedSettings::TISORateType isoRateType;
+ TInt param = 0;
+ TInt isoRate = 0;
+ TRAPD(err, m_advancedSettings->GetISORateL(isoRateType, param, isoRate));
+ if (err)
+ return 0;
+ if (isoRate != KErrNotFound)
+ return isoRate;
+ } else {
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ }
+#endif // POST_31_PLATFORM
+ return 0;
+}
+
+QList<int> S60CameraSettings::supportedIsoSensitivities()
+{
+ QList<int> isoSentitivities;
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ RArray<TInt> supportedIsoRates;
+ CleanupClosePushL(supportedIsoRates);
+
+ TRAPD(err, m_advancedSettings->GetSupportedIsoRatesL(supportedIsoRates));
+ if (err != KErrNone) {
+ if (err != KErrNotSupported) // Don's emit error if ISO is not supported
+ emit error(QCamera::CameraError, tr("Failure while querying supported iso sensitivities."));
+ } else {
+ for (int i = 0; i < supportedIsoRates.Count(); ++i)
+ isoSentitivities << supportedIsoRates[i];
+ }
+ CleanupStack::PopAndDestroy(); // RArray<TInt> supportedIsoRates
+ } else {
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ }
+
+ return isoSentitivities;
+#else // S60 3.1 Platform
+ return isoSentitivities;
+#endif // POST_31_PLATFORM
+}
+
+void S60CameraSettings::setManualIsoSensitivity(int iso)
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ TRAPD(err, m_advancedSettings->SetISORateL(CCamera::CCameraAdvancedSettings::EISOManual, iso));
+ if (err)
+ emit error(QCamera::CameraError, tr("Setting manual iso sensitivity failed."));
+ return;
+ } else {
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ }
+#else // S60 3.1 Platform
+ Q_UNUSED(iso);
+ emit error(QCamera::NotSupportedFeatureError, tr("Setting manual iso sensitivity is not supported."));
+#endif // POST_31_PLATFORM
+}
+
+void S60CameraSettings::setAutoIsoSensitivity()
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ TRAPD(err, m_advancedSettings->SetISORateL(CCamera::CCameraAdvancedSettings::EISOAutoUnPrioritised, 0));
+ if (err)
+ emit error(QCamera::CameraError, tr("Setting auto iso sensitivity failed."));
+ return;
+ }
+ else
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+#else // S60 3.1 Platform
+ emit error(QCamera::NotSupportedFeatureError, tr("Setting auto iso sensitivity is not supported."));
+#endif // POST_31_PLATFORM
+}
+
+qreal S60CameraSettings::aperture()
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings)
+ return qreal(m_advancedSettings->Aperture()) / KSymbianFineResolutionFactor;
+ else
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ return 0;
+#else // S60 3.1 Platform
+ return 0;
+#endif // POST_31_PLATFORM
+}
+
+QList<qreal> S60CameraSettings::supportedApertures()
+{
+ QList<qreal> apertures;
+
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ RArray<TInt> supportedApertures;
+ TValueInfo info = ENotActive;
+
+ TRAPD(err, m_advancedSettings->GetAperturesL(supportedApertures, info));
+ if (err != KErrNone)
+ if (err != KErrNotSupported)
+ emit error(QCamera::CameraError, tr("Failure while querying supported apertures."));
+ else {
+ for (int i = 0; i < supportedApertures.Count(); i++) {
+ qreal q = qreal(supportedApertures[i]) / KSymbianFineResolutionFactor;
+ apertures.append(q);
+ }
+ }
+ supportedApertures.Close();
+ }
+ else
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ return apertures;
+#else // S60 3.1 Platform
+ return apertures;
+#endif // POST_31_PLATFORM
+}
+
+void S60CameraSettings::setManualAperture(qreal aperture)
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ int symbianAperture = (aperture * KSymbianFineResolutionFactor); // KSymbianFineResolutionFactor = 100
+ m_advancedSettings->SetAperture(symbianAperture);
+ }
+ else
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+#else // S60 3.1
+ Q_UNUSED(aperture);
+ emit error(QCamera::NotSupportedFeatureError, tr("Setting manual aperture is not supported."));
+#endif // POST_31_PLATFORM
+}
+
+void S60CameraSettings::lockExposure(bool lock)
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ m_advancedSettings->SetExposureLockOn(lock);
+ return;
+ }
+ else
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+#else // S60 3.1
+ Q_UNUSED(lock);
+ emit error(QCamera::NotSupportedFeatureError, tr("Locking exposure is not supported."));
+#endif // POST_31_PLATFORM
+}
+
+bool S60CameraSettings::isExposureLocked()
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings)
+ return m_advancedSettings->ExposureLockOn();
+ else
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+#endif // POST_31_PLATFORM
+ return false;
+}
+
+qreal S60CameraSettings::shutterSpeed()
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ qreal shutterSpeed = qreal(m_advancedSettings->ShutterSpeed()) / 1000000.0;
+ return shutterSpeed; // In seconds
+ } else {
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ }
+ return 0;
+#else // S60 3.1 Platform
+ return 0;
+#endif // POST_31_PLATFORM
+}
+
+QList<qreal> S60CameraSettings::supportedShutterSpeeds()
+{
+ QList<qreal> speeds;
+
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ RArray<TInt> supportedSpeeds;
+ TValueInfo info = ENotActive;
+
+ TRAPD(err, m_advancedSettings->GetShutterSpeedsL(supportedSpeeds, info));
+ if (err != KErrNone)
+ if (err != KErrNotSupported)
+ emit error(QCamera::CameraError, tr("Failure while querying supported shutter speeds."));
+ else {
+ for (int i = 0; i < supportedSpeeds.Count(); i++) {
+ qreal q = qreal(supportedSpeeds[i]) / 1000000.0;
+ speeds.append(q); // In seconds
+ }
+ }
+ supportedSpeeds.Close();
+ }
+ else
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ return speeds;
+#else // S60 3.1 Platform
+ return speeds;
+#endif // POST_31_PLATFORM
+}
+
+void S60CameraSettings::setManualShutterSpeed(qreal speed)
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ TInt shutterSpeed = speed * 1000000; // From seconds to microseconds
+ m_advancedSettings->SetShutterSpeed(shutterSpeed);
+ } else {
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ }
+#else // S60 3.1
+ emit error(QCamera::NotSupportedFeatureError, tr("Setting manual shutter speed is not supported."));
+ Q_UNUSED(speed);
+#endif // POST_31_PLATFORM
+}
+
+void S60CameraSettings::setExposureCompensation(qreal ev)
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ TInt evStep = ev * KSymbianFineResolutionFactor;
+ m_advancedSettings->SetExposureCompensationStep(evStep);
+ } else {
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ }
+#else // S60 3.1 Platform
+ Q_UNUSED(ev);
+ emit error(QCamera::NotSupportedFeatureError, tr("Setting exposure compensation is not supported."));
+#endif // POST_31_PLATFORM
+}
+
+qreal S60CameraSettings::exposureCompensation()
+{
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ TInt evStepSymbian = 0;
+ m_advancedSettings->GetExposureCompensationStep(evStepSymbian);
+ qreal evStep = evStepSymbian;
+ evStep /= KSymbianFineResolutionFactor;
+ return evStep;
+ } else {
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ }
+ return 0;
+#else // S60 3.1 Platform
+ return 0;
+#endif // POST_31_PLATFORM
+}
+
+QList<qreal> S60CameraSettings::supportedExposureCompensationValues()
+{
+ QList<qreal> valueList;
+
+#ifdef POST_31_PLATFORM
+ if (m_advancedSettings) {
+ RArray<TInt> evSteps;
+ TValueInfo info;
+ TRAPD(err, m_advancedSettings->GetExposureCompensationStepsL(evSteps, info));
+ if (err) {
+ if (err != KErrNotSupported)
+ emit error(QCamera::CameraError, tr("Failure while querying supported exposure compensation values."));
+ return valueList;
+ }
+
+ if (info == ENotActive || evSteps.Count() == 0) {
+ // EV not supported, return empty list
+ return valueList;
+ }
+
+ for (int i = 0; i < evSteps.Count(); ++i) {
+ qreal appendValue = evSteps[i];
+ appendValue /= KSymbianFineResolutionFactor;
+ valueList.append(appendValue);
+ }
+ }
+ else
+ emit error(QCamera::CameraError, tr("Unexpected camera error."));
+ return valueList;
+#else // S60 3.1 Platform
+ return valueList;
+#endif // POST_31_PLATFORM
+}
+
+void S60CameraSettings::setSharpeningLevel(int value)
+{
+#ifdef POST_31_PLATFORM
+ if (m_imageProcessingSettings && isSharpeningSupported())
+ m_imageProcessingSettings->SetTransformationValue(KUidECamEventImageProcessingAdjustSharpness, value);
+ else
+ emit error(QCamera::NotSupportedFeatureError, tr("Setting sharpening level is not supported."));
+#else // S60 3.1
+ Q_UNUSED(value);
+ emit error(QCamera::NotSupportedFeatureError, tr("Setting sharpening level is not supported."));
+#endif // POST_31_PLATFORM
+}
+
+bool S60CameraSettings::isSharpeningSupported() const
+{
+#ifdef POST_31_PLATFORM
+ if (m_imageProcessingSettings) {
+ RArray<TUid> suppTransforms;
+ TRAPD(err, m_imageProcessingSettings->GetSupportedTransformationsL(suppTransforms));
+ if (err)
+ return false;
+
+ if (suppTransforms.Find(KUidECamEventImageProcessingAdjustSharpness))
+ return true;
+ }
+ return false;
+#else // S60 3.1 Platform
+ return false;
+#endif // POST_31_PLATFORM
+}
+
+int S60CameraSettings::sharpeningLevel() const
+{
+#ifdef POST_31_PLATFORM
+ if (m_imageProcessingSettings && isSharpeningSupported())
+ return m_imageProcessingSettings->TransformationValue(KUidECamEventImageProcessingAdjustSharpness);
+ else
+ return 0;
+#else // S60 3.1 Platform
+ return 0;
+#endif // POST_31_PLATFORM
+}
+
+void S60CameraSettings::setSaturation(int value)
+{
+#ifdef POST_31_PLATFORM
+ if (m_imageProcessingSettings) {
+ RArray<TUid> suppTransforms;
+ TRAPD(err, m_imageProcessingSettings->GetSupportedTransformationsL(suppTransforms));
+ if (err)
+ if (err != KErrNotSupported)
+ emit error(QCamera::CameraError, tr("Failure while querying supported transformations."));
+
+ if (suppTransforms.Find(KUidECamEventtImageProcessingAdjustSaturation))
+ m_imageProcessingSettings->SetTransformationValue(KUidECamEventtImageProcessingAdjustSaturation, value == -1 ? 0 : value*2-100);
+ else
+ emit error(QCamera::NotSupportedFeatureError, tr("Setting saturation is not supported."));
+ }
+ else
+ emit error(QCamera::NotSupportedFeatureError, tr("Setting saturation is not supported."));
+#else // S60 3.1
+ Q_UNUSED(value);
+ emit error(QCamera::NotSupportedFeatureError, tr("Setting saturation is not supported."));
+#endif // POST_31_PLATFORM
+}
+
+int S60CameraSettings::saturation()
+{
+#ifdef POST_31_PLATFORM
+ if (m_imageProcessingSettings) {
+ RArray<TUid> suppTransforms;
+ TRAPD(err, m_imageProcessingSettings->GetSupportedTransformationsL(suppTransforms));
+ if (err)
+ if (err != KErrNotSupported)
+ emit error(QCamera::CameraError, tr("Failure while querying supported transformations."));
+
+ if (suppTransforms.Find(KUidECamEventtImageProcessingAdjustSaturation))
+ return m_imageProcessingSettings->TransformationValue(KUidECamEventtImageProcessingAdjustSaturation);
+ }
+ return 0;
+#else // S60 3.1 Platform
+ return 0;
+#endif // POST_31_PLATFORM
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60camerasettings.h b/src/plugins/symbian/ecam/s60camerasettings.h
new file mode 100644
index 000000000..4ecb131b2
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60camerasettings.h
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60CAMERASETTINGS_H
+#define S60CAMERASETTINGS_H
+
+#include "qcamera.h"
+
+#include "s60cameraengine.h"
+#include "s60cameraengineobserver.h"
+
+#include <e32base.h>
+
+QT_USE_NAMESPACE
+
+/*
+ * Class handling CCamera AdvancedSettings and ImageProcessing operations.
+ */
+class S60CameraSettings : public QObject,
+ public MAdvancedSettingsObserver
+{
+ Q_OBJECT
+
+public: // Static Contructor & Destructor
+
+ static S60CameraSettings* New(int &error, QObject *parent = 0, CCameraEngine *engine = 0);
+ ~S60CameraSettings();
+
+public: // Methods
+
+ // Focus
+ QCameraFocus::FocusMode focusMode();
+ void setFocusMode(QCameraFocus::FocusMode mode);
+ QCameraFocus::FocusModes supportedFocusModes();
+ void startFocusing();
+ void cancelFocusing();
+
+ // Zoom
+ qreal opticalZoomFactorL() const;
+ void setOpticalZoomFactorL(const qreal zoomFactor);
+ QList<qreal> supportedDigitalZoomFactors() const;
+ qreal digitalZoomFactorL() const;
+ void setDigitalZoomFactorL(const qreal zoomFactor);
+
+ // Flash
+ bool isFlashReady();
+
+ // Exposure
+ void setExposureMode(QCameraExposure::ExposureMode mode);
+ void lockExposure(bool lock);
+ bool isExposureLocked();
+
+ // Metering Mode
+ QCameraExposure::MeteringMode meteringMode();
+ void setMeteringMode(QCameraExposure::MeteringMode mode);
+ bool isMeteringModeSupported(QCameraExposure::MeteringMode mode);
+
+ // ISO Sensitivity
+ int isoSensitivity();
+ void setManualIsoSensitivity(int iso);
+ void setAutoIsoSensitivity();
+ QList<int> supportedIsoSensitivities();
+
+ // Aperture
+ qreal aperture();
+ void setManualAperture(qreal aperture);
+ QList<qreal> supportedApertures();
+
+ // Shutter Speed
+ qreal shutterSpeed();
+ void setManualShutterSpeed(qreal speed);
+ QList<qreal> supportedShutterSpeeds();
+
+ // ExposureCompensation
+ qreal exposureCompensation();
+ void setExposureCompensation(qreal ev);
+ QList<qreal> supportedExposureCompensationValues();
+
+ // Sharpening Level
+ int sharpeningLevel() const;
+ void setSharpeningLevel(int value);
+ bool isSharpeningSupported() const;
+
+ // Saturation
+ int saturation();
+ void setSaturation(int value);
+
+signals: // Notifications
+
+ // For QCameraExposureControl
+ void flashReady(bool ready);
+ void apertureChanged();
+ void apertureRangeChanged();
+ void shutterSpeedChanged();
+ void isoSensitivityChanged();
+ void evChanged();
+
+ // For QCameraLocksControl
+ void exposureStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason);
+ void focusStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason);
+
+ // Errors
+ void error(int, const QString&);
+
+protected: // Protected constructors
+
+ S60CameraSettings(QObject *parent, CCameraEngine *engine);
+ void ConstructL();
+
+protected: // MAdvancedSettingsObserver
+
+ void HandleAdvancedEvent(const TECAMEvent& aEvent);
+
+private: // Internal
+
+ bool queryAdvancedSettingsInfo();
+
+private: // Enums
+
+ enum EcamErrors {
+ KErrECamCameraDisabled = -12100, // The camera has been disabled, hence calls do not succeed
+ KErrECamSettingDisabled = -12101, // This parameter or operation is supported, but presently is disabled.
+ KErrECamParameterNotInRange = -12102, // This value is out of range.
+ KErrECamSettingNotSupported = -12103, // This parameter or operation is not supported.
+ KErrECamNotOptimalFocus = -12104 // The optimum focus is lost
+ };
+
+private: // Data
+
+#ifndef S60_31_PLATFORM // Post S60 3.1 Platforms
+ CCamera::CCameraAdvancedSettings *m_advancedSettings;
+ CCamera::CCameraImageProcessing *m_imageProcessingSettings;
+#endif // S60_31_PLATFORM
+ CCameraEngine *m_cameraEngine;
+ QList<int> m_supportedSymbianDigitalZoomFactors;
+ bool m_continuousFocusing;
+};
+
+#endif // S60CAMERASETTINGS_H
diff --git a/src/plugins/symbian/ecam/s60cameraviewfinderengine.cpp b/src/plugins/symbian/ecam/s60cameraviewfinderengine.cpp
new file mode 100644
index 000000000..55d7cbc67
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraviewfinderengine.cpp
@@ -0,0 +1,789 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QDesktopWidget>
+#include <qcamera.h>
+#include <qabstractvideosurface.h>
+#include <qvideoframe.h>
+
+#include "s60cameraviewfinderengine.h"
+#include "s60cameraengine.h"
+#include "s60cameracontrol.h"
+#include "s60videowidgetcontrol.h"
+#include "s60videowidgetdisplay.h"
+#include "s60videorenderercontrol.h"
+#include "s60videowindowcontrol.h"
+#include "s60videowindowdisplay.h"
+#include "s60cameraconstants.h"
+
+#include <coemain.h> // CCoeEnv
+#include <coecntrl.h> // CCoeControl
+#include <w32std.h>
+
+// Helper function
+TRect qRect2TRect(const QRect &qr)
+{
+ return TRect(TPoint(qr.left(), qr.top()), TSize(qr.width(), qr.height()));
+}
+
+
+S60CameraViewfinderEngine::S60CameraViewfinderEngine(S60CameraControl *control,
+ CCameraEngine *engine,
+ QObject *parent):
+ QObject(parent),
+ m_cameraEngine(engine),
+ m_cameraControl(0),
+ m_viewfinderOutput(0),
+ m_viewfinderDisplay(0),
+ m_viewfinderSurface(0),
+ m_wsSession(CCoeEnv::Static()->WsSession()),
+ m_screenDevice(*CCoeEnv::Static()->ScreenDevice()),
+ m_window(0),
+ m_desktopWidget(0),
+ m_vfState(EVFNotConnectedNotStarted),
+ m_viewfinderSize(KDefaultViewfinderSize),
+ m_actualViewFinderSize(KDefaultViewfinderSize),
+ m_viewfinderAspectRatio(0.0),
+ m_viewfinderType(OutputTypeNotSet),
+ m_viewfinderNativeType(EBitmapViewFinder), // Default type
+ m_isViewFinderVisible(true), // True by default (only QVideoWidgetControl supports being hidden)
+ m_uiLandscape(true),
+ m_vfErrorsSignalled(0)
+{
+ m_cameraControl = control;
+
+ // Check whether platform supports DirectScreen ViewFinder
+ if (m_cameraEngine) {
+ if (m_cameraEngine->IsDirectViewFinderSupported())
+ m_viewfinderNativeType = EDirectScreenViewFinder;
+ else
+ m_viewfinderNativeType = EBitmapViewFinder;
+
+ MCameraViewfinderObserver *vfObserver = this;
+ m_cameraEngine->SetViewfinderObserver(vfObserver);
+ }
+ else
+ m_cameraControl->setError(KErrGeneral, tr("Unexpected camera error."));
+ // From now on it is safe to assume engine exists
+
+ // Check the UI orientation
+ QDesktopWidget* desktopWidget = QApplication::desktop();
+ QRect screenRect = desktopWidget->screenGeometry();
+ if (screenRect.width() > screenRect.height())
+ m_uiLandscape = true;
+ else
+ m_uiLandscape = false;
+
+ // Detect UI Rotations
+ m_desktopWidget = QApplication::desktop();
+ if (m_desktopWidget)
+ connect(m_desktopWidget, SIGNAL(resized(int)), this, SLOT(handleDesktopResize(int)));
+}
+
+S60CameraViewfinderEngine::~S60CameraViewfinderEngine()
+{
+ // No need to stop viewfinder:
+ // Engine has stopped it already
+ // Surface will be stopped by VideoRendererControl
+
+ m_viewfinderOutput = 0;
+ m_viewfinderSurface = 0;
+}
+
+void S60CameraViewfinderEngine::setNewCameraEngine(CCameraEngine *engine)
+{
+ m_cameraEngine = engine;
+
+ if (m_cameraEngine) {
+ // And set observer to the new CameraEngine
+ MCameraViewfinderObserver *vfObserver = this;
+ m_cameraEngine->SetViewfinderObserver(vfObserver);
+ }
+}
+
+void S60CameraViewfinderEngine::handleDesktopResize(int screen)
+{
+ Q_UNUSED(screen);
+ // UI Rotation is handled by the QVideoWidgetControl, thus this is needed
+ // only for the QVideoRendererControl
+ if (m_viewfinderType == OutputTypeRenderer) {
+ QSize newResolution(-1,-1);
+ if (m_viewfinderSurface)
+ newResolution = m_viewfinderSurface->nativeResolution();
+
+ if (newResolution.width() == -1 || newResolution.height() == -1) {
+ QDesktopWidget* desktopWidget = QApplication::desktop();
+ QRect screenRect = desktopWidget->screenGeometry();
+ newResolution = QSize(screenRect.width(), screenRect.height());
+ }
+
+ resetViewfinderSize(newResolution);
+ }
+
+ // Rotate Camera if UI has rotated
+ checkAndRotateCamera();
+}
+
+void S60CameraViewfinderEngine::setVideoWidgetControl(QObject *viewfinderOutput)
+{
+ // Release old control if it has not already been done
+ if (m_viewfinderOutput)
+ releaseControl(m_viewfinderType);
+
+ // Rotate Camera if UI has rotated
+ checkAndRotateCamera();
+
+ S60VideoWidgetControl* viewFinderWidgetControl =
+ qobject_cast<S60VideoWidgetControl*>(viewfinderOutput);
+
+ if (viewFinderWidgetControl) {
+ // Check whether platform supports DirectScreen ViewFinder
+ if (m_cameraEngine) {
+ if (m_cameraEngine->IsDirectViewFinderSupported())
+ m_viewfinderNativeType = EDirectScreenViewFinder;
+ else
+ m_viewfinderNativeType = EBitmapViewFinder;
+ }
+ else
+ return;
+
+ m_viewfinderDisplay = viewFinderWidgetControl->display();
+
+ if (m_viewfinderNativeType == EDirectScreenViewFinder) {
+ m_viewfinderDisplay->setPaintingEnabled(false); // No Qt Painter painting - Direct rendering
+ connect(m_viewfinderDisplay, SIGNAL(windowHandleChanged(RWindow *)), this, SLOT(resetViewfinderDisplay()));
+ } else {
+ m_viewfinderDisplay->setPaintingEnabled(true); // Qt Painter painting - Bitmap rendering
+ connect(this, SIGNAL(viewFinderFrameReady(const CFbsBitmap &)), m_viewfinderDisplay, SLOT(setFrame(const CFbsBitmap &)));
+ }
+
+ connect(m_viewfinderDisplay, SIGNAL(visibilityChanged(bool)), this, SLOT(handleVisibilityChange(bool)));
+ connect(m_viewfinderDisplay, SIGNAL(displayRectChanged(QRect, QRect)), this, SLOT(resetVideoWindowSize()));
+ connect(m_viewfinderDisplay, SIGNAL(windowHandleChanged(RWindow*)), this, SLOT(handleWindowChange(RWindow*)));
+
+ m_viewfinderSize = m_viewfinderDisplay->extentRect().size();
+ m_viewfinderOutput = viewfinderOutput;
+ m_viewfinderType = OutputTypeVideoWidget;
+ m_isViewFinderVisible = m_viewfinderDisplay->isVisible();
+
+ switch (m_vfState) {
+ case EVFNotConnectedNotStarted:
+ m_vfState = EVFIsConnectedNotStarted;
+ break;
+ case EVFNotConnectedIsStarted:
+ if (m_isViewFinderVisible)
+ m_vfState = EVFIsConnectedIsStartedIsVisible;
+ else
+ m_vfState = EVFIsConnectedIsStartedNotVisible;
+ break;
+ case EVFIsConnectedNotStarted:
+ case EVFIsConnectedIsStartedNotVisible:
+ case EVFIsConnectedIsStartedIsVisible:
+ // Already connected, state does not change
+ break;
+ default:
+ emit error(QCamera::CameraError, tr("General viewfinder error."));
+ break;
+ }
+
+ if (m_vfState == EVFIsConnectedIsStartedIsVisible)
+ startViewfinder(true); // Internal start (i.e. start if started externally)
+ }
+}
+
+void S60CameraViewfinderEngine::setVideoRendererControl(QObject *viewfinderOutput)
+{
+ // Release old control if it has not already been done
+ if (m_viewfinderOutput)
+ releaseControl(m_viewfinderType);
+
+ // Rotate Camera if UI has rotated
+ checkAndRotateCamera();
+
+ S60VideoRendererControl* viewFinderRenderControl =
+ qobject_cast<S60VideoRendererControl*>(viewfinderOutput);
+
+ if (viewFinderRenderControl) {
+ m_viewfinderNativeType = EBitmapViewFinder; // Always Bitmap
+
+ connect(viewFinderRenderControl, SIGNAL(viewFinderSurfaceSet()),
+ this, SLOT(rendererSurfaceSet()));
+
+ Q_ASSERT(!viewFinderRenderControl->surface());
+ m_viewfinderOutput = viewfinderOutput;
+ m_viewfinderType = OutputTypeRenderer;
+ // RendererControl viewfinder is "visible" when surface is set
+ m_isViewFinderVisible = false;
+ if (EVFIsConnectedIsStartedIsVisible)
+ m_vfState = EVFIsConnectedIsStartedNotVisible;
+
+ // Use display resolution as default viewfinder resolution
+ m_viewfinderSize = QApplication::desktop()->screenGeometry().size();
+
+ switch (m_vfState) {
+ case EVFNotConnectedNotStarted:
+ m_vfState = EVFIsConnectedNotStarted;
+ break;
+ case EVFNotConnectedIsStarted:
+ m_vfState = EVFIsConnectedIsStartedIsVisible; // GraphicsItem "always visible" (FrameWork decides to draw/not draw)
+ break;
+ case EVFIsConnectedNotStarted:
+ case EVFIsConnectedIsStartedNotVisible:
+ case EVFIsConnectedIsStartedIsVisible:
+ // Already connected, state does not change
+ break;
+ default:
+ emit error(QCamera::CameraError, tr("General viewfinder error."));
+ break;
+ }
+
+ if (m_vfState == EVFIsConnectedIsStartedIsVisible)
+ startViewfinder(true);
+ }
+}
+
+void S60CameraViewfinderEngine::setVideoWindowControl(QObject *viewfinderOutput)
+{
+ // Release old control if it has not already been done
+ if (m_viewfinderOutput)
+ releaseControl(m_viewfinderType);
+
+ // Rotate Camera if UI has rotated
+ checkAndRotateCamera();
+
+ S60VideoWindowControl* viewFinderWindowControl =
+ qobject_cast<S60VideoWindowControl*>(viewfinderOutput);
+
+ if (viewFinderWindowControl) {
+ // Check whether platform supports DirectScreen ViewFinder
+ if (m_cameraEngine) {
+ if (m_cameraEngine->IsDirectViewFinderSupported())
+ m_viewfinderNativeType = EDirectScreenViewFinder;
+ else
+ m_viewfinderNativeType = EBitmapViewFinder;
+ } else {
+ return;
+ }
+
+ m_viewfinderDisplay = viewFinderWindowControl->display();
+
+ if (m_viewfinderNativeType == EDirectScreenViewFinder) {
+ m_viewfinderDisplay->setPaintingEnabled(false); // No Qt Painter painting - Direct rendering
+ connect(m_viewfinderDisplay, SIGNAL(windowHandleChanged(RWindow *)), this, SLOT(resetViewfinderDisplay()));
+ } else {
+ m_viewfinderDisplay->setPaintingEnabled(true); // Qt Painter painting - Bitmap rendering
+ connect(this, SIGNAL(viewFinderFrameReady(const CFbsBitmap &)), m_viewfinderDisplay, SLOT(setFrame(const CFbsBitmap &)));
+ }
+
+ connect(m_viewfinderDisplay, SIGNAL(displayRectChanged(QRect, QRect)), this, SLOT(resetVideoWindowSize()));
+ connect(m_viewfinderDisplay, SIGNAL(visibilityChanged(bool)), this, SLOT(handleVisibilityChange(bool)));
+ connect(m_viewfinderDisplay, SIGNAL(windowHandleChanged(RWindow*)), this, SLOT(handleWindowChange(RWindow*)));
+
+ m_viewfinderSize = m_viewfinderDisplay->extentRect().size();
+ m_viewfinderOutput = viewfinderOutput;
+ m_viewfinderType = OutputTypeVideoWindow;
+ m_isViewFinderVisible = m_viewfinderDisplay->isVisible();
+
+ switch (m_vfState) {
+ case EVFNotConnectedNotStarted:
+ m_vfState = EVFIsConnectedNotStarted;
+ break;
+ case EVFNotConnectedIsStarted:
+ if (m_isViewFinderVisible)
+ m_vfState = EVFIsConnectedIsStartedIsVisible;
+ else
+ m_vfState = EVFIsConnectedIsStartedNotVisible;
+ break;
+ case EVFIsConnectedNotStarted:
+ case EVFIsConnectedIsStartedNotVisible:
+ case EVFIsConnectedIsStartedIsVisible:
+ // Already connected, state does not change
+ break;
+ default:
+ emit error(QCamera::CameraError, tr("General viewfinder error."));
+ break;
+ }
+
+ if (m_vfState == EVFIsConnectedIsStartedIsVisible)
+ startViewfinder(true); // Internal start (i.e. start if started externally)
+ }
+}
+
+void S60CameraViewfinderEngine::releaseControl(ViewfinderOutputType type)
+{
+ if (m_vfState == EVFIsConnectedIsStartedIsVisible)
+ stopViewfinder(true);
+
+ if (m_viewfinderOutput) {
+ switch (type) {
+ case OutputTypeNotSet:
+ return;
+ case OutputTypeVideoWidget:
+ if (m_viewfinderType != OutputTypeVideoWidget)
+ return;
+ disconnect(m_viewfinderOutput);
+ m_viewfinderOutput->disconnect(this);
+ Q_ASSERT(m_viewfinderDisplay);
+ disconnect(m_viewfinderDisplay);
+ m_viewfinderDisplay->disconnect(this);
+ m_viewfinderDisplay = 0;
+ // Invalidate the extent rect
+ qobject_cast<S60VideoWidgetControl*>(m_viewfinderOutput)->setExtentRect(QRect());
+ break;
+ case OutputTypeVideoWindow:
+ if (m_viewfinderType != OutputTypeVideoWindow)
+ return;
+ disconnect(m_viewfinderOutput);
+ m_viewfinderOutput->disconnect(this);
+ Q_ASSERT(m_viewfinderDisplay);
+ disconnect(m_viewfinderDisplay);
+ m_viewfinderDisplay->disconnect(this);
+ m_viewfinderDisplay = 0;
+ break;
+ case OutputTypeRenderer:
+ if (m_viewfinderType != OutputTypeRenderer)
+ return;
+ disconnect(m_viewfinderOutput);
+ m_viewfinderOutput->disconnect(this);
+ if (m_viewfinderSurface)
+ m_viewfinderSurface->disconnect(this);
+ disconnect(this, SIGNAL(viewFinderFrameReady(const CFbsBitmap &)),
+ this, SLOT(viewFinderBitmapReady(const CFbsBitmap &)));
+ break;
+ default:
+ emit error(QCamera::CameraError, tr("Unexpected viewfinder error."));
+ return;
+ }
+ }
+
+ Q_ASSERT(!m_viewfinderDisplay);
+ m_viewfinderOutput = 0;
+ m_viewfinderType = OutputTypeNotSet;
+
+ // Update state
+ switch (m_vfState) {
+ case EVFNotConnectedNotStarted:
+ case EVFNotConnectedIsStarted:
+ // Do nothing
+ break;
+ case EVFIsConnectedNotStarted:
+ m_vfState = EVFNotConnectedNotStarted;
+ break;
+ case EVFIsConnectedIsStartedNotVisible:
+ case EVFIsConnectedIsStartedIsVisible:
+ m_vfState = EVFNotConnectedIsStarted;
+ break;
+ default:
+ emit error(QCamera::CameraError, tr("General viewfinder error."));
+ break;
+ }
+}
+
+void S60CameraViewfinderEngine::startViewfinder(const bool internalStart)
+{
+ if (!internalStart) {
+ switch (m_vfState) {
+ case EVFNotConnectedNotStarted:
+ m_vfState = EVFNotConnectedIsStarted;
+ break;
+ case EVFIsConnectedNotStarted:
+ if (m_isViewFinderVisible)
+ m_vfState = EVFIsConnectedIsStartedIsVisible;
+ else
+ m_vfState = EVFIsConnectedIsStartedNotVisible;
+ break;
+ case EVFNotConnectedIsStarted:
+ case EVFIsConnectedIsStartedNotVisible:
+ case EVFIsConnectedIsStartedIsVisible:
+ // Already started, state does not change
+ break;
+ default:
+ emit error(QCamera::CameraError, tr("General viewfinder error."));
+ break;
+ }
+ }
+
+ // Start viewfinder
+ if (m_vfState == EVFIsConnectedIsStartedIsVisible) {
+
+ if (!m_cameraEngine)
+ return;
+
+ if (m_viewfinderNativeType == EDirectScreenViewFinder) {
+
+ if (RWindow *window = m_viewfinderDisplay ? m_viewfinderDisplay->windowHandle() : 0) {
+ m_window = window;
+ } else {
+ emit error(QCamera::CameraError, tr("Requesting window for viewfinder failed."));
+ return;
+ }
+
+ const QRect extentRect = m_viewfinderDisplay ? m_viewfinderDisplay->extentRect() : QRect();
+ const QRect clipRect = m_viewfinderDisplay ? m_viewfinderDisplay->clipRect() : QRect();
+
+ TRect extentRectSymbian = qRect2TRect(extentRect);
+ TRect clipRectSymbian = qRect2TRect(clipRect);
+ TRAPD(err, m_cameraEngine->StartDirectViewFinderL(m_wsSession, m_screenDevice, *m_window, extentRectSymbian, clipRectSymbian));
+ if (err) {
+ if (err == KErrNotSupported) {
+ emit error(QCamera::NotSupportedFeatureError, tr("Requested viewfinder size is not supported."));
+ } else {
+ emit error(QCamera::CameraError, tr("Starting viewfinder failed."));
+ }
+ return;
+ }
+
+ m_actualViewFinderSize = QSize(extentRectSymbian.Size().iWidth, extentRectSymbian.Size().iHeight);
+ m_viewfinderAspectRatio = qreal(m_actualViewFinderSize.width()) / qreal(m_actualViewFinderSize.height());
+
+ } else { // Bitmap ViewFinder
+ TSize size = TSize(m_viewfinderSize.width(), m_viewfinderSize.height());
+
+ if( m_viewfinderType == OutputTypeRenderer && m_viewfinderSurface) {
+ if (!m_surfaceFormat.isValid()) {
+ emit error(QCamera::NotSupportedFeatureError, tr("Invalid surface format."));
+ return;
+ }
+
+ // Start rendering to surface with correct size and format
+ if (!m_viewfinderSurface->isFormatSupported(m_surfaceFormat) ||
+ !m_viewfinderSurface->start(m_surfaceFormat)) {
+ emit error(QCamera::NotSupportedFeatureError, tr("Failed to start surface."));
+ return;
+ }
+
+ if (!m_viewfinderSurface->isActive())
+ return;
+ }
+
+ TRAPD(vfErr, m_cameraEngine->StartViewFinderL(size));
+ if (vfErr) {
+ if (vfErr == KErrNotSupported) {
+ emit error(QCamera::NotSupportedFeatureError, tr("Requested viewfinder size is not supported."));
+ } else {
+ emit error(QCamera::CameraError, tr("Starting viewfinder failed."));
+ }
+ return;
+ }
+
+ m_actualViewFinderSize = QSize(size.iWidth, size.iHeight);
+ m_viewfinderAspectRatio = qreal(m_actualViewFinderSize.width()) / qreal(m_actualViewFinderSize.height());
+
+ // Notify control about the frame size (triggers frame position calculation)
+ if (m_viewfinderDisplay) {
+ m_viewfinderDisplay->setNativeSize(m_actualViewFinderSize);
+ } else {
+ if (m_viewfinderType == OutputTypeRenderer && m_viewfinderSurface) {
+ m_viewfinderSurface->stop();
+ QVideoSurfaceFormat format = m_viewfinderSurface->surfaceFormat();
+ format.setFrameSize(QSize(m_actualViewFinderSize));
+ format.setViewport(QRect(0, 0, m_actualViewFinderSize.width(), m_actualViewFinderSize.height()));
+ m_viewfinderSurface->start(format);
+ }
+ }
+ }
+ }
+}
+
+void S60CameraViewfinderEngine::stopViewfinder(const bool internalStop)
+{
+ // Stop if viewfinder is started
+ if (m_vfState == EVFIsConnectedIsStartedIsVisible) {
+ if (m_viewfinderOutput && m_viewfinderType == OutputTypeRenderer && m_viewfinderSurface) {
+ // Stop surface if one still exists
+ m_viewfinderSurface->stop();
+ }
+
+ if (m_cameraEngine)
+ m_cameraEngine->StopViewFinder();
+ }
+
+ // Update state
+ if (!internalStop) {
+ switch (m_vfState) {
+ case EVFNotConnectedNotStarted:
+ case EVFIsConnectedNotStarted:
+ // Discard
+ break;
+ case EVFNotConnectedIsStarted:
+ m_vfState = EVFNotConnectedNotStarted;
+ break;
+ case EVFIsConnectedIsStartedNotVisible:
+ case EVFIsConnectedIsStartedIsVisible:
+ m_vfState = EVFIsConnectedNotStarted;
+ break;
+ default:
+ emit error(QCamera::CameraError, tr("General viewfinder error."));
+ break;
+ }
+ }
+}
+
+void S60CameraViewfinderEngine::MceoViewFinderFrameReady(CFbsBitmap& aFrame)
+{
+ emit viewFinderFrameReady(aFrame);
+ if (m_cameraEngine)
+ m_cameraEngine->ReleaseViewFinderBuffer();
+}
+
+void S60CameraViewfinderEngine::resetViewfinderSize(const QSize size)
+{
+ m_viewfinderSize = size;
+
+ if(m_vfState != EVFIsConnectedIsStartedIsVisible) {
+ // Set native size to Window/Renderer Control
+ if (m_viewfinderDisplay)
+ m_viewfinderDisplay->setNativeSize(m_actualViewFinderSize);
+ return;
+ }
+
+ stopViewfinder(true);
+
+ startViewfinder(true);
+}
+
+void S60CameraViewfinderEngine::resetVideoWindowSize()
+{
+ if (m_viewfinderDisplay)
+ resetViewfinderSize(m_viewfinderDisplay->extentRect().size());
+}
+
+void S60CameraViewfinderEngine::resetViewfinderDisplay()
+{
+ if (m_viewfinderNativeType == EDirectScreenViewFinder) {
+
+ switch (m_viewfinderType) {
+ case OutputTypeVideoWidget: {
+ if (!m_viewfinderOutput)
+ return;
+
+ // First stop viewfinder
+ stopViewfinder(true);
+
+ RWindow *window = m_viewfinderDisplay->windowHandle();
+ if (!window) {
+ return;
+ }
+
+ // Then start it with the new WindowID
+ startViewfinder(true);
+ break;
+ }
+ case OutputTypeRenderer:
+ case OutputTypeVideoWindow:
+ // Do nothing
+ break;
+
+ default:
+ // Not ViewFinder Output has been set, Discard
+ break;
+ }
+ }
+}
+
+void S60CameraViewfinderEngine::rendererSurfaceSet()
+{
+ S60VideoRendererControl* viewFinderRenderControl =
+ qobject_cast<S60VideoRendererControl*>(m_viewfinderOutput);
+
+ // Reset old surface if needed
+ if (m_viewfinderSurface) {
+ handleVisibilityChange(false);
+ disconnect(m_viewfinderSurface);
+ if (viewFinderRenderControl->surface())
+ stopViewfinder(true); // Temporary stop
+ else
+ stopViewfinder(); // Stop for good
+ m_viewfinderSize = QApplication::desktop()->screenGeometry().size();
+ m_viewfinderSurface = 0;
+ }
+
+ // Set new surface
+ m_viewfinderSurface = viewFinderRenderControl->surface();
+ if (!m_viewfinderSurface)
+ return;
+ if (!m_viewfinderSurface->nativeResolution().isEmpty()) {
+ if (m_viewfinderSurface->nativeResolution() != m_viewfinderSize)
+ resetViewfinderSize(m_viewfinderSurface->nativeResolution());
+ }
+
+ connect(m_viewfinderSurface, SIGNAL(nativeResolutionChanged(const QSize&)),
+ this, SLOT(resetViewfinderSize(QSize)));
+
+ // Set Surface Properties
+ if (m_viewfinderSurface->supportedPixelFormats().contains(QVideoFrame::Format_RGB32))
+ m_surfaceFormat = QVideoSurfaceFormat(m_actualViewFinderSize, QVideoFrame::Format_RGB32);
+ else if (m_viewfinderSurface->supportedPixelFormats().contains(QVideoFrame::Format_ARGB32))
+ m_surfaceFormat = QVideoSurfaceFormat(m_actualViewFinderSize, QVideoFrame::Format_ARGB32);
+ else {
+ return;
+ }
+ m_surfaceFormat.setFrameRate(KViewfinderFrameRate);
+ m_surfaceFormat.setYCbCrColorSpace(QVideoSurfaceFormat::YCbCr_Undefined); // EColor16MU (compatible with EColor16MA)
+ m_surfaceFormat.setPixelAspectRatio(1,1); // PAR 1:1
+
+
+ connect(this, SIGNAL(viewFinderFrameReady(const CFbsBitmap &)),
+ this, SLOT(viewFinderBitmapReady(const CFbsBitmap &)));
+
+ // Surface set, viewfinder is "visible"
+ handleVisibilityChange(true);
+}
+
+void S60CameraViewfinderEngine::viewFinderBitmapReady(const CFbsBitmap &bitmap)
+{
+ CFbsBitmap *bitmapPtr = const_cast<CFbsBitmap*>(&bitmap);
+ QPixmap pixmap = QPixmap::fromSymbianCFbsBitmap(bitmapPtr);
+
+ QImage newImage = pixmap.toImage();
+ if (newImage.format() != QImage::Format_ARGB32 &&
+ newImage.format() != QImage::Format_RGB32) {
+ newImage = newImage.convertToFormat(QImage::Format_RGB32);
+ }
+
+ if (!newImage.isNull()) {
+ QVideoFrame newFrame(newImage);
+ if (newFrame.isValid()) {
+ if (!m_viewfinderSurface->present(newFrame)) {
+ // Presenting may fail even if there are no errors (e.g. busy)
+ if (m_viewfinderSurface->error()) {
+ if (m_vfErrorsSignalled < KMaxVFErrorsSignalled) {
+ emit error(QCamera::CameraError, tr("Presenting viewfinder frame failed."));
+ ++m_vfErrorsSignalled;
+ }
+ }
+ }
+ } else {
+ if (m_vfErrorsSignalled < KMaxVFErrorsSignalled) {
+ emit error(QCamera::CameraError, tr("Invalid viewfinder frame was received."));
+ ++m_vfErrorsSignalled;
+ }
+ }
+
+ } else {
+ if (m_vfErrorsSignalled < KMaxVFErrorsSignalled) {
+ emit error(QCamera::CameraError, tr("Failed to convert viewfinder frame to presentable image."));
+ ++m_vfErrorsSignalled;
+ }
+ }
+}
+
+void S60CameraViewfinderEngine::handleVisibilityChange(const bool isVisible)
+{
+ if (m_isViewFinderVisible == isVisible)
+ return;
+
+ m_isViewFinderVisible = isVisible;
+
+ if (m_isViewFinderVisible) {
+ switch (m_vfState) {
+ case EVFNotConnectedNotStarted:
+ case EVFIsConnectedNotStarted:
+ case EVFNotConnectedIsStarted:
+ case EVFIsConnectedIsStartedIsVisible:
+ // Discard
+ break;
+ case EVFIsConnectedIsStartedNotVisible:
+ m_vfState = EVFIsConnectedIsStartedIsVisible;
+ break;
+ default:
+ emit error(QCamera::CameraError, tr("General viewfinder error."));
+ break;
+ }
+ startViewfinder(true);
+ } else {
+ // Stopping takes care of the state change
+ stopViewfinder(true);
+ }
+}
+
+void S60CameraViewfinderEngine::handleWindowChange(RWindow *handle)
+{
+ stopViewfinder(true);
+
+ if (handle) // New handle available, start viewfinder
+ startViewfinder(true);
+}
+
+void S60CameraViewfinderEngine::checkAndRotateCamera()
+{
+ bool isUiNowLandscape = false;
+ QDesktopWidget* desktopWidget = QApplication::desktop();
+ QRect screenRect = desktopWidget->screenGeometry();
+
+ if (screenRect.width() > screenRect.height())
+ isUiNowLandscape = true;
+ else
+ isUiNowLandscape = false;
+
+ // Rotate camera if possible
+ if (isUiNowLandscape != m_uiLandscape) {
+ stopViewfinder(true);
+
+ // Request orientation reset
+ m_cameraControl->resetCameraOrientation();
+ }
+ m_uiLandscape = isUiNowLandscape;
+}
+
+void S60CameraViewfinderEngine::handleContentAspectRatioChange(const QSize& newSize)
+{
+ qreal newAspectRatio = qreal(newSize.width()) / qreal(newSize.height());
+ // Check if aspect ratio changed
+ if (qFuzzyCompare(newAspectRatio, m_viewfinderAspectRatio))
+ return;
+
+ // Resize viewfinder by reducing either width or height to comply with the new aspect ratio
+ QSize newNativeResolution;
+ if (newAspectRatio > m_viewfinderAspectRatio) { // New AspectRatio is wider => Reduce height
+ newNativeResolution = QSize(m_actualViewFinderSize.width(), (m_actualViewFinderSize.width() / newAspectRatio));
+ } else { // New AspectRatio is higher => Reduce width
+ newNativeResolution = QSize((m_actualViewFinderSize.height() * newAspectRatio), m_actualViewFinderSize.height());
+ }
+
+ // Notify aspect ratio change (use actual content size to notify that)
+ // This triggers item size/position re-calculation
+ if (m_viewfinderDisplay)
+ m_viewfinderDisplay->setNativeSize(newNativeResolution);
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60cameraviewfinderengine.h b/src/plugins/symbian/ecam/s60cameraviewfinderengine.h
new file mode 100644
index 000000000..c5df760d9
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60cameraviewfinderengine.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef S60CAMERAVIEWFINDERENGINE_H
+#define S60CAMERAVIEWFINDERENGINE_H
+
+#include <QtCore/qsize.h>
+#include <QtGui/qpixmap.h>
+
+#include <qvideosurfaceformat.h>
+
+#include "s60cameraengineobserver.h"
+
+class CCameraEngine;
+class S60CameraControl;
+class QAbstractVideoSurface;
+
+// For DirectScreen ViewFinder
+class RWsSession;
+class CWsScreenDevice;
+class RWindowBase;
+class RWindow;
+class QDesktopWidget;
+
+class S60VideoDisplay;
+
+/*
+ * Class implementing video output selection for the viewfinder and the handler of
+ * all common viewfinder operations.
+ */
+class S60CameraViewfinderEngine : public QObject, public MCameraViewfinderObserver
+{
+ Q_OBJECT
+
+public: // Enums
+
+ /*
+ * Defines whether viewfinder output backend control is of type
+ * QVideoWidgetControl, QVideoRendererControl or QVideoWindowControl
+ */
+ enum ViewfinderOutputType {
+ OutputTypeNotSet = 0, // No viewfinder output connected
+ OutputTypeVideoWidget, // Using QVideoWidget
+ OutputTypeRenderer, // (Using QGraphicsVideoItem with) QVideoRendererControl
+ OutputTypeVideoWindow // Using QGraphicsVideoItem with QVideoWindow
+ };
+
+public: // Constructor & Destructor
+
+ S60CameraViewfinderEngine(S60CameraControl *control,
+ CCameraEngine *engine,
+ QObject *parent = 0);
+ ~S60CameraViewfinderEngine();
+
+public: // Methods
+
+ // Setting Viewfinder Output
+ void setVideoWidgetControl(QObject *viewfinderOutput);
+ void setVideoRendererControl(QObject *viewfinderOutput);
+ void setVideoWindowControl(QObject *viewfinderOutput);
+ void releaseControl(ViewfinderOutputType type);
+
+ // Controls
+ void startViewfinder(const bool internalStart = false);
+ void stopViewfinder(const bool internalStop = false);
+
+ // Start using new CameraEngine
+ void setNewCameraEngine(CCameraEngine *engine);
+
+protected: // MCameraViewfinderObserver
+
+ void MceoViewFinderFrameReady(CFbsBitmap& aFrame);
+
+private: // Internal operation
+
+ void checkAndRotateCamera();
+
+signals:
+
+ void error(int error, const QString &errorString);
+ void viewFinderFrameReady(const CFbsBitmap &bitmap);
+
+private slots:
+
+ void resetViewfinderSize(const QSize size);
+ void resetVideoWindowSize();
+ void resetViewfinderDisplay();
+ void viewFinderBitmapReady(const CFbsBitmap &bitmap);
+ void handleVisibilityChange(const bool isVisible);
+ void handleWindowChange(RWindow *handle);
+ void handleDesktopResize(int screen);
+ void handleContentAspectRatioChange(const QSize& newSize);
+ void rendererSurfaceSet();
+
+private: // Enums
+
+ /*
+ * Defines the internal state of the viewfinder. ViewFinder will only be
+ * started if output is connected to Camera and Camera is started (and
+ * ViewFinder widget is visible in case of QVideoWidget).
+ */
+ enum ViewFinderState {
+ EVFNotConnectedNotStarted = 0, // 0 - No output connected, viewfinder is not started
+ EVFNotConnectedIsStarted, // 1 - No output connected, viewfinder is started
+ EVFIsConnectedNotStarted, // 2 - Output is connected, viewfinder is not started
+ EVFIsConnectedIsStartedNotVisible, // 3 - Output is connected, viewfinder is started but is not visible
+ EVFIsConnectedIsStartedIsVisible // 4 - Output is connected, viewfinder is started and is visible
+ };
+
+ /*
+ * The native type of ViewFinder. DirectScreen ViewFinder is used with
+ * QVideoWidget if support for it is available in the platform. For
+ * QGraphicsVideoItem Bitmap ViewFinder is always used.
+ */
+ enum NativeViewFinderType {
+ EBitmapViewFinder = 0,
+ EDirectScreenViewFinder
+ };
+
+private: // Data
+
+ CCameraEngine *m_cameraEngine;
+ S60CameraControl *m_cameraControl;
+ QObject *m_viewfinderOutput;
+ S60VideoDisplay *m_viewfinderDisplay;
+ QAbstractVideoSurface *m_viewfinderSurface; // Used only by QVideoRendererControl
+ RWsSession &m_wsSession;
+ CWsScreenDevice &m_screenDevice;
+ RWindowBase *m_window;
+ QDesktopWidget *m_desktopWidget;
+ ViewFinderState m_vfState;
+ QSize m_viewfinderSize;
+ // Actual viewfinder size, which may differ from requested
+ // (m_viewfinderSize), if the size/aspect ratio was not supported.
+ QSize m_actualViewFinderSize;
+ qreal m_viewfinderAspectRatio;
+ ViewfinderOutputType m_viewfinderType;
+ NativeViewFinderType m_viewfinderNativeType;
+ QVideoSurfaceFormat m_surfaceFormat; // Used only by QVideoRendererControl
+ bool m_isViewFinderVisible;
+ bool m_uiLandscape; // For detecting UI rotation
+ int m_vfErrorsSignalled;
+};
+
+#endif // S60CAMERAVIEWFINDERENGINE_H
diff --git a/src/plugins/symbian/ecam/s60imagecapturesession.cpp b/src/plugins/symbian/ecam/s60imagecapturesession.cpp
new file mode 100644
index 000000000..16d240c7b
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60imagecapturesession.cpp
@@ -0,0 +1,1884 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+#include <QtCore/qdir.h>
+
+#include "s60imagecapturesession.h"
+#include "s60videowidgetcontrol.h"
+#include "s60cameraservice.h"
+#include "s60cameraconstants.h"
+
+#include <fbs.h> // CFbsBitmap
+#include <pathinfo.h>
+#include <imageconversion.h> // ICL Decoder (for SnapShot) & Encoder (for Bitmap Images)
+
+S60ImageCaptureDecoder::S60ImageCaptureDecoder(S60ImageCaptureSession *imageSession,
+ RFs *fileSystemAccess,
+ const TDesC8 *data,
+ const TDesC16 *fileName) :
+ CActive(CActive::EPriorityStandard),
+ m_imageSession(imageSession),
+ m_fs(fileSystemAccess),
+ m_jpegImageData(data),
+ m_jpegImageFile(fileName),
+ m_fileInput(false)
+{
+ CActiveScheduler::Add(this);
+}
+
+S60ImageCaptureDecoder::~S60ImageCaptureDecoder()
+{
+ if (m_imageDecoder) {
+ delete m_imageDecoder;
+ m_imageDecoder = 0;
+ }
+}
+
+S60ImageCaptureDecoder *S60ImageCaptureDecoder::FileNewL(S60ImageCaptureSession *imageSession,
+ RFs *fileSystemAccess,
+ const TDesC16 *fileName)
+{
+ S60ImageCaptureDecoder* self = new (ELeave) S60ImageCaptureDecoder(imageSession,
+ fileSystemAccess,
+ 0,
+ fileName);
+ CleanupStack::PushL(self);
+ self->ConstructL(true);
+ CleanupStack::Pop(self);
+ return self;
+}
+
+S60ImageCaptureDecoder *S60ImageCaptureDecoder::DataNewL(S60ImageCaptureSession *imageSession,
+ RFs *fileSystemAccess,
+ const TDesC8 *data)
+{
+ S60ImageCaptureDecoder* self = new (ELeave) S60ImageCaptureDecoder(imageSession,
+ fileSystemAccess,
+ data,
+ 0);
+ CleanupStack::PushL(self);
+ self->ConstructL(false);
+ CleanupStack::Pop(self);
+ return self;
+}
+
+void S60ImageCaptureDecoder::ConstructL(const bool fileInput)
+{
+ if (fileInput) {
+ if (!m_imageSession || !m_fs || !m_jpegImageFile)
+ User::Leave(KErrGeneral);
+ m_imageDecoder = CImageDecoder::FileNewL(*m_fs, *m_jpegImageFile);
+ } else {
+ if (!m_imageSession || !m_fs || !m_jpegImageData)
+ User::Leave(KErrGeneral);
+ m_imageDecoder = CImageDecoder::DataNewL(*m_fs, *m_jpegImageData);
+ }
+}
+
+void S60ImageCaptureDecoder::decode(CFbsBitmap *destBitmap)
+{
+ if (m_imageDecoder) {
+ m_imageDecoder->Convert(&iStatus, *destBitmap, 0);
+ SetActive();
+ }
+ else
+ m_imageSession->setError(KErrGeneral, QLatin1String("Preview image creation failed."));
+}
+
+TFrameInfo *S60ImageCaptureDecoder::frameInfo()
+{
+ if (m_imageDecoder) {
+ m_frameInfo = m_imageDecoder->FrameInfo();
+ return &m_frameInfo;
+ }
+ else
+ return 0;
+}
+
+void S60ImageCaptureDecoder::RunL()
+{
+ m_imageSession->handleImageDecoded(iStatus.Int());
+}
+
+void S60ImageCaptureDecoder::DoCancel()
+{
+ if (m_imageDecoder)
+ m_imageDecoder->Cancel();
+}
+
+TInt S60ImageCaptureDecoder::RunError(TInt aError)
+{
+ m_imageSession->setError(aError, QLatin1String("Preview image creation failed."));
+ return KErrNone;
+}
+
+//=============================================================================
+
+S60ImageCaptureEncoder::S60ImageCaptureEncoder(S60ImageCaptureSession *imageSession,
+ RFs *fileSystemAccess,
+ const TDesC16 *fileName,
+ TInt jpegQuality) :
+ CActive(CActive::EPriorityStandard),
+ m_imageSession(imageSession),
+ m_fileSystemAccess(fileSystemAccess),
+ m_fileName(fileName),
+ m_jpegQuality(jpegQuality)
+{
+ CActiveScheduler::Add(this);
+}
+
+S60ImageCaptureEncoder::~S60ImageCaptureEncoder()
+{
+ if (m_frameImageData) {
+ delete m_frameImageData;
+ m_frameImageData = 0;
+ }
+ if (m_imageEncoder) {
+ delete m_imageEncoder;
+ m_imageEncoder = 0;
+ }
+}
+
+S60ImageCaptureEncoder *S60ImageCaptureEncoder::NewL(S60ImageCaptureSession *imageSession,
+ RFs *fileSystemAccess,
+ const TDesC16 *fileName,
+ TInt jpegQuality)
+{
+ S60ImageCaptureEncoder* self = new (ELeave) S60ImageCaptureEncoder(imageSession,
+ fileSystemAccess,
+ fileName,
+ jpegQuality);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+}
+
+void S60ImageCaptureEncoder::ConstructL()
+{
+ if (!m_imageSession || !m_fileSystemAccess || !m_fileName)
+ User::Leave(KErrGeneral);
+
+ m_imageEncoder = CImageEncoder::FileNewL(*m_fileSystemAccess,
+ *m_fileName,
+ CImageEncoder::EOptionNone,
+ KImageTypeJPGUid);
+ CleanupStack::PushL(m_imageEncoder);
+
+ // Set Jpeg Quality
+ m_frameImageData = CFrameImageData::NewL();
+ CleanupStack::PushL(m_frameImageData);
+
+ TJpegImageData* jpegFormat = new( ELeave ) TJpegImageData;
+ CleanupStack::PushL(jpegFormat);
+
+ jpegFormat->iQualityFactor = m_jpegQuality;
+
+ // jpegFormat (TJpegImageData) ownership transferred to m_frameImageData (CFrameImageData)
+ User::LeaveIfError( m_frameImageData->AppendImageData(jpegFormat));
+
+ CleanupStack::Pop(jpegFormat);
+ CleanupStack::Pop(m_frameImageData);
+ CleanupStack::Pop(m_imageEncoder);
+}
+
+void S60ImageCaptureEncoder::encode(CFbsBitmap *sourceBitmap)
+{
+ if (m_imageEncoder) {
+ m_imageEncoder->Convert(&iStatus, *sourceBitmap, m_frameImageData);
+ SetActive();
+ }
+ else
+ m_imageSession->setError(KErrGeneral, QLatin1String("Saving image to file failed."));
+}
+
+void S60ImageCaptureEncoder::RunL()
+{
+ m_imageSession->handleImageEncoded(iStatus.Int());
+}
+
+void S60ImageCaptureEncoder::DoCancel()
+{
+ if (m_imageEncoder)
+ m_imageEncoder->Cancel();
+}
+
+TInt S60ImageCaptureEncoder::RunError(TInt aError)
+{
+ m_imageSession->setError(aError, QLatin1String("Saving image to file failed."));
+ return KErrNone;
+}
+
+//=============================================================================
+
+S60ImageCaptureSession::S60ImageCaptureSession(QObject *parent) :
+ QObject(parent),
+ m_cameraEngine(0),
+ m_advancedSettings(0),
+ m_cameraInfo(0),
+ m_previewBitmap(0),
+ m_activeScheduler(0),
+ m_fileSystemAccess(0),
+ m_imageDecoder(0),
+ m_imageEncoder(0),
+ m_error(KErrNone),
+ m_activeDeviceIndex(KDefaultCameraDevice),
+ m_cameraStarted(false),
+ m_icState(EImageCaptureNotPrepared),
+ m_currentCodec(QString()),
+ m_captureSize(QSize()),
+ m_symbianImageQuality(QtMultimediaKit::HighQuality * KSymbianImageQualityCoefficient),
+ m_captureSettingsSet(false),
+ m_stillCaptureFileName(QString()),
+ m_requestedStillCaptureFileName(QString()),
+ m_currentImageId(0),
+ m_captureWhenReady(false),
+ m_previewDecodingOngoing(false),
+ m_previewInWaitLoop(false)
+{
+ // Define supported image codecs
+ m_supportedImageCodecs << "image/jpeg";
+
+ initializeImageCaptureSettings();
+
+ // Install ActiveScheduler if needed
+ if (!CActiveScheduler::Current()) {
+ m_activeScheduler = new CActiveScheduler;
+ CActiveScheduler::Install(m_activeScheduler);
+ }
+}
+
+S60ImageCaptureSession::~S60ImageCaptureSession()
+{
+ // Delete AdvancedSettings (Should already be destroyed by CameraControl)
+ deleteAdvancedSettings();
+
+ m_formats.clear();
+ m_supportedImageCodecs.clear();
+
+ if (m_imageDecoder) {
+ m_imageDecoder->Cancel();
+ delete m_imageDecoder;
+ m_imageDecoder = 0;
+ }
+ if (m_imageEncoder) {
+ m_imageEncoder->Cancel();
+ delete m_imageEncoder;
+ m_imageEncoder = 0;
+ }
+
+ if (m_previewBitmap) {
+ delete m_previewBitmap;
+ m_previewBitmap = 0;
+ }
+
+ // Uninstall ActiveScheduler if needed
+ if (m_activeScheduler) {
+ CActiveScheduler::Install(0);
+ delete m_activeScheduler;
+ m_activeScheduler = 0;
+ }
+}
+
+CCamera::TFormat S60ImageCaptureSession::defaultImageFormat()
+{
+ // Primary Camera
+ if (m_activeDeviceIndex == 0)
+ return KDefaultImageFormatPrimaryCam;
+
+ // Secondary Camera or other
+ else
+ return KDefaultImageFormatSecondaryCam;
+}
+
+bool S60ImageCaptureSession::isDeviceReady()
+{
+#ifdef Q_CC_NOKIAX86 // Emulator
+ return true;
+#endif
+
+ if (m_cameraEngine)
+ return m_cameraEngine->IsCameraReady();
+
+ return false;
+}
+
+void S60ImageCaptureSession::deleteAdvancedSettings()
+{
+ if (m_advancedSettings) {
+ delete m_advancedSettings;
+ m_advancedSettings = 0;
+ emit advancedSettingChanged();
+ }
+}
+
+void S60ImageCaptureSession::setCameraHandle(CCameraEngine* camerahandle)
+{
+ if (camerahandle) {
+ m_cameraEngine = camerahandle;
+ resetSession();
+
+ // Set default settings
+ initializeImageCaptureSettings();
+ }
+}
+
+void S60ImageCaptureSession::setCurrentDevice(TInt deviceindex)
+{
+ m_activeDeviceIndex = deviceindex;
+}
+
+void S60ImageCaptureSession::notifySettingsSet()
+{
+ m_captureSettingsSet = true;
+}
+
+void S60ImageCaptureSession::resetSession(bool errorHandling)
+{
+ // Delete old AdvancedSettings
+ deleteAdvancedSettings();
+
+ m_captureWhenReady = false;
+ m_previewDecodingOngoing = false;
+ m_previewInWaitLoop = false;
+ m_stillCaptureFileName = QString();
+ m_requestedStillCaptureFileName = QString();
+ m_icState = EImageCaptureNotPrepared;
+
+ m_error = KErrNone;
+ m_currentFormat = defaultImageFormat();
+
+ int err = KErrNone;
+ m_advancedSettings = S60CameraSettings::New(err, this, m_cameraEngine);
+ if (err == KErrNotSupported) {
+ m_advancedSettings = 0;
+#ifndef S60_31_PLATFORM // Post S60 3.1 Platform
+ // Adv. settings may not be supported for other than the Primary Camera
+ if (m_cameraEngine->CurrentCameraIndex() == 0)
+ setError(err, tr("Unexpected camera error."));
+#endif // !S60_31_PLATFORM
+ } else if (err != KErrNone) { // Other errors
+ m_advancedSettings = 0;
+ qWarning("Failed to create camera settings handler.");
+ if (errorHandling)
+ emit cameraError(QCamera::ServiceMissingError, tr("Failed to recover from error."));
+ else
+ setError(err, tr("Unexpected camera error."));
+ return;
+ }
+
+ if (m_advancedSettings) {
+ if (m_cameraEngine)
+ m_cameraEngine->SetAdvancedObserver(m_advancedSettings);
+ else
+ setError(KErrNotReady, tr("Unexpected camera error."));
+ }
+
+ updateImageCaptureFormats();
+
+ emit advancedSettingChanged();
+}
+
+S60CameraSettings* S60ImageCaptureSession::advancedSettings()
+{
+ return m_advancedSettings;
+}
+
+/*
+ * This function can be used both internally and from Control classes using
+ * this session. The error notification will go to the client application
+ * either through QCameraImageCapture (if captureError is true) or QCamera (if
+ * captureError is false, default) error signal.
+ */
+void S60ImageCaptureSession::setError(const TInt error,
+ const QString &description,
+ const bool captureError)
+{
+ if (error == KErrNone)
+ return;
+
+ m_error = error;
+ QCameraImageCapture::Error cameraError = fromSymbianErrorToQtMultimediaError(error);
+
+ if (captureError) {
+ emit this->captureError(m_currentImageId, cameraError, description);
+ if (cameraError != QCameraImageCapture::NotSupportedFeatureError)
+ resetSession(true);
+ } else {
+ emit this->cameraError(cameraError, description);
+ if (cameraError != QCamera::NotSupportedFeatureError)
+ resetSession(true);
+ }
+}
+
+QCameraImageCapture::Error S60ImageCaptureSession::fromSymbianErrorToQtMultimediaError(int aError)
+{
+ switch(aError) {
+ case KErrNone:
+ return QCameraImageCapture::NoError; // No errors have occurred
+ case KErrNotReady:
+ return QCameraImageCapture::NotReadyError; // Not ready for operation
+ case KErrNotSupported:
+ return QCameraImageCapture::NotSupportedFeatureError; // The feature is not supported
+ case KErrNoMemory:
+ return QCameraImageCapture::OutOfSpaceError; // Out of disk space
+ case KErrNotFound:
+ case KErrBadHandle:
+ return QCameraImageCapture::ResourceError; // No resources available
+
+ default:
+ return QCameraImageCapture::ResourceError; // Other error has occurred
+ }
+}
+
+int S60ImageCaptureSession::currentImageId() const
+{
+ return m_currentImageId;
+}
+
+void S60ImageCaptureSession::initializeImageCaptureSettings()
+{
+ if (m_captureSettingsSet)
+ return;
+
+ m_currentCodec = KDefaultImageCodec;
+ m_captureSize = QSize(-1, -1);
+ m_currentFormat = defaultImageFormat();
+
+ // Resolution
+ if (m_cameraEngine) {
+ QList<QSize> resolutions = supportedCaptureSizesForCodec(imageCaptureCodec());
+ foreach (QSize reso, resolutions) {
+ if ((reso.width() * reso.height()) > (m_captureSize.width() * m_captureSize.height()))
+ m_captureSize = reso;
+ }
+ } else {
+ m_captureSize = KDefaultImageResolution;
+ }
+
+ m_symbianImageQuality = KDefaultImageQuality;
+}
+
+/*
+ * This function selects proper format to be used for the captured image based
+ * on the requested image codec.
+ */
+CCamera::TFormat S60ImageCaptureSession::selectFormatForCodec(const QString &codec)
+{
+ CCamera::TFormat format = CCamera::EFormatMonochrome;
+
+ if (codec == "image/jpg" || codec == "image/jpeg") {
+ // Primary Camera
+ if (m_activeDeviceIndex == 0)
+ format = KDefaultImageFormatPrimaryCam;
+
+ // Secondary Camera or other
+ else
+ format = KDefaultImageFormatSecondaryCam;
+
+ return format;
+ }
+
+ setError(KErrNotSupported, tr("Failed to select color format to be used with image codec."));
+ return format;
+}
+
+int S60ImageCaptureSession::prepareImageCapture()
+{
+ if (m_cameraEngine) {
+ if (!m_cameraEngine->IsCameraReady()) {
+ // Reset state to make sure camera is prepared before capturing image
+ m_icState = EImageCaptureNotPrepared;
+ return KErrNotReady;
+ }
+
+ // First set the quality
+ CCamera *camera = m_cameraEngine->Camera();
+ if (camera)
+ camera->SetJpegQuality(m_symbianImageQuality);
+ else
+ setError(KErrNotReady, tr("Setting image quality failed."), true);
+
+ // Then prepare with correct resolution and format
+ TSize captureSize = TSize(m_captureSize.width(), m_captureSize.height());
+ TRAPD(symbianError, m_cameraEngine->PrepareL(captureSize, m_currentFormat));
+ if (!symbianError)
+ m_icState = EImageCapturePrepared;
+
+ // Check if CaptureSize was modified
+ if (captureSize.iWidth != m_captureSize.width() || captureSize.iHeight != m_captureSize.height())
+ m_captureSize = QSize(captureSize.iWidth, captureSize.iHeight);
+ emit captureSizeChanged(m_captureSize);
+
+#ifdef ECAM_PREVIEW_API
+ // Subscribe previews
+ MCameraPreviewObserver *observer = this;
+ m_cameraEngine->EnablePreviewProvider(observer);
+#endif // ECAM_PREVIEW_API
+
+ return symbianError;
+ }
+
+ return KErrGeneral;
+}
+
+void S60ImageCaptureSession::releaseImageCapture()
+{
+ // Make sure ImageCapture is prepared the next time it is being activated
+ m_icState = EImageCaptureNotPrepared;
+
+#ifdef ECAM_PREVIEW_API
+ // Cancel preview subscription
+ m_cameraEngine->DisablePreviewProvider();
+#endif // ECAM_PREVIEW_API
+}
+
+int S60ImageCaptureSession::capture(const QString &fileName)
+{
+ if (!m_cameraStarted) {
+ m_captureWhenReady = true;
+ m_requestedStillCaptureFileName = fileName; // Save name, it will be processed during actual capture
+ return 0;
+ }
+
+ if (m_icState < EImageCapturePrepared) {
+ int prepareSuccess = prepareImageCapture();
+ if (prepareSuccess) {
+ setError(prepareSuccess, tr("Failure during image capture preparation."), true);
+ return 0;
+ }
+ } else if (m_icState > EImageCapturePrepared) {
+ setError(KErrNotReady, tr("Previous operation is still ongoing."), true);
+ return 0;
+ }
+
+ m_icState = EImageCaptureCapturing;
+
+ // Give new ID for the new image
+ m_currentImageId += 1;
+
+ emit readyForCaptureChanged(false);
+
+ processFileName(fileName);
+
+ if (m_cameraEngine) {
+ TRAPD(err, m_cameraEngine->CaptureL());
+ setError(err, tr("Image capture failed."), true);
+ } else {
+ setError(KErrNotReady, tr("Unexpected camera error."), true);
+ }
+
+#ifdef Q_CC_NOKIAX86 // Emulator
+ QImage *snapImage = new QImage(QLatin1String("C:/Data/testimage.jpg"));
+ emit imageExposed(m_currentImageId);
+ emit imageCaptured(m_currentImageId, *snapImage);
+ emit imageSaved(m_currentImageId, m_stillCaptureFileName);
+#endif // Q_CC_NOKIAX86
+
+ return m_currentImageId;
+}
+
+void S60ImageCaptureSession::cancelCapture()
+{
+ if (m_icState != EImageCaptureCapturing)
+ return;
+
+ if (m_cameraEngine)
+ m_cameraEngine->CancelCapture();
+
+ m_icState = EImageCapturePrepared;
+}
+
+void S60ImageCaptureSession::processFileName(const QString &fileName)
+{
+ // Empty FileName - Use default file name and path (C:\Data\Images\image.jpg)
+ if (fileName.isEmpty()) {
+ // Make sure default directory exists
+ QDir videoDir(QDir::rootPath());
+ if (!videoDir.exists(KDefaultImagePath))
+ videoDir.mkpath(KDefaultImagePath);
+ QString defaultFile = KDefaultImagePath;
+ defaultFile.append("\\");
+ defaultFile.append(KDefaultImageFileName);
+ m_stillCaptureFileName = defaultFile;
+
+ } else { // Not empty
+
+ QString fullFileName;
+
+ // Relative FileName
+ if (!fileName.contains(":")) {
+ // Extract file name and path from the URL
+ fullFileName = KDefaultImagePath;
+ if (fileName.at(0) != '\\')
+ fullFileName.append("\\");
+ fullFileName.append(QDir::toNativeSeparators(QDir::cleanPath(fileName)));
+
+ // Absolute FileName
+ } else {
+ // Extract file name and path from the given location
+ fullFileName = QDir::toNativeSeparators(QDir::cleanPath(fileName));
+ }
+
+ QString fileNameOnly = fullFileName.right(fullFileName.length() - fullFileName.lastIndexOf("\\") - 1);
+ QString directory = fullFileName.left(fullFileName.lastIndexOf("\\"));
+ if (directory.lastIndexOf("\\") == (directory.length() - 1))
+ directory = directory.left(directory.length() - 1);
+
+ // URL is Absolute path, not including file name
+ if (!fileNameOnly.contains(".")) {
+ if (fileNameOnly != "") {
+ directory.append("\\");
+ directory.append(fileNameOnly);
+ }
+ fileNameOnly = KDefaultImageFileName;
+ }
+
+ // Make sure absolute directory exists
+ QDir imageDir(QDir::rootPath());
+ if (!imageDir.exists(directory))
+ imageDir.mkpath(directory);
+
+ QString resolvedFileName = directory;
+ resolvedFileName.append("\\");
+ resolvedFileName.append(fileNameOnly);
+ m_stillCaptureFileName = resolvedFileName;
+ }
+}
+
+void S60ImageCaptureSession::MceoFocusComplete()
+{
+ emit focusStatusChanged(QCamera::Locked, QCamera::LockAcquired);
+}
+
+void S60ImageCaptureSession::MceoCapturedDataReady(TDesC8* aData)
+{
+ emit imageExposed(m_currentImageId);
+
+ m_icState = EImageCaptureWritingImage;
+
+ TFileName path = convertImagePath();
+
+ // Try to save image and inform if it was succcesful
+ TRAPD(err, saveImageL(aData, path));
+ if (err) {
+ if (m_previewDecodingOngoing)
+ m_previewDecodingOngoing = false; // Reset
+
+ setError(err, tr("Writing captured image to a file failed."), true);
+ m_icState = EImageCapturePrepared;
+ return;
+ }
+
+ m_icState = EImageCapturePrepared;
+
+}
+
+void S60ImageCaptureSession::MceoCapturedBitmapReady(CFbsBitmap* aBitmap)
+{
+ emit imageExposed(m_currentImageId);
+
+ m_icState = EImageCaptureWritingImage;
+
+ if(aBitmap)
+ {
+#ifndef ECAM_PREVIEW_API
+ if (m_previewDecodingOngoing) {
+ m_previewInWaitLoop = true;
+ CActiveScheduler::Start(); // Wait for the completion of the previous Preview generation
+ }
+
+ // Delete old instances if needed
+ if (m_imageDecoder) {
+ delete m_imageDecoder;
+ m_imageDecoder = 0;
+ }
+ if (m_previewBitmap) {
+ delete m_previewBitmap;
+ m_previewBitmap = 0;
+ }
+#endif // ECAM_CAMERA_API
+ if (m_imageEncoder) {
+ delete m_imageEncoder;
+ m_imageEncoder = 0;
+ }
+ if (m_fileSystemAccess) {
+ m_fileSystemAccess->Close();
+ delete m_fileSystemAccess;
+ m_fileSystemAccess = 0;
+ }
+
+ TInt saveError = KErrNone;
+ TFileName path = convertImagePath();
+
+ // Create FileSystem access
+ m_fileSystemAccess = new RFs;
+ if (!m_fileSystemAccess) {
+ setError(KErrNoMemory, tr("Failed to write captured image to a file."));
+ return;
+ }
+ saveError = m_fileSystemAccess->Connect();
+ if (saveError) {
+ setError(saveError, tr("Failed to write captured image to a file."));
+ return;
+ }
+
+ TRAP(saveError, m_imageEncoder = S60ImageCaptureEncoder::NewL(this,
+ m_fileSystemAccess,
+ &path,
+ m_symbianImageQuality));
+ if (saveError)
+ setError(saveError, tr("Saving captured image failed."), true);
+ m_previewDecodingOngoing = true;
+ m_imageEncoder->encode(aBitmap);
+
+ } else {
+ setError(KErrBadHandle, tr("Unexpected camera error."), true);
+ }
+
+ m_icState = EImageCapturePrepared;
+}
+
+void S60ImageCaptureSession::MceoHandleError(TCameraEngineError aErrorType, TInt aError)
+{
+ Q_UNUSED(aErrorType);
+ setError(aError, tr("General camera error."));
+}
+
+TFileName S60ImageCaptureSession::convertImagePath()
+{
+ TFileName path = KNullDesC();
+
+ // Convert to Symbian path
+ TPtrC16 attachmentPath(KNullDesC);
+
+ // Path is already included in filename
+ attachmentPath.Set(reinterpret_cast<const TUint16*>(QDir::toNativeSeparators(m_stillCaptureFileName).utf16()));
+ path.Append(attachmentPath);
+
+ return path;
+}
+
+/*
+ * Creates (asynchronously) Preview Image from Jpeg ImageBuffer and also
+ * writes Jpeg (synchronously) to a file.
+ */
+void S60ImageCaptureSession::saveImageL(TDesC8 *aData, TFileName &aPath)
+{
+ if (aData == 0)
+ setError(KErrGeneral, tr("Captured image data is not available."), true);
+
+ if (aPath.Size() > 0) {
+#ifndef ECAM_PREVIEW_API
+ if (m_previewDecodingOngoing) {
+ m_previewInWaitLoop = true;
+ CActiveScheduler::Start(); // Wait for the completion of the previous Preview generation
+ }
+
+ // Delete old instances if needed
+ if (m_imageDecoder) {
+ delete m_imageDecoder;
+ m_imageDecoder = 0;
+ }
+ if (m_previewBitmap) {
+ delete m_previewBitmap;
+ m_previewBitmap = 0;
+ }
+#endif // ECAM_PREVIEW_API
+ if (m_fileSystemAccess) {
+ m_fileSystemAccess->Close();
+ delete m_fileSystemAccess;
+ m_fileSystemAccess = 0;
+ }
+
+ RFs *fileSystemAccess = new (ELeave) RFs;
+ User::LeaveIfError(fileSystemAccess->Connect());
+ CleanupClosePushL(*fileSystemAccess);
+
+#ifndef ECAM_PREVIEW_API
+ // Generate Thumbnail to be used as Preview
+ S60ImageCaptureDecoder *imageDecoder = S60ImageCaptureDecoder::DataNewL(this, fileSystemAccess, aData);
+ CleanupStack::PushL(imageDecoder);
+
+ // Set proper Preview Size
+ TSize scaledSize((m_captureSize.width() / KSnapshotDownScaleFactor), (m_captureSize.height() / KSnapshotDownScaleFactor));
+ if (scaledSize.iWidth < KSnapshotMinWidth || scaledSize.iHeight < KSnapshotMinHeight)
+ scaledSize.SetSize((m_captureSize.width() / (KSnapshotDownScaleFactor/2)), (m_captureSize.height() / (KSnapshotDownScaleFactor/2)));
+ if (scaledSize.iWidth < KSnapshotMinWidth || scaledSize.iHeight < KSnapshotMinHeight)
+ scaledSize.SetSize((m_captureSize.width() / (KSnapshotDownScaleFactor/4)), (m_captureSize.height() / (KSnapshotDownScaleFactor/4)));
+ if (scaledSize.iWidth < KSnapshotMinWidth || scaledSize.iHeight < KSnapshotMinHeight)
+ scaledSize.SetSize(m_captureSize.width(), m_captureSize.height());
+
+ TFrameInfo *info = imageDecoder->frameInfo();
+ if (!info) {
+ setError(KErrGeneral, tr("Preview image creation failed."));
+ return;
+ }
+
+ CFbsBitmap *previewBitmap = new (ELeave) CFbsBitmap;
+ CleanupStack::PushL(previewBitmap);
+ TInt bitmapCreationErr = previewBitmap->Create(scaledSize, info->iFrameDisplayMode);
+ if (bitmapCreationErr) {
+ setError(bitmapCreationErr, tr("Preview creation failed."));
+ return;
+ }
+
+ // Jpeg conversion completes in RunL
+ m_previewDecodingOngoing = true;
+ imageDecoder->decode(previewBitmap);
+#endif // ECAM_PREVIEW_API
+
+ RFile file;
+ TInt fileWriteErr = KErrNone;
+ fileWriteErr = file.Replace(*fileSystemAccess, aPath, EFileWrite);
+ if (fileWriteErr)
+ User::Leave(fileWriteErr);
+ CleanupClosePushL(file); // Close if Leaves
+
+ fileWriteErr = file.Write(*aData);
+ if (fileWriteErr)
+ User::Leave(fileWriteErr);
+
+ CleanupStack::PopAndDestroy(&file);
+#ifdef ECAM_PREVIEW_API
+ CleanupStack::PopAndDestroy(fileSystemAccess);
+#else // !ECAM_PREVIEW_API
+ // Delete when Image is decoded
+ CleanupStack::Pop(previewBitmap);
+ CleanupStack::Pop(imageDecoder);
+ CleanupStack::Pop(fileSystemAccess);
+
+ // Set member variables (Cannot leave any more)
+ m_previewBitmap = previewBitmap;
+ m_imageDecoder = imageDecoder;
+ m_fileSystemAccess = fileSystemAccess;
+#endif // ECAM_PREVIEW_API
+
+ emit imageSaved(m_currentImageId, m_stillCaptureFileName);
+
+ // Inform that we can continue taking more pictures
+ emit readyForCaptureChanged(true);
+
+ // For custom preview generation, image buffer gets released in RunL()
+#ifdef ECAM_PREVIEW_API
+ releaseImageBuffer();
+#endif // ECAM_PREVIEW_API
+
+ } else {
+ setError(KErrPathNotFound, tr("Invalid path given."), true);
+ }
+}
+
+void S60ImageCaptureSession::releaseImageBuffer()
+{
+ if (m_cameraEngine)
+ m_cameraEngine->ReleaseImageBuffer();
+ else
+ setError(KErrNotReady, tr("Unexpected camera error."), true);
+}
+
+/*
+ * Queries camera properties
+ * Results are returned to member variable m_info
+ *
+ * @return boolean indicating if querying the info was a success
+ */
+bool S60ImageCaptureSession::queryCurrentCameraInfo()
+{
+ if (m_cameraEngine) {
+ m_cameraInfo = m_cameraEngine->CameraInfo();
+ return true;
+ }
+
+ return false;
+}
+
+/*
+ * This function handles different camera status changes
+ */
+void S60ImageCaptureSession::cameraStatusChanged(QCamera::Status status)
+{
+ if (status == QCamera::ActiveStatus) {
+ m_cameraStarted = true;
+ if (m_captureWhenReady)
+ capture(m_requestedStillCaptureFileName);
+ }else if (status == QCamera::UnloadedStatus) {
+ m_cameraStarted = false;
+ m_icState = EImageCaptureNotPrepared;
+ }
+ else
+ m_cameraStarted = false;
+}
+
+QSize S60ImageCaptureSession::captureSize() const
+{
+ return m_captureSize;
+}
+
+QSize S60ImageCaptureSession::minimumCaptureSize()
+{
+ return supportedCaptureSizesForCodec(formatMap().key(m_currentFormat)).first();
+}
+QSize S60ImageCaptureSession::maximumCaptureSize()
+{
+ return supportedCaptureSizesForCodec(formatMap().key(m_currentFormat)).last();
+}
+
+void S60ImageCaptureSession::setCaptureSize(const QSize &size)
+{
+ if (size.isNull() ||
+ size.isEmpty() ||
+ size == QSize(-1,-1)) {
+ // An empty QSize indicates the encoder should make an optimal choice based on what is
+ // available from the image source and the limitations of the codec.
+ m_captureSize = supportedCaptureSizesForCodec(formatMap().key(m_currentFormat)).last();
+ }
+ else
+ m_captureSize = size;
+}
+
+QList<QSize> S60ImageCaptureSession::supportedCaptureSizesForCodec(const QString &codecName)
+{
+ QList<QSize> list;
+
+ // If we have CameraEngine loaded and we can update CameraInfo
+ if (m_cameraEngine && queryCurrentCameraInfo()) {
+ CCamera::TFormat format;
+ if (codecName == "")
+ format = defaultImageFormat();
+ else
+ format = selectFormatForCodec(codecName);
+
+ CCamera *camera = m_cameraEngine->Camera();
+ TSize imageSize;
+ if (camera) {
+ for (int i = 0; i < m_cameraInfo->iNumImageSizesSupported; i++) {
+ camera->EnumerateCaptureSizes(imageSize, i, format);
+ list << QSize(imageSize.iWidth, imageSize.iHeight); // Add resolution to the list
+ }
+ }
+ }
+
+#ifdef Q_CC_NOKIAX86 // Emulator
+ // Add some for testing purposes
+ list << QSize(50, 50);
+ list << QSize(100, 100);
+ list << QSize(800,600);
+#endif
+
+ return list;
+}
+
+QMap<QString, int> S60ImageCaptureSession::formatMap()
+{
+ QMap<QString, int> formats;
+
+ // Format list copied from CCamera::TFormat (in ecam.h)
+ formats.insert("Monochrome", 0x0001);
+ formats.insert("16bitRGB444", 0x0002);
+ formats.insert("16BitRGB565", 0x0004);
+ formats.insert("32BitRGB888", 0x0008);
+ formats.insert("Jpeg", 0x0010);
+ formats.insert("Exif", 0x0020);
+ formats.insert("FbsBitmapColor4K", 0x0040);
+ formats.insert("FbsBitmapColor64K", 0x0080);
+ formats.insert("FbsBitmapColor16M", 0x0100);
+ formats.insert("UserDefined", 0x0200);
+ formats.insert("YUV420Interleaved", 0x0400);
+ formats.insert("YUV420Planar", 0x0800);
+ formats.insert("YUV422", 0x1000);
+ formats.insert("YUV422Reversed", 0x2000);
+ formats.insert("YUV444", 0x4000);
+ formats.insert("YUV420SemiPlanar", 0x8000);
+ formats.insert("FbsBitmapColor16MU", 0x00010000);
+ formats.insert("MJPEG", 0x00020000);
+ formats.insert("EncodedH264", 0x00040000);
+
+ return formats;
+}
+
+QMap<QString, QString> S60ImageCaptureSession::codecDescriptionMap()
+{
+ QMap<QString, QString> formats;
+
+ formats.insert("image/jpg", "JPEG image codec");
+
+ return formats;
+}
+
+QStringList S60ImageCaptureSession::supportedImageCaptureCodecs()
+{
+#ifdef Q_CC_NOKIAX86 // Emulator
+ return formatMap().keys();
+#endif
+
+ return m_supportedImageCodecs;
+}
+
+void S60ImageCaptureSession::updateImageCaptureFormats()
+{
+ m_formats.clear();
+ if (m_cameraEngine && queryCurrentCameraInfo()) {
+ TUint32 supportedFormats = m_cameraInfo->iImageFormatsSupported;
+
+#ifdef S60_3X_PLATFORM // S60 3.1 & 3.2
+ int maskEnd = CCamera::EFormatFbsBitmapColor16MU;
+#else // S60 5.0 or later
+ int maskEnd = CCamera::EFormatEncodedH264;
+#endif // S60_3X_PLATFORM
+
+ for (int mask = CCamera::EFormatMonochrome; mask <= maskEnd; mask <<= 1) {
+ if (supportedFormats & mask)
+ m_formats << mask; // Store mask of supported format
+ }
+ }
+}
+
+QString S60ImageCaptureSession::imageCaptureCodec()
+{
+ return m_currentCodec;
+}
+void S60ImageCaptureSession::setImageCaptureCodec(const QString &codecName)
+{
+ if (!codecName.isEmpty()) {
+ if (supportedImageCaptureCodecs().contains(codecName, Qt::CaseInsensitive) ||
+ codecName == "image/jpg") {
+ m_currentCodec = codecName;
+ m_currentFormat = selectFormatForCodec(m_currentCodec);
+ } else {
+ setError(KErrNotSupported, tr("Requested image codec is not supported"));
+ }
+ } else {
+ m_currentCodec = KDefaultImageCodec;
+ m_currentFormat = selectFormatForCodec(m_currentCodec);
+ }
+}
+
+QString S60ImageCaptureSession::imageCaptureCodecDescription(const QString &codecName)
+{
+ QString description = codecDescriptionMap().value(codecName);
+ return description;
+}
+
+QtMultimediaKit::EncodingQuality S60ImageCaptureSession::captureQuality() const
+{
+ switch (m_symbianImageQuality) {
+ case KJpegQualityVeryLow:
+ return QtMultimediaKit::VeryLowQuality;
+ case KJpegQualityLow:
+ return QtMultimediaKit::LowQuality;
+ case KJpegQualityNormal:
+ return QtMultimediaKit::NormalQuality;
+ case KJpegQualityHigh:
+ return QtMultimediaKit::HighQuality;
+ case KJpegQualityVeryHigh:
+ return QtMultimediaKit::VeryHighQuality;
+
+ default:
+ // Return normal as default
+ return QtMultimediaKit::NormalQuality;
+ }
+}
+
+void S60ImageCaptureSession::setCaptureQuality(const QtMultimediaKit::EncodingQuality &quality)
+{
+ // Use sensible presets
+ switch (quality) {
+ case QtMultimediaKit::VeryLowQuality:
+ m_symbianImageQuality = KJpegQualityVeryLow;
+ break;
+ case QtMultimediaKit::LowQuality:
+ m_symbianImageQuality = KJpegQualityLow;
+ break;
+ case QtMultimediaKit::NormalQuality:
+ m_symbianImageQuality = KJpegQualityNormal;
+ break;
+ case QtMultimediaKit::HighQuality:
+ m_symbianImageQuality = KJpegQualityHigh;
+ break;
+ case QtMultimediaKit::VeryHighQuality:
+ m_symbianImageQuality = KJpegQualityVeryHigh;
+ break;
+
+ default:
+ m_symbianImageQuality = quality * KSymbianImageQualityCoefficient;
+ break;
+ }
+}
+
+qreal S60ImageCaptureSession::maximumZoom()
+{
+ qreal maxZoomFactor = 1.0;
+
+ if (queryCurrentCameraInfo()) {
+ maxZoomFactor = m_cameraInfo->iMaxZoomFactor;
+
+ if (maxZoomFactor == 0.0 || maxZoomFactor == 1.0) {
+ return 1.0; // Not supported
+ } else {
+ return maxZoomFactor;
+ }
+ } else {
+ return 1.0;
+ }
+}
+
+qreal S60ImageCaptureSession::minZoom()
+{
+ qreal minZoomValue = 1.0;
+
+ if (queryCurrentCameraInfo()) {
+ minZoomValue = m_cameraInfo->iMinZoomFactor;
+ if (minZoomValue == 0.0 || minZoomValue == 1.0)
+ return 1.0; // Macro Zoom is not supported
+ else {
+ return minZoomValue;
+ }
+
+ } else {
+ return 1.0;
+ }
+}
+
+qreal S60ImageCaptureSession::maxDigitalZoom()
+{
+ qreal maxDigitalZoomFactor = 1.0;
+
+ if (queryCurrentCameraInfo()) {
+ maxDigitalZoomFactor = m_cameraInfo->iMaxDigitalZoomFactor;
+ return maxDigitalZoomFactor;
+ } else {
+ return 1.0;
+ }
+}
+
+void S60ImageCaptureSession::doSetZoomFactorL(qreal optical, qreal digital)
+{
+#if !defined(USE_S60_32_ECAM_ADVANCED_SETTINGS_HEADER) & !defined(USE_S60_50_ECAM_ADVANCED_SETTINGS_HEADER)
+ // Convert Zoom Factor to Zoom Value if AdvSettings are not available
+ int digitalSymbian = (digital * m_cameraInfo->iMaxDigitalZoom) / maxDigitalZoom();
+ if (m_cameraInfo->iMaxDigitalZoom != 0 && digital == 1.0)
+ digitalSymbian = 1; // Make sure zooming out to initial value if requested
+#endif // !USE_S60_32_ECAM_ADVANCED_SETTINGS_HEADER & !USE_S60_50_ECAM_ADVANCED_SETTINGS_HEADER
+
+ if (m_cameraEngine && !m_cameraEngine->IsCameraReady())
+ return;
+
+ if (m_cameraEngine && queryCurrentCameraInfo()) {
+ CCamera *camera = m_cameraEngine->Camera();
+ if (camera) {
+
+ // Optical Zoom
+ if (!qFuzzyCompare(optical, qreal(1.0)) && !qFuzzyCompare(optical, qreal(0.0))) {
+ setError(KErrNotSupported, tr("Requested optical zoom factor is not supported."));
+ return;
+ }
+
+ // Digital Zoom (Smooth Zoom - Zoom value set in steps)
+ if (digital != digitalZoomFactor()) {
+ if ((digital > 1.0 || qFuzzyCompare(digital, qreal(1.0))) &&
+ digital <= m_cameraInfo->iMaxDigitalZoomFactor) {
+#if defined(USE_S60_32_ECAM_ADVANCED_SETTINGS_HEADER) | defined(USE_S60_50_ECAM_ADVANCED_SETTINGS_HEADER)
+ if (m_advancedSettings) {
+ qreal currentZoomFactor = m_advancedSettings->digitalZoomFactorL();
+
+ QList<qreal> smoothZoomSetValues;
+ QList<qreal> factors = m_advancedSettings->supportedDigitalZoomFactors();
+ if (currentZoomFactor < digital) {
+ for (int i = 0; i < factors.count(); ++i) {
+ if (factors.at(i) > currentZoomFactor && factors.at(i) < digital)
+ smoothZoomSetValues << factors.at(i);
+ }
+
+ for (int i = 0; i < smoothZoomSetValues.count(); i = i + KSmoothZoomStep) {
+ m_advancedSettings->setDigitalZoomFactorL(smoothZoomSetValues[i]); // Using Zoom Factor
+ }
+
+ } else {
+ for (int i = 0; i < factors.count(); ++i) {
+ if (factors.at(i) < currentZoomFactor && factors.at(i) > digital)
+ smoothZoomSetValues << factors.at(i);
+ }
+
+ for (int i = (smoothZoomSetValues.count() - 1); i >= 0; i = i - KSmoothZoomStep) {
+ m_advancedSettings->setDigitalZoomFactorL(smoothZoomSetValues[i]); // Using Zoom Factor
+ }
+ }
+
+ // Set final value
+ m_advancedSettings->setDigitalZoomFactorL(digital);
+ }
+ else
+ setError(KErrNotReady, tr("Zooming failed."));
+#else // No advanced settigns
+ // Define zoom steps
+ int currentZoomFactor = camera->DigitalZoomFactor();
+ int difference = abs(currentZoomFactor - digitalSymbian);
+ int midZoomValue = currentZoomFactor;
+
+ if (currentZoomFactor < digitalSymbian) {
+ while (midZoomValue < (digitalSymbian - KSmoothZoomStep)) {
+ midZoomValue = midZoomValue + KSmoothZoomStep;
+ camera->SetDigitalZoomFactorL(midZoomValue);
+ }
+ } else {
+ while (midZoomValue > (digitalSymbian + KSmoothZoomStep)) {
+ midZoomValue = midZoomValue - KSmoothZoomStep;
+ camera->SetDigitalZoomFactorL(midZoomValue);
+ }
+ }
+
+ // Set final and emit signal
+ camera->SetDigitalZoomFactorL(digitalSymbian);
+#endif // USE_S60_32_ECAM_ADVANCED_SETTINGS_HEADER | USE_S60_50_ECAM_ADVANCED_SETTINGS_HEADER
+ } else {
+ setError(KErrNotSupported, tr("Requested digital zoom factor is not supported."));
+ return;
+ }
+ }
+ }
+ } else {
+ setError(KErrGeneral, tr("Unexpected camera error."));
+ }
+}
+
+qreal S60ImageCaptureSession::opticalZoomFactor()
+{
+ qreal factor = 1.0;
+
+#if defined(USE_S60_32_ECAM_ADVANCED_SETTINGS_HEADER) | defined(USE_S60_50_ECAM_ADVANCED_SETTINGS_HEADER)
+ if (m_advancedSettings) {
+ TRAPD(err, factor = m_advancedSettings->opticalZoomFactorL());
+ if (err)
+ return 1.0;
+ }
+#else // No advanced settigns
+ if (m_cameraEngine && m_cameraInfo) {
+ if (m_cameraEngine->Camera()) {
+ if (m_cameraInfo->iMaxZoom != 0)
+ factor = (m_cameraEngine->Camera()->ZoomFactor()* maximumZoom()) / m_cameraInfo->iMaxZoom;
+ else
+ factor = 1.0;
+ }
+ }
+#endif // USE_S60_32_ECAM_ADVANCED_SETTINGS_HEADER | USE_S60_50_ECAM_ADVANCED_SETTINGS_HEADER
+
+ if (factor == 0.0) // If not supported
+ factor = 1.0;
+
+ return factor;
+}
+
+qreal S60ImageCaptureSession::digitalZoomFactor()
+{
+ qreal factor = 1.0;
+
+#if defined(USE_S60_32_ECAM_ADVANCED_SETTINGS_HEADER) | defined(USE_S60_50_ECAM_ADVANCED_SETTINGS_HEADER)
+ if (m_advancedSettings) {
+ TRAPD(err, factor = m_advancedSettings->digitalZoomFactorL());
+ if (err)
+ return 1.0;
+ }
+#else // No advanced settigns
+ if (m_cameraEngine && m_cameraInfo) {
+ if (m_cameraEngine->Camera()) {
+ if (m_cameraInfo->iMaxDigitalZoom != 0)
+ factor = (m_cameraEngine->Camera()->DigitalZoomFactor()* maxDigitalZoom()) / m_cameraInfo->iMaxDigitalZoom;
+ else
+ factor = 1.0;
+ }
+ }
+#endif // USE_S60_32_ECAM_ADVANCED_SETTINGS_HEADER | USE_S60_50_ECAM_ADVANCED_SETTINGS_HEADER
+
+ if (factor == 0.0)
+ factor = 1.0;
+
+ return factor;
+}
+
+void S60ImageCaptureSession::setFlashMode(QCameraExposure::FlashModes mode)
+{
+ TRAPD(err, doSetFlashModeL(mode));
+ setError(err, tr("Failed to set flash mode."));
+}
+
+void S60ImageCaptureSession::doSetFlashModeL(QCameraExposure::FlashModes mode)
+{
+ if (m_cameraEngine && m_cameraEngine->Camera()) {
+ CCamera *camera = m_cameraEngine->Camera();
+ switch(mode) {
+ case QCameraExposure::FlashOff:
+ camera->SetFlashL(CCamera::EFlashNone);
+ break;
+ case QCameraExposure::FlashAuto:
+ camera->SetFlashL(CCamera::EFlashAuto);
+ break;
+ case QCameraExposure::FlashOn:
+ camera->SetFlashL(CCamera::EFlashForced);
+ break;
+ case QCameraExposure::FlashRedEyeReduction:
+ camera->SetFlashL(CCamera::EFlashRedEyeReduce);
+ break;
+ case QCameraExposure::FlashFill:
+ camera->SetFlashL(CCamera::EFlashFillIn);
+ break;
+
+ default:
+ setError(KErrNotSupported, tr("Requested flash mode is not suported"));
+ break;
+ }
+ } else {
+ setError(KErrNotReady, tr("Unexpected camera error."));
+ }
+}
+
+QCameraExposure::FlashMode S60ImageCaptureSession::flashMode()
+{
+ if (m_cameraEngine && m_cameraEngine->Camera()) {
+ CCamera *camera = m_cameraEngine->Camera();
+ switch(camera->Flash()) {
+ case CCamera::EFlashAuto:
+ return QCameraExposure::FlashAuto;
+ case CCamera::EFlashForced:
+ return QCameraExposure::FlashOn;
+ case CCamera::EFlashRedEyeReduce:
+ return QCameraExposure::FlashRedEyeReduction;
+ case CCamera::EFlashFillIn:
+ return QCameraExposure::FlashFill;
+ case CCamera::EFlashNone:
+ return QCameraExposure::FlashOff;
+
+ default:
+ return QCameraExposure::FlashAuto; // Most probable default
+ }
+ } else {
+ setError(KErrNotReady, tr("Unexpected camera error."));
+ }
+
+ return QCameraExposure::FlashOff;
+}
+
+QCameraExposure::FlashModes S60ImageCaptureSession::supportedFlashModes()
+{
+ QCameraExposure::FlashModes modes = QCameraExposure::FlashOff;
+
+ if (queryCurrentCameraInfo()) {
+ TInt supportedModes = m_cameraInfo->iFlashModesSupported;
+
+ if (supportedModes == 0)
+ return modes;
+
+ if (supportedModes & CCamera::EFlashManual)
+ modes |= QCameraExposure::FlashOff;
+ if (supportedModes & CCamera::EFlashForced)
+ modes |= QCameraExposure::FlashOn;
+ if (supportedModes & CCamera::EFlashAuto)
+ modes |= QCameraExposure::FlashAuto;
+ if (supportedModes & CCamera::EFlashFillIn)
+ modes |= QCameraExposure::FlashFill;
+ if (supportedModes & CCamera::EFlashRedEyeReduce)
+ modes |= QCameraExposure::FlashRedEyeReduction;
+ }
+
+ return modes;
+}
+
+QCameraExposure::ExposureMode S60ImageCaptureSession::exposureMode()
+{
+ if (m_cameraEngine && m_cameraEngine->Camera()) {
+ CCamera* camera = m_cameraEngine->Camera();
+ switch(camera->Exposure()) {
+ case CCamera::EExposureManual:
+ return QCameraExposure::ExposureManual;
+ case CCamera::EExposureAuto:
+ return QCameraExposure::ExposureAuto;
+ case CCamera::EExposureNight:
+ return QCameraExposure::ExposureNight;
+ case CCamera::EExposureBacklight:
+ return QCameraExposure::ExposureBacklight;
+ case CCamera::EExposureSport:
+ return QCameraExposure::ExposureSports;
+ case CCamera::EExposureSnow:
+ return QCameraExposure::ExposureSnow;
+ case CCamera::EExposureBeach:
+ return QCameraExposure::ExposureBeach;
+
+ default:
+ return QCameraExposure::ExposureAuto;
+ }
+ }
+
+ return QCameraExposure::ExposureAuto;
+}
+
+bool S60ImageCaptureSession::isExposureModeSupported(QCameraExposure::ExposureMode mode) const
+{
+ TInt supportedModes = m_cameraInfo->iExposureModesSupported;
+
+ if (supportedModes == 0)
+ return false;
+
+ switch (mode) {
+ case QCameraExposure::ExposureManual:
+ if(supportedModes & CCamera::EExposureManual)
+ return true;
+ else
+ return false;
+ case QCameraExposure::ExposureAuto:
+ return true; // Always supported
+ case QCameraExposure::ExposureNight:
+ if(supportedModes & CCamera::EExposureNight)
+ return true;
+ else
+ return false;
+ case QCameraExposure::ExposureBacklight:
+ if(supportedModes & CCamera::EExposureBacklight)
+ return true;
+ else
+ return false;
+ case QCameraExposure::ExposureSports:
+ if(supportedModes & CCamera::EExposureSport)
+ return true;
+ else
+ return false;
+ case QCameraExposure::ExposureSnow:
+ if(supportedModes & CCamera::EExposureSnow)
+ return true;
+ else
+ return false;
+ case QCameraExposure::ExposureBeach:
+ if(supportedModes & CCamera::EExposureBeach)
+ return true;
+ else
+ return false;
+
+ default:
+ return false;
+ }
+}
+
+void S60ImageCaptureSession::setExposureMode(QCameraExposure::ExposureMode mode)
+{
+ TRAPD(err, doSetExposureModeL(mode));
+ setError(err, tr("Failed to set exposure mode."));
+}
+
+void S60ImageCaptureSession::doSetExposureModeL( QCameraExposure::ExposureMode mode)
+{
+ if (m_cameraEngine && m_cameraEngine->Camera()) {
+ CCamera *camera = m_cameraEngine->Camera();
+ switch(mode) {
+ case QCameraExposure::ExposureManual:
+ camera->SetExposureL(CCamera::EExposureManual);
+ break;
+ case QCameraExposure::ExposureAuto:
+ camera->SetExposureL(CCamera::EExposureAuto);
+ break;
+ case QCameraExposure::ExposureNight:
+ camera->SetExposureL(CCamera::EExposureNight);
+ break;
+ case QCameraExposure::ExposureBacklight:
+ camera->SetExposureL(CCamera::EExposureBacklight);
+ break;
+ case QCameraExposure::ExposureSports:
+ camera->SetExposureL(CCamera::EExposureSport);
+ break;
+ case QCameraExposure::ExposureSnow:
+ camera->SetExposureL(CCamera::EExposureSnow);
+ break;
+ case QCameraExposure::ExposureBeach:
+ camera->SetExposureL(CCamera::EExposureBeach);
+ break;
+ case QCameraExposure::ExposureLargeAperture:
+ case QCameraExposure::ExposureSmallAperture:
+ break;
+ case QCameraExposure::ExposurePortrait:
+ case QCameraExposure::ExposureSpotlight:
+ default:
+ setError(KErrNotSupported, tr("Requested exposure mode is not suported"));
+ break;
+ }
+ } else {
+ setError(KErrNotReady, tr("Unexpected camera error."));
+ }
+}
+
+int S60ImageCaptureSession::contrast() const
+{
+ if (m_cameraEngine && m_cameraEngine->Camera()) {
+ return m_cameraEngine->Camera()->Contrast();
+ } else {
+ return 0;
+ }
+}
+
+void S60ImageCaptureSession::setContrast(int value)
+{
+ if (m_cameraEngine && m_cameraEngine->Camera()) {
+ TRAPD(err, m_cameraEngine->Camera()->SetContrastL(value));
+ setError(err, tr("Failed to set contrast."));
+ } else {
+ setError(KErrNotReady, tr("Unexpected camera error."));
+ }
+}
+
+int S60ImageCaptureSession::brightness() const
+{
+ if (m_cameraEngine && m_cameraEngine->Camera()) {
+ return m_cameraEngine->Camera()->Brightness();
+ } else {
+ return 0;
+ }
+}
+
+void S60ImageCaptureSession::setBrightness(int value)
+{
+ if (m_cameraEngine && m_cameraEngine->Camera()) {
+ TRAPD(err, m_cameraEngine->Camera()->SetBrightnessL(value));
+ setError(err, tr("Failed to set brightness."));
+ } else {
+ setError(KErrNotReady, tr("Unexpected camera error."));
+ }
+}
+
+ QCameraImageProcessing::WhiteBalanceMode S60ImageCaptureSession::whiteBalanceMode()
+{
+ if (m_cameraEngine && m_cameraEngine->Camera()) {
+ CCamera::TWhiteBalance mode = m_cameraEngine->Camera()->WhiteBalance();
+ switch(mode) {
+ case CCamera::EWBAuto:
+ return QCameraImageProcessing::WhiteBalanceAuto;
+ case CCamera::EWBDaylight:
+ return QCameraImageProcessing::WhiteBalanceSunlight;
+ case CCamera::EWBCloudy:
+ return QCameraImageProcessing::WhiteBalanceCloudy;
+ case CCamera::EWBTungsten:
+ return QCameraImageProcessing::WhiteBalanceTungsten;
+ case CCamera::EWBFluorescent:
+ return QCameraImageProcessing::WhiteBalanceFluorescent;
+ case CCamera::EWBFlash:
+ return QCameraImageProcessing::WhiteBalanceFlash;
+ case CCamera::EWBBeach:
+ return QCameraImageProcessing::WhiteBalanceSunset;
+ case CCamera::EWBManual:
+ return QCameraImageProcessing::WhiteBalanceManual;
+ case CCamera::EWBShade:
+ return QCameraImageProcessing::WhiteBalanceShade;
+
+ default:
+ return QCameraImageProcessing::WhiteBalanceAuto;
+ }
+ }
+
+ return QCameraImageProcessing::WhiteBalanceAuto;
+}
+
+void S60ImageCaptureSession::setWhiteBalanceMode( QCameraImageProcessing::WhiteBalanceMode mode)
+{
+ TRAPD(err, doSetWhiteBalanceModeL(mode));
+ setError(err, tr("Failed to set white balance mode."));
+}
+
+void S60ImageCaptureSession::doSetWhiteBalanceModeL( QCameraImageProcessing::WhiteBalanceMode mode)
+{
+ if (m_cameraEngine && m_cameraEngine->Camera()) {
+ CCamera* camera = m_cameraEngine->Camera();
+ switch(mode) {
+ case QCameraImageProcessing::WhiteBalanceAuto:
+ camera->SetWhiteBalanceL(CCamera::EWBAuto);
+ break;
+ case QCameraImageProcessing::WhiteBalanceSunlight:
+ camera->SetWhiteBalanceL(CCamera::EWBDaylight);
+ break;
+ case QCameraImageProcessing::WhiteBalanceCloudy:
+ camera->SetWhiteBalanceL(CCamera::EWBCloudy);
+ break;
+ case QCameraImageProcessing::WhiteBalanceTungsten:
+ camera->SetWhiteBalanceL(CCamera::EWBTungsten);
+ break;
+ case QCameraImageProcessing::WhiteBalanceFluorescent:
+ camera->SetWhiteBalanceL(CCamera::EWBFluorescent);
+ break;
+ case QCameraImageProcessing::WhiteBalanceFlash:
+ camera->SetWhiteBalanceL(CCamera::EWBFlash);
+ break;
+ case QCameraImageProcessing::WhiteBalanceSunset:
+ camera->SetWhiteBalanceL(CCamera::EWBBeach);
+ break;
+ case QCameraImageProcessing::WhiteBalanceManual:
+ camera->SetWhiteBalanceL(CCamera::EWBManual);
+ break;
+ case QCameraImageProcessing::WhiteBalanceShade:
+ camera->SetWhiteBalanceL(CCamera::EWBShade);
+ break;
+
+ default:
+ setError(KErrNotSupported, tr("Requested white balance mode is not suported"));
+ break;
+ }
+ } else {
+ setError(KErrNotReady, tr("Unexpected camera error."));
+ }
+}
+
+bool S60ImageCaptureSession::isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const
+{
+ if (m_cameraEngine) {
+ TInt supportedModes = m_cameraInfo->iWhiteBalanceModesSupported;
+ switch (mode) {
+ case QCameraImageProcessing::WhiteBalanceManual:
+ if (supportedModes & CCamera::EWBManual)
+ return true;
+ else
+ return false;
+ case QCameraImageProcessing::WhiteBalanceAuto:
+ if (supportedModes & CCamera::EWBAuto)
+ return true;
+ else
+ return false;
+ case QCameraImageProcessing::WhiteBalanceSunlight:
+ if (supportedModes & CCamera::EWBDaylight)
+ return true;
+ else
+ return false;
+ case QCameraImageProcessing::WhiteBalanceCloudy:
+ if (supportedModes & CCamera::EWBCloudy)
+ return true;
+ else
+ return false;
+ case QCameraImageProcessing::WhiteBalanceShade:
+ if (supportedModes & CCamera::EWBShade)
+ return true;
+ else
+ return false;
+ case QCameraImageProcessing::WhiteBalanceTungsten:
+ if (supportedModes & CCamera::EWBTungsten)
+ return true;
+ else
+ return false;
+ case QCameraImageProcessing::WhiteBalanceFluorescent:
+ if (supportedModes & CCamera::EWBFluorescent)
+ return true;
+ else
+ return false;
+ case QCameraImageProcessing::WhiteBalanceIncandescent: // Not available in Symbian
+ return false;
+ case QCameraImageProcessing::WhiteBalanceFlash:
+ if (supportedModes & CCamera::EWBFlash)
+ return true;
+ else
+ return false;
+ case QCameraImageProcessing::WhiteBalanceSunset:
+ if (supportedModes & CCamera::EWBBeach)
+ return true;
+ else
+ return false;
+
+ default:
+ return false;
+ }
+ }
+
+ return false;
+}
+
+/*
+ * ====================
+ * S60 3.1 AutoFocosing
+ * ====================
+ */
+bool S60ImageCaptureSession::isFocusSupported() const
+{
+ return m_cameraEngine->IsAutoFocusSupported();
+}
+
+void S60ImageCaptureSession::startFocus()
+{
+ if (m_cameraEngine) {
+ TRAPD(err, m_cameraEngine->StartFocusL());
+ setError(err, tr("Failed to start focusing."));
+ }
+ else
+ setError(KErrNotReady, tr("Unexpected camera error."));
+}
+
+void S60ImageCaptureSession::cancelFocus()
+{
+ if (m_cameraEngine) {
+ TRAPD(err, m_cameraEngine->FocusCancel());
+ setError(err, tr("Failed to cancel focusing."));
+ }
+ else
+ setError(KErrNotReady, tr("Unexpected camera error."));
+}
+
+void S60ImageCaptureSession::handleImageDecoded(int error)
+{
+ // Delete unneeded objects
+ if (m_imageDecoder) {
+ delete m_imageDecoder;
+ m_imageDecoder = 0;
+ }
+ if (m_fileSystemAccess) {
+ m_fileSystemAccess->Close();
+ delete m_fileSystemAccess;
+ m_fileSystemAccess = 0;
+ }
+
+ // Check status of decoding
+ if (error != KErrNone) {
+ if (m_previewBitmap) {
+ m_previewBitmap->Reset();
+ delete m_previewBitmap;
+ m_previewBitmap = 0;
+ }
+ releaseImageBuffer();
+ if (m_previewInWaitLoop) {
+ CActiveScheduler::Stop(); // Notify to continue execution of next Preview Image generation
+ m_previewInWaitLoop = false; // Reset
+ }
+ setError(error, tr("Preview creation failed."));
+ return;
+ }
+
+ m_previewDecodingOngoing = false;
+
+ QPixmap prevPixmap = QPixmap::fromSymbianCFbsBitmap(m_previewBitmap);
+ QImage preview = prevPixmap.toImage();
+
+ if (m_previewBitmap) {
+ m_previewBitmap->Reset();
+ delete m_previewBitmap;
+ m_previewBitmap = 0;
+ }
+
+ QT_TRYCATCH_LEAVING( emit imageCaptured(m_currentImageId, preview) );
+
+ // Release image resources (if not already done)
+ releaseImageBuffer();
+
+ if (m_previewInWaitLoop) {
+ CActiveScheduler::Stop(); // Notify to continue execution of next Preview Image generation
+ m_previewInWaitLoop = false; // Reset
+ }
+}
+
+void S60ImageCaptureSession::handleImageEncoded(int error)
+{
+ // Check status of encoding
+ if (error != KErrNone) {
+ releaseImageBuffer();
+ if (m_previewInWaitLoop) {
+ CActiveScheduler::Stop(); // Notify to continue execution of next Preview Image generation
+ m_previewInWaitLoop = false; // Reset
+ }
+ setError(error, tr("Saving captured image to file failed."));
+ return;
+ } else {
+ QT_TRYCATCH_LEAVING( emit imageSaved(m_currentImageId, m_stillCaptureFileName) );
+ }
+
+ if (m_imageEncoder) {
+ delete m_imageEncoder;
+ m_imageEncoder = 0;
+ }
+
+#ifndef ECAM_PREVIEW_API
+ // Start preview generation
+ TInt previewError = KErrNone;
+ TFileName fileName = convertImagePath();
+ TRAP(previewError, m_imageDecoder = S60ImageCaptureDecoder::FileNewL(this, m_fileSystemAccess, &fileName));
+ if (previewError) {
+ setError(previewError, tr("Failed to create preview image."));
+ return;
+ }
+
+ // Set proper Preview Size
+ TSize scaledSize((m_captureSize.width() / KSnapshotDownScaleFactor), (m_captureSize.height() / KSnapshotDownScaleFactor));
+ if (scaledSize.iWidth < KSnapshotMinWidth || scaledSize.iHeight < KSnapshotMinHeight)
+ scaledSize.SetSize((m_captureSize.width() / (KSnapshotDownScaleFactor/2)), (m_captureSize.height() / (KSnapshotDownScaleFactor/2)));
+ if (scaledSize.iWidth < KSnapshotMinWidth || scaledSize.iHeight < KSnapshotMinHeight)
+ scaledSize.SetSize((m_captureSize.width() / (KSnapshotDownScaleFactor/4)), (m_captureSize.height() / (KSnapshotDownScaleFactor/4)));
+ if (scaledSize.iWidth < KSnapshotMinWidth || scaledSize.iHeight < KSnapshotMinHeight)
+ scaledSize.SetSize(m_captureSize.width(), m_captureSize.height());
+
+ TFrameInfo *info = m_imageDecoder->frameInfo();
+ if (!info) {
+ setError(KErrGeneral, tr("Preview image creation failed."));
+ return;
+ }
+
+ m_previewBitmap = new CFbsBitmap;
+ if (!m_previewBitmap) {
+ setError(KErrNoMemory, tr("Failed to create preview image."));
+ return;
+ }
+ previewError = m_previewBitmap->Create(scaledSize, info->iFrameDisplayMode);
+ if (previewError) {
+ setError(previewError, tr("Preview creation failed."));
+ return;
+ }
+
+ // Jpeg decoding completes in handleImageDecoded()
+ m_imageDecoder->decode(m_previewBitmap);
+#endif // ECAM_PREVIEW_API
+
+ // Buffer can be released since Preview is created from file
+ releaseImageBuffer();
+
+ // Inform that we can continue taking more pictures
+ QT_TRYCATCH_LEAVING( emit readyForCaptureChanged(true) );
+}
+
+#ifdef ECAM_PREVIEW_API
+void S60ImageCaptureSession::MceoPreviewReady(CFbsBitmap& aPreview)
+{
+ QPixmap previewPixmap = QPixmap::fromSymbianCFbsBitmap(&aPreview);
+ QImage preview = previewPixmap.toImage();
+
+ // Notify preview availability
+ emit imageCaptured(m_currentImageId, preview);
+}
+#endif // ECAM_PREVIEW_API
+
+// End of file
+
diff --git a/src/plugins/symbian/ecam/s60imagecapturesession.h b/src/plugins/symbian/ecam/s60imagecapturesession.h
new file mode 100644
index 000000000..9cae05fc9
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60imagecapturesession.h
@@ -0,0 +1,359 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60IMAGECAPTURESESSION_H
+#define S60IMAGECAPTURESESSION_H
+
+#include <QtCore/qurl.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qmap.h>
+#include <QtGui/qicon.h>
+
+#include <qcamera.h>
+#include <qcamerafocus.h>
+#include <qcameraimagecapture.h>
+#include <qvideoframe.h>
+
+#include "s60camerasettings.h"
+#include "s60cameraengine.h"
+#include "s60cameraengineobserver.h"
+#include "s60cameraconstants.h" // Default Jpeg Quality
+
+#include <icl/imagedata.h> // TFrameInfo
+
+QT_USE_NAMESPACE
+
+class S60CameraService;
+class CImageDecoder;
+class CImageEncoder;
+class CFrameImageData;
+class RFs;
+class S60ImageCaptureSession;
+
+/*
+ * This class implements asynchronous image decoding service for the
+ * S60ImageCaptureSession.
+ */
+class S60ImageCaptureDecoder : public CActive
+{
+public: // Static Contructor & Destructor
+
+ static S60ImageCaptureDecoder* FileNewL(S60ImageCaptureSession *imageSession = 0,
+ RFs *fileSystemAccess = 0,
+ const TDesC16 *fileName = 0);
+ static S60ImageCaptureDecoder* DataNewL(S60ImageCaptureSession *imageSession = 0,
+ RFs *fileSystemAccess = 0,
+ const TDesC8 *data = 0);
+ ~S60ImageCaptureDecoder();
+
+public: // Operations
+
+ void decode(CFbsBitmap *destBitmap);
+ TFrameInfo *frameInfo();
+
+protected: // CActive
+
+ void RunL();
+ void DoCancel();
+ TInt RunError(TInt aError);
+
+protected: // Protected constructors
+
+ S60ImageCaptureDecoder(S60ImageCaptureSession *imageSession,
+ RFs *fileSystemAccess,
+ const TDesC8 *data,
+ const TDesC16 *fileName);
+ void ConstructL(const bool fileInput = false);
+
+private: // Data
+
+ S60ImageCaptureSession *m_imageSession;
+ CImageDecoder *m_imageDecoder;
+ RFs *m_fs;
+ const TDesC8 *m_jpegImageData;
+ const TDesC16 *m_jpegImageFile;
+ bool m_fileInput;
+ TFrameInfo m_frameInfo;
+
+};
+
+//=============================================================================
+
+/*
+ * This class implements asynchronous image encoding service for the
+ * S60ImageCaptureSession.
+ */
+class S60ImageCaptureEncoder : public CActive
+{
+public: // Static Contructor & Destructor
+
+ static S60ImageCaptureEncoder* NewL(S60ImageCaptureSession *imageSession = 0,
+ RFs *fileSystemAccess = 0,
+ const TDesC16 *fileName = 0,
+ TInt jpegQuality = KDefaultImageQuality);
+ ~S60ImageCaptureEncoder();
+
+public: // Operations
+
+ void encode(CFbsBitmap *sourceBitmap);
+
+protected: // CActive
+
+ void RunL();
+ void DoCancel();
+ TInt RunError(TInt aError);
+
+protected: // Protected constructors
+
+ S60ImageCaptureEncoder(S60ImageCaptureSession *imageSession,
+ RFs *fileSystemAccess,
+ const TDesC16 *fileName,
+ TInt jpegQuality);
+ void ConstructL();
+
+private: // Data
+
+ S60ImageCaptureSession *m_imageSession;
+ CImageEncoder *m_imageEncoder;
+ RFs *m_fileSystemAccess;
+ const TDesC16 *m_fileName;
+ CFrameImageData *m_frameImageData;
+ TInt m_jpegQuality;
+
+};
+
+//=============================================================================
+
+/*
+ * Session handling all image capture activities.
+ */
+class S60ImageCaptureSession : public QObject,
+#ifdef ECAM_PREVIEW_API
+ public MCameraPreviewObserver,
+#endif // ECAM_PREVIEW_API
+ public MCameraEngineImageCaptureObserver
+{
+ Q_OBJECT
+
+public: // Enums
+
+ enum ImageCaptureState {
+ EImageCaptureNotPrepared = 0, // 0 - ImageCapture has not been prepared
+ EImageCapturePrepared, // 1 - ImageCapture has been prepared
+ EImageCaptureCapturing, // 2 - Image capture ongoing
+ EImageCaptureWritingImage // 3 - Image captured and image writing to file ongoing
+ };
+
+public: // Constructor & Destructor
+
+ S60ImageCaptureSession(QObject *parent = 0);
+ ~S60ImageCaptureSession();
+
+public: // Methods
+
+ void setError(const TInt error, const QString &description, const bool captureError = false);
+ int currentImageId() const;
+
+ bool isDeviceReady();
+ void setCameraHandle(CCameraEngine* camerahandle);
+ void setCurrentDevice(TInt deviceindex);
+ void notifySettingsSet();
+
+ // Ecam Advanced Settings
+ S60CameraSettings* advancedSettings();
+ void deleteAdvancedSettings();
+
+ // Controls
+ int prepareImageCapture();
+ void releaseImageCapture();
+ int capture(const QString &fileName);
+ void cancelCapture();
+ void releaseImageBuffer();
+
+ // Image Resolution
+ QSize captureSize() const;
+ QSize minimumCaptureSize();
+ QSize maximumCaptureSize();
+ QList<QSize> supportedCaptureSizesForCodec(const QString &codecName);
+ void setCaptureSize(const QSize &size);
+
+ // Image Codec
+ QStringList supportedImageCaptureCodecs();
+ QString imageCaptureCodec();
+ void setImageCaptureCodec(const QString &codecName);
+ QString imageCaptureCodecDescription(const QString &codecName);
+
+ // Image Quality
+ QtMultimediaKit::EncodingQuality captureQuality() const;
+ void setCaptureQuality(const QtMultimediaKit::EncodingQuality &quality);
+
+ // S60 3.1 Focus Control (S60 3.2 and later via S60CameraSettings class)
+ bool isFocusSupported() const;
+ void startFocus();
+ void cancelFocus();
+
+ // Zoom Control
+ qreal maximumZoom();
+ qreal minZoom();
+ qreal maxDigitalZoom();
+ void doSetZoomFactorL(qreal optical, qreal digital);
+ qreal opticalZoomFactor();
+ qreal digitalZoomFactor();
+
+ // Exposure Mode Control
+ QCameraExposure::ExposureMode exposureMode();
+ void setExposureMode(QCameraExposure::ExposureMode mode);
+ bool isExposureModeSupported(QCameraExposure::ExposureMode mode) const;
+
+ // Flash Mode Control
+ QCameraExposure::FlashMode flashMode();
+ void setFlashMode(QCameraExposure::FlashModes mode);
+ QCameraExposure::FlashModes supportedFlashModes();
+
+ // Contrast Control
+ int contrast() const;
+ void setContrast(int value);
+
+ // Brightness Control
+ int brightness() const;
+ void setBrightness(int value);
+
+ // White Balance Mode Control
+ QCameraImageProcessing::WhiteBalanceMode whiteBalanceMode();
+ void setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode);
+ bool isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const;
+
+public: // Image Decoding & Encoding Notifications
+
+ void handleImageDecoded(int error);
+ void handleImageEncoded(int error);
+
+protected: // MCameraEngineObserver
+
+ void MceoFocusComplete();
+ void MceoCapturedDataReady(TDesC8* aData);
+ void MceoCapturedBitmapReady(CFbsBitmap* aBitmap);
+ void MceoHandleError(TCameraEngineError aErrorType, TInt aError);
+
+#ifdef ECAM_PREVIEW_API
+protected: // MCameraPreviewObserver
+
+ void MceoPreviewReady(CFbsBitmap& aPreview);
+#endif // ECAM_PREVIEW_API
+
+private: // Internal
+
+ QCameraImageCapture::Error fromSymbianErrorToQtMultimediaError(int aError);
+
+ void initializeImageCaptureSettings();
+ void resetSession(bool errorHandling = false);
+
+ CCamera::TFormat selectFormatForCodec(const QString &codec);
+ CCamera::TFormat defaultImageFormat();
+ bool queryCurrentCameraInfo();
+ QMap<QString, int> formatMap();
+ QMap<QString, QString> codecDescriptionMap();
+ void updateImageCaptureFormats();
+
+ void doSetWhiteBalanceModeL(QCameraImageProcessing::WhiteBalanceMode mode);
+
+ void doSetFlashModeL(QCameraExposure::FlashModes mode);
+ void doSetExposureModeL(QCameraExposure::ExposureMode mode);
+
+ void saveImageL(TDesC8 *aData, TFileName &aPath);
+ void processFileName(const QString &fileName);
+ TFileName convertImagePath();
+
+signals: // Notifications
+
+ void stateChanged(QCamera::State);
+ void advancedSettingChanged();
+ void captureSizeChanged(const QSize&);
+
+ // Error signals
+ void cameraError(int, const QString&); // For QCamera::error
+ void captureError(int, int, const QString&); // For QCameraImageCapture::error
+
+ // Capture notifications
+ void readyForCaptureChanged(bool);
+ void imageExposed(int);
+ void imageCaptured(const int, const QImage&);
+ void imageSaved(const int, const QString&);
+
+ // Focus notifications
+ void focusStatusChanged(QCamera::LockStatus, QCamera::LockChangeReason);
+
+private slots: // Internal Slots
+
+ void cameraStatusChanged(QCamera::Status);
+
+private: // Data
+
+ CCameraEngine *m_cameraEngine;
+ S60CameraSettings *m_advancedSettings;
+ mutable TCameraInfo *m_cameraInfo;
+ CFbsBitmap *m_previewBitmap;
+ CActiveScheduler *m_activeScheduler;
+ RFs *m_fileSystemAccess;
+ S60ImageCaptureDecoder *m_imageDecoder;
+ S60ImageCaptureEncoder *m_imageEncoder;
+ mutable int m_error; // Symbian ErrorCode
+ TInt m_activeDeviceIndex;
+ bool m_cameraStarted;
+ ImageCaptureState m_icState;
+ QStringList m_supportedImageCodecs;
+ QString m_currentCodec;
+ CCamera::TFormat m_currentFormat;
+ QSize m_captureSize;
+ int m_symbianImageQuality;
+ bool m_captureSettingsSet;
+ QString m_stillCaptureFileName;
+ QString m_requestedStillCaptureFileName;
+ mutable int m_currentImageId;
+ QList<uint> m_formats;
+ // This indicates that image capture should be triggered right after
+ // camera and image setting initialization has completed
+ bool m_captureWhenReady;
+ bool m_previewDecodingOngoing;
+ bool m_previewInWaitLoop;
+};
+
+#endif // S60IMAGECAPTURESESSION_H
diff --git a/src/plugins/symbian/ecam/s60imageencodercontrol.cpp b/src/plugins/symbian/ecam/s60imageencodercontrol.cpp
new file mode 100644
index 000000000..bfbf8d36b
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60imageencodercontrol.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+
+#include "s60imageencodercontrol.h"
+#include "s60imagecapturesession.h"
+
+S60ImageEncoderControl::S60ImageEncoderControl(QObject *parent) :
+ QImageEncoderControl(parent)
+{
+}
+
+S60ImageEncoderControl::S60ImageEncoderControl(S60ImageCaptureSession *session, QObject *parent) :
+ QImageEncoderControl(parent)
+{
+ m_session = session;
+}
+
+S60ImageEncoderControl::~S60ImageEncoderControl()
+{
+}
+
+QList<QSize> S60ImageEncoderControl::supportedResolutions(
+ const QImageEncoderSettings &settings, bool *continuous) const
+{
+ QList<QSize> resolutions = m_session->supportedCaptureSizesForCodec(settings.codec());
+
+ // Discrete resolutions are returned
+ if (continuous)
+ *continuous = false;
+
+ return resolutions;
+}
+QStringList S60ImageEncoderControl::supportedImageCodecs() const
+{
+ return m_session->supportedImageCaptureCodecs();
+}
+
+QString S60ImageEncoderControl::imageCodecDescription(const QString &codec) const
+{
+ return m_session->imageCaptureCodecDescription(codec);
+}
+
+QImageEncoderSettings S60ImageEncoderControl::imageSettings() const
+{
+ // Update setting values from session
+ QImageEncoderSettings settings;
+ settings.setCodec(m_session->imageCaptureCodec());
+ settings.setResolution(m_session->captureSize());
+ settings.setQuality(m_session->captureQuality());
+
+ return settings;
+}
+void S60ImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings)
+{
+ // Notify that settings have been implicitly set and there's no need to
+ // initialize them in case camera is changed
+ m_session->notifySettingsSet();
+
+ if (!settings.isNull()) {
+ if (!settings.codec().isEmpty()) {
+ if (settings.resolution() != QSize(-1,-1)) { // Codec, Resolution & Quality
+ m_session->setImageCaptureCodec(settings.codec());
+ m_session->setCaptureSize(settings.resolution());
+ m_session->setCaptureQuality(settings.quality());
+ } else { // Codec and Quality
+ m_session->setImageCaptureCodec(settings.codec());
+ m_session->setCaptureQuality(settings.quality());
+ }
+ } else {
+ if (settings.resolution() != QSize(-1,-1)) { // Resolution & Quality
+ m_session->setCaptureSize(settings.resolution());
+ m_session->setCaptureQuality(settings.quality());
+ }
+ else // Only Quality
+ m_session->setCaptureQuality(settings.quality());
+ }
+
+ // Prepare ImageCapture with the settings and set error if needed
+ int prepareSuccess = m_session->prepareImageCapture();
+
+ // Preparation fails with KErrNotReady if camera has not been started.
+ // That can be ignored since settings are set internally in that case.
+ if (prepareSuccess != KErrNotReady && prepareSuccess != KErrNone)
+ m_session->setError(prepareSuccess, tr("Failure in preparation of image capture."));
+ }
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60imageencodercontrol.h b/src/plugins/symbian/ecam/s60imageencodercontrol.h
new file mode 100644
index 000000000..99a308286
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60imageencodercontrol.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60IMAGEENCODERCONTROL_H
+#define S60IMAGEENCODERCONTROL_H
+
+#include <QtCore/qobject.h>
+#include "qimageencodercontrol.h"
+
+QT_USE_NAMESPACE
+
+class S60ImageCaptureSession;
+
+/*
+ * Control for setting encoding settings for the captured image.
+ */
+class S60ImageEncoderControl : public QImageEncoderControl
+{
+ Q_OBJECT
+
+public: // Contructors & Destructor
+
+ S60ImageEncoderControl(QObject *parent = 0);
+ S60ImageEncoderControl(S60ImageCaptureSession *session, QObject *parent = 0);
+ ~S60ImageEncoderControl();
+
+public: // QImageEncoderControl
+
+ // Codec
+ QStringList supportedImageCodecs() const;
+ QString imageCodecDescription(const QString &codec) const;
+
+ // Resolution
+ QList<QSize> supportedResolutions(const QImageEncoderSettings &settings,
+ bool *continuous = 0) const;
+
+ // Settings
+ QImageEncoderSettings imageSettings() const;
+ void setImageSettings(const QImageEncoderSettings &settings);
+
+private: // Data
+
+ S60ImageCaptureSession *m_session;
+};
+
+#endif // S60IMAGEENCODERCONTROL_H
diff --git a/src/plugins/symbian/ecam/s60mediacontainercontrol.cpp b/src/plugins/symbian/ecam/s60mediacontainercontrol.cpp
new file mode 100644
index 000000000..f0d20f4e3
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60mediacontainercontrol.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "s60mediacontainercontrol.h"
+#include "s60videocapturesession.h"
+#include "s60cameraconstants.h"
+
+S60MediaContainerControl::S60MediaContainerControl(QObject *parent):
+ QMediaContainerControl(parent)
+{
+}
+
+S60MediaContainerControl::S60MediaContainerControl(S60VideoCaptureSession *session, QObject *parent):
+ QMediaContainerControl(parent)
+{
+ m_session = session;
+
+ // Set default video container
+ m_supportedContainers = m_session->supportedVideoContainers();
+
+ if (!m_supportedContainers.isEmpty()) {
+ // Check if default container is supported
+ if (m_supportedContainers.indexOf(KMimeTypeDefaultContainer) != -1)
+ setContainerMimeType(KMimeTypeDefaultContainer);
+ // Otherwise use first in the list
+ else
+ setContainerMimeType(m_supportedContainers[0]); // First as default
+ } else {
+ m_session->setError(KErrGeneral, tr("No supported video containers found."));
+ }
+}
+
+S60MediaContainerControl::~S60MediaContainerControl()
+{
+ m_supportedContainers.clear();
+ m_containerDescriptions.clear();
+}
+
+QStringList S60MediaContainerControl::supportedContainers() const
+{
+ return m_session->supportedVideoContainers();
+}
+
+QString S60MediaContainerControl::containerMimeType() const
+{
+ return m_session->videoContainer();
+}
+
+void S60MediaContainerControl::setContainerMimeType(const QString &containerMimeType)
+{
+ m_session->setVideoContainer(containerMimeType);
+}
+
+QString S60MediaContainerControl::containerDescription(const QString &containerMimeType) const
+{
+ return m_session->videoContainerDescription(containerMimeType);
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60mediacontainercontrol.h b/src/plugins/symbian/ecam/s60mediacontainercontrol.h
new file mode 100644
index 000000000..057b4bc43
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60mediacontainercontrol.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60MEDIACONTAINERCONTROL_H
+#define S60MEDIACONTAINERCONTROL_H
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/qmap.h>
+#include <qmediacontainercontrol.h>
+
+QT_USE_NAMESPACE
+
+class S60VideoCaptureSession;
+
+/*
+ * Control for setting container (file format) for video recorded using
+ * QMediaRecorder.
+ */
+class S60MediaContainerControl : public QMediaContainerControl
+{
+ Q_OBJECT
+
+public: // Contructors & Destructor
+
+ S60MediaContainerControl(QObject *parent = 0);
+ S60MediaContainerControl(S60VideoCaptureSession *session, QObject *parent = 0);
+ virtual ~S60MediaContainerControl();
+
+public: // QMediaContainerControl
+
+ QStringList supportedContainers() const;
+ QString containerMimeType() const;
+ void setContainerMimeType(const QString &containerMimeType);
+
+ QString containerDescription(const QString &containerMimeType) const;
+
+private: // Data
+
+ S60VideoCaptureSession *m_session;
+ QStringList m_supportedContainers;
+ QMap<QString, QString> m_containerDescriptions;
+};
+
+#endif // S60MEDIACONTAINERCONTROL_H
diff --git a/src/plugins/symbian/ecam/s60mediarecordercontrol.cpp b/src/plugins/symbian/ecam/s60mediarecordercontrol.cpp
new file mode 100644
index 000000000..2a1394fa5
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60mediarecordercontrol.cpp
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "s60cameraservice.h"
+#include "s60mediarecordercontrol.h"
+#include "s60cameracontrol.h"
+#include "s60videocapturesession.h"
+
+S60MediaRecorderControl::S60MediaRecorderControl(QObject *parent) :
+ QMediaRecorderControl(parent)
+{
+}
+
+S60MediaRecorderControl::S60MediaRecorderControl(S60CameraService *service,
+ S60VideoCaptureSession *session,
+ QObject *parent):
+ QMediaRecorderControl(parent),
+ m_state(QMediaRecorder::StoppedState) // Default RecorderState
+{
+ m_session = session;
+ m_service = service;
+ m_cameraControl = qobject_cast<S60CameraControl *>(m_service->requestControl(QCameraControl_iid));
+
+ // Connect signals
+ connect(m_session, SIGNAL(stateChanged(S60VideoCaptureSession::TVideoCaptureState)),
+ this, SLOT(updateState(S60VideoCaptureSession::TVideoCaptureState)));
+ connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(durationChanged(qint64)));
+ connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool)));
+ connect(m_session, SIGNAL(error(int,const QString &)), this, SIGNAL(error(int,const QString &)));
+}
+
+S60MediaRecorderControl::~S60MediaRecorderControl()
+{
+ // Release requested control
+ if (m_cameraControl)
+ m_service->releaseControl(m_cameraControl);
+}
+
+QUrl S60MediaRecorderControl::outputLocation() const
+{
+ return m_session->outputLocation();
+}
+
+bool S60MediaRecorderControl::setOutputLocation(const QUrl& sink)
+{
+ // Output location can only be set in StoppedState
+ if (m_state == QMediaRecorder::StoppedState)
+ return m_session->setOutputLocation(sink);
+
+ // Do not signal error, but notify that setting was not effective
+ return false;
+}
+
+QMediaRecorder::State S60MediaRecorderControl::convertInternalStateToQtState(S60VideoCaptureSession::TVideoCaptureState aState) const
+{
+ QMediaRecorder::State state;
+
+ switch (aState) {
+ case S60VideoCaptureSession::ERecording:
+ state = QMediaRecorder::RecordingState;
+ break;
+ case S60VideoCaptureSession::EPaused:
+ state = QMediaRecorder::PausedState;
+ break;
+
+ default:
+ // All others
+ state = QMediaRecorder::StoppedState;
+ break;
+ }
+
+ return state;
+}
+
+void S60MediaRecorderControl::updateState(S60VideoCaptureSession::TVideoCaptureState state)
+{
+ QMediaRecorder::State newState = convertInternalStateToQtState(state);
+
+ if (m_state != newState) {
+ m_state = newState;
+ emit stateChanged(m_state);
+ }
+}
+
+QMediaRecorder::State S60MediaRecorderControl::state() const
+{
+ return m_state;
+}
+
+qint64 S60MediaRecorderControl::duration() const
+{
+ return m_session->position();
+}
+
+/*
+This method is called after encoder configuration is done.
+Encoder can load necessary resources at this point,
+to reduce delay before recording is started. Calling this method reduces the
+latency when calling record() to start video recording.
+*/
+void S60MediaRecorderControl::applySettings()
+{
+ m_session->applyAllSettings();
+}
+
+void S60MediaRecorderControl::record()
+{
+ if (m_state == QMediaRecorder::RecordingState)
+ return;
+
+ if (m_cameraControl && m_cameraControl->captureMode() != QCamera::CaptureVideo) {
+ emit error(QCamera::CameraError, tr("Video capture mode is not selected."));
+ return;
+ }
+
+ m_session->startRecording();
+}
+
+void S60MediaRecorderControl::pause()
+{
+ if (m_state != QMediaRecorder::RecordingState) {
+ // Discard
+ return;
+ }
+
+ m_session->pauseRecording();
+}
+
+void S60MediaRecorderControl::stop()
+{
+ if (m_state == QMediaRecorder::StoppedState) {
+ // Ignore
+ return;
+ }
+
+ m_session->stopRecording();
+}
+
+bool S60MediaRecorderControl::isMuted() const
+{
+ return m_session->isMuted();
+}
+
+void S60MediaRecorderControl::setMuted(bool muted)
+{
+ m_session->setMuted(muted);
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60mediarecordercontrol.h b/src/plugins/symbian/ecam/s60mediarecordercontrol.h
new file mode 100644
index 000000000..5db7477bd
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60mediarecordercontrol.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60MEDIARECORDERCONTROL_H
+#define S60MEDIARECORDERCONTROL_H
+
+#include <QtCore/qurl.h>
+#include <qmediarecorder.h>
+#include <qmediarecordercontrol.h>
+
+#include "s60videocapturesession.h"
+
+QT_USE_NAMESPACE
+
+class S60VideoCaptureSession;
+class S60CameraService;
+class S60CameraControl;
+
+/*
+ * Control for video recording operations.
+ */
+class S60MediaRecorderControl : public QMediaRecorderControl
+{
+ Q_OBJECT
+
+public: // Contructors & Destructor
+
+ S60MediaRecorderControl(QObject *parent = 0);
+ S60MediaRecorderControl(S60CameraService *service,
+ S60VideoCaptureSession *session,
+ QObject *parent = 0);
+ ~S60MediaRecorderControl();
+
+public: // QMediaRecorderControl
+
+ QUrl outputLocation() const;
+ bool setOutputLocation(const QUrl &sink);
+
+ QMediaRecorder::State state() const;
+
+ qint64 duration() const;
+
+ bool isMuted() const;
+
+ void applySettings();
+
+/*
+Q_SIGNALS: // QMediaRecorderControl
+ void stateChanged(QMediaRecorder::State state);
+ void durationChanged(qint64 position);
+ void mutedChanged(bool muted);
+ void error(int error, const QString &errorString);
+*/
+
+public slots: // QMediaRecorderControl
+
+ void record();
+ void pause();
+ void stop();
+ void setMuted(bool);
+
+private:
+
+ QMediaRecorder::State convertInternalStateToQtState(
+ S60VideoCaptureSession::TVideoCaptureState aState) const;
+
+private slots:
+
+ void updateState(S60VideoCaptureSession::TVideoCaptureState state);
+
+private: // Data
+
+ S60VideoCaptureSession *m_session;
+ S60CameraService *m_service;
+ S60CameraControl *m_cameraControl;
+ QMediaRecorder::State m_state;
+
+};
+
+#endif // S60MEDIARECORDERCONTROL_H
diff --git a/src/plugins/symbian/ecam/s60videocapturesession.cpp b/src/plugins/symbian/ecam/s60videocapturesession.cpp
new file mode 100644
index 000000000..7158f8696
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60videocapturesession.cpp
@@ -0,0 +1,2995 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qtimer.h>
+
+#include "s60videocapturesession.h"
+#include "s60cameraconstants.h"
+
+#include <utf.h>
+#include <bautils.h>
+
+#ifdef S60_DEVVIDEO_RECORDING_SUPPORTED
+#include <mmf/devvideo/devvideorecord.h>
+#endif
+
+S60VideoCaptureSession::S60VideoCaptureSession(QObject *parent) :
+ QObject(parent),
+ m_cameraEngine(0),
+ m_videoRecorder(0),
+ m_position(0),
+ m_error(KErrNone),
+ m_cameraStarted(false),
+ m_captureState(ENotInitialized), // Default state
+ m_sink(QUrl()),
+ m_requestedSink(QUrl()),
+ m_captureSettingsSet(false),
+ m_container(QString()),
+ m_requestedContainer(QString()),
+ m_muted(false),
+ m_maxClipSize(-1),
+ m_videoControllerMap(QHash<int, QHash<int,VideoFormatData> >()),
+ m_videoParametersForEncoder(QList<MaxResolutionRatesAndTypes>()),
+ m_openWhenReady(false),
+ m_prepareAfterOpenComplete(false),
+ m_startAfterPrepareComplete(false),
+ m_uncommittedSettings(false),
+ m_commitSettingsWhenReady(false)
+{
+#ifdef S60_DEVVIDEO_RECORDING_SUPPORTED
+ // Populate info of supported codecs, and their resolution, etc.
+ TRAPD(err, doPopulateVideoCodecsDataL());
+ setError(err, tr("Failed to gather video codec information."));
+#endif // S60_DEVVIDEO_RECORDING_SUPPORTED
+
+ initializeVideoCaptureSettings();
+
+ m_durationTimer = new QTimer;
+ m_durationTimer->setInterval(KDurationChangedInterval);
+ connect(m_durationTimer, SIGNAL(timeout()), this, SLOT(durationTimerTriggered()));
+}
+
+S60VideoCaptureSession::~S60VideoCaptureSession()
+{
+ if (m_captureState >= ERecording)
+ m_videoRecorder->Stop();
+
+ if (m_captureState >= EInitialized)
+ m_videoRecorder->Close();
+
+ if (m_videoRecorder) {
+ delete m_videoRecorder;
+ m_videoRecorder = 0;
+ }
+
+ if (m_durationTimer) {
+ delete m_durationTimer;
+ m_durationTimer = 0;
+ }
+
+ // Clear all data structures
+ foreach (MaxResolutionRatesAndTypes structure, m_videoParametersForEncoder) {
+ structure.frameRatePictureSizePair.clear();
+ structure.mimeTypes.clear();
+ }
+ m_videoParametersForEncoder.clear();
+
+ m_videoCodecList.clear();
+ m_audioCodecList.clear();
+
+ QList<TInt> controllers = m_videoControllerMap.keys();
+ for (int i = 0; i < controllers.size(); ++i) {
+ foreach(VideoFormatData data, m_videoControllerMap[controllers[i]]){
+ data.supportedMimeTypes.clear();
+ }
+ m_videoControllerMap[controllers[i]].clear();
+ }
+ m_videoControllerMap.clear();
+}
+
+/*
+ * This function can be used both internally and from Control classes using this session.
+ * The error notification will go to client application through QMediaRecorder error signal.
+ */
+void S60VideoCaptureSession::setError(const TInt error, const QString &description)
+{
+ if (error == KErrNone)
+ return;
+
+ m_error = error;
+ QMediaRecorder::Error recError = fromSymbianErrorToQtMultimediaError(m_error);
+
+ // Stop/Close/Reset only of other than "not supported" error
+ if (m_error != KErrNotSupported) {
+ if (m_captureState >= ERecording)
+ m_videoRecorder->Stop();
+
+ if (m_captureState >= EInitialized)
+ m_videoRecorder->Close();
+
+ // Reset state
+ if (m_captureState != ENotInitialized) {
+ if (m_durationTimer->isActive())
+ m_durationTimer->stop();
+ m_captureState = ENotInitialized;
+ emit stateChanged(m_captureState);
+ }
+ }
+
+ emit this->error(recError, description);
+
+ // Reset only of other than "not supported" error
+ if (m_error != KErrNotSupported)
+ resetSession(true);
+ else
+ m_error = KErrNone; // Reset error
+}
+
+QMediaRecorder::Error S60VideoCaptureSession::fromSymbianErrorToQtMultimediaError(int aError)
+{
+ switch(aError) {
+ case KErrNone:
+ return QMediaRecorder::NoError; // No errors have occurred
+ case KErrArgument:
+ case KErrNotSupported:
+ return QMediaRecorder::FormatError; // The feature/format is not supported
+ case KErrNoMemory:
+ case KErrNotFound:
+ case KErrBadHandle:
+ return QMediaRecorder::ResourceError; // Not able to use camera/recorder resources
+
+ default:
+ return QMediaRecorder::ResourceError; // Other error has occurred
+ }
+}
+
+/*
+ * This function applies all recording settings to make latency during the
+ * start of the recording as short as possible. After this it is not possible to
+ * set settings (inc. output location) before stopping the recording.
+ */
+void S60VideoCaptureSession::applyAllSettings()
+{
+ switch (m_captureState) {
+ case ENotInitialized:
+ case EInitializing:
+ m_commitSettingsWhenReady = true;
+ return;
+ case EInitialized:
+ setOutputLocation(QUrl());
+ m_prepareAfterOpenComplete = true;
+ return;
+ case EOpening:
+ m_prepareAfterOpenComplete = true;
+ return;
+ case EOpenComplete:
+ // Do nothing, ready to commit
+ break;
+ case EPreparing:
+ m_commitSettingsWhenReady = true;
+ return;
+ case EPrepared:
+ // Revert state internally, since logically applying settings means going
+ // from OpenComplete ==> Preparing ==> Prepared.
+ m_captureState = EOpenComplete;
+ break;
+ case ERecording:
+ case EPaused:
+ setError(KErrNotReady, tr("Cannot apply settings while recording."));
+ return;
+
+ default:
+ setError(KErrGeneral, tr("Unexpected camera error."));
+ return;
+ }
+
+ // Commit settings - State is now OpenComplete (possibly reverted from Prepared)
+ commitVideoEncoderSettings();
+
+ // If capture state has been changed to:
+ // * Opening: A different media container has been requested
+ // * Other: Failure during the setting committing
+ // ==> Return
+ if (m_captureState != EOpenComplete)
+ return;
+
+ // Start preparing
+ m_captureState = EPreparing;
+ emit stateChanged(m_captureState);
+
+ if (m_cameraEngine->IsCameraReady())
+ m_videoRecorder->Prepare();
+}
+
+void S60VideoCaptureSession::setCameraHandle(CCameraEngine* cameraHandle)
+{
+ m_cameraEngine = cameraHandle;
+
+ // Initialize settings for the new camera
+ initializeVideoCaptureSettings();
+
+ resetSession();
+}
+
+void S60VideoCaptureSession::notifySettingsSet()
+{
+ m_captureSettingsSet = true;
+}
+
+void S60VideoCaptureSession::doInitializeVideoRecorderL()
+{
+ if (m_captureState > ENotInitialized)
+ resetSession();
+
+ m_captureState = EInitializing;
+ emit stateChanged(m_captureState);
+
+ // Open Dummy file to be able to query supported settings
+ int cameraHandle = m_cameraEngine->Camera() ? m_cameraEngine->Camera()->Handle() : 0;
+
+ TUid controllerUid;
+ TUid formatUid;
+ selectController(m_requestedContainer, controllerUid, formatUid);
+
+ if (m_videoRecorder) {
+ // File open completes in MvruoOpenComplete
+ TRAPD(err, m_videoRecorder->OpenFileL(KDummyVideoFile, cameraHandle, controllerUid, formatUid));
+ setError(err, tr("Failed to initialize video recorder."));
+ m_container = m_requestedContainer;
+ } else {
+ setError(KErrNotReady, tr("Unexpected camera error."));
+ }
+}
+
+void S60VideoCaptureSession::resetSession(bool errorHandling)
+{
+ if (m_videoRecorder) {
+ delete m_videoRecorder;
+ m_videoRecorder = 0;
+ }
+
+ if (m_captureState != ENotInitialized) {
+ if (m_durationTimer->isActive())
+ m_durationTimer->stop();
+ m_captureState = ENotInitialized;
+ emit stateChanged(m_captureState);
+ }
+
+ // Reset error to be able to recover
+ m_error = KErrNone;
+
+ // Reset flags
+ m_openWhenReady = false;
+ m_prepareAfterOpenComplete = false;
+ m_startAfterPrepareComplete = false;
+ m_uncommittedSettings = false;
+ m_commitSettingsWhenReady = false;
+
+ TRAPD(err, m_videoRecorder = CVideoRecorderUtility::NewL(*this));
+ if (err) {
+ qWarning("Failed to create video recorder.");
+ if (errorHandling)
+ emit error(QMediaRecorder::ResourceError, tr("Failed to recover from video error."));
+ else
+ setError(err, tr("Failure in creation of video recorder device."));
+ return;
+ }
+
+ updateVideoCaptureContainers();
+}
+
+QList<QSize> S60VideoCaptureSession::supportedVideoResolutions(bool *continuous)
+{
+ QList<QSize> resolutions;
+
+ // Secondary Camera
+ if (m_cameraEngine->CurrentCameraIndex() != 0) {
+ TCameraInfo *info = m_cameraEngine->CameraInfo();
+ if (info) {
+ TInt videoResolutionCount = info->iNumVideoFrameSizesSupported;
+ CCamera *camera = m_cameraEngine->Camera();
+ if (camera) {
+ for (TInt i = 0; i < videoResolutionCount; ++i) {
+ TSize checkedResolution;
+ camera->EnumerateVideoFrameSizes(checkedResolution, i, CCamera::EFormatYUV420Planar);
+ QSize qtResolution(checkedResolution.iWidth, checkedResolution.iHeight);
+ if (!resolutions.contains(qtResolution))
+ resolutions.append(qtResolution);
+ }
+ } else {
+ setError(KErrGeneral, tr("Could not query supported video resolutions."));
+ }
+ } else {
+ setError(KErrGeneral, tr("Could not query supported video resolutions."));
+ }
+
+ // Primary Camera
+ } else {
+
+ if (m_videoParametersForEncoder.count() > 0) {
+
+ // Also arbitrary resolutions are supported
+ if (continuous)
+ *continuous = true;
+
+ // Append all supported resolutions to the list
+ foreach (MaxResolutionRatesAndTypes parameters, m_videoParametersForEncoder)
+ for (int i = 0; i < parameters.frameRatePictureSizePair.count(); ++i)
+ if (!resolutions.contains(parameters.frameRatePictureSizePair[i].frameSize))
+ resolutions.append(parameters.frameRatePictureSizePair[i].frameSize);
+ }
+ }
+
+#ifdef Q_CC_NOKIAX86 // Emulator
+ resolutions << QSize(160, 120);
+ resolutions << QSize(352, 288);
+ resolutions << QSize(640,480);
+#endif // Q_CC_NOKIAX86
+
+ return resolutions;
+}
+
+QList<QSize> S60VideoCaptureSession::supportedVideoResolutions(const QVideoEncoderSettings &settings, bool *continuous)
+{
+ QList<QSize> supportedFrameSizes;
+
+ // Secondary Camera
+ if (m_cameraEngine->CurrentCameraIndex() != 0) {
+ TCameraInfo *info = m_cameraEngine->CameraInfo();
+ if (info) {
+ TInt videoResolutionCount = info->iNumVideoFrameSizesSupported;
+ CCamera *camera = m_cameraEngine->Camera();
+ if (camera) {
+ for (TInt i = 0; i < videoResolutionCount; ++i) {
+ TSize checkedResolution;
+ camera->EnumerateVideoFrameSizes(checkedResolution, i, CCamera::EFormatYUV420Planar);
+ QSize qtResolution(checkedResolution.iWidth, checkedResolution.iHeight);
+ if (!supportedFrameSizes.contains(qtResolution))
+ supportedFrameSizes.append(qtResolution);
+ }
+ } else {
+ setError(KErrGeneral, tr("Could not query supported video resolutions."));
+ }
+ } else {
+ setError(KErrGeneral, tr("Could not query supported video resolutions."));
+ }
+
+ // Primary Camera
+ } else {
+
+ if (settings.codec().isEmpty())
+ return supportedFrameSizes;
+
+ if (!m_videoCodecList.contains(settings.codec(), Qt::CaseInsensitive))
+ return supportedFrameSizes;
+
+ // Also arbitrary resolutions are supported
+ if (continuous)
+ *continuous = true;
+
+ // Find maximum resolution (using defined framerate if set)
+ for (int i = 0; i < m_videoParametersForEncoder.count(); ++i) {
+ // Check if encoder supports the requested codec
+ if (!m_videoParametersForEncoder[i].mimeTypes.contains(settings.codec(), Qt::CaseInsensitive))
+ continue;
+
+ foreach (SupportedFrameRatePictureSize pair, m_videoParametersForEncoder[i].frameRatePictureSizePair) {
+ if (!supportedFrameSizes.contains(pair.frameSize)) {
+ QSize maxForMime = maximumResolutionForMimeType(settings.codec());
+ if (settings.frameRate() != 0) {
+ if (settings.frameRate() <= pair.frameRate) {
+ if ((pair.frameSize.width() * pair.frameSize.height()) <= (maxForMime.width() * maxForMime.height()))
+ supportedFrameSizes.append(pair.frameSize);
+ }
+ } else {
+ if ((pair.frameSize.width() * pair.frameSize.height()) <= (maxForMime.width() * maxForMime.height()))
+ supportedFrameSizes.append(pair.frameSize);
+ }
+ }
+ }
+ }
+ }
+
+#ifdef Q_CC_NOKIAX86 // Emulator
+ supportedFrameSizes << QSize(160, 120);
+ supportedFrameSizes << QSize(352, 288);
+ supportedFrameSizes << QSize(640,480);
+#endif
+
+ return supportedFrameSizes;
+}
+
+QList<qreal> S60VideoCaptureSession::supportedVideoFrameRates(bool *continuous)
+{
+ QList<qreal> supportedRatesList;
+
+ if (m_videoParametersForEncoder.count() > 0) {
+ // Insert min and max to the list
+ supportedRatesList.append(1.0); // Use 1fps as sensible minimum
+ qreal foundMaxFrameRate(0.0);
+
+ // Also arbitrary framerates are supported
+ if (continuous)
+ *continuous = true;
+
+ // Find max framerate
+ foreach (MaxResolutionRatesAndTypes parameters, m_videoParametersForEncoder) {
+ for (int i = 0; i < parameters.frameRatePictureSizePair.count(); ++i) {
+ qreal maxFrameRate = parameters.frameRatePictureSizePair[i].frameRate;
+ if (maxFrameRate > foundMaxFrameRate)
+ foundMaxFrameRate = maxFrameRate;
+ }
+ }
+
+ supportedRatesList.append(foundMaxFrameRate);
+ }
+
+ // Add also other standard framerates to the list
+ if (!supportedRatesList.isEmpty()) {
+ if (supportedRatesList.last() > 30.0) {
+ if (!supportedRatesList.contains(30.0))
+ supportedRatesList.insert(1, 30.0);
+ }
+ if (supportedRatesList.last() > 25.0) {
+ if (!supportedRatesList.contains(25.0))
+ supportedRatesList.insert(1, 25.0);
+ }
+ if (supportedRatesList.last() > 15.0) {
+ if (!supportedRatesList.contains(15.0))
+ supportedRatesList.insert(1, 15.0);
+ }
+ if (supportedRatesList.last() > 10.0) {
+ if (!supportedRatesList.contains(10))
+ supportedRatesList.insert(1, 10.0);
+ }
+ }
+
+#ifdef Q_CC_NOKIAX86 // Emulator
+ supportedRatesList << 30.0 << 25.0 << 15.0 << 10.0 << 5.0;
+#endif
+
+ return supportedRatesList;
+}
+
+QList<qreal> S60VideoCaptureSession::supportedVideoFrameRates(const QVideoEncoderSettings &settings, bool *continuous)
+{
+ QList<qreal> supportedFrameRates;
+
+ if (settings.codec().isEmpty())
+ return supportedFrameRates;
+ if (!m_videoCodecList.contains(settings.codec(), Qt::CaseInsensitive))
+ return supportedFrameRates;
+
+ // Also arbitrary framerates are supported
+ if (continuous)
+ *continuous = true;
+
+ // Find maximum framerate (using defined resolution if set)
+ for (int i = 0; i < m_videoParametersForEncoder.count(); ++i) {
+ // Check if encoder supports the requested codec
+ if (!m_videoParametersForEncoder[i].mimeTypes.contains(settings.codec(), Qt::CaseInsensitive))
+ continue;
+
+ foreach (SupportedFrameRatePictureSize pair, m_videoParametersForEncoder[i].frameRatePictureSizePair) {
+ if (!supportedFrameRates.contains(pair.frameRate)) {
+ qreal maxRateForMime = maximumFrameRateForMimeType(settings.codec());
+ if (settings.resolution().width() != 0 && settings.resolution().height() != 0) {
+ if((settings.resolution().width() * settings.resolution().height()) <= (pair.frameSize.width() * pair.frameSize.height())) {
+ if (pair.frameRate <= maxRateForMime)
+ supportedFrameRates.append(pair.frameRate);
+ }
+ } else {
+ if (pair.frameRate <= maxRateForMime)
+ supportedFrameRates.append(pair.frameRate);
+ }
+ }
+ }
+ }
+
+ // Add also other standard framerates to the list
+ if (!supportedFrameRates.isEmpty()) {
+ if (supportedFrameRates.last() > 30.0) {
+ if (!supportedFrameRates.contains(30.0))
+ supportedFrameRates.insert(1, 30.0);
+ }
+ if (supportedFrameRates.last() > 25.0) {
+ if (!supportedFrameRates.contains(25.0))
+ supportedFrameRates.insert(1, 25.0);
+ }
+ if (supportedFrameRates.last() > 15.0) {
+ if (!supportedFrameRates.contains(15.0))
+ supportedFrameRates.insert(1, 15.0);
+ }
+ if (supportedFrameRates.last() > 10.0) {
+ if (!supportedFrameRates.contains(10))
+ supportedFrameRates.insert(1, 10.0);
+ }
+ }
+
+#ifdef Q_CC_NOKIAX86 // Emulator
+ supportedFrameRates << 30.0 << 25.0 << 15.0 << 10.0 << 5.0;
+#endif
+
+ return supportedFrameRates;
+}
+
+bool S60VideoCaptureSession::setOutputLocation(const QUrl &sink)
+{
+ m_requestedSink = sink;
+
+ if (m_error)
+ return false;
+
+ switch (m_captureState) {
+ case ENotInitialized:
+ case EInitializing:
+ case EOpening:
+ case EPreparing:
+ m_openWhenReady = true;
+ return true;
+
+ case EInitialized:
+ case EOpenComplete:
+ case EPrepared:
+ // Continue
+ break;
+
+ case ERecording:
+ case EPaused:
+ setError(KErrNotReady, tr("Cannot set file name while recording."));
+ return false;
+
+ default:
+ setError(KErrGeneral, tr("Unexpected camera error."));
+ return false;
+ }
+
+ // Empty URL - Use default file name and path (C:\Data\Videos\video.mp4)
+ if (sink.isEmpty()) {
+
+ // Make sure default directory exists
+ QDir videoDir(QDir::rootPath());
+ if (!videoDir.exists(KDefaultVideoPath))
+ videoDir.mkpath(KDefaultVideoPath);
+ QString defaultFile = KDefaultVideoPath;
+ defaultFile.append("\\");
+ defaultFile.append(KDefaultVideoFileName);
+ m_sink.setUrl(defaultFile);
+
+ } else { // Non-empty URL
+
+ QString fullUrl = sink.scheme();
+
+ // Relative URL
+ if (sink.isRelative()) {
+
+ // Extract file name and path from the URL
+ fullUrl = KDefaultVideoPath;
+ fullUrl.append("\\");
+ fullUrl.append(QDir::toNativeSeparators(sink.path()));
+
+ // Absolute URL
+ } else {
+
+ // Extract file name and path from the URL
+ if (fullUrl == "file") {
+ fullUrl = QDir::toNativeSeparators(sink.path().right(sink.path().length() - 1));
+ } else {
+ fullUrl.append(":");
+ fullUrl.append(QDir::toNativeSeparators(sink.path()));
+ }
+ }
+
+ QString fileName = fullUrl.right(fullUrl.length() - fullUrl.lastIndexOf("\\") - 1);
+ QString directory = fullUrl.left(fullUrl.lastIndexOf("\\"));
+ if (directory.lastIndexOf("\\") == (directory.length() - 1))
+ directory = directory.left(directory.length() - 1);
+
+ // URL is Absolute path, not including file name
+ if (!fileName.contains(".")) {
+ if (fileName != "") {
+ directory.append("\\");
+ directory.append(fileName);
+ }
+ fileName = KDefaultVideoFileName;
+ }
+
+ // Make sure absolute directory exists
+ QDir videoDir(QDir::rootPath());
+ if (!videoDir.exists(directory))
+ videoDir.mkpath(directory);
+
+ QString resolvedURL = directory;
+ resolvedURL.append("\\");
+ resolvedURL.append(fileName);
+ m_sink = QUrl(resolvedURL);
+ }
+
+ // State is either Initialized, OpenComplete or Prepared, Close previously opened file
+ if (m_videoRecorder)
+ m_videoRecorder->Close();
+ else
+ setError(KErrNotReady, tr("Unexpected camera error."));
+
+ // Open file
+
+ QString fileName = QDir::toNativeSeparators(m_sink.toString());
+ TPtrC16 fileSink(reinterpret_cast<const TUint16*>(fileName.utf16()));
+
+ int cameraHandle = m_cameraEngine->Camera() ? m_cameraEngine->Camera()->Handle() : 0;
+
+ TUid controllerUid;
+ TUid formatUid;
+ selectController(m_requestedContainer, controllerUid, formatUid);
+
+ if (m_videoRecorder) {
+ // File open completes in MvruoOpenComplete
+ TRAPD(err, m_videoRecorder->OpenFileL(fileSink, cameraHandle, controllerUid, formatUid));
+ setError(err, tr("Failed to initialize video recorder."));
+ m_container = m_requestedContainer;
+ m_captureState = EOpening;
+ emit stateChanged(m_captureState);
+ }
+ else
+ setError(KErrNotReady, tr("Unexpected camera error."));
+
+ m_uncommittedSettings = true;
+ return true;
+}
+
+QUrl S60VideoCaptureSession::outputLocation() const
+{
+ return m_sink;
+}
+
+qint64 S60VideoCaptureSession::position()
+{
+ // Update position only if recording is ongoing
+ if ((m_captureState == ERecording) && m_videoRecorder) {
+ // Signal will be automatically emitted of position changes
+ TRAPD(err, m_position = m_videoRecorder->DurationL().Int64() / 1000);
+ setError(err, tr("Cannot retrieve video position."));
+ }
+
+ return m_position;
+}
+
+S60VideoCaptureSession::TVideoCaptureState S60VideoCaptureSession::state() const
+{
+ return m_captureState;
+}
+
+bool S60VideoCaptureSession::isMuted() const
+{
+ return m_muted;
+}
+
+void S60VideoCaptureSession::setMuted(const bool muted)
+{
+ // CVideoRecorderUtility can mute/unmute only if not recording
+ if (m_captureState > EPrepared) {
+ if (muted)
+ setError(KErrNotSupported, tr("Muting audio is not supported during recording."));
+ else
+ setError(KErrNotSupported, tr("Unmuting audio is not supported during recording."));
+ return;
+ }
+
+ // Check if request is already active
+ if (muted == isMuted())
+ return;
+
+ m_muted = muted;
+
+ m_uncommittedSettings = true;
+}
+
+void S60VideoCaptureSession::commitVideoEncoderSettings()
+{
+ if (m_captureState == EOpenComplete) {
+
+ if (m_container != m_requestedContainer) {
+ setOutputLocation(m_requestedSink);
+ return;
+ }
+
+ TRAPD(err, doSetCodecsL());
+ if (err) {
+ setError(err, tr("Failed to set audio or video codec."));
+ m_audioSettings.setCodec(KMimeTypeDefaultAudioCodec);
+ m_videoSettings.setCodec(KMimeTypeDefaultVideoCodec);
+ }
+
+ doSetVideoResolution(m_videoSettings.resolution());
+ doSetFrameRate(m_videoSettings.frameRate());
+ doSetBitrate(m_videoSettings.bitRate());
+
+ // Audio/Video EncodingMode are not supported in Symbian
+
+#ifndef S60_31_PLATFORM
+ if (m_audioSettings.sampleRate() != -1 && m_audioSettings.sampleRate() != 0) {
+ TRAP(err, m_videoRecorder->SetAudioSampleRateL((TInt)m_audioSettings.sampleRate()));
+ if (err != KErrNotSupported) {
+ setError(err, tr("Setting audio sample rate failed."));
+ } else {
+ setError(err, tr("Setting audio sample rate is not supported."));
+ m_audioSettings.setSampleRate(KDefaultSampleRate); // Reset
+ }
+ }
+#endif // S60_31_PLATFORM
+
+ TRAP(err, m_videoRecorder->SetAudioBitRateL((TInt)m_audioSettings.bitRate()));
+ if (err != KErrNotSupported) {
+ if (err == KErrArgument) {
+ setError(KErrNotSupported, tr("Requested audio bitrate is not supported or previously set codec is not supported with requested bitrate."));
+ int fallback = 16000;
+ TRAP(err, m_videoRecorder->SetAudioBitRateL(TInt(fallback)));
+ if (err == KErrNone)
+ m_audioSettings.setBitRate(fallback);
+ } else {
+ setError(err, tr("Setting audio bitrate failed."));
+ }
+ }
+
+#ifndef S60_31_PLATFORM
+ if (m_audioSettings.channelCount() != -1) {
+ TRAP(err, m_videoRecorder->SetAudioChannelsL(TUint(m_audioSettings.channelCount())));
+ if (err != KErrNotSupported) {
+ setError(err, tr("Setting audio channel count failed."));
+ } else {
+ setError(err, tr("Setting audio channel count is not supported."));
+ m_audioSettings.setChannelCount(KDefaultChannelCount); // Reset
+ }
+ }
+#endif // S60_31_PLATFORM
+
+ TBool isAudioMuted = EFalse;
+ TRAP(err, isAudioMuted = !m_videoRecorder->AudioEnabledL());
+ if (err != KErrNotSupported && err != KErrNone)
+ setError(err, tr("Failure when checking if audio is enabled."));
+
+ if (m_muted != (bool)isAudioMuted) {
+ TRAP(err, m_videoRecorder->SetAudioEnabledL(TBool(!m_muted)));
+ if (err) {
+ if (err != KErrNotSupported) {
+ setError(err, tr("Failed to mute/unmute audio."));
+ } else {
+ setError(err, tr("Muting/unmuting audio is not supported."));
+ }
+ }
+ else
+ emit mutedChanged(m_muted);
+ }
+
+ m_uncommittedSettings = false; // Reset
+ }
+}
+
+void S60VideoCaptureSession::queryAudioEncoderSettings()
+{
+ if (!m_videoRecorder)
+ return;
+
+ switch (m_captureState) {
+ case ENotInitialized:
+ case EInitializing:
+ case EOpening:
+ case EPreparing:
+ return;
+
+ // Possible to query settings from CVideoRecorderUtility
+ case EInitialized:
+ case EOpenComplete:
+ case EPrepared:
+ case ERecording:
+ case EPaused:
+ break;
+
+ default:
+ return;
+ }
+
+ TInt err = KErrNone;
+
+ // Codec
+ TFourCC audioCodec;
+ TRAP(err, audioCodec = m_videoRecorder->AudioTypeL());
+ if (err) {
+ if (err != KErrNotSupported)
+ setError(err, tr("Querying audio codec failed."));
+ }
+ QString codec = "";
+ foreach (TFourCC aCodec, m_audioCodecList) {
+ if (audioCodec == aCodec)
+ codec = m_audioCodecList.key(aCodec);
+ }
+ m_audioSettings.setCodec(codec);
+
+#ifndef S60_31_PLATFORM
+ // Samplerate
+ TInt sampleRate = -1;
+ TRAP(err, sampleRate = m_videoRecorder->AudioSampleRateL());
+ if (err) {
+ if (err != KErrNotSupported)
+ setError(err, tr("Querying audio sample rate failed."));
+ }
+ m_audioSettings.setSampleRate(int(sampleRate));
+#endif // S60_31_PLATFORM
+
+ // BitRate
+ TInt bitRate = -1;
+ TRAP(err, bitRate = m_videoRecorder->AudioBitRateL());
+ if (err) {
+ if (err != KErrNotSupported)
+ setError(err, tr("Querying audio bitrate failed."));
+ }
+ m_audioSettings.setBitRate(int(bitRate));
+
+#ifndef S60_31_PLATFORM
+ // ChannelCount
+ TUint channelCount = 0;
+ TRAP(err, channelCount = m_videoRecorder->AudioChannelsL());
+ if (err) {
+ if (err != KErrNotSupported)
+ setError(err, tr("Querying audio channel count failed."));
+ }
+ if (channelCount != 0)
+ m_audioSettings.setChannelCount(int(channelCount));
+ else
+ m_audioSettings.setChannelCount(-1);
+#endif // S60_31_PLATFORM
+
+ // EncodingMode
+ m_audioSettings.setEncodingMode(QtMultimediaKit::ConstantQualityEncoding);
+
+ // IsMuted
+ TBool isEnabled = ETrue;
+ TRAP(err, isEnabled = m_videoRecorder->AudioEnabledL());
+ if (err) {
+ if (err != KErrNotSupported)
+ setError(err, tr("Querying whether audio is muted failed."));
+ }
+ m_muted = bool(!isEnabled);
+}
+
+void S60VideoCaptureSession::queryVideoEncoderSettings()
+{
+ if (!m_videoRecorder)
+ return;
+
+ switch (m_captureState) {
+ case ENotInitialized:
+ case EInitializing:
+ case EOpening:
+ case EPreparing:
+ return;
+
+ // Possible to query settings from CVideoRecorderUtility
+ case EInitialized:
+ case EOpenComplete:
+ case EPrepared:
+ case ERecording:
+ case EPaused:
+ break;
+
+ default:
+ return;
+ }
+
+ TInt err = KErrNone;
+
+ // Codec
+ const TDesC8 &videoMimeType = m_videoRecorder->VideoFormatMimeType();
+ QString videoMimeTypeString = "";
+ if (videoMimeType.Length() > 0) {
+ // First convert the 8-bit descriptor to Unicode
+ HBufC16* videoCodec;
+ videoCodec = CnvUtfConverter::ConvertToUnicodeFromUtf8L(videoMimeType);
+ CleanupStack::PushL(videoCodec);
+
+ // Then deep copy QString from that
+ videoMimeTypeString = QString::fromUtf16(videoCodec->Ptr(), videoCodec->Length());
+ m_videoSettings.setCodec(videoMimeTypeString);
+
+ CleanupStack::PopAndDestroy(videoCodec);
+ }
+
+ // Resolution
+ TSize symbianResolution;
+ TRAP(err, m_videoRecorder->GetVideoFrameSizeL(symbianResolution));
+ if (err) {
+ if (err != KErrNotSupported)
+ setError(err, tr("Querying video resolution failed."));
+ }
+ QSize resolution = QSize(symbianResolution.iWidth, symbianResolution.iHeight);
+ m_videoSettings.setResolution(resolution);
+
+ // FrameRate
+ TReal32 frameRate = 0;
+ TRAP(err, frameRate = m_videoRecorder->VideoFrameRateL());
+ if (err) {
+ if (err != KErrNotSupported)
+ setError(err, tr("Querying video framerate failed."));
+ }
+ m_videoSettings.setFrameRate(qreal(frameRate));
+
+ // BitRate
+ TInt bitRate = -1;
+ TRAP(err, bitRate = m_videoRecorder->VideoBitRateL());
+ if (err) {
+ if (err != KErrNotSupported)
+ setError(err, tr("Querying video bitrate failed."));
+ }
+ m_videoSettings.setBitRate(int(bitRate));
+
+ // EncodingMode
+ m_audioSettings.setEncodingMode(QtMultimediaKit::ConstantQualityEncoding);
+}
+
+void S60VideoCaptureSession::videoEncoderSettings(QVideoEncoderSettings &videoSettings)
+{
+ switch (m_captureState) {
+ // CVideoRecorderUtility, return requested settings
+ case ENotInitialized:
+ case EInitializing:
+ case EInitialized:
+ case EOpening:
+ case EOpenComplete:
+ case EPreparing:
+ break;
+
+ // Possible to query settings from CVideoRecorderUtility
+ case EPrepared:
+ case ERecording:
+ case EPaused:
+ queryVideoEncoderSettings();
+ break;
+
+ default:
+ videoSettings = QVideoEncoderSettings();
+ setError(KErrGeneral, tr("Unexpected video error."));
+ return;
+ }
+
+ videoSettings = m_videoSettings;
+}
+
+void S60VideoCaptureSession::audioEncoderSettings(QAudioEncoderSettings &audioSettings)
+{
+ switch (m_captureState) {
+ // CVideoRecorderUtility, return requested settings
+ case ENotInitialized:
+ case EInitializing:
+ case EInitialized:
+ case EOpening:
+ case EOpenComplete:
+ case EPreparing:
+ break;
+
+ // Possible to query settings from CVideoRecorderUtility
+ case EPrepared:
+ case ERecording:
+ case EPaused:
+ queryAudioEncoderSettings();
+ break;
+
+ default:
+ audioSettings = QAudioEncoderSettings();
+ setError(KErrGeneral, tr("Unexpected video error."));
+ return;
+ }
+
+ audioSettings = m_audioSettings;
+}
+
+void S60VideoCaptureSession::validateRequestedCodecs()
+{
+ if (!m_audioCodecList.contains(m_audioSettings.codec())) {
+ m_audioSettings.setCodec(KMimeTypeDefaultAudioCodec);
+ setError(KErrNotSupported, tr("Currently selected audio codec is not supported by the platform."));
+ }
+ if (!m_videoCodecList.contains(m_videoSettings.codec())) {
+ m_videoSettings.setCodec(KMimeTypeDefaultVideoCodec);
+ setError(KErrNotSupported, tr("Currently selected video codec is not supported by the platform."));
+ }
+}
+
+void S60VideoCaptureSession::setVideoCaptureQuality(const QtMultimediaKit::EncodingQuality quality,
+ const VideoQualityDefinition mode)
+{
+ // Sensible presets
+ switch (mode) {
+ case ENoVideoQuality:
+ // Do nothing
+ break;
+ case EOnlyVideoQuality:
+ if (quality == QtMultimediaKit::VeryLowQuality) {
+ m_videoSettings.setResolution(QSize(128,96));
+ m_videoSettings.setFrameRate(10);
+ m_videoSettings.setBitRate(64000);
+ } else if (quality == QtMultimediaKit::LowQuality) {
+ m_videoSettings.setResolution(QSize(176,144));
+ m_videoSettings.setFrameRate(15);
+ m_videoSettings.setBitRate(64000);
+ } else if (quality == QtMultimediaKit::NormalQuality) {
+ m_videoSettings.setResolution(QSize(176,144));
+ m_videoSettings.setFrameRate(15);
+ m_videoSettings.setBitRate(128000);
+ } else if (quality == QtMultimediaKit::HighQuality) {
+ m_videoSettings.setResolution(QSize(352,288));
+ m_videoSettings.setFrameRate(15);
+ m_videoSettings.setBitRate(384000);
+ } else if (quality == QtMultimediaKit::VeryHighQuality) {
+ if (m_cameraEngine && m_cameraEngine->CurrentCameraIndex() == 0)
+ m_videoSettings.setResolution(QSize(640,480)); // Primary camera
+ else
+ m_videoSettings.setResolution(QSize(352,288)); // Other cameras
+ m_videoSettings.setFrameRate(15);
+ m_videoSettings.setBitRate(2000000);
+ } else {
+ m_videoSettings.setQuality(QtMultimediaKit::NormalQuality);
+ setError(KErrNotSupported, tr("Unsupported video quality."));
+ return;
+ }
+ break;
+ case EVideoQualityAndResolution:
+ if (quality == QtMultimediaKit::VeryLowQuality) {
+ m_videoSettings.setFrameRate(10);
+ m_videoSettings.setBitRate(64000);
+ } else if (quality == QtMultimediaKit::LowQuality) {
+ m_videoSettings.setFrameRate(15);
+ m_videoSettings.setBitRate(64000);
+ } else if (quality == QtMultimediaKit::NormalQuality) {
+ m_videoSettings.setFrameRate(15);
+ m_videoSettings.setBitRate(128000);
+ } else if (quality == QtMultimediaKit::HighQuality) {
+ m_videoSettings.setFrameRate(15);
+ m_videoSettings.setBitRate(384000);
+ } else if (quality == QtMultimediaKit::VeryHighQuality) {
+ m_videoSettings.setFrameRate(15);
+ m_videoSettings.setBitRate(2000000);
+ } else {
+ m_videoSettings.setQuality(QtMultimediaKit::NormalQuality);
+ setError(KErrNotSupported, tr("Unsupported video quality."));
+ return;
+ }
+ break;
+ case EVideoQualityAndFrameRate:
+ if (quality == QtMultimediaKit::VeryLowQuality) {
+ m_videoSettings.setResolution(QSize(128,96));
+ m_videoSettings.setBitRate(64000);
+ } else if (quality == QtMultimediaKit::LowQuality) {
+ m_videoSettings.setResolution(QSize(176,144));
+ m_videoSettings.setBitRate(64000);
+ } else if (quality == QtMultimediaKit::NormalQuality) {
+ m_videoSettings.setResolution(QSize(176,144));
+ m_videoSettings.setBitRate(128000);
+ } else if (quality == QtMultimediaKit::HighQuality) {
+ m_videoSettings.setResolution(QSize(352,288));
+ m_videoSettings.setBitRate(384000);
+ } else if (quality == QtMultimediaKit::VeryHighQuality) {
+ if (m_cameraEngine && m_cameraEngine->CurrentCameraIndex() == 0)
+ m_videoSettings.setResolution(QSize(640,480)); // Primary camera
+ else
+ m_videoSettings.setResolution(QSize(352,288)); // Other cameras
+ m_videoSettings.setBitRate(2000000);
+ } else {
+ m_videoSettings.setQuality(QtMultimediaKit::NormalQuality);
+ setError(KErrNotSupported, tr("Unsupported video quality."));
+ return;
+ }
+ break;
+ case EVideoQualityAndBitRate:
+ if (quality == QtMultimediaKit::VeryLowQuality) {
+ m_videoSettings.setResolution(QSize(128,96));
+ m_videoSettings.setFrameRate(10);
+ } else if (quality == QtMultimediaKit::LowQuality) {
+ m_videoSettings.setResolution(QSize(176,144));
+ m_videoSettings.setFrameRate(15);
+ } else if (quality == QtMultimediaKit::NormalQuality) {
+ m_videoSettings.setResolution(QSize(176,144));
+ m_videoSettings.setFrameRate(15);
+ } else if (quality == QtMultimediaKit::HighQuality) {
+ m_videoSettings.setResolution(QSize(352,288));
+ m_videoSettings.setFrameRate(15);
+ } else if (quality == QtMultimediaKit::VeryHighQuality) {
+ if (m_cameraEngine && m_cameraEngine->CurrentCameraIndex() == 0)
+ m_videoSettings.setResolution(QSize(640,480)); // Primary camera
+ else
+ m_videoSettings.setResolution(QSize(352,288)); // Other cameras
+ m_videoSettings.setFrameRate(15);
+ } else {
+ m_videoSettings.setQuality(QtMultimediaKit::NormalQuality);
+ setError(KErrNotSupported, tr("Unsupported video quality."));
+ return;
+ }
+ break;
+ case EVideoQualityAndResolutionAndBitRate:
+ if (quality == QtMultimediaKit::VeryLowQuality) {
+ m_videoSettings.setFrameRate(10);
+ } else if (quality == QtMultimediaKit::LowQuality) {
+ m_videoSettings.setFrameRate(15);
+ } else if (quality == QtMultimediaKit::NormalQuality) {
+ m_videoSettings.setFrameRate(15);
+ } else if (quality == QtMultimediaKit::HighQuality) {
+ m_videoSettings.setFrameRate(15);
+ } else if (quality == QtMultimediaKit::VeryHighQuality) {
+ m_videoSettings.setFrameRate(15);
+ } else {
+ m_videoSettings.setQuality(QtMultimediaKit::NormalQuality);
+ setError(KErrNotSupported, tr("Unsupported video quality."));
+ return;
+ }
+ break;
+ case EVideoQualityAndResolutionAndFrameRate:
+ if (quality == QtMultimediaKit::VeryLowQuality) {
+ m_videoSettings.setBitRate(64000);
+ } else if (quality == QtMultimediaKit::LowQuality) {
+ m_videoSettings.setBitRate(64000);
+ } else if (quality == QtMultimediaKit::NormalQuality) {
+ m_videoSettings.setBitRate(128000);
+ } else if (quality == QtMultimediaKit::HighQuality) {
+ m_videoSettings.setBitRate(384000);
+ } else if (quality == QtMultimediaKit::VeryHighQuality) {
+ m_videoSettings.setBitRate(2000000);
+ } else {
+ m_videoSettings.setQuality(QtMultimediaKit::NormalQuality);
+ setError(KErrNotSupported, tr("Unsupported video quality."));
+ return;
+ }
+ break;
+ case EVideoQualityAndFrameRateAndBitRate:
+ if (quality == QtMultimediaKit::VeryLowQuality) {
+ m_videoSettings.setResolution(QSize(128,96));
+ } else if (quality == QtMultimediaKit::LowQuality) {
+ m_videoSettings.setResolution(QSize(176,144));
+ } else if (quality == QtMultimediaKit::NormalQuality) {
+ m_videoSettings.setResolution(QSize(176,144));
+ } else if (quality == QtMultimediaKit::HighQuality) {
+ m_videoSettings.setResolution(QSize(352,288));
+ } else if (quality == QtMultimediaKit::VeryHighQuality) {
+ if (m_cameraEngine && m_cameraEngine->CurrentCameraIndex() == 0)
+ m_videoSettings.setResolution(QSize(640,480)); // Primary camera
+ else
+ m_videoSettings.setResolution(QSize(352,288)); // Other cameras
+ } else {
+ m_videoSettings.setQuality(QtMultimediaKit::NormalQuality);
+ setError(KErrNotSupported, tr("Unsupported video quality."));
+ return;
+ }
+ break;
+ }
+
+ m_videoSettings.setQuality(quality);
+ m_uncommittedSettings = true;
+}
+
+void S60VideoCaptureSession::setAudioCaptureQuality(const QtMultimediaKit::EncodingQuality quality,
+ const AudioQualityDefinition mode)
+{
+ // Based on audio quality definition mode, select proper SampleRate and BitRate
+ switch (mode) {
+ case EOnlyAudioQuality:
+ switch (quality) {
+ case QtMultimediaKit::VeryLowQuality:
+ m_audioSettings.setBitRate(16000);
+ m_audioSettings.setSampleRate(-1);
+ break;
+ case QtMultimediaKit::LowQuality:
+ m_audioSettings.setBitRate(16000);
+ m_audioSettings.setSampleRate(-1);
+ break;
+ case QtMultimediaKit::NormalQuality:
+ m_audioSettings.setBitRate(32000);
+ m_audioSettings.setSampleRate(-1);
+ break;
+ case QtMultimediaKit::HighQuality:
+ m_audioSettings.setBitRate(64000);
+ m_audioSettings.setSampleRate(-1);
+ break;
+ case QtMultimediaKit::VeryHighQuality:
+ m_audioSettings.setBitRate(64000);
+ m_audioSettings.setSampleRate(-1);
+ break;
+ default:
+ m_audioSettings.setQuality(QtMultimediaKit::NormalQuality);
+ setError(KErrNotSupported, tr("Unsupported audio quality."));
+ return;
+ }
+ break;
+ case EAudioQualityAndBitRate:
+ switch (quality) {
+ case QtMultimediaKit::VeryLowQuality:
+ m_audioSettings.setSampleRate(-1);
+ break;
+ case QtMultimediaKit::LowQuality:
+ m_audioSettings.setSampleRate(-1);
+ break;
+ case QtMultimediaKit::NormalQuality:
+ m_audioSettings.setSampleRate(-1);
+ break;
+ case QtMultimediaKit::HighQuality:
+ m_audioSettings.setSampleRate(-1);
+ break;
+ case QtMultimediaKit::VeryHighQuality:
+ m_audioSettings.setSampleRate(-1);
+ break;
+ default:
+ m_audioSettings.setQuality(QtMultimediaKit::NormalQuality);
+ setError(KErrNotSupported, tr("Unsupported audio quality."));
+ return;
+ }
+ break;
+ case EAudioQualityAndSampleRate:
+ switch (quality) {
+ case QtMultimediaKit::VeryLowQuality:
+ m_audioSettings.setBitRate(16000);
+ break;
+ case QtMultimediaKit::LowQuality:
+ m_audioSettings.setBitRate(16000);
+ break;
+ case QtMultimediaKit::NormalQuality:
+ m_audioSettings.setBitRate(32000);
+ break;
+ case QtMultimediaKit::HighQuality:
+ m_audioSettings.setBitRate(64000);
+ break;
+ case QtMultimediaKit::VeryHighQuality:
+ m_audioSettings.setBitRate(64000);
+ break;
+ default:
+ m_audioSettings.setQuality(QtMultimediaKit::NormalQuality);
+ setError(KErrNotSupported, tr("Unsupported audio quality."));
+ return;
+ }
+ break;
+ case ENoAudioQuality:
+ // No actions required, just set quality parameter
+ break;
+
+ default:
+ setError(KErrGeneral, tr("Unexpected camera error."));
+ return;
+ }
+
+ m_audioSettings.setQuality(quality);
+ m_uncommittedSettings = true;
+}
+
+int S60VideoCaptureSession::initializeVideoRecording()
+{
+ if (m_error)
+ return m_error;
+
+ TRAPD(symbianError, doInitializeVideoRecorderL());
+ setError(symbianError, tr("Failed to initialize video recorder."));
+
+ return symbianError;
+}
+
+void S60VideoCaptureSession::releaseVideoRecording()
+{
+ if (m_captureState >= ERecording) {
+ m_videoRecorder->Stop();
+ if (m_durationTimer->isActive())
+ m_durationTimer->stop();
+ }
+
+ if (m_captureState >= EInitialized)
+ m_videoRecorder->Close();
+
+ // Reset state
+ m_captureState = ENotInitialized;
+
+ // Reset error to be able to recover from error
+ m_error = KErrNone;
+
+ // Reset flags
+ m_openWhenReady = false;
+ m_prepareAfterOpenComplete = false;
+ m_startAfterPrepareComplete = false;
+ m_uncommittedSettings = false;
+ m_commitSettingsWhenReady = false;
+}
+
+void S60VideoCaptureSession::startRecording()
+{
+ if (m_error) {
+ setError(m_error, tr("Unexpected recording error."));
+ return;
+ }
+
+ switch (m_captureState) {
+ case ENotInitialized:
+ case EInitializing:
+ case EInitialized:
+ if (m_captureState == EInitialized)
+ setOutputLocation(m_requestedSink);
+ m_startAfterPrepareComplete = true;
+ return;
+
+ case EOpening:
+ case EPreparing:
+ // Execute FileOpenL() and Prepare() asap and then start recording
+ m_startAfterPrepareComplete = true;
+ return;
+ case EOpenComplete:
+ case EPrepared:
+ if (m_captureState == EPrepared && !m_uncommittedSettings)
+ break;
+
+ // Revert state internally, since logically applying settings means going
+ // from OpenComplete ==> Preparing ==> Prepared.
+ m_captureState = EOpenComplete;
+ m_startAfterPrepareComplete = true;
+
+ // Commit settings and prepare with them
+ applyAllSettings();
+ return;
+ case ERecording:
+ // Discard
+ return;
+ case EPaused:
+ // Continue
+ break;
+
+ default:
+ setError(KErrGeneral, tr("Unexpected camera error."));
+ return;
+ }
+
+ // State should now be either Prepared with no Uncommitted Settings or Paused
+
+ if (!m_cameraStarted) {
+ m_startAfterPrepareComplete = true;
+ return;
+ }
+
+ if (m_cameraEngine && !m_cameraEngine->IsCameraReady()) {
+ setError(KErrNotReady, tr("Camera not ready to start video recording."));
+ return;
+ }
+
+ if (m_videoRecorder) {
+ m_videoRecorder->Record();
+ m_captureState = ERecording;
+ emit stateChanged(m_captureState);
+ m_durationTimer->start();
+
+ // Reset all flags
+ m_openWhenReady = false;
+ m_prepareAfterOpenComplete = false;
+ m_startAfterPrepareComplete = false;
+ } else {
+ setError(KErrNotReady, tr("Unexpected camera error."));
+ }
+}
+
+void S60VideoCaptureSession::pauseRecording()
+{
+ if (m_captureState == ERecording) {
+ if (m_videoRecorder) {
+ TRAPD(err, m_videoRecorder->PauseL());
+ setError(err, tr("Pausing video recording failed."));
+ m_captureState = EPaused;
+ emit stateChanged(m_captureState);
+ if (m_durationTimer->isActive())
+ m_durationTimer->stop();
+
+ // Notify last duration
+ TRAP(err, m_position = m_videoRecorder->DurationL().Int64() / 1000);
+ setError(err, tr("Cannot retrieve video position."));
+ emit positionChanged(m_position);
+ }
+ else
+ setError(KErrNotReady, tr("Unexpected camera error."));
+ }
+}
+
+void S60VideoCaptureSession::stopRecording(const bool reInitialize)
+{
+ if (m_captureState != ERecording && m_captureState != EPaused)
+ return; // Ignore
+
+ if (m_videoRecorder) {
+ m_videoRecorder->Stop();
+ m_videoRecorder->Close();
+
+ // Notify muting is disabled if needed
+ if (m_muted)
+ emit mutedChanged(false);
+
+ m_captureState = ENotInitialized;
+ emit stateChanged(m_captureState);
+
+ if (m_durationTimer->isActive())
+ m_durationTimer->stop();
+
+ // VideoRecording will be re-initialized unless explicitly requested not to do so
+ if (reInitialize) {
+ if (m_cameraEngine->IsCameraReady())
+ initializeVideoRecording();
+ }
+ }
+ else
+ setError(KErrNotReady, tr("Unexpected camera error."));
+}
+
+void S60VideoCaptureSession::updateVideoCaptureContainers()
+{
+ TRAPD(err, doUpdateVideoCaptureContainersL());
+ setError(err, tr("Failed to gather video container information."));
+}
+
+void S60VideoCaptureSession::doUpdateVideoCaptureContainersL()
+{
+ // Clear container data structure
+ QList<TInt> mapControllers = m_videoControllerMap.keys();
+ for (int i = 0; i < mapControllers.size(); ++i) {
+ foreach(VideoFormatData data, m_videoControllerMap[mapControllers[i]]){
+ data.supportedMimeTypes.clear();
+ }
+ m_videoControllerMap[mapControllers[i]].clear();
+ }
+ m_videoControllerMap.clear();
+
+ // Resolve the supported video format and retrieve a list of controllers
+ CMMFControllerPluginSelectionParameters* pluginParameters =
+ CMMFControllerPluginSelectionParameters::NewLC();
+ CMMFFormatSelectionParameters* format =
+ CMMFFormatSelectionParameters::NewLC();
+
+ // Set the play and record format selection parameters to be blank.
+ // Format support is only retrieved if requested.
+ pluginParameters->SetRequiredPlayFormatSupportL(*format);
+ pluginParameters->SetRequiredRecordFormatSupportL(*format);
+
+ // Set the media IDs
+ RArray<TUid> mediaIds;
+ CleanupClosePushL(mediaIds);
+
+ User::LeaveIfError(mediaIds.Append(KUidMediaTypeVideo));
+
+ // Get plugins that support at least video
+ pluginParameters->SetMediaIdsL(mediaIds,
+ CMMFPluginSelectionParameters::EAllowOtherMediaIds);
+ pluginParameters->SetPreferredSupplierL(KNullDesC,
+ CMMFPluginSelectionParameters::EPreferredSupplierPluginsFirstInList);
+
+ // Array to hold all the controllers support the match data
+ RMMFControllerImplInfoArray controllers;
+ CleanupResetAndDestroyPushL(controllers);
+ pluginParameters->ListImplementationsL(controllers);
+
+ // Find the first controller with at least one record format available
+ for (TInt index = 0; index < controllers.Count(); ++index) {
+
+ m_videoControllerMap.insert(controllers[index]->Uid().iUid, QHash<TInt,VideoFormatData>());
+
+ const RMMFFormatImplInfoArray& recordFormats = controllers[index]->RecordFormats();
+ for (TInt j = 0; j < recordFormats.Count(); ++j) {
+ VideoFormatData formatData;
+ formatData.description = QString::fromUtf16(
+ recordFormats[j]->DisplayName().Ptr(),
+ recordFormats[j]->DisplayName().Length());
+
+ const CDesC8Array& mimeTypes = recordFormats[j]->SupportedMimeTypes();
+ for (int k = 0; k < mimeTypes.Count(); ++k) {
+ TPtrC8 mimeType = mimeTypes[k];
+ QString type = QString::fromUtf8((char *)mimeType.Ptr(),
+ mimeType.Length());
+ formatData.supportedMimeTypes.append(type);
+ }
+
+ m_videoControllerMap[controllers[index]->Uid().iUid].insert(recordFormats[j]->Uid().iUid, formatData);
+ }
+ }
+
+ CleanupStack::PopAndDestroy(&controllers);
+ CleanupStack::PopAndDestroy(&mediaIds);
+ CleanupStack::PopAndDestroy(format);
+ CleanupStack::PopAndDestroy(pluginParameters);
+}
+
+/*
+ * This goes through the available controllers and selects proper one based
+ * on the format. Function sets proper UIDs to be used for controller and format.
+ */
+void S60VideoCaptureSession::selectController(const QString &format,
+ TUid &controllerUid,
+ TUid &formatUid)
+{
+ QList<TInt> controllers = m_videoControllerMap.keys();
+ QList<TInt> formats;
+
+ for (int i = 0; i < controllers.count(); ++i) {
+ formats = m_videoControllerMap[controllers[i]].keys();
+ for (int j = 0; j < formats.count(); ++j) {
+ VideoFormatData formatData = m_videoControllerMap[controllers[i]][formats[j]];
+ if (formatData.supportedMimeTypes.contains(format, Qt::CaseInsensitive)) {
+ controllerUid = TUid::Uid(controllers[i]);
+ formatUid = TUid::Uid(formats[j]);
+ }
+ }
+ }
+}
+
+QStringList S60VideoCaptureSession::supportedVideoCaptureCodecs()
+{
+ return m_videoCodecList;
+}
+
+QStringList S60VideoCaptureSession::supportedAudioCaptureCodecs()
+{
+ QStringList keys = m_audioCodecList.keys();
+ keys.sort();
+ return keys;
+}
+
+QList<int> S60VideoCaptureSession::supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous)
+{
+ QList<int> rates;
+
+ TRAPD(err, rates = doGetSupportedSampleRatesL(settings, continuous));
+ if (err != KErrNotSupported)
+ setError(err, tr("Failed to query information of supported sample rates."));
+
+ return rates;
+}
+
+QList<int> S60VideoCaptureSession::doGetSupportedSampleRatesL(const QAudioEncoderSettings &settings, bool *continuous)
+{
+ QList<int> sampleRates;
+
+ if (m_captureState < EOpenComplete)
+ return sampleRates;
+
+#ifndef S60_31_PLATFORM
+ RArray<TUint> supportedSampleRates;
+ CleanupClosePushL(supportedSampleRates);
+
+ if (!settings.codec().isEmpty()) {
+
+ TFourCC currentAudioCodec;
+ currentAudioCodec = m_videoRecorder->AudioTypeL();
+
+ TFourCC requestedAudioCodec;
+ if (qstrcmp(settings.codec().toLocal8Bit().constData(), "audio/aac") == 0)
+ requestedAudioCodec.Set(KMMFFourCCCodeAAC);
+ else if (qstrcmp(settings.codec().toLocal8Bit().constData(), "audio/amr") == 0)
+ requestedAudioCodec.Set(KMMFFourCCCodeAMR);
+ m_videoRecorder->SetAudioTypeL(requestedAudioCodec);
+
+ m_videoRecorder->GetSupportedAudioSampleRatesL(supportedSampleRates);
+
+ m_videoRecorder->SetAudioTypeL(currentAudioCodec);
+ }
+ else
+ m_videoRecorder->GetSupportedAudioSampleRatesL(supportedSampleRates);
+
+ for (int i = 0; i < supportedSampleRates.Count(); ++i)
+ sampleRates.append(int(supportedSampleRates[i]));
+
+ CleanupStack::PopAndDestroy(); // RArray<TUint> supportedSampleRates
+#else // S60 3.1 Platform
+ Q_UNUSED(settings);
+#endif // S60_31_PLATFORM
+
+ if (continuous)
+ *continuous = false;
+
+ return sampleRates;
+}
+
+void S60VideoCaptureSession::setAudioSampleRate(const int sampleRate)
+{
+ if (sampleRate != -1)
+ m_audioSettings.setSampleRate(sampleRate);
+
+ m_uncommittedSettings = true;
+}
+
+void S60VideoCaptureSession::setAudioBitRate(const int bitRate)
+{
+ if (bitRate != -1)
+ m_audioSettings.setBitRate(bitRate);
+
+ m_uncommittedSettings = true;
+}
+
+void S60VideoCaptureSession::setAudioChannelCount(const int channelCount)
+{
+ if (channelCount != -1)
+ m_audioSettings.setChannelCount(channelCount);
+
+ m_uncommittedSettings = true;
+}
+
+void S60VideoCaptureSession::setVideoCaptureCodec(const QString &codecName)
+{
+ if (codecName == m_videoSettings.codec())
+ return;
+
+ if (codecName.isEmpty())
+ m_videoSettings.setCodec(KMimeTypeDefaultVideoCodec); // Use default
+ else
+ m_videoSettings.setCodec(codecName);
+
+ m_uncommittedSettings = true;
+}
+
+void S60VideoCaptureSession::setAudioCaptureCodec(const QString &codecName)
+{
+ if (codecName == m_audioSettings.codec())
+ return;
+
+ if (codecName.isEmpty()) {
+ m_audioSettings.setCodec(KMimeTypeDefaultAudioCodec); // Use default
+ } else {
+ // If information of supported codecs is already available check that
+ // given codec is supported
+ if (m_captureState >= EOpenComplete) {
+ if (m_audioCodecList.contains(codecName)) {
+ m_audioSettings.setCodec(codecName);
+ m_uncommittedSettings = true;
+ } else {
+ setError(KErrNotSupported, tr("Requested audio codec is not supported"));
+ }
+ } else {
+ m_audioSettings.setCodec(codecName);
+ m_uncommittedSettings = true;
+ }
+ }
+}
+
+QString S60VideoCaptureSession::videoCaptureCodecDescription(const QString &codecName)
+{
+ QString codecDescription;
+ if (codecName.contains("video/H263-2000", Qt::CaseInsensitive))
+ codecDescription.append("H.263 Video Codec");
+ else if (codecName.contains("video/mp4v-es", Qt::CaseInsensitive))
+ codecDescription.append("MPEG-4 Part 2 Video Codec");
+ else if (codecName.contains("video/H264", Qt::CaseInsensitive))
+ codecDescription.append("H.264 AVC (MPEG-4 Part 10) Video Codec");
+ else
+ codecDescription.append("Video Codec");
+
+ return codecDescription;
+}
+
+void S60VideoCaptureSession::doSetCodecsL()
+{
+ // Determine Profile and Level for the video codec if needed
+ // (MimeType/Profile-level-id contains "profile" if profile/level info is available)
+ if (!m_videoSettings.codec().contains(QString("profile"), Qt::CaseInsensitive))
+ m_videoSettings.setCodec(determineProfileAndLevel());
+
+ if (m_videoRecorder) {
+ TPtrC16 str(reinterpret_cast<const TUint16*>(m_videoSettings.codec().utf16()));
+ HBufC8* videoCodec(0);
+ videoCodec = CnvUtfConverter::ConvertFromUnicodeToUtf8L(str);
+ CleanupStack::PushL(videoCodec);
+
+ TFourCC audioCodec = m_audioCodecList[m_audioSettings.codec()];
+
+ TInt vErr = KErrNone;
+ TInt aErr = KErrNone;
+ TRAP(vErr, m_videoRecorder->SetVideoTypeL(*videoCodec));
+ TRAP(aErr, m_videoRecorder->SetAudioTypeL(audioCodec));
+
+ User::LeaveIfError(vErr);
+ User::LeaveIfError(aErr);
+
+ CleanupStack::PopAndDestroy(videoCodec);
+ }
+ else
+ setError(KErrNotReady, tr("Unexpected camera error."));
+}
+
+QString S60VideoCaptureSession::determineProfileAndLevel()
+{
+ QString determinedMimeType = m_videoSettings.codec();
+
+ // H.263
+ if (determinedMimeType.contains(QString("video/H263-2000"), Qt::CaseInsensitive)) {
+ if ((m_videoSettings.resolution().width() * m_videoSettings.resolution().height()) > (176*144)) {
+ if (m_videoSettings.frameRate() > 15.0)
+ determinedMimeType.append("; profile=0; level=20");
+ else
+ determinedMimeType.append("; profile=0; level=40");
+ } else {
+ if (m_videoSettings.bitRate() > 64000)
+ determinedMimeType.append("; profile=0; level=45");
+ else
+ determinedMimeType.append("; profile=0; level=10");
+ }
+
+ // MPEG-4
+ } else if (determinedMimeType.contains(QString("video/mp4v-es"), Qt::CaseInsensitive)) {
+ if ((m_videoSettings.resolution().width() * m_videoSettings.resolution().height()) > (720*480)) {
+ determinedMimeType.append("; profile-level-id=6");
+ } else if ((m_videoSettings.resolution().width() * m_videoSettings.resolution().height()) > (640*480)) {
+ determinedMimeType.append("; profile-level-id=5");
+ } else if ((m_videoSettings.resolution().width() * m_videoSettings.resolution().height()) > (352*288)) {
+ determinedMimeType.append("; profile-level-id=4");
+ } else if ((m_videoSettings.resolution().width() * m_videoSettings.resolution().height()) > (176*144)) {
+ if (m_videoSettings.frameRate() > 15.0)
+ determinedMimeType.append("; profile-level-id=3");
+ else
+ determinedMimeType.append("; profile-level-id=2");
+ } else {
+ if (m_videoSettings.bitRate() > 64000)
+ determinedMimeType.append("; profile-level-id=9");
+ else
+ determinedMimeType.append("; profile-level-id=1");
+ }
+
+ // H.264
+ } else if (determinedMimeType.contains(QString("video/H264"), Qt::CaseInsensitive)) {
+ if ((m_videoSettings.resolution().width() * m_videoSettings.resolution().height()) > (640*480)) {
+ determinedMimeType.append("; profile-level-id=42801F");
+ } else if ((m_videoSettings.resolution().width() * m_videoSettings.resolution().height()) > (352*288)) {
+ determinedMimeType.append("; profile-level-id=42801E");
+ } else if ((m_videoSettings.resolution().width() * m_videoSettings.resolution().height()) > (176*144)) {
+ if (m_videoSettings.frameRate() > 15.0)
+ determinedMimeType.append("; profile-level-id=428015");
+ else
+ determinedMimeType.append("; profile-level-id=42800C");
+ } else {
+ determinedMimeType.append("; profile-level-id=42900B");
+ }
+ }
+
+ return determinedMimeType;
+}
+
+void S60VideoCaptureSession::setBitrate(const int bitrate)
+{
+ m_videoSettings.setBitRate(bitrate);
+
+ m_uncommittedSettings = true;
+}
+
+void S60VideoCaptureSession::doSetBitrate(const int &bitrate)
+{
+ if (bitrate != -1) {
+ if (m_videoRecorder) {
+ TRAPD(err, m_videoRecorder->SetVideoBitRateL(bitrate));
+ if (err) {
+ if (err == KErrNotSupported || err == KErrArgument) {
+ setError(KErrNotSupported, tr("Requested video bitrate is not supported."));
+ m_videoSettings.setBitRate(64000); // Reset
+ } else {
+ setError(err, tr("Failed to set video bitrate."));
+ }
+ }
+ } else {
+ setError(KErrNotReady, tr("Unexpected camera error."));
+ }
+ }
+}
+
+void S60VideoCaptureSession::setVideoResolution(const QSize &resolution)
+{
+ m_videoSettings.setResolution(resolution);
+
+ m_uncommittedSettings = true;
+}
+
+void S60VideoCaptureSession::doSetVideoResolution(const QSize &resolution)
+{
+ TSize size((TInt)resolution.width(), (TInt)resolution.height());
+
+ // Make sure resolution is not too big if main camera is not used
+ if (m_cameraEngine->CurrentCameraIndex() != 0) {
+ TCameraInfo *info = m_cameraEngine->CameraInfo();
+ if (info) {
+ TInt videoResolutionCount = info->iNumVideoFrameSizesSupported;
+ TSize maxCameraVideoResolution = TSize(0,0);
+ CCamera *camera = m_cameraEngine->Camera();
+ if (camera) {
+ for (TInt i = 0; i < videoResolutionCount; ++i) {
+ TSize checkedResolution;
+ // Use YUV video max frame size in the check (Through
+ // CVideoRecorderUtility/DevVideoRecord it is possible to
+ // query only encoder maximums)
+ camera->EnumerateVideoFrameSizes(checkedResolution, i, CCamera::EFormatYUV420Planar);
+ if ((checkedResolution.iWidth * checkedResolution.iHeight) >
+ (maxCameraVideoResolution.iWidth * maxCameraVideoResolution.iHeight))
+ maxCameraVideoResolution = checkedResolution;
+ }
+ if ((maxCameraVideoResolution.iWidth * maxCameraVideoResolution.iHeight) <
+ (size.iWidth * size.iHeight)) {
+ size = maxCameraVideoResolution;
+ setError(KErrNotSupported, tr("Requested resolution is not supported for this camera."));
+ }
+ }
+ else
+ setError(KErrGeneral, tr("Could not query supported video resolutions."));
+ }else
+ setError(KErrGeneral, tr("Could not query supported video resolutions."));
+ }
+
+ if (resolution.width() != -1 && resolution.height() != -1) {
+ if (m_videoRecorder) {
+ TRAPD(err, m_videoRecorder->SetVideoFrameSizeL((TSize)size));
+ if (err == KErrNotSupported || err == KErrArgument) {
+ setError(KErrNotSupported, tr("Requested video resolution is not supported."));
+ TSize fallBack(640,480);
+ TRAPD(err, m_videoRecorder->SetVideoFrameSizeL(fallBack));
+ if (err == KErrNone) {
+ m_videoSettings.setResolution(QSize(fallBack.iWidth,fallBack.iHeight));
+ } else {
+ fallBack = TSize(176,144);
+ TRAPD(err, m_videoRecorder->SetVideoFrameSizeL(fallBack));
+ if (err == KErrNone)
+ m_videoSettings.setResolution(QSize(fallBack.iWidth,fallBack.iHeight));
+ }
+ } else {
+ setError(err, tr("Failed to set video resolution."));
+ }
+ } else {
+ setError(KErrNotReady, tr("Unexpected camera error."));
+ }
+ }
+}
+
+void S60VideoCaptureSession::setFrameRate(qreal rate)
+{
+ m_videoSettings.setFrameRate(rate);
+
+ m_uncommittedSettings = true;
+}
+
+void S60VideoCaptureSession::doSetFrameRate(qreal rate)
+{
+ if (rate != 0) {
+ if (m_videoRecorder) {
+ bool continuous = false;
+ QList<qreal> list = supportedVideoFrameRates(&continuous);
+ qreal maxRate = 0.0;
+ foreach (qreal fRate, list)
+ if (fRate > maxRate)
+ maxRate = fRate;
+ if (maxRate >= rate && rate > 0) {
+ TRAPD(err, m_videoRecorder->SetVideoFrameRateL((TReal32)rate));
+ if (err == KErrNotSupported) {
+ setError(KErrNotSupported, tr("Requested framerate is not supported."));
+ TReal32 fallBack = 15.0;
+ TRAPD(err, m_videoRecorder->SetVideoFrameRateL(fallBack));
+ if (err == KErrNone)
+ m_videoSettings.setFrameRate((qreal)fallBack);
+ } else {
+ if (err == KErrArgument) {
+ setError(KErrNotSupported, tr("Requested framerate is not supported."));
+ m_videoSettings.setFrameRate(15.0); // Reset
+ } else {
+ setError(err, tr("Failed to set video framerate."));
+ }
+ }
+ } else {
+ setError(KErrNotSupported, tr("Requested framerate is not supported."));
+ m_videoSettings.setFrameRate(15.0); // Reset
+ }
+ } else {
+ setError(KErrNotReady, tr("Unexpected camera error."));
+ }
+ }
+}
+
+void S60VideoCaptureSession::setVideoEncodingMode(const QtMultimediaKit::EncodingMode mode)
+{
+ // This has no effect as it has no support in Symbian
+
+ if (mode == QtMultimediaKit::ConstantQualityEncoding) {
+ m_videoSettings.setEncodingMode(mode);
+ return;
+ }
+
+ setError(KErrNotSupported, tr("Requested video encoding mode is not supported"));
+
+ // m_uncommittedSettings = true;
+}
+
+void S60VideoCaptureSession::setAudioEncodingMode(const QtMultimediaKit::EncodingMode mode)
+{
+ // This has no effect as it has no support in Symbian
+
+ if (mode == QtMultimediaKit::ConstantQualityEncoding) {
+ m_audioSettings.setEncodingMode(mode);
+ return;
+ }
+
+ setError(KErrNotSupported, tr("Requested audio encoding mode is not supported"));
+
+ // m_uncommittedSettings = true;
+}
+
+void S60VideoCaptureSession::initializeVideoCaptureSettings()
+{
+ // Check if user has already requested some settings
+ if (m_captureSettingsSet)
+ return;
+
+ QSize resolution(-1, -1);
+ qreal frameRate(0);
+ int bitRate(-1);
+
+ if (m_cameraEngine) {
+
+ if (m_videoRecorder && m_captureState >= EInitialized) {
+
+ // Resolution
+ QList<QSize> resos = supportedVideoResolutions(0);
+ foreach (QSize reso, resos) {
+ if ((reso.width() * reso.height()) > (resolution.width() * resolution.height()))
+ resolution = reso;
+ }
+
+ // Needed to query supported framerates for this codec/resolution pair
+ m_videoSettings.setCodec(KMimeTypeDefaultVideoCodec);
+ m_videoSettings.setResolution(resolution);
+
+ // FrameRate
+ QList<qreal> fRates = supportedVideoFrameRates(m_videoSettings, 0);
+ foreach (qreal rate, fRates) {
+ if (rate > frameRate)
+ frameRate = rate;
+ }
+
+ // BitRate
+#ifdef SYMBIAN_3_PLATFORM
+ if (m_cameraEngine->CurrentCameraIndex() == 0)
+ bitRate = KBiR_H264_PLID_42801F // 14Mbps
+ else
+ bitRate = KBiR_H264_PLID_428016 // 4Mbps
+#else // Other platforms
+ if (m_cameraEngine->CurrentCameraIndex() == 0)
+ bitRate = KBiR_MPEG4_PLID_4 // 2/4Mbps
+ else
+ bitRate = KBiR_MPEG4_PLID_3 // 384kbps
+#endif // SYMBIAN_3_PLATFORM
+
+ } else {
+#ifdef SYMBIAN_3_PLATFORM
+ if (m_cameraEngine->CurrentCameraIndex() == 0) {
+ // Primary camera
+ resolution = KResH264_PLID_42801F; // 1280x720
+ frameRate = KFrR_H264_PLID_42801F; // 30fps
+ bitRate = KBiR_H264_PLID_42801F; // 14Mbps
+ } else {
+ // Other cameras
+ resolution = KResH264_PLID_42801E; // 640x480
+ frameRate = KFrR_H264_PLID_428014; // 30fps
+ bitRate = KBiR_H264_PLID_428016; // 4Mbps
+ }
+#else // Other platforms
+ if (m_cameraEngine->CurrentCameraIndex() == 0) {
+ // Primary camera
+ resolution = KResMPEG4_PLID_4; // 640x480
+ frameRate = KFrR_MPEG4_PLID_4; // 15/30fps
+ bitRate = KBiR_MPEG4_PLID_4; // 2/4Mbps
+ } else {
+ // Other cameras
+ resolution = KResMPEG4_PLID_3; // 352x288
+ frameRate = KFrR_MPEG4; // 15fps
+ bitRate = KBiR_MPEG4_PLID_3; // 384kbps
+ }
+#endif // SYMBIAN_3_PLATFORM
+ }
+ } else {
+#ifdef SYMBIAN_3_PLATFORM
+ resolution = KResH264_PLID_42801F;
+ frameRate = KFrR_H264_PLID_42801F;
+ bitRate = KBiR_H264_PLID_42801F;
+#else // Pre-Symbian3 Platforms
+ resolution = KResMPEG4_PLID_4;
+ frameRate = KFrR_MPEG4_PLID_4;
+ bitRate = KBiR_MPEG4_PLID_4;
+#endif // SYMBIAN_3_PLATFORM
+ }
+
+ // Set specified settings (Resolution, FrameRate and BitRate)
+ m_videoSettings.setResolution(resolution);
+ m_videoSettings.setFrameRate(frameRate);
+ m_videoSettings.setBitRate(bitRate);
+
+ // Video Settings: Codec, EncodingMode and Quality
+ m_videoSettings.setCodec(KMimeTypeDefaultVideoCodec);
+ m_videoSettings.setEncodingMode(QtMultimediaKit::ConstantQualityEncoding);
+ m_videoSettings.setQuality(QtMultimediaKit::VeryHighQuality);
+
+ // Audio Settings
+ m_audioSettings.setCodec(KMimeTypeDefaultAudioCodec);
+ m_audioSettings.setBitRate(KDefaultBitRate);
+ m_audioSettings.setSampleRate(KDefaultSampleRate);
+ m_audioSettings.setChannelCount(KDefaultChannelCount);
+ m_audioSettings.setEncodingMode(QtMultimediaKit::ConstantQualityEncoding);
+ m_audioSettings.setQuality(QtMultimediaKit::VeryHighQuality);
+}
+
+QSize S60VideoCaptureSession::pixelAspectRatio()
+{
+#ifndef S60_31_PLATFORM
+ TVideoAspectRatio par;
+ TRAPD(err, m_videoRecorder->GetPixelAspectRatioL(par));
+ if (err)
+ setError(err, tr("Failed to query current pixel aspect ratio."));
+ return QSize(par.iNumerator, par.iDenominator);
+#else // S60_31_PLATFORM
+ return QSize();
+#endif // !S60_31_PLATFORM
+}
+
+void S60VideoCaptureSession::setPixelAspectRatio(const QSize par)
+{
+#ifndef S60_31_PLATFORM
+
+ const TVideoAspectRatio videoPar(par.width(), par.height());
+ TRAPD(err, m_videoRecorder->SetPixelAspectRatioL(videoPar));
+ if (err)
+ setError(err, tr("Failed to set pixel aspect ratio."));
+#else // S60_31_PLATFORM
+ Q_UNUSED(par);
+#endif // !S60_31_PLATFORM
+
+ m_uncommittedSettings = true;
+}
+
+int S60VideoCaptureSession::gain()
+{
+ TInt gain = 0;
+ TRAPD(err, gain = m_videoRecorder->GainL());
+ if (err)
+ setError(err, tr("Failed to query video gain."));
+ return (int)gain;
+}
+
+void S60VideoCaptureSession::setGain(const int gain)
+{
+ TRAPD(err, m_videoRecorder->SetGainL(gain));
+ if (err)
+ setError(err, tr("Failed to set video gain."));
+
+ m_uncommittedSettings = true;
+}
+
+int S60VideoCaptureSession::maxClipSizeInBytes() const
+{
+ return m_maxClipSize;
+}
+
+void S60VideoCaptureSession::setMaxClipSizeInBytes(const int size)
+{
+ TRAPD(err, m_videoRecorder->SetMaxClipSizeL(size));
+ if (err) {
+ setError(err, tr("Failed to set maximum video size."));
+ } else
+ m_maxClipSize = size;
+
+ m_uncommittedSettings = true;
+}
+
+void S60VideoCaptureSession::MvruoOpenComplete(TInt aError)
+{
+ if (m_error)
+ return;
+
+ if (aError == KErrNone && m_videoRecorder) {
+ if (m_captureState == EInitializing) {
+ // Dummy file open completed, initialize settings
+ TRAPD(err, doPopulateAudioCodecsL());
+ setError(err, tr("Failed to gather information of supported audio codecs."));
+
+ // For DevVideoRecord codecs are populated during
+ // doPopulateVideoCodecsDataL()
+ TRAP(err, doPopulateVideoCodecsL());
+ setError(err, tr("Failed to gather information of supported video codecs."));
+#ifndef S60_DEVVIDEO_RECORDING_SUPPORTED
+ // Max parameters needed to be populated, if not using DevVideoRecord
+ // Otherwise done already in constructor
+ doPopulateMaxVideoParameters();
+#endif // S60_DEVVIDEO_RECORDING_SUPPORTED
+
+ m_captureState = EInitialized;
+ emit stateChanged(m_captureState);
+
+ // Initialize settings if not already done
+ initializeVideoCaptureSettings();
+
+ // Validate codecs to be used
+ validateRequestedCodecs();
+
+ if (m_openWhenReady || m_prepareAfterOpenComplete || m_startAfterPrepareComplete) {
+ setOutputLocation(m_requestedSink);
+ m_openWhenReady = false; // Reset
+ }
+ if (m_commitSettingsWhenReady) {
+ applyAllSettings();
+ m_commitSettingsWhenReady = false; // Reset
+ }
+ return;
+
+ } else if (m_captureState == EOpening) {
+ // Actual file open completed
+ m_captureState = EOpenComplete;
+ emit stateChanged(m_captureState);
+
+ // Prepare right away
+ if (m_startAfterPrepareComplete || m_prepareAfterOpenComplete) {
+ m_prepareAfterOpenComplete = false; // Reset
+
+ // Commit settings and prepare with them
+ applyAllSettings();
+ }
+ return;
+
+ } else if (m_captureState == ENotInitialized) {
+ // Resources released while waiting OpenFileL to complete
+ m_videoRecorder->Close();
+ return;
+
+ } else {
+ setError(KErrGeneral, tr("Unexpected camera error."));
+ return;
+ }
+ }
+
+ m_videoRecorder->Close();
+ if (aError == KErrNotFound || aError == KErrNotSupported || aError == KErrArgument)
+ setError(KErrGeneral, tr("Requested video container or controller is not supported."));
+ else
+ setError(KErrGeneral, tr("Failure during video recorder initialization."));
+}
+
+void S60VideoCaptureSession::MvruoPrepareComplete(TInt aError)
+{
+ if (m_error)
+ return;
+
+ if(aError == KErrNone) {
+ if (m_captureState == ENotInitialized) {
+ // Resources released while waiting for Prepare to complete
+ m_videoRecorder->Close();
+ return;
+ }
+
+ emit captureSizeChanged(m_videoSettings.resolution());
+
+ m_captureState = EPrepared;
+ emit stateChanged(EPrepared);
+
+ // Check the actual active settings
+ queryAudioEncoderSettings();
+ queryVideoEncoderSettings();
+
+ if (m_openWhenReady == true) {
+ setOutputLocation(m_requestedSink);
+ m_openWhenReady = false; // Reset
+ }
+
+ if (m_commitSettingsWhenReady) {
+ applyAllSettings();
+ m_commitSettingsWhenReady = false; // Reset
+ }
+
+ if (m_startAfterPrepareComplete) {
+ m_startAfterPrepareComplete = false; // Reset
+ startRecording();
+ }
+ } else {
+ m_videoRecorder->Close();
+ if (aError == KErrNotSupported)
+ setError(aError, tr("Camera preparation for video recording failed because of unsupported setting."));
+ else
+ setError(aError, tr("Failed to prepare camera for video recording."));
+ }
+}
+
+void S60VideoCaptureSession::MvruoRecordComplete(TInt aError)
+{
+ if (!m_videoRecorder) {
+ setError(KErrNotReady, tr("Unexpected camera error."));
+ return;
+ }
+
+ if((aError == KErrNone || aError == KErrCompletion)) {
+ m_videoRecorder->Stop();
+
+ // Reset state
+ if (m_captureState != ENotInitialized) {
+ m_captureState = ENotInitialized;
+ emit stateChanged(m_captureState);
+ if (m_durationTimer->isActive())
+ m_durationTimer->stop();
+ }
+
+ if (m_cameraEngine->IsCameraReady())
+ initializeVideoRecording();
+ }
+ m_videoRecorder->Close();
+
+ // Notify muting is disabled if needed
+ if (m_muted)
+ emit mutedChanged(false);
+
+ if (aError == KErrDiskFull)
+ setError(aError, tr("Not enough space for video, recording stopped."));
+ else
+ setError(aError, tr("Recording stopped due to unexpected error."));
+}
+
+void S60VideoCaptureSession::MvruoEvent(const TMMFEvent& aEvent)
+{
+ Q_UNUSED(aEvent);
+}
+
+#ifdef S60_DEVVIDEO_RECORDING_SUPPORTED
+void S60VideoCaptureSession::MdvroReturnPicture(TVideoPicture *aPicture)
+{
+ // Not used
+ Q_UNUSED(aPicture);
+}
+
+void S60VideoCaptureSession::MdvroSupplementalInfoSent()
+{
+ // Not used
+}
+
+void S60VideoCaptureSession::MdvroNewBuffers()
+{
+ // Not used
+}
+
+void S60VideoCaptureSession::MdvroFatalError(TInt aError)
+{
+ setError(aError, tr("Unexpected camera error."));
+}
+
+void S60VideoCaptureSession::MdvroInitializeComplete(TInt aError)
+{
+ // Not used
+ Q_UNUSED(aError);
+}
+
+void S60VideoCaptureSession::MdvroStreamEnd()
+{
+ // Not used
+}
+
+/*
+ * This populates video codec information (supported codecs, resolutions,
+ * framerates, etc.) using DevVideoRecord API.
+ */
+void S60VideoCaptureSession::doPopulateVideoCodecsDataL()
+{
+ RArray<TUid> encoders;
+ CleanupClosePushL(encoders);
+
+ CMMFDevVideoRecord *mDevVideoRecord = CMMFDevVideoRecord::NewL(*this);
+ CleanupStack::PushL(mDevVideoRecord);
+
+ // Retrieve list of all encoders provided by the platform
+ mDevVideoRecord->GetEncoderListL(encoders);
+
+ for (int i = 0; i < encoders.Count(); ++i ) {
+
+ CVideoEncoderInfo *encoderInfo = mDevVideoRecord->VideoEncoderInfoLC(encoders[i]);
+
+ // Discard encoders that are not HW accelerated and do not support direct capture
+ if (encoderInfo->Accelerated() == false || encoderInfo->SupportsDirectCapture() == false) {
+ CleanupStack::Check(encoderInfo);
+ CleanupStack::PopAndDestroy(encoderInfo);
+ continue;
+ }
+
+ m_videoParametersForEncoder.append(MaxResolutionRatesAndTypes());
+ int newIndex = m_videoParametersForEncoder.count() - 1;
+
+ m_videoParametersForEncoder[newIndex].bitRate = (int)encoderInfo->MaxBitrate();
+
+ // Get supported MIME Types
+ const RPointerArray<CCompressedVideoFormat> &videoFormats = encoderInfo->SupportedOutputFormats();
+ for(int x = 0; x < videoFormats.Count(); ++x) {
+ QString codecMimeType = QString::fromUtf8((char *)videoFormats[x]->MimeType().Ptr(),videoFormats[x]->MimeType().Length());
+
+ m_videoParametersForEncoder[newIndex].mimeTypes.append(codecMimeType);
+ }
+
+ // Get supported maximum Resolution/Framerate pairs
+ const RArray<TPictureRateAndSize> &ratesAndSizes = encoderInfo->MaxPictureRates();
+ SupportedFrameRatePictureSize data;
+ for(int j = 0; j < ratesAndSizes.Count(); ++j) {
+ data.frameRate = ratesAndSizes[j].iPictureRate;
+ data.frameSize = QSize(ratesAndSizes[j].iPictureSize.iWidth, ratesAndSizes[j].iPictureSize.iHeight);
+
+ // Save data to the hash
+ m_videoParametersForEncoder[newIndex].frameRatePictureSizePair.append(data);
+ }
+
+ CleanupStack::Check(encoderInfo);
+ CleanupStack::PopAndDestroy(encoderInfo);
+ }
+
+ CleanupStack::Check(mDevVideoRecord);
+ CleanupStack::PopAndDestroy(mDevVideoRecord);
+ CleanupStack::PopAndDestroy(); // RArray<TUid> encoders
+}
+#endif // S60_DEVVIDEO_RECORDING_SUPPORTED
+
+QStringList S60VideoCaptureSession::supportedVideoContainers()
+{
+ QStringList containers;
+
+ QList<TInt> controllers = m_videoControllerMap.keys();
+ for (int i = 0; i < controllers.count(); ++i) {
+ foreach (VideoFormatData formatData, m_videoControllerMap[controllers[i]]) {
+ for (int j = 0; j < formatData.supportedMimeTypes.count(); ++j) {
+ if (containers.contains(formatData.supportedMimeTypes[j], Qt::CaseInsensitive) == false)
+ containers.append(formatData.supportedMimeTypes[j]);
+ }
+ }
+ }
+
+ return containers;
+}
+
+bool S60VideoCaptureSession::isSupportedVideoContainer(const QString &containerName)
+{
+ return supportedVideoContainers().contains(containerName, Qt::CaseInsensitive);
+}
+
+QString S60VideoCaptureSession::videoContainer() const
+{
+ return m_container;
+}
+
+void S60VideoCaptureSession::setVideoContainer(const QString &containerName)
+{
+ if (containerName == m_requestedContainer)
+ return;
+
+ if (containerName.isEmpty()) {
+ m_requestedContainer = KMimeTypeDefaultContainer; // Use default
+ } else {
+ if (supportedVideoContainers().contains(containerName)) {
+ m_requestedContainer = containerName;
+ } else {
+ setError(KErrNotSupported, tr("Requested video container is not supported."));
+ m_requestedContainer = KMimeTypeDefaultContainer; // Reset to default
+ }
+ }
+
+ m_uncommittedSettings = true;
+}
+
+QString S60VideoCaptureSession::videoContainerDescription(const QString &containerName)
+{
+ QList<TInt> formats;
+ QList<TInt> encoders = m_videoControllerMap.keys();
+ for (int i = 0; i < encoders.count(); ++i) {
+ formats = m_videoControllerMap[encoders[i]].keys();
+ for (int j = 0; j < formats.count(); ++j) {
+ if (m_videoControllerMap[encoders[i]][formats[j]].supportedMimeTypes.contains(containerName, Qt::CaseInsensitive))
+ return m_videoControllerMap[encoders[i]][formats[j]].description;
+ }
+ }
+
+ return QString();
+}
+
+void S60VideoCaptureSession::cameraStatusChanged(QCamera::Status status)
+{
+ if (status == QCamera::ActiveStatus) {
+ m_cameraStarted = true;
+
+ // Continue preparation or start recording if previously requested
+ if (m_captureState == EInitialized
+ && (m_openWhenReady || m_prepareAfterOpenComplete || m_startAfterPrepareComplete)) {
+ setOutputLocation(m_requestedSink);
+ m_openWhenReady = false; // Reset
+ } else if ((m_captureState == EOpenComplete || m_captureState == EPrepared)
+ && (m_prepareAfterOpenComplete || m_startAfterPrepareComplete)) {
+ startRecording();
+ m_prepareAfterOpenComplete = false; // Reset
+ }
+
+ } else if (status == QCamera::UnloadedStatus) {
+ m_cameraStarted = false;
+ releaseVideoRecording();
+ } else {
+ m_cameraStarted = false;
+ }
+}
+
+void S60VideoCaptureSession::durationTimerTriggered()
+{
+ // Update position only if recording is ongoing
+ if ((m_captureState == ERecording) && m_videoRecorder) {
+ // Signal will be automatically emitted of position changes
+ TRAPD(err, m_position = m_videoRecorder->DurationL().Int64() / 1000);
+ setError(err, tr("Cannot retrieve video position."));
+
+ emit positionChanged(m_position);
+ }
+}
+
+void S60VideoCaptureSession::doPopulateAudioCodecsL()
+{
+ if (m_captureState == EInitializing) {
+ m_audioCodecList.clear();
+
+ RArray<TFourCC> audioTypes;
+ CleanupClosePushL(audioTypes);
+
+ if (m_videoRecorder)
+ m_videoRecorder->GetSupportedAudioTypesL(audioTypes);
+ else
+ setError(KErrNotReady, tr("Unexpected camera error."));
+
+ for (TInt i = 0; i < audioTypes.Count(); i++) {
+ TUint32 codec = audioTypes[i].FourCC();
+
+ if (codec == KMMFFourCCCodeAMR)
+ m_audioCodecList.insert(QString("audio/amr"), KMMFFourCCCodeAMR);
+ if (codec == KMMFFourCCCodeAAC)
+ m_audioCodecList.insert(QString("audio/aac"), KMMFFourCCCodeAAC);
+ }
+ CleanupStack::PopAndDestroy(&audioTypes);
+ }
+}
+
+void S60VideoCaptureSession::doPopulateVideoCodecsL()
+{
+ if (m_captureState == EInitializing) {
+ m_videoCodecList.clear();
+
+ CDesC8ArrayFlat* videoTypes = new (ELeave) CDesC8ArrayFlat(10);
+ CleanupStack::PushL(videoTypes);
+
+ if (m_videoRecorder)
+ m_videoRecorder->GetSupportedVideoTypesL(*videoTypes);
+ else
+ setError(KErrNotReady, tr("Unexpected camera error."));
+
+ for (TInt i = 0; i < videoTypes->Count(); i++) {
+ TPtrC8 videoType = videoTypes->MdcaPoint(i);
+ QString codecMimeType = QString::fromUtf8((char *)videoType.Ptr(), videoType.Length());
+#ifdef S60_DEVVIDEO_RECORDING_SUPPORTED
+ for (int j = 0; j < m_videoParametersForEncoder.size(); ++j) {
+ if (m_videoParametersForEncoder[j].mimeTypes.contains(codecMimeType, Qt::CaseInsensitive)) {
+ m_videoCodecList << codecMimeType;
+ break;
+ }
+ }
+#else // CVideoRecorderUtility
+ m_videoCodecList << codecMimeType;
+#endif // S60_DEVVIDEO_RECORDING_SUPPORTED
+ }
+ CleanupStack::PopAndDestroy(videoTypes);
+ }
+}
+
+#ifndef S60_DEVVIDEO_RECORDING_SUPPORTED
+/*
+ * Maximum resolution, framerate and bitrate can not be queried via MMF or
+ * ECam, but needs to be set according to the definitions of the video
+ * standard in question. In video standards, the values often depend on each
+ * other, but the below function defines constant maximums.
+ */
+void S60VideoCaptureSession::doPopulateMaxVideoParameters()
+{
+ m_videoParametersForEncoder.append(MaxResolutionRatesAndTypes()); // For H.263
+ m_videoParametersForEncoder.append(MaxResolutionRatesAndTypes()); // For MPEG-4
+ m_videoParametersForEncoder.append(MaxResolutionRatesAndTypes()); // For H.264
+
+ for (int i = 0; i < m_videoCodecList.count(); ++i) {
+
+ // Use all lower case for comparisons
+ QString codec = m_videoCodecList[i].toLower();
+
+ if (codec.contains("video/h263-2000", Qt::CaseInsensitive)) {
+ // H.263
+ if (codec == "video/h263-2000" ||
+ codec == "video/h263-2000; profile=0" ||
+ codec == "video/h263-2000; profile=0; level=10" ||
+ codec == "video/h263-2000; profile=3") {
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(15.0, QSize(176,144)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 64000)
+ m_videoParametersForEncoder[0].bitRate = 64000;
+ continue;
+ } else if (codec == "video/h263-2000; profile=0; level=20") {
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(15.0, QSize(352,288)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 128000)
+ m_videoParametersForEncoder[0].bitRate = 128000;
+ continue;
+ } else if (codec == "video/h263-2000; profile=0; level=30") {
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(30.0, QSize(352,288)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 384000)
+ m_videoParametersForEncoder[0].bitRate = 384000;
+ continue;
+ } else if (codec == "video/h263-2000; profile=0; level=40") {
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(30.0, QSize(352,288)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 2048000)
+ m_videoParametersForEncoder[0].bitRate = 2048000;
+ continue;
+ } else if (codec == "video/h263-2000; profile=0; level=45") {
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(15.0, QSize(176,144)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 128000)
+ m_videoParametersForEncoder[0].bitRate = 128000;
+ continue;
+ } else if (codec == "video/h263-2000; profile=0; level=50") {
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(15.0, QSize(352,288)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 4096000)
+ m_videoParametersForEncoder[0].bitRate = 4096000;
+ continue;
+ }
+
+ } else if (codec.contains("video/mp4v-es", Qt::CaseInsensitive)) {
+ // Mpeg-4
+ if (codec == "video/mp4v-es" ||
+ codec == "video/mp4v-es; profile-level-id=1" ||
+ codec == "video/mp4v-es; profile-level-id=8") {
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(15.0, QSize(176,144)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 64000)
+ m_videoParametersForEncoder[0].bitRate = 64000;
+ continue;
+ } else if (codec == "video/mp4v-es; profile-level-id=2" ||
+ codec == "video/mp4v-es; profile-level-id=9") {
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(15.0, QSize(352,288)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 128000)
+ m_videoParametersForEncoder[0].bitRate = 128000;
+ continue;
+ } else if (codec == "video/mp4v-es; profile-level-id=3") {
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(30.0, QSize(352,288)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 384000)
+ m_videoParametersForEncoder[0].bitRate = 384000;
+ continue;
+ } else if (codec == "video/mp4v-es; profile-level-id=4") {
+#if (defined(S60_31_PLATFORM) | defined(S60_32_PLATFORM))
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(15.0, QSize(640,480)));
+#else // S60 5.0 and later platforms
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(30.0, QSize(640,480)));
+#endif
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 4000000)
+ m_videoParametersForEncoder[0].bitRate = 4000000;
+ continue;
+ } else if (codec == "video/mp4v-es; profile-level-id=5") {
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(25.0, QSize(720,576)));
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(30.0, QSize(720,480)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 8000000)
+ m_videoParametersForEncoder[0].bitRate = 8000000;
+ continue;
+ } else if (codec == "video/mp4v-es; profile-level-id=6") {
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(30.0, QSize(1280,720)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 12000000)
+ m_videoParametersForEncoder[0].bitRate = 12000000;
+ continue;
+ }
+
+ } else if (codec.contains("video/h264", Qt::CaseInsensitive)) {
+ // H.264
+ if (codec == "video/h264" ||
+ codec == "video/h264; profile-level-id=42800a") {
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(15.0, QSize(176,144)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 64000)
+ m_videoParametersForEncoder[0].bitRate = 64000;
+ continue;
+ } else if (codec == "video/h264; profile-level-id=42900b") { // BP, L1b
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(15.0, QSize(176,144)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 128000)
+ m_videoParametersForEncoder[0].bitRate = 128000;
+ continue;
+ } else if (codec == "video/h264; profile-level-id=42800b") { // BP, L1.1
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(7.5, QSize(352,288)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 192000)
+ m_videoParametersForEncoder[0].bitRate = 192000;
+ continue;
+ } else if (codec == "video/h264; profile-level-id=42800c") { // BP, L1.2
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(15.0, QSize(352,288)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 384000)
+ m_videoParametersForEncoder[0].bitRate = 384000;
+ continue;
+ } else if (codec == "video/h264; profile-level-id=42800d") { // BP, L1.3
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(30.0, QSize(352,288)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 768000)
+ m_videoParametersForEncoder[0].bitRate = 768000;
+ continue;
+ } else if (codec == "video/h264; profile-level-id=428014") { // BP, L2
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(30.0, QSize(352,288)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 2000000)
+ m_videoParametersForEncoder[0].bitRate = 2000000;
+ continue;
+ } else if (codec == "video/h264; profile-level-id=428015") { // BP, L2.1
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(50.0, QSize(352,288)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 4000000)
+ m_videoParametersForEncoder[0].bitRate = 4000000;
+ continue;
+ } else if (codec == "video/h264; profile-level-id=428016") { // BP, L2.2
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(16.9, QSize(640,480)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 4000000)
+ m_videoParametersForEncoder[0].bitRate = 4000000;
+ continue;
+ } else if (codec == "video/h264; profile-level-id=42801e") { // BP, L3
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(33.8, QSize(640,480)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 10000000)
+ m_videoParametersForEncoder[0].bitRate = 10000000;
+ continue;
+ } else if (codec == "video/h264; profile-level-id=42801f") { // BP, L3.1
+ m_videoParametersForEncoder[0].frameRatePictureSizePair.append(SupportedFrameRatePictureSize(30.0, QSize(1280,720)));
+ m_videoParametersForEncoder[0].mimeTypes.append(codec);
+ if (m_videoParametersForEncoder[0].bitRate < 14000000)
+ m_videoParametersForEncoder[0].bitRate = 14000000;
+ continue;
+ }
+ }
+ }
+}
+#endif // S60_DEVVIDEO_RECORDING_SUPPORTED
+
+/*
+ * This function returns the maximum resolution defined by the video standards
+ * for different MIME Types.
+ */
+QSize S60VideoCaptureSession::maximumResolutionForMimeType(const QString &mimeType) const
+{
+ QSize maxSize(-1,-1);
+ // Use all lower case for comparisons
+ QString lowerMimeType = mimeType.toLower();
+
+ if (lowerMimeType == "video/h263-2000") {
+ maxSize = KResH263;
+ } else if (lowerMimeType == "video/h263-2000; profile=0") {
+ maxSize = KResH263_Profile0;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=10") {
+ maxSize = KResH263_Profile0_Level10;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=20") {
+ maxSize = KResH263_Profile0_Level20;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=30") {
+ maxSize = KResH263_Profile0_Level30;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=40") {
+ maxSize = KResH263_Profile0_Level40;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=45") {
+ maxSize = KResH263_Profile0_Level45;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=50") {
+ maxSize = KResH263_Profile0_Level50;
+ } else if (lowerMimeType == "video/h263-2000; profile=3") {
+ maxSize = KResH263_Profile3;
+ } else if (lowerMimeType == "video/mp4v-es") {
+ maxSize = KResMPEG4;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=1") {
+ maxSize = KResMPEG4_PLID_1;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=2") {
+ maxSize = KResMPEG4_PLID_2;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=3") {
+ maxSize = KResMPEG4_PLID_3;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=4") {
+ maxSize = KResMPEG4_PLID_4;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=5") {
+ maxSize = KResMPEG4_PLID_5;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=6") {
+ maxSize = KResMPEG4_PLID_6;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=8") {
+ maxSize = KResMPEG4_PLID_8;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=9") {
+ maxSize = KResMPEG4_PLID_9;
+ } else if (lowerMimeType == "video/h264") {
+ maxSize = KResH264;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42800a" ||
+ lowerMimeType == "video/h264; profile-level-id=4d400a" ||
+ lowerMimeType == "video/h264; profile-level-id=64400a") { // L1
+ maxSize = KResH264_PLID_42800A;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42900b" ||
+ lowerMimeType == "video/h264; profile-level-id=4d500b" ||
+ lowerMimeType == "video/h264; profile-level-id=644009") { // L1.b
+ maxSize = KResH264_PLID_42900B;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42800b" ||
+ lowerMimeType == "video/h264; profile-level-id=4d400b" ||
+ lowerMimeType == "video/h264; profile-level-id=64400b") { // L1.1
+ maxSize = KResH264_PLID_42800B;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42800c" ||
+ lowerMimeType == "video/h264; profile-level-id=4d400c" ||
+ lowerMimeType == "video/h264; profile-level-id=64400c") { // L1.2
+ maxSize = KResH264_PLID_42800C;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42800d" ||
+ lowerMimeType == "video/h264; profile-level-id=4d400d" ||
+ lowerMimeType == "video/h264; profile-level-id=64400d") { // L1.3
+ maxSize = KResH264_PLID_42800D;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428014" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4014" ||
+ lowerMimeType == "video/h264; profile-level-id=644014") { // L2
+ maxSize = KResH264_PLID_428014;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428015" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4015" ||
+ lowerMimeType == "video/h264; profile-level-id=644015") { // L2.1
+ maxSize = KResH264_PLID_428015;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428016" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4016" ||
+ lowerMimeType == "video/h264; profile-level-id=644016") { // L2.2
+ maxSize = KResH264_PLID_428016;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42801e" ||
+ lowerMimeType == "video/h264; profile-level-id=4d401e" ||
+ lowerMimeType == "video/h264; profile-level-id=64401e") { // L3
+ maxSize = KResH264_PLID_42801E;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42801f" ||
+ lowerMimeType == "video/h264; profile-level-id=4d401f" ||
+ lowerMimeType == "video/h264; profile-level-id=64401f") { // L3.1
+ maxSize = KResH264_PLID_42801F;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428020" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4020" ||
+ lowerMimeType == "video/h264; profile-level-id=644020") { // L3.2
+ maxSize = KResH264_PLID_428020;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428028" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4028" ||
+ lowerMimeType == "video/h264; profile-level-id=644028") { // L4
+ maxSize = KResH264_PLID_428028;
+ }
+
+ return maxSize;
+}
+
+/*
+ * This function returns the maximum framerate defined by the video standards
+ * for different MIME Types.
+ */
+
+qreal S60VideoCaptureSession::maximumFrameRateForMimeType(const QString &mimeType) const
+{
+ qreal maxRate(-1.0);
+ // Use all lower case for comparisons
+ QString lowerMimeType = mimeType.toLower();
+
+ if (lowerMimeType == "video/h263-2000") {
+ maxRate = KFrR_H263;
+ } else if (lowerMimeType == "video/h263-2000; profile=0") {
+ maxRate = KFrR_H263_Profile0;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=10") {
+ maxRate = KFrR_H263_Profile0_Level10;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=20") {
+ maxRate = KFrR_H263_Profile0_Level20;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=30") {
+ maxRate = KFrR_H263_Profile0_Level30;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=40") {
+ maxRate = KFrR_H263_Profile0_Level40;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=45") {
+ maxRate = KFrR_H263_Profile0_Level45;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=50") {
+ maxRate = KFrR_H263_Profile0_Level50;
+ } else if (lowerMimeType == "video/h263-2000; profile=3") {
+ maxRate = KFrR_H263_Profile3;
+ } else if (lowerMimeType == "video/mp4v-es") {
+ maxRate = KFrR_MPEG4;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=1") {
+ maxRate = KFrR_MPEG4_PLID_1;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=2") {
+ maxRate = KFrR_MPEG4_PLID_2;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=3") {
+ maxRate = KFrR_MPEG4_PLID_3;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=4") {
+ maxRate = KFrR_MPEG4_PLID_4;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=5") {
+ maxRate = KFrR_MPEG4_PLID_5;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=6") {
+ maxRate = KFrR_MPEG4_PLID_6;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=8") {
+ maxRate = KFrR_MPEG4_PLID_8;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=9") {
+ maxRate = KFrR_MPEG4_PLID_9;
+ } else if (lowerMimeType == "video/h264") {
+ maxRate = KFrR_H264;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42800a" ||
+ lowerMimeType == "video/h264; profile-level-id=4d400a" ||
+ lowerMimeType == "video/h264; profile-level-id=64400a") { // L1
+ maxRate = KFrR_H264_PLID_42800A;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42900b" ||
+ lowerMimeType == "video/h264; profile-level-id=4d500b" ||
+ lowerMimeType == "video/h264; profile-level-id=644009") { // L1.b
+ maxRate = KFrR_H264_PLID_42900B;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42800b" ||
+ lowerMimeType == "video/h264; profile-level-id=4d400b" ||
+ lowerMimeType == "video/h264; profile-level-id=64400b") { // L1.1
+ maxRate = KFrR_H264_PLID_42800B;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42800c" ||
+ lowerMimeType == "video/h264; profile-level-id=4d400c" ||
+ lowerMimeType == "video/h264; profile-level-id=64400c") { // L1.2
+ maxRate = KFrR_H264_PLID_42800C;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42800d" ||
+ lowerMimeType == "video/h264; profile-level-id=4d400d" ||
+ lowerMimeType == "video/h264; profile-level-id=64400d") { // L1.3
+ maxRate = KFrR_H264_PLID_42800D;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428014" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4014" ||
+ lowerMimeType == "video/h264; profile-level-id=644014") { // L2
+ maxRate = KFrR_H264_PLID_428014;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428015" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4015" ||
+ lowerMimeType == "video/h264; profile-level-id=644015") { // L2.1
+ maxRate = KFrR_H264_PLID_428015;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428016" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4016" ||
+ lowerMimeType == "video/h264; profile-level-id=644016") { // L2.2
+ maxRate = KFrR_H264_PLID_428016;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42801e" ||
+ lowerMimeType == "video/h264; profile-level-id=4d401e" ||
+ lowerMimeType == "video/h264; profile-level-id=64401e") { // L3
+ maxRate = KFrR_H264_PLID_42801E;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42801f" ||
+ lowerMimeType == "video/h264; profile-level-id=4d401f" ||
+ lowerMimeType == "video/h264; profile-level-id=64401f") { // L3.1
+ maxRate = KFrR_H264_PLID_42801F;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428020" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4020" ||
+ lowerMimeType == "video/h264; profile-level-id=644020") { // L3.2
+ maxRate = KFrR_H264_PLID_428020;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428028" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4028" ||
+ lowerMimeType == "video/h264; profile-level-id=644028") { // L4
+ maxRate = KFrR_H264_PLID_428028;
+ }
+
+ return maxRate;
+}
+
+/*
+ * This function returns the maximum bitrate defined by the video standards
+ * for different MIME Types.
+ */
+int S60VideoCaptureSession::maximumBitRateForMimeType(const QString &mimeType) const
+{
+ int maxRate(-1.0);
+ // Use all lower case for comparisons
+ QString lowerMimeType = mimeType.toLower();
+
+ if (lowerMimeType == "video/h263-2000") {
+ maxRate = KBiR_H263;
+ } else if (lowerMimeType == "video/h263-2000; profile=0") {
+ maxRate = KBiR_H263_Profile0;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=10") {
+ maxRate = KBiR_H263_Profile0_Level10;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=20") {
+ maxRate = KBiR_H263_Profile0_Level20;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=30") {
+ maxRate = KBiR_H263_Profile0_Level30;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=40") {
+ maxRate = KBiR_H263_Profile0_Level40;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=45") {
+ maxRate = KBiR_H263_Profile0_Level45;
+ } else if (lowerMimeType == "video/h263-2000; profile=0; level=50") {
+ maxRate = KBiR_H263_Profile0_Level50;
+ } else if (lowerMimeType == "video/h263-2000; profile=3") {
+ maxRate = KBiR_H263_Profile3;
+ } else if (lowerMimeType == "video/mp4v-es") {
+ maxRate = KBiR_MPEG4;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=1") {
+ maxRate = KBiR_MPEG4_PLID_1;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=2") {
+ maxRate = KBiR_MPEG4_PLID_2;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=3") {
+ maxRate = KBiR_MPEG4_PLID_3;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=4") {
+ maxRate = KBiR_MPEG4_PLID_4;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=5") {
+ maxRate = KBiR_MPEG4_PLID_5;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=6") {
+ maxRate = KBiR_MPEG4_PLID_6;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=8") {
+ maxRate = KBiR_MPEG4_PLID_8;
+ } else if (lowerMimeType == "video/mp4v-es; profile-level-id=9") {
+ maxRate = KBiR_MPEG4_PLID_9;
+ } else if (lowerMimeType == "video/h264") {
+ maxRate = KBiR_H264;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42800a" ||
+ lowerMimeType == "video/h264; profile-level-id=4d400a" ||
+ lowerMimeType == "video/h264; profile-level-id=64400a") { // L1
+ maxRate = KBiR_H264_PLID_42800A;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42900b" ||
+ lowerMimeType == "video/h264; profile-level-id=4d500b" ||
+ lowerMimeType == "video/h264; profile-level-id=644009") { // L1.b
+ maxRate = KBiR_H264_PLID_42900B;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42800b" ||
+ lowerMimeType == "video/h264; profile-level-id=4d400b" ||
+ lowerMimeType == "video/h264; profile-level-id=64400b") { // L1.1
+ maxRate = KBiR_H264_PLID_42800B;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42800c" ||
+ lowerMimeType == "video/h264; profile-level-id=4d400c" ||
+ lowerMimeType == "video/h264; profile-level-id=64400c") { // L1.2
+ maxRate = KBiR_H264_PLID_42800C;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42800d" ||
+ lowerMimeType == "video/h264; profile-level-id=4d400d" ||
+ lowerMimeType == "video/h264; profile-level-id=64400d") { // L1.3
+ maxRate = KBiR_H264_PLID_42800D;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428014" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4014" ||
+ lowerMimeType == "video/h264; profile-level-id=644014") { // L2
+ maxRate = KBiR_H264_PLID_428014;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428015" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4015" ||
+ lowerMimeType == "video/h264; profile-level-id=644015") { // L2.1
+ maxRate = KBiR_H264_PLID_428015;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428016" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4016" ||
+ lowerMimeType == "video/h264; profile-level-id=644016") { // L2.2
+ maxRate = KBiR_H264_PLID_428016;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42801e" ||
+ lowerMimeType == "video/h264; profile-level-id=4d401e" ||
+ lowerMimeType == "video/h264; profile-level-id=64401e") { // L3
+ maxRate = KBiR_H264_PLID_42801E;
+ } else if (lowerMimeType == "video/h264; profile-level-id=42801f" ||
+ lowerMimeType == "video/h264; profile-level-id=4d401f" ||
+ lowerMimeType == "video/h264; profile-level-id=64401f") { // L3.1
+ maxRate = KBiR_H264_PLID_42801F;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428020" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4020" ||
+ lowerMimeType == "video/h264; profile-level-id=644020") { // L3.2
+ maxRate = KBiR_H264_PLID_428020;
+ } else if (lowerMimeType == "video/h264; profile-level-id=428028" ||
+ lowerMimeType == "video/h264; profile-level-id=4d4028" ||
+ lowerMimeType == "video/h264; profile-level-id=644028") { // L4
+ maxRate = KBiR_H264_PLID_428028;
+ }
+
+ return maxRate;
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60videocapturesession.h b/src/plugins/symbian/ecam/s60videocapturesession.h
new file mode 100644
index 000000000..cfa101f57
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60videocapturesession.h
@@ -0,0 +1,414 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEOCAPTURESESSION_H
+#define S60VIDEOCAPTURESESSION_H
+
+#include <QtCore/qurl.h>
+#include <QtCore/qhash.h>
+
+#include <qmediaencodersettings.h>
+#include <qcamera.h>
+#include <qmediarecorder.h>
+
+#include "s60cameraengine.h"
+
+#include <e32base.h>
+#include <videorecorder.h> // CVideoRecorderUtility
+#ifdef S60_DEVVIDEO_RECORDING_SUPPORTED
+#include <mmf/devvideo/devvideorecord.h>
+#endif // S60_DEVVIDEO_RECORDING_SUPPORTED
+
+QT_USE_NAMESPACE
+
+class QTimer;
+
+/*
+ * VideoSession is the main class handling all video recording related
+ * operations. It uses mainly CVideoRecorderUtility to do it's tasks, but if
+ * DevVideoRecord is available it is used to provide more detailed
+ * information of the supported video settings.
+ */
+class S60VideoCaptureSession : public QObject,
+ public MVideoRecorderUtilityObserver
+#ifdef S60_DEVVIDEO_RECORDING_SUPPORTED
+ ,public MMMFDevVideoRecordObserver
+#endif // S60_DEVVIDEO_RECORDING_SUPPORTED
+{
+ Q_OBJECT
+ Q_ENUMS(Error)
+ Q_ENUMS(EcamErrors)
+ Q_ENUMS(TVideoCaptureState)
+
+public: // Enums
+
+ enum TVideoCaptureState
+ {
+ ENotInitialized = 0, // 0 - VideoRecording is not initialized, instance may or may not be created
+ EInitializing, // 1 - Initialization is ongoing
+ EInitialized, // 2 - VideoRecording is initialized, OpenFile is called with dummy file
+ EOpening, // 3 - OpenFile called with actual output location, waiting completion
+ EOpenComplete, // 4 - OpenFile completed with the actual output location
+ EPreparing, // 5 - Preparing VideoRecording to use set video settings
+ EPrepared, // 6 - VideoRecording is prepared with the set settings, ready to record
+ ERecording, // 7 - Video recording is ongoing
+ EPaused // 8 - Video recording has been started and paused
+ };
+
+ enum AudioQualityDefinition
+ {
+ ENoAudioQuality = 0, // 0 - Both BitRate and SampleRate settings available
+ EOnlyAudioQuality, // 1 - No BitRate or SampleRate settings available, use Quality to set them
+ EAudioQualityAndBitRate, // 2 - BitRate setting available, use Quality to set SampleRate
+ EAudioQualityAndSampleRate, // 3 - SampleRate setting available, use Quality to set BitRate
+ };
+
+ enum VideoQualityDefinition
+ {
+ ENoVideoQuality = 0, // 0 - All, Resolution, FrameRate and BitRate available
+ EOnlyVideoQuality, // 1 - None available, use Quality to set Resolution, FrameRate and BitRate
+ EVideoQualityAndResolution, // 2 - Only Resolution available, use Quality to set FrameRate and BitRate
+ EVideoQualityAndFrameRate, // 3 - Only FrameRate available, use Quality to set Resolution and BitRate
+ EVideoQualityAndBitRate, // 4 - Only BitRate available, use Quality to set Resolution and FrameRate
+ EVideoQualityAndResolutionAndBitRate, // 5 - No FrameRate available, use Quality to set it
+ EVideoQualityAndResolutionAndFrameRate, // 6 - No BitRate available, use Quality to set it
+ EVideoQualityAndFrameRateAndBitRate // 7 - No Resolution available, use Quality to set it
+ };
+
+public: // Constructor & Destructor
+
+ S60VideoCaptureSession(QObject *parent = 0);
+ ~S60VideoCaptureSession();
+
+public: // MVideoRecorderUtilityObserver
+
+ void MvruoOpenComplete(TInt aError);
+ void MvruoPrepareComplete(TInt aError);
+ void MvruoRecordComplete(TInt aError);
+ void MvruoEvent(const TMMFEvent& aEvent);
+
+#ifdef S60_DEVVIDEO_RECORDING_SUPPORTED
+public: // MMMFDevVideoRecordObserver
+ void MdvroReturnPicture(TVideoPicture *aPicture);
+ void MdvroSupplementalInfoSent();
+ void MdvroNewBuffers();
+ void MdvroFatalError(TInt aError);
+ void MdvroInitializeComplete(TInt aError);
+ void MdvroStreamEnd();
+#endif // S60_DEVVIDEO_RECORDING_SUPPORTED
+
+public: // Methods
+
+ void setError(const TInt error, const QString &description);
+ void setCameraHandle(CCameraEngine* cameraHandle);
+ void notifySettingsSet();
+
+ qint64 position();
+ TVideoCaptureState state() const;
+ bool isMuted() const;
+
+ // Controls
+ int initializeVideoRecording();
+ void releaseVideoRecording();
+ void applyAllSettings();
+
+ void startRecording();
+ void pauseRecording();
+ void stopRecording(const bool reInitialize = true);
+ void setMuted(const bool muted);
+
+ // Output Location
+ bool setOutputLocation(const QUrl &sink);
+ QUrl outputLocation() const;
+
+ // Resolution
+ void setVideoResolution(const QSize &resolution);
+ QList<QSize> supportedVideoResolutions(bool *continuous);
+ QList<QSize> supportedVideoResolutions(const QVideoEncoderSettings &settings, bool *continuous);
+
+ // Framerate
+ void setFrameRate(const qreal rate);
+ QList<qreal> supportedVideoFrameRates(bool *continuous);
+ QList<qreal> supportedVideoFrameRates(const QVideoEncoderSettings &settings, bool *continuous);
+
+ // Other Video Settings
+ void setBitrate(const int bitrate);
+ void setVideoEncodingMode(const QtMultimediaKit::EncodingMode mode);
+
+ // Video Codecs
+ void setVideoCaptureCodec(const QString &codecName);
+ QStringList supportedVideoCaptureCodecs();
+ QString videoCaptureCodecDescription(const QString &codecName);
+
+ // Audio Codecs
+ void setAudioCaptureCodec(const QString &codecName);
+ QStringList supportedAudioCaptureCodecs();
+
+ // Encoder Settings
+ void videoEncoderSettings(QVideoEncoderSettings &videoSettings);
+ void audioEncoderSettings(QAudioEncoderSettings &audioSettings);
+
+ // Quality
+ void setVideoCaptureQuality(const QtMultimediaKit::EncodingQuality quality,
+ const VideoQualityDefinition mode);
+ void setAudioCaptureQuality(const QtMultimediaKit::EncodingQuality quality,
+ const AudioQualityDefinition mode);
+
+ // Video Containers
+ QString videoContainer() const;
+ void setVideoContainer(const QString &containerName);
+ QStringList supportedVideoContainers();
+ bool isSupportedVideoContainer(const QString &containerName);
+ QString videoContainerDescription(const QString &containerName);
+
+ // Audio Settings
+ QList<int> supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous);
+ void setAudioSampleRate(const int sampleRate);
+ void setAudioBitRate(const int bitRate);
+ void setAudioChannelCount(const int channelCount);
+ void setAudioEncodingMode(const QtMultimediaKit::EncodingMode mode);
+
+ // Video Options
+ QSize pixelAspectRatio();
+ void setPixelAspectRatio(const QSize par);
+ int gain();
+ void setGain(const int gain);
+ int maxClipSizeInBytes() const;
+ void setMaxClipSizeInBytes(const int size);
+
+private: // Internal
+
+ QMediaRecorder::Error fromSymbianErrorToQtMultimediaError(int aError);
+
+ void initializeVideoCaptureSettings();
+ void doInitializeVideoRecorderL();
+ void commitVideoEncoderSettings();
+ void queryAudioEncoderSettings();
+ void queryVideoEncoderSettings();
+ void validateRequestedCodecs();
+ void resetSession(bool errorHandling = false);
+
+ void doSetCodecsL();
+ QString determineProfileAndLevel();
+ void doSetVideoResolution(const QSize &resolution);
+ void doSetFrameRate(qreal rate);
+ void doSetBitrate(const int &bitrate);
+
+ void updateVideoCaptureContainers();
+ void doUpdateVideoCaptureContainersL();
+ void selectController(const QString &format,
+ TUid &controllerUid,
+ TUid &formatUid);
+
+ void doPopulateVideoCodecsDataL();
+ void doPopulateVideoCodecsL();
+#ifndef S60_DEVVIDEO_RECORDING_SUPPORTED
+ void doPopulateMaxVideoParameters();
+#endif // S60_DEVVIDEO_RECORDING_SUPPORTED
+ void doPopulateAudioCodecsL();
+
+ QList<int> doGetSupportedSampleRatesL(const QAudioEncoderSettings &settings,
+ bool *continuous);
+ QSize maximumResolutionForMimeType(const QString &mimeType) const;
+ qreal maximumFrameRateForMimeType(const QString &mimeType) const;
+ int maximumBitRateForMimeType(const QString &mimeType) const;
+
+signals: // Notification Signals
+
+ void stateChanged(S60VideoCaptureSession::TVideoCaptureState);
+ void positionChanged(qint64);
+ void mutedChanged(bool);
+ void captureSizeChanged(const QSize&);
+ void error(int, const QString&);
+
+private slots: // Internal Slots
+
+ void cameraStatusChanged(QCamera::Status);
+ void durationTimerTriggered();
+
+private: // Structs
+
+ /*
+ * This structure holds the information of supported video mime types for
+ * the format and also description for it.
+ */
+ struct VideoFormatData {
+ QString description;
+ QStringList supportedMimeTypes;
+ };
+
+ /*
+ * This structure is used to define supported resolutions and framerate
+ * (depending on each other) for each supported encoder mime type (defining
+ * encoder, profile and level)
+ */
+ struct SupportedFrameRatePictureSize {
+ SupportedFrameRatePictureSize() {}
+ SupportedFrameRatePictureSize(qreal rate, QSize size):
+ frameRate(rate),
+ frameSize(size) {}
+ qreal frameRate;
+ QSize frameSize;
+ };
+
+ /*
+ * This structure defines supported resolution/framerate pairs and maximum
+ * bitrate for a single encodec device. It also the supported mime types
+ * (codec, profile and level) of the encoder device.
+ *
+ * Structure defines 2 contructors:
+ * - First with no attributes
+ * - Second, which will construct the sructure appending one
+ * resolution/framerate pair to the list of
+ * SupportedFrameRatePictureSizes and setting the given bitrate as
+ * maximum. This second constructor is for convenience.
+ *
+ * This struct is used in m_videoParametersForEncoder (QList).
+ *
+ * Here's a visualization of an example strcuture:
+ * STRUCT:
+ * |-- Resolution/FrameRate Pairs:
+ * | |- VGA / 30fps
+ * | |- 720p / 25fps
+ * | |- Etc.
+ * |
+ * |-- MimeTypes:
+ * | |- video/mp4v-es; profile-level-id=1
+ * | |- video/mp4v-es; profile-level-id=2
+ * | |- Etc.
+ * |
+ * |-- Max BitRate: 1Mbps
+ */
+ struct MaxResolutionRatesAndTypes {
+ MaxResolutionRatesAndTypes() {}
+ MaxResolutionRatesAndTypes(QSize size, qreal fRate, int bRate):
+ bitRate(bRate)
+ {
+ frameRatePictureSizePair.append(SupportedFrameRatePictureSize(fRate,size));
+ }
+ QList<SupportedFrameRatePictureSize> frameRatePictureSizePair;
+ QStringList mimeTypes;
+ int bitRate;
+ };
+
+private: // Data
+
+ CCameraEngine *m_cameraEngine;
+ CVideoRecorderUtility *m_videoRecorder;
+ QTimer *m_durationTimer;
+ qint64 m_position;
+ // Symbian ErrorCode
+ mutable int m_error;
+ // This defines whether Camera is in ActiveStatus or not
+ bool m_cameraStarted;
+ // Internal state of the video recorder
+ TVideoCaptureState m_captureState;
+ // Actual output file name/path
+ QUrl m_sink;
+ // Requested output file name/path, this may be different from m_sink if
+ // asynchronous operation was ongoing in the CVideoRecorderUtility when new
+ // outputLocation was set.
+ QUrl m_requestedSink;
+ // Requested videoSettings. The may not be active settings before those are
+ // committed (with commitVideoEncoderSettings())
+ QVideoEncoderSettings m_videoSettings;
+ // Requested audioSettings. The may not be active settings before those are
+ // committed (with commitVideoEncoderSettings())
+ QAudioEncoderSettings m_audioSettings;
+ // Tells whether settings should be initialized when changing the camera
+ bool m_captureSettingsSet;
+ // Active container
+ QString m_container;
+ // Requested container, this may be different from m_container if
+ // asynchronous operation was ongoing in the CVideoRecorderUtility when new
+ // container was set.
+ QString m_requestedContainer;
+ // Requested muted value. This may not be active value before settings are
+ // committed (with commitVideoEncoderSettings())
+ bool m_muted;
+ // Maximum ClipSize in Bytes
+ int m_maxClipSize;
+ // List of supported video codec mime types
+ QStringList m_videoCodecList;
+ // Hash of supported video codec mime types and corresponding FourCC codes
+ QHash<QString, TFourCC> m_audioCodecList;
+ // Map of video capture controllers information. It is populated during
+ // doUpdateVideoCaptureContainersL().
+ //
+ // Here's a visualization of an example strcuture:
+ // m_videoControllerMap(HASH):
+ // |
+ // |-- Controller 1 : HASH
+ // | |- Container 1 (UID) : FormatData
+ // | | |- Description
+ // | | |- List of supported MimeTypes
+ // | |- Container 2 (UID) : FormatData
+ // | | |- Description
+ // | | |- List of supported MimeTypes
+ // | |- Etc.
+ // |
+ // |-- Controller 2: HASH
+ // | |- Container 1 (UID) : FormatData
+ // | | |- Description
+ // | | |- List of supported MimeTypes
+ // | |- Etc.
+ //
+ QHash<TInt, QHash<TInt,VideoFormatData> > m_videoControllerMap;
+ // List of Encoder information. If DevVideoRecord is available info is
+ // gathered during doPopulateVideoCodecsDataL() for each encoder (hw
+ // accelerated and supporting camera input) found. If DevVideoRecord is not
+ // available, the info is set in doPopulateMaxVideoParameters() based on
+ // supported codec list received from CVideoRecorderUtility.
+ QList<MaxResolutionRatesAndTypes> m_videoParametersForEncoder;
+ // Set if OpenFileL should be executed when currently ongoing operation
+ // is completed.
+ bool m_openWhenReady;
+ // Set if video capture should be prepared after OpenFileL has completed
+ bool m_prepareAfterOpenComplete;
+ // Set if video capture should be started when Prepare has completed
+ bool m_startAfterPrepareComplete;
+ // Tells if settings have been set after last Prepare()
+ bool m_uncommittedSettings;
+ // Tells if settings need to be applied after ongoing operation has finished
+ bool m_commitSettingsWhenReady;
+};
+
+#endif // S60VIDEOCAPTURESESSION_H
diff --git a/src/plugins/symbian/ecam/s60videodevicecontrol.cpp b/src/plugins/symbian/ecam/s60videodevicecontrol.cpp
new file mode 100644
index 000000000..3d55d3110
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60videodevicecontrol.cpp
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+#include <QtGui/qicon.h>
+
+#include "s60videodevicecontrol.h"
+#include "s60cameracontrol.h"
+#include "s60cameraconstants.h"
+
+S60VideoDeviceControl::S60VideoDeviceControl(QObject *parent) :
+ QVideoDeviceControl(parent)
+{
+}
+
+S60VideoDeviceControl::S60VideoDeviceControl(S60CameraControl *control, QObject *parent) :
+ QVideoDeviceControl(parent),
+ m_selectedDevice(KDefaultCameraDevice)
+{
+ m_control = control;
+ connect(m_control, SIGNAL(devicesChanged()), this, SIGNAL(devicesChanged()));
+}
+
+S60VideoDeviceControl::~S60VideoDeviceControl()
+{
+}
+
+int S60VideoDeviceControl::deviceCount() const
+{
+ return S60CameraControl::deviceCount();
+}
+
+QString S60VideoDeviceControl::deviceName(int index) const
+{
+ return S60CameraControl::name(index);
+}
+
+QString S60VideoDeviceControl::deviceDescription(int index) const
+{
+ return S60CameraControl::description(index);
+}
+
+QIcon S60VideoDeviceControl::deviceIcon(int index) const
+{
+ Q_UNUSED(index);
+ return QIcon();
+}
+
+int S60VideoDeviceControl::defaultDevice() const
+{
+ return KDefaultCameraDevice;
+}
+
+int S60VideoDeviceControl::selectedDevice() const
+{
+ return m_selectedDevice;
+}
+
+void S60VideoDeviceControl::setSelectedDevice(int index)
+{
+ // Inform that we selected new device
+ if (m_selectedDevice != index) {
+ m_control->setSelectedDevice(index);
+ m_selectedDevice = index;
+ emit selectedDeviceChanged(m_selectedDevice);
+ emit selectedDeviceChanged(deviceName(m_selectedDevice));
+ }
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60videodevicecontrol.h b/src/plugins/symbian/ecam/s60videodevicecontrol.h
new file mode 100644
index 000000000..03249441a
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60videodevicecontrol.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEODEVICECONTROL_H
+#define S60VIDEODEVICECONTROL_H
+
+#include "qvideodevicecontrol.h"
+
+QT_USE_NAMESPACE
+
+class S60CameraControl;
+class QString;
+class QIcon;
+
+/*
+ * Control for providing information of the video device (r. camera) and to
+ * enable other camera device (e.g. secondary camera if one exists).
+ */
+class S60VideoDeviceControl : public QVideoDeviceControl
+{
+ Q_OBJECT
+
+public: // Constructors & Destructor
+
+ S60VideoDeviceControl(QObject *parent);
+ S60VideoDeviceControl(S60CameraControl *control, QObject *parent = 0);
+ virtual ~S60VideoDeviceControl();
+
+public: // QVideoDeviceControl
+
+ int deviceCount() const;
+
+ QString deviceName(int index) const;
+ QString deviceDescription(int index) const;
+ QIcon deviceIcon(int index) const;
+
+ int defaultDevice() const;
+ int selectedDevice() const;
+
+public slots: // QVideoDeviceControl
+
+ void setSelectedDevice(int index);
+
+/*
+Q_SIGNALS:
+void selectedDeviceChanged(int index);
+void selectedDeviceChanged(const QString &deviceName);
+void devicesChanged();
+*/
+
+private: // Data
+
+ S60CameraControl *m_control;
+ int m_selectedDevice;
+};
+
+#endif // S60VIDEODEVICECONTROL_H
diff --git a/src/plugins/symbian/ecam/s60videoencodercontrol.cpp b/src/plugins/symbian/ecam/s60videoencodercontrol.cpp
new file mode 100644
index 000000000..34b28e28e
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60videoencodercontrol.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "s60videoencodercontrol.h"
+#include "s60videocapturesession.h"
+
+S60VideoEncoderControl::S60VideoEncoderControl(QObject *parent) :
+ QVideoEncoderControl(parent)
+{
+}
+
+S60VideoEncoderControl::S60VideoEncoderControl(S60VideoCaptureSession *session, QObject *parent) :
+ QVideoEncoderControl(parent)
+{
+ m_session = session;
+}
+
+S60VideoEncoderControl::~S60VideoEncoderControl()
+{
+}
+
+QStringList S60VideoEncoderControl::supportedVideoCodecs() const
+{
+ return m_session->supportedVideoCaptureCodecs();
+}
+
+QString S60VideoEncoderControl::videoCodecDescription(const QString &codecName) const
+{
+ return m_session->videoCaptureCodecDescription(codecName);
+}
+
+QList<qreal> S60VideoEncoderControl::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const
+{
+ if (!settings.isNull())
+ return m_session->supportedVideoFrameRates(settings, continuous);
+ return m_session->supportedVideoFrameRates(continuous);
+}
+
+QList<QSize> S60VideoEncoderControl::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const
+{
+ if (!settings.isNull())
+ return m_session->supportedVideoResolutions(settings, continuous);
+ return m_session->supportedVideoResolutions(continuous);
+}
+
+QStringList S60VideoEncoderControl::supportedEncodingOptions(const QString &codec) const
+{
+ // Possible settings: EncodingMode, Codec, Resolution, FrameRate, BitRate, Quality
+ // Possible (codec specific) options: PixelAspectRatio, Gain, MaxClipSizeInBytes
+
+ // Following options are valid for all codecs
+ Q_UNUSED(codec);
+
+ QStringList options;
+ options.append("pixelAspectRatio");
+ options.append("gain");
+ options.append("maxClipSizeInBytes");
+
+ return options;
+}
+
+QVariant S60VideoEncoderControl::encodingOption(const QString &codec, const QString &name) const
+{
+ Q_UNUSED(codec);
+
+ // Possible settings: EncodingMode, Codec, Resolution, FrameRate, BitRate, Quality
+ // Possible (codec specific) options: PixelAspectRatio, Gain, MaxClipSizeInBytes
+
+ QVariant returnValue;
+
+ if (qstrcmp(name.toLocal8Bit().constData(), "pixelAspectRatio") == 0)
+ returnValue.setValue(m_session->pixelAspectRatio());
+ else if (qstrcmp(name.toLocal8Bit().constData(), "gain") == 0)
+ returnValue.setValue((int)m_session->gain());
+ else if (qstrcmp(name.toLocal8Bit().constData(), "maxClipSizeInBytes") == 0)
+ returnValue.setValue(m_session->maxClipSizeInBytes());
+
+ return returnValue;
+}
+
+void S60VideoEncoderControl::setEncodingOption(
+ const QString &codec, const QString &name, const QVariant &value)
+{
+ // Set the codec first if not already set
+ m_session->setVideoCaptureCodec(codec);
+
+ if (qstrcmp(name.toLocal8Bit().constData(), "pixelAspectRatio") == 0)
+ m_session->setPixelAspectRatio(value.toSize());
+ else if (qstrcmp(name.toLocal8Bit().constData(), "gain") == 0)
+ m_session->setGain(value.toInt());
+ else if (qstrcmp(name.toLocal8Bit().constData(), "maxClipSizeInBytes") == 0)
+ m_session->setMaxClipSizeInBytes(value.toInt());
+ else
+ m_session->setError(KErrNotSupported, tr("Requested encoding option is not supported"));
+}
+
+QVideoEncoderSettings S60VideoEncoderControl::videoSettings() const
+{
+ QVideoEncoderSettings settings;
+ m_session->videoEncoderSettings(settings);
+
+ return settings;
+}
+
+void S60VideoEncoderControl::setVideoSettings(const QVideoEncoderSettings &settings)
+{
+ // Notify that settings have been implicitly set and there's no need to
+ // initialize them in case camera is changed
+ m_session->notifySettingsSet();
+
+ if (settings.codec().isEmpty()
+ || (settings.resolution() == QSize(-1,-1) && settings.frameRate() == 0 && settings.bitRate() == -1)) {
+ if (!settings.codec().isEmpty())
+ m_session->setVideoCaptureCodec(settings.codec());
+ m_session->setVideoEncodingMode(settings.encodingMode());
+ m_session->setVideoCaptureQuality(settings.quality(), S60VideoCaptureSession::EOnlyVideoQuality);
+ } else if (settings.resolution() != QSize(-1,-1) && settings.frameRate() == 0 && settings.bitRate() == -1) { // Only Resolution
+ m_session->setVideoCaptureCodec(settings.codec());
+ m_session->setVideoEncodingMode(settings.encodingMode());
+ m_session->setVideoResolution(settings.resolution());
+ m_session->setVideoCaptureQuality(settings.quality(), S60VideoCaptureSession::EVideoQualityAndResolution);
+
+ } else if (settings.resolution() == QSize(-1,-1) && settings.frameRate() != 0 && settings.bitRate() == -1) { // Only Framerate
+ m_session->setVideoCaptureCodec(settings.codec());
+ m_session->setVideoEncodingMode(settings.encodingMode());
+ m_session->setFrameRate(settings.frameRate());
+ m_session->setVideoCaptureQuality(settings.quality(), S60VideoCaptureSession::EVideoQualityAndFrameRate);
+
+ } else if (settings.resolution() == QSize(-1,-1) && settings.frameRate() == 0 && settings.bitRate() != -1) { // Only BitRate
+ m_session->setVideoCaptureCodec(settings.codec());
+ m_session->setVideoEncodingMode(settings.encodingMode());
+ m_session->setBitrate(settings.bitRate());
+ m_session->setVideoCaptureQuality(settings.quality(), S60VideoCaptureSession::EVideoQualityAndBitRate);
+
+ } else if (settings.resolution() != QSize(-1,-1) && settings.frameRate() != 0 && settings.bitRate() == -1) { // Resolution and FrameRate
+ m_session->setVideoCaptureCodec(settings.codec());
+ m_session->setVideoEncodingMode(settings.encodingMode());
+ m_session->setVideoResolution(settings.resolution());
+ m_session->setFrameRate(settings.frameRate());
+ m_session->setVideoCaptureQuality(settings.quality(), S60VideoCaptureSession::EVideoQualityAndResolutionAndFrameRate);
+
+ } else if (settings.resolution() != QSize(-1,-1) && settings.frameRate() == 0 && settings.bitRate() != -1) { // Resolution and BitRate
+ m_session->setVideoCaptureCodec(settings.codec());
+ m_session->setVideoEncodingMode(settings.encodingMode());
+ m_session->setVideoResolution(settings.resolution());
+ m_session->setBitrate(settings.bitRate());
+ m_session->setVideoCaptureQuality(settings.quality(), S60VideoCaptureSession::EVideoQualityAndResolutionAndBitRate);
+
+ } else if (settings.resolution() == QSize(-1,-1) && settings.frameRate() != 0 && settings.bitRate() != -1) { // FrameRate and BitRate
+ m_session->setVideoCaptureCodec(settings.codec());
+ m_session->setVideoEncodingMode(settings.encodingMode());
+ m_session->setFrameRate(settings.frameRate());
+ m_session->setBitrate(settings.bitRate());
+ m_session->setVideoCaptureQuality(settings.quality(), S60VideoCaptureSession::EVideoQualityAndFrameRateAndBitRate);
+
+ } else { // All: Resolution, BitRate and FrameRate
+ m_session->setVideoCaptureCodec(settings.codec());
+ m_session->setVideoEncodingMode(settings.encodingMode());
+ m_session->setVideoResolution(settings.resolution());
+ m_session->setFrameRate(settings.frameRate());
+ m_session->setBitrate(settings.bitRate());
+ m_session->setVideoCaptureQuality(settings.quality(), S60VideoCaptureSession::ENoVideoQuality);
+ }
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60videoencodercontrol.h b/src/plugins/symbian/ecam/s60videoencodercontrol.h
new file mode 100644
index 000000000..4554d9291
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60videoencodercontrol.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEOENCODERCONTROL_H
+#define S60VIDEOENCODERCONTROL_H
+
+#include <QtCore/qstringlist.h>
+#include <QtCore/qmap.h>
+
+#include "qvideoencodercontrol.h"
+
+QT_USE_NAMESPACE
+
+class S60VideoCaptureSession;
+
+/*
+ * Control for video settings when recording video using QMediaRecorder.
+ */
+class S60VideoEncoderControl : public QVideoEncoderControl
+{
+ Q_OBJECT
+
+public: // Contructors & Destructor
+
+ S60VideoEncoderControl(QObject *parent = 0);
+ S60VideoEncoderControl(S60VideoCaptureSession *session, QObject *parent = 0);
+ virtual ~S60VideoEncoderControl();
+
+public: // QVideoEncoderControl
+
+ // Resolution
+ QList<QSize> supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous = 0) const;
+
+ // Framerate
+ QList<qreal> supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous = 0) const;
+
+ // Video Codec
+ QStringList supportedVideoCodecs() const;
+ QString videoCodecDescription(const QString &codecName) const;
+
+ // Video Settings
+ QVideoEncoderSettings videoSettings() const;
+ void setVideoSettings(const QVideoEncoderSettings &settings);
+
+ // Encoding Options
+ QStringList supportedEncodingOptions(const QString &codec) const;
+ QVariant encodingOption(const QString &codec, const QString &name) const;
+ void setEncodingOption(const QString &codec, const QString &name, const QVariant &value);
+
+private: // Data
+
+ S60VideoCaptureSession* m_session;
+
+};
+
+#endif // S60VIDEOENCODERCONTROL_H
diff --git a/src/plugins/symbian/ecam/s60videorenderercontrol.cpp b/src/plugins/symbian/ecam/s60videorenderercontrol.cpp
new file mode 100644
index 000000000..8cc3546b5
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60videorenderercontrol.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qabstractvideosurface.h>
+
+#include "s60videorenderercontrol.h"
+
+S60VideoRendererControl::S60VideoRendererControl(QObject *parent) :
+ QVideoRendererControl(parent),
+ m_surface(0)
+{
+}
+
+S60VideoRendererControl::~S60VideoRendererControl()
+{
+ // Stop surface if still active
+ if (m_surface)
+ if (m_surface->isActive())
+ m_surface->stop();
+}
+
+QAbstractVideoSurface *S60VideoRendererControl::surface() const
+{
+ return m_surface;
+}
+
+void S60VideoRendererControl::setSurface(QAbstractVideoSurface *surface)
+{
+ if (surface == 0) {
+ // Stop current surface if needed
+ if (m_surface)
+ if (m_surface->isActive())
+ m_surface->stop();
+ }
+
+ m_surface = surface;
+ emit viewFinderSurfaceSet();
+}
+
+// End of file
diff --git a/src/plugins/symbian/ecam/s60videorenderercontrol.h b/src/plugins/symbian/ecam/s60videorenderercontrol.h
new file mode 100644
index 000000000..b35433f86
--- /dev/null
+++ b/src/plugins/symbian/ecam/s60videorenderercontrol.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEORENDERERCONTROL_H
+#define S60VIDEORENDERERCONTROL_H
+
+#include <qvideorenderercontrol.h>
+
+/*
+ * Control for QGraphicsVideoItem. Viewfinder frames are streamed to a surface
+ * which is drawn to the display by the Qt Graphics Vide Framework.
+ * VideoRendererControl uses only Bitmap Viewfinder.
+ */
+class S60VideoRendererControl : public QVideoRendererControl
+{
+ Q_OBJECT
+
+public: // Constructor & Destructor
+
+ S60VideoRendererControl(QObject *parent = 0);
+ virtual ~S60VideoRendererControl();
+
+public: // S60VideoRendererControl
+
+ QAbstractVideoSurface *surface() const;
+ void setSurface(QAbstractVideoSurface *surface);
+
+signals: // Internal Signals
+
+ void viewFinderSurfaceSet();
+
+private: // Data
+
+ QAbstractVideoSurface *m_surface;
+
+};
+
+#endif // S60VIDEORENDERERCONTROL_H
diff --git a/src/plugins/symbian/mmf/audiosource/audiosource_s60.pri b/src/plugins/symbian/mmf/audiosource/audiosource_s60.pri
new file mode 100644
index 000000000..7732600fa
--- /dev/null
+++ b/src/plugins/symbian/mmf/audiosource/audiosource_s60.pri
@@ -0,0 +1,31 @@
+INCLUDEPATH += $$PWD
+
+DEFINES += AUDIOSOURCEUSED
+
+symbian:LIBS += -lmediaclientaudio \
+ -lmmfcontrollerframework \
+ -lefsrv \
+ -lbafl \
+
+!contains(S60_VERSION, 3.1) {
+ contains(audiorouting_s60_enabled,yes) {
+ #We use audioinputrouting.lib for recording audio from different sources -lmediaclientaudioinputstream \ -lcone \
+ DEFINES += AUDIOINPUT_ROUTING
+ message("Audio Input Routing enabled onwards 3.2 SDK")
+ LIBS += -laudioinputrouting
+ }
+}
+
+HEADERS += $$PWD/s60audioencodercontrol.h \
+ $$PWD/s60audiomediarecordercontrol.h \
+ $$PWD/s60audioendpointselector.h \
+ $$PWD/s60audiocaptureservice.h \
+ $$PWD/s60audiocapturesession.h \
+ $$PWD/S60audiocontainercontrol.h
+
+SOURCES += $$PWD/s60audioencodercontrol.cpp \
+ $$PWD/s60audiomediarecordercontrol.cpp \
+ $$PWD/s60audioendpointselector.cpp \
+ $$PWD/s60audiocaptureservice.cpp \
+ $$PWD/s60audiocapturesession.cpp \
+ $$PWD/S60audiocontainercontrol.cpp
diff --git a/src/plugins/symbian/mmf/audiosource/s60audiocaptureservice.cpp b/src/plugins/symbian/mmf/audiosource/s60audiocaptureservice.cpp
new file mode 100644
index 000000000..742ac8f82
--- /dev/null
+++ b/src/plugins/symbian/mmf/audiosource/s60audiocaptureservice.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+#include <QDebug>
+
+#include "s60audiocaptureservice.h"
+#include "s60audiocapturesession.h"
+#include "s60audioendpointselector.h"
+#include "s60audioencodercontrol.h"
+#include "s60audiomediarecordercontrol.h"
+#include "s60audiocontainercontrol.h"
+
+S60AudioCaptureService::S60AudioCaptureService(QObject *parent):
+ QMediaService(parent)
+{
+ DP0("S60AudioCaptureService::S60AudioCaptureService +++");
+
+ m_session = new S60AudioCaptureSession(this);
+ m_encoderControl = new S60AudioEncoderControl(m_session,this);
+ m_recorderControl = new S60AudioMediaRecorderControl(m_session,this);
+ m_endpointSelector = new S60AudioEndpointSelector(m_session,this);
+ m_containerControl = new S60AudioContainerControl(m_session, this);
+
+ DP0("S60AudioCaptureService::S60AudioCaptureService ---");
+}
+
+S60AudioCaptureService::~S60AudioCaptureService()
+{
+ DP0("S60AudioCaptureService::~S60AudioCaptureService +++");
+ DP0("S60AudioCaptureService::~S60AudioCaptureService ---");
+}
+
+QMediaControl *S60AudioCaptureService::requestControl(const char *name)
+{
+ DP0("S60AudioCaptureService::requestControl");
+
+ if (qstrcmp(name,QMediaRecorderControl_iid) == 0)
+ return m_recorderControl;
+
+ if (qstrcmp(name,QAudioEncoderControl_iid) == 0)
+ return m_encoderControl;
+
+ if (qstrcmp(name,QAudioEndpointSelector_iid) == 0)
+ return m_endpointSelector;
+
+ if (qstrcmp(name,QMediaContainerControl_iid) == 0)
+ return m_containerControl;
+
+ return 0;
+}
+
+void S60AudioCaptureService::releaseControl(QMediaControl *control)
+{
+ DP0("S60AudioCaptureService::releaseControl +++");
+
+ Q_UNUSED(control)
+
+ DP0("S60AudioCaptureService::releaseControl ---");
+}
diff --git a/src/plugins/symbian/mmf/audiosource/s60audiocaptureservice.h b/src/plugins/symbian/mmf/audiosource/s60audiocaptureservice.h
new file mode 100644
index 000000000..86d71a994
--- /dev/null
+++ b/src/plugins/symbian/mmf/audiosource/s60audiocaptureservice.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60AUDIOCAPTURESERVICE_H
+#define S60AUDIOCAPTURESERVICE_H
+
+#include <QtCore/qobject.h>
+
+#include <qmediaservice.h>
+
+QT_USE_NAMESPACE
+
+class S60AudioCaptureSession;
+class S60AudioEncoderControl;
+class S60AudioMediaRecorderControl;
+class S60AudioEndpointSelector;
+class S60AudioContainerControl;
+
+
+class S60AudioCaptureService : public QMediaService
+{
+ Q_OBJECT
+public:
+ S60AudioCaptureService(QObject *parent = 0);
+ ~S60AudioCaptureService();
+
+ QMediaControl *requestControl(const char *name);
+ void releaseControl(QMediaControl *control);
+private:
+ S60AudioCaptureSession *m_session;
+ S60AudioEncoderControl *m_encoderControl;
+ S60AudioEndpointSelector *m_endpointSelector;
+ S60AudioMediaRecorderControl *m_recorderControl;
+ S60AudioContainerControl *m_containerControl;
+};
+
+#endif // S60AUDIOCAPTURESERVICE_H
diff --git a/src/plugins/symbian/mmf/audiosource/s60audiocapturesession.cpp b/src/plugins/symbian/mmf/audiosource/s60audiocapturesession.cpp
new file mode 100644
index 000000000..79b6a53a0
--- /dev/null
+++ b/src/plugins/symbian/mmf/audiosource/s60audiocapturesession.cpp
@@ -0,0 +1,937 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60audiocapturesession.h"
+#include <QtCore/qdebug.h>
+#include <QtCore/qurl.h>
+#include <QDir>
+
+#include <mda/common/audio.h>
+#include <mda/common/resource.h>
+#include <mda/client/utility.h>
+#include <mdaaudiosampleeditor.h>
+#include <mmf/common/mmfcontrollerpluginresolver.h>
+#include <mmf/common/mmfcontroller.h>
+#include <badesca.h>
+#include <bautils.h>
+#include <f32file.h>
+
+#ifdef AUDIOINPUT_ROUTING
+const QString S60AudioCaptureSession::microPhone("Microphone");
+const QString S60AudioCaptureSession::voiceCall("Voice Call");
+const QString S60AudioCaptureSession::fmRadio("FM Radio");
+#endif
+
+S60AudioCaptureSession::S60AudioCaptureSession(QObject *parent):
+ QObject(parent)
+ , m_recorderUtility(NULL)
+ , m_captureState(ENotInitialized)
+ , m_controllerIdMap(QHash<QString, ControllerData>())
+ , m_audioCodeclist(QHash<QString, CodecData>())
+ , m_error(QMediaRecorder::NoError)
+ , m_isMuted(false)
+{
+ DP0("S60AudioCaptureSession::S60AudioCaptureSession +++");
+#ifdef AUDIOINPUT_ROUTING
+ m_audioInput = NULL;
+ m_setActiveEndPoint = FALSE;
+ m_audioEndpoint = S60AudioCaptureSession::microPhone;
+#endif //AUDIOINPUT_ROUTING
+ TRAPD(err, initializeSessionL());
+ setError(err);
+
+ DP0("S60AudioCaptureSession::S60AudioCaptureSession ---");
+}
+
+void S60AudioCaptureSession::initializeSessionL()
+{
+ DP0("S60AudioCaptureSession::initializeSessionL +++");
+
+ m_recorderUtility = CMdaAudioRecorderUtility::NewL(*this, 0, EMdaPriorityNormal, EMdaPriorityPreferenceTimeAndQuality);
+ updateAudioContainersL();
+ populateAudioCodecsDataL();
+ setDefaultSettings();
+#ifdef AUDIOINPUT_ROUTING
+ initAudioInputs();
+#endif
+ User::LeaveIfError(m_fsSession.Connect());
+ m_captureState = EInitialized;
+ emit stateChanged(m_captureState);
+
+ DP0("S60AudioCaptureSession::initializeSessionL ---");
+}
+
+void S60AudioCaptureSession::setError(TInt aError)
+{
+ DP0("S60AudioCaptureSession::setError +++");
+
+ DP1("S60AudioCaptureSession::setError:", aError);
+
+ if (aError == KErrNone)
+ return;
+
+ m_error = aError;
+ QMediaRecorder::Error recorderError = fromSymbianErrorToMultimediaError(m_error);
+
+ // TODO: fix to user friendly string at some point
+ // These error string are only dev usable
+ QString symbianError;
+ symbianError.append("Symbian:");
+ symbianError.append(QString::number(m_error));
+ stop();
+ emit error(recorderError, symbianError);
+
+ DP0("S60AudioCaptureSession::setError ---");
+}
+
+QMediaRecorder::Error S60AudioCaptureSession::fromSymbianErrorToMultimediaError(int error)
+{
+ DP0("S60AudioCaptureSession::fromSymbianErrorToMultimediaError +++");
+
+ DP1("S60AudioCaptureSession::fromSymbianErrorToMultimediaError:", error);
+
+ switch(error) {
+ case KErrNoMemory:
+ case KErrNotFound:
+ case KErrBadHandle:
+ case KErrAbort:
+ case KErrCorrupt:
+ case KErrGeneral:
+ case KErrPathNotFound:
+ case KErrUnknown:
+ case KErrNotReady:
+ case KErrInUse:
+ case KErrAccessDenied:
+ case KErrLocked:
+ case KErrPermissionDenied:
+ case KErrAlreadyExists:
+ return QMediaRecorder::ResourceError;
+ case KErrNotSupported:
+ case KErrArgument:
+ return QMediaRecorder::FormatError;
+ case KErrNone:
+ default:
+ DP0("S60AudioCaptureSession::fromSymbianErrorToMultimediaError: ---");
+ return QMediaRecorder::NoError;
+ }
+}
+
+S60AudioCaptureSession::~S60AudioCaptureSession()
+{
+ DP0("S60AudioCaptureSession::~S60AudioCaptureSession +++");
+ //stop the utility before deleting it
+ stop();
+ if (m_recorderUtility)
+ delete m_recorderUtility;
+ m_fsSession.Close();
+ DP0("S60AudioCaptureSession::~S60AudioCaptureSession ---");
+}
+
+QAudioFormat S60AudioCaptureSession::format() const
+{
+ DP0("S60AudioCaptureSession::format");
+
+ return m_format;
+}
+
+bool S60AudioCaptureSession::setFormat(const QAudioFormat &format)
+{
+ DP0("S60AudioCaptureSession::setFormat +++");
+
+ m_format = format;
+
+ DP0("S60AudioCaptureSession::setFormat ---");
+
+ return true;
+}
+
+QAudioEncoderSettings S60AudioCaptureSession::settings() const
+{
+ DP0("S60AudioCaptureSession::settings");
+
+ return m_audioEncoderSettings;
+}
+
+bool S60AudioCaptureSession::setEncoderSettings(const QAudioEncoderSettings &setting)
+{
+ DP0("S60AudioCaptureSession::setEncoderSettings +++");
+
+ m_audioEncoderSettings = setting;
+
+ DP0("S60AudioCaptureSession::setEncoderSettings ---");
+
+ return true;
+}
+
+QStringList S60AudioCaptureSession::supportedAudioCodecs() const
+{
+ DP0("S60AudioCaptureSession::supportedAudioCodecs");
+
+ return m_audioCodeclist.keys();
+}
+
+QStringList S60AudioCaptureSession::supportedAudioContainers() const
+{
+ DP0("S60AudioCaptureSession::supportedAudioContainers");
+
+ return m_controllerIdMap.keys();
+}
+
+QString S60AudioCaptureSession::codecDescription(const QString &codecName)
+{
+ DP0("S60AudioCaptureSession::codecDescription +++");
+
+ if (m_audioCodeclist.keys().contains(codecName)) {
+
+ DP0("S60AudioCaptureSession::codecDescription ---");
+ return m_audioCodeclist.value(codecName).codecDescription;
+ }
+ else {
+ DP0("S60AudioCaptureSession::codecDescription ---");
+
+ return QString();
+ }
+}
+
+QString S60AudioCaptureSession::audioContainerDescription(const QString &containerName)
+{
+ DP0("S60AudioCaptureSession::audioContainerDescription +++");
+
+ if (m_controllerIdMap.keys().contains(containerName)) {
+ DP0("S60AudioCaptureSession::audioContainerDescription ---");
+
+ return m_controllerIdMap.value(containerName).destinationFormatDescription;
+ }
+ else {
+ DP0("S60AudioCaptureSession::audioContainerDescription ---");
+
+ return QString();
+ }
+}
+
+bool S60AudioCaptureSession::setAudioCodec(const QString &codecName)
+{
+ DP0("S60AudioCaptureSession::setAudioCodec");
+
+ QStringList codecs = supportedAudioCodecs();
+ if(codecs.contains(codecName)) {
+ m_format.setCodec(codecName);
+ return true;
+ }
+ return false;
+}
+
+bool S60AudioCaptureSession::setAudioContainer(const QString &containerMimeType)
+{
+ DP0("S60AudioCaptureSession::setAudioContainer");
+
+ QStringList containers = supportedAudioContainers();
+ if (containerMimeType == "audio/mpeg")
+ {
+ m_container = "audio/mp4";
+ return true;
+ }
+ if(containers.contains(containerMimeType)) {
+ m_container = containerMimeType;
+ return true;
+ }
+ return false;
+}
+
+QString S60AudioCaptureSession::audioCodec() const
+{
+ DP0("S60AudioCaptureSession::audioCodec");
+
+ return m_format.codec();
+}
+
+QString S60AudioCaptureSession::audioContainer() const
+{
+ DP0("S60AudioCaptureSession::audioContainer");
+
+ return m_container;
+}
+
+QUrl S60AudioCaptureSession::outputLocation() const
+{
+ DP0("S60AudioCaptureSession::outputLocation");
+
+ return m_sink;
+}
+
+bool S60AudioCaptureSession::setOutputLocation(const QUrl& sink)
+{
+ DP0("S60AudioCaptureSession::setOutputLocation");
+
+ QString filename = QDir::toNativeSeparators(sink.toString());
+ TPtrC16 path(reinterpret_cast<const TUint16*>(filename.utf16()));
+ TRAPD(err, BaflUtils::EnsurePathExistsL(m_fsSession,path));
+ if (err == KErrNone) {
+ m_sink = sink;
+ setError(err);
+ return true;
+ }else {
+ setError(err);
+ return false;
+ }
+}
+
+qint64 S60AudioCaptureSession::position() const
+{
+ DP0("S60AudioCaptureSession::position");
+
+ if ((m_captureState != ERecording) || !m_recorderUtility)
+ return 0;
+
+ return m_recorderUtility->Duration().Int64() / 1000;
+}
+
+void S60AudioCaptureSession::prepareSinkL()
+{
+ DP0("S60AudioCaptureSession::prepareSinkL +++");
+
+ /* If m_outputLocation is null, set a default location */
+ if (m_sink.isEmpty()) {
+ QDir outputDir(QDir::rootPath());
+ int lastImage = 0;
+ int fileCount = 0;
+ foreach(QString fileName, outputDir.entryList(QStringList() << "recordclip_*")) {
+ int imgNumber = fileName.mid(5, fileName.size() - 9).toInt();
+ lastImage = qMax(lastImage, imgNumber);
+ if (outputDir.exists(fileName))
+ fileCount += 1;
+ }
+ lastImage += fileCount;
+ m_sink = QUrl(QDir::toNativeSeparators(outputDir.canonicalPath() + QString("/recordclip_%1").arg(lastImage + 1, 4, 10, QLatin1Char('0'))));
+ }
+
+ QString sink = QDir::toNativeSeparators(m_sink.toString());
+ TPtrC16 path(reinterpret_cast<const TUint16*>(sink.utf16()));
+ if (BaflUtils::FileExists(m_fsSession, path))
+ BaflUtils::DeleteFile(m_fsSession, path);
+
+ int index = sink.lastIndexOf('.');
+ if (index != -1)
+ sink.chop(sink.length()-index);
+
+ sink.append(m_controllerIdMap.value(m_container).fileExtension);
+ m_sink.setUrl(sink);
+
+ DP0("S60AudioCaptureSession::prepareSinkL ---");
+}
+
+void S60AudioCaptureSession::record()
+{
+ DP0("S60AudioCaptureSession::record +++");
+
+ if (!m_recorderUtility)
+ return;
+
+ if (m_captureState == EInitialized || m_captureState == ERecordComplete) {
+ prepareSinkL();
+ QString filename = m_sink.toString();
+ TPtrC16 sink(reinterpret_cast<const TUint16*>(filename.utf16()));
+ TUid controllerUid(TUid::Uid(m_controllerIdMap.value(m_container).controllerUid));
+ TUid formatUid(TUid::Uid(m_controllerIdMap.value(m_container).destinationFormatUid));
+
+ TRAPD(err,m_recorderUtility->OpenFileL(sink));
+ setError(err);
+ }else if (m_captureState == EPaused) {
+ m_recorderUtility->SetPosition(m_pausedPosition);
+ TRAPD(error, m_recorderUtility->RecordL());
+ setError(error);
+ m_captureState = ERecording;
+ emit stateChanged(m_captureState);
+ }
+
+ DP0("S60AudioCaptureSession::record ---");
+}
+
+void S60AudioCaptureSession::mute(bool muted)
+{
+ DP0("S60AudioCaptureSession::mute +++");
+
+ if (!m_recorderUtility)
+ return;
+
+ if (muted)
+ m_recorderUtility->SetGain(0);
+ else
+ m_recorderUtility->SetGain(m_recorderUtility->MaxGain());
+
+ m_isMuted = muted;
+
+ DP0("S60AudioCaptureSession::mute ---");
+}
+
+bool S60AudioCaptureSession::muted()
+{
+ DP0("S60AudioCaptureSession::muted");
+
+ return m_isMuted;
+}
+
+void S60AudioCaptureSession::setDefaultSettings()
+{
+ DP0("S60AudioCaptureSession::setDefaultSettings +++");
+
+ // Setting AMR to default format if supported
+ if (m_controllerIdMap.count() > 0) {
+ if ( m_controllerIdMap.contains("audio/amr"))
+ m_container = QString("audio/amr");
+ else
+ m_container = m_controllerIdMap.keys()[0];
+ }
+ if (m_audioCodeclist.keys().count() > 0) {
+ if (m_audioCodeclist.keys().contains("AMR")) {
+ m_format.setSampleSize(8);
+ m_format.setChannels(1);
+ m_format.setFrequency(8000);
+ m_format.setSampleType(QAudioFormat::SignedInt);
+ m_format.setCodec("AMR");
+ }else
+ m_format.setCodec(m_audioCodeclist.keys()[0]);
+ }
+
+ DP0("S60AudioCaptureSession::setDefaultSettings ---");
+}
+
+void S60AudioCaptureSession::pause()
+{
+ DP0("S60AudioCaptureSession::pause +++");
+
+ if (!m_recorderUtility)
+ return;
+
+ m_pausedPosition = m_recorderUtility->Position();
+ m_recorderUtility->Stop();
+ m_captureState = EPaused;
+ emit stateChanged(m_captureState);
+
+ DP0("S60AudioCaptureSession::pause ---");
+}
+
+void S60AudioCaptureSession::stop()
+{
+ DP0("S60AudioCaptureSession::stop +++");
+
+ if (!m_recorderUtility)
+ return;
+
+ m_recorderUtility->Stop();
+
+#ifdef AUDIOINPUT_ROUTING
+ //delete audio input instance before closing the utility.
+ if (m_audioInput)
+ {
+ delete m_audioInput;
+ m_audioInput = NULL;
+ }
+#endif //AUDIOINPUT_ROUTING
+
+ m_recorderUtility->Close();
+ m_captureState = ERecordComplete;
+ emit stateChanged(m_captureState);
+}
+
+#ifdef AUDIOINPUT_ROUTING
+
+void S60AudioCaptureSession::initAudioInputs()
+{
+ DP0(" S60AudioCaptureSession::initAudioInputs +++");
+
+ m_audioInputs[S60AudioCaptureSession::microPhone] = QString("Microphone associated with the currently active speaker.");
+ m_audioInputs[S60AudioCaptureSession::voiceCall] = QString("Audio stream associated with the current phone call.");
+ m_audioInputs[S60AudioCaptureSession::fmRadio] = QString("Audio of the currently tuned FM radio station.");
+
+ DP0(" S60AudioCaptureSession::initAudioInputs ---");
+}
+
+#endif //AUDIOINPUT_ROUTING
+
+void S60AudioCaptureSession::setActiveEndpoint(const QString& audioEndpoint)
+{
+ DP0(" S60AudioCaptureSession::setActiveEndpoint +++");
+
+ if (!m_audioInputs.keys().contains(audioEndpoint))
+ return;
+
+ if (activeEndpoint().compare(audioEndpoint) != 0) {
+ m_audioEndpoint = audioEndpoint;
+#ifdef AUDIOINPUT_ROUTING
+ m_setActiveEndPoint = TRUE;
+#endif
+ }
+
+ DP0(" S60AudioCaptureSession::setActiveEndpoint ---");
+}
+
+QList<QString> S60AudioCaptureSession::availableEndpoints() const
+{
+ DP0(" S60AudioCaptureSession::availableEndpoints");
+
+ return m_audioInputs.keys();
+}
+
+QString S60AudioCaptureSession::endpointDescription(const QString& name) const
+{
+ DP0(" S60AudioCaptureSession::endpointDescription +++");
+
+ if (m_audioInputs.keys().contains(name))
+ return m_audioInputs.value(name);
+ return QString();
+}
+
+QString S60AudioCaptureSession::activeEndpoint() const
+{
+ DP0(" S60AudioCaptureSession::activeEndpoint");
+
+ QString inputSourceName = NULL;
+#ifdef AUDIOINPUT_ROUTING
+ if (m_audioInput) {
+ CAudioInput::TAudioInputArray input = m_audioInput->AudioInput();
+ inputSourceName = qStringFromTAudioInputPreference(input[0]);
+ }
+#endif //AUDIOINPUT_ROUTING
+ return inputSourceName;
+}
+
+QString S60AudioCaptureSession::defaultEndpoint() const
+{
+ DP0(" S60AudioCaptureSession::defaultEndpoint");
+
+#ifdef AUDIOINPUT_ROUTING
+ return QString(S60AudioCaptureSession::microPhone);
+#else
+ return NULL;
+#endif
+}
+
+#ifdef AUDIOINPUT_ROUTING
+
+void S60AudioCaptureSession::doSetAudioInputL(const QString& name)
+{
+ DP0(" S60AudioCaptureSession::doSetAudioInputL +++");
+ DP1(" S60AudioCaptureSession::doSetAudioInputL:", name);
+ TInt err(KErrNone);
+
+ if (!m_recorderUtility)
+ return;
+
+ CAudioInput::TAudioInputPreference input = CAudioInput::EDefaultMic;
+
+ if (name.compare(S60AudioCaptureSession::voiceCall) == 0)
+ input = CAudioInput::EVoiceCall;
+// commented because they are not supported on 9.2
+ else if (name.compare(S60AudioCaptureSession::fmRadio) == 0)
+ input = CAudioInput::EFMRadio;
+ else // S60AudioCaptureSession::microPhone
+ input = CAudioInput::EDefaultMic;
+
+ RArray<CAudioInput::TAudioInputPreference> inputArray;
+ inputArray.Append(input);
+
+ if (m_audioInput){
+ TRAP(err,m_audioInput->SetAudioInputL(inputArray.Array()));
+
+ if (err == KErrNone) {
+ emit activeEndpointChanged(name);
+ }
+ else{
+ setError(err);
+ }
+ }
+ inputArray.Close();
+
+ DP0(" S60AudioCaptureSession::doSetAudioInputL ---");
+}
+
+
+QString S60AudioCaptureSession::qStringFromTAudioInputPreference(CAudioInput::TAudioInputPreference input) const
+{
+ DP0(" S60AudioCaptureSession::qStringFromTAudioInputPreference");
+
+ if (input == CAudioInput::EVoiceCall)
+ return S60AudioCaptureSession::voiceCall;
+ else if (input == CAudioInput::EFMRadio)
+ return S60AudioCaptureSession::fmRadio;
+ else
+ return S60AudioCaptureSession::microPhone; // CAudioInput::EDefaultMic
+}
+#endif //AUDIOINPUT_ROUTING
+
+
+void S60AudioCaptureSession::MoscoStateChangeEvent(CBase* aObject,
+ TInt aPreviousState, TInt aCurrentState, TInt aErrorCode)
+{
+ DP0("S60AudioCaptureSession::MoscoStateChangeEvent +++");
+
+ if (aErrorCode==KErrNone) {
+ TRAPD(err, MoscoStateChangeEventL(aObject, aPreviousState, aCurrentState, NULL));
+ setError(err);
+ }
+ else {
+ setError(aErrorCode);
+ }
+ DP1("S60AudioCaptureSession::MoscoStateChangeEvent, aErrorCode:", aErrorCode);
+ DP0("S60AudioCaptureSession::MoscoStateChangeEvent ---");
+}
+
+void S60AudioCaptureSession::MoscoStateChangeEventL(CBase* aObject,
+ TInt aPreviousState, TInt aCurrentState, TInt aErrorCode)
+{
+ DP0("S60AudioCaptureSession::MoscoStateChangeEventL +++");
+
+ DP5("S60AudioCaptureSession::MoscoStateChangeEventL - aPreviousState:", aPreviousState,
+ "aCurrentState:", aCurrentState, "aErrorCode:", aErrorCode);
+ if (aObject != m_recorderUtility)
+ return;
+
+ switch(aCurrentState) {
+ case CMdaAudioClipUtility::EOpen: {
+ if(aPreviousState == CMdaAudioClipUtility::ENotReady) {
+ applyAudioSettingsL();
+ m_recorderUtility->SetGain(m_recorderUtility->MaxGain());
+ TRAPD(err, m_recorderUtility->RecordL());
+ setError(err);
+ m_captureState = EOpenCompelete;
+ emit stateChanged(m_captureState);
+ }
+ break;
+ }
+ case CMdaAudioClipUtility::ENotReady: {
+ m_captureState = EInitialized;
+ emit stateChanged(m_captureState);
+ break;
+ }
+ case CMdaAudioClipUtility::ERecording: {
+ m_captureState = ERecording;
+ emit stateChanged(m_captureState);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+
+ DP0("S60AudioCaptureSession::MoscoStateChangeEventL ---");
+}
+
+void S60AudioCaptureSession::updateAudioContainersL()
+{
+ DP0("S60AudioCaptureSession::updateAudioContainersL +++");
+
+ CMMFControllerPluginSelectionParameters* pluginParameters =
+ CMMFControllerPluginSelectionParameters::NewLC();
+ CMMFFormatSelectionParameters* formatParameters =
+ CMMFFormatSelectionParameters::NewLC();
+
+ pluginParameters->SetRequiredRecordFormatSupportL(*formatParameters);
+
+ RArray<TUid> ids;
+ CleanupClosePushL(ids);
+ User::LeaveIfError(ids.Append(KUidMediaTypeAudio));
+
+ pluginParameters->SetMediaIdsL(ids,
+ CMMFPluginSelectionParameters::EAllowOnlySuppliedMediaIds);
+
+ RMMFControllerImplInfoArray controllers;
+ CleanupResetAndDestroyPushL(controllers);
+
+ //Get all audio record controllers/formats that are supported
+ pluginParameters->ListImplementationsL(controllers);
+
+ for (TInt index=0; index<controllers.Count(); index++) {
+ const RMMFFormatImplInfoArray& recordFormats =
+ controllers[index]->RecordFormats();
+ for (TInt j=0; j<recordFormats.Count(); j++) {
+ const CDesC8Array& mimeTypes = recordFormats[j]->SupportedMimeTypes();
+ const CDesC8Array& fileExtensions = recordFormats[j]->SupportedFileExtensions();
+ TInt mimeCount = mimeTypes.Count();
+ TInt fileExtCount = fileExtensions.Count();
+
+ if (mimeCount > 0 && fileExtCount > 0) {
+ TPtrC8 extension = fileExtensions[0];
+ TPtrC8 mimeType = mimeTypes[0];
+ QString type = QString::fromUtf8((char *)mimeType.Ptr(), mimeType.Length());
+
+ if (type != "audio/basic") {
+ ControllerData data;
+ data.controllerUid = controllers[index]->Uid().iUid;
+ data.destinationFormatUid = recordFormats[j]->Uid().iUid;
+ data.destinationFormatDescription = QString::fromUtf16(
+ recordFormats[j]->DisplayName().Ptr(),
+ recordFormats[j]->DisplayName().Length());
+ data.fileExtension = QString::fromUtf8((char *)extension.Ptr(), extension.Length());
+ m_controllerIdMap[type] = data;
+ }
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy(4);//controllers, ids, formatParameters, pluginParameters
+
+ DP0("S60AudioCaptureSession::updateAudioContainersL ---");
+}
+
+void S60AudioCaptureSession::retrieveSupportedAudioSampleRatesL()
+{
+ DP0("S60AudioCaptureSession::retrieveSupportedAudioSampleRatesL +++");
+
+ if (!m_recorderUtility) {
+ DP0("No RecorderUtility");
+ return;
+ }
+
+ m_supportedSampleRates.clear();
+
+ RArray<TUint> supportedSampleRates;
+ CleanupClosePushL(supportedSampleRates);
+ m_recorderUtility->GetSupportedSampleRatesL(supportedSampleRates);
+ for (TInt j = 0; j < supportedSampleRates.Count(); j++ )
+ m_supportedSampleRates.append(supportedSampleRates[j]);
+
+ CleanupStack::PopAndDestroy(&supportedSampleRates);
+
+ DP0("S60AudioCaptureSession::retrieveSupportedAudioSampleRatesL ---");
+}
+
+QList<int> S60AudioCaptureSession::supportedAudioSampleRates(const QAudioEncoderSettings &settings) const
+{
+ DP0("S60AudioCaptureSession::supportedAudioSampleRates +++");
+
+ QList<int> supportedSampleRates;
+
+ if (!settings.codec().isEmpty()) {
+ if (settings.codec() == "AMR")
+ supportedSampleRates.append(8000);
+ else
+ supportedSampleRates = m_supportedSampleRates;
+ }else
+ supportedSampleRates = m_supportedSampleRates;
+
+ DP0("S60AudioCaptureSession::supportedAudioSampleRates ---");
+
+ return supportedSampleRates;
+}
+
+void S60AudioCaptureSession::populateAudioCodecsDataL()
+{
+ DP0("S60AudioCaptureSession::populateAudioCodecsDataL +++");
+
+ if (!m_recorderUtility) {
+ DP0("No RecorderUtility");
+
+ return;
+ }
+
+ if (m_controllerIdMap.contains("audio/amr")) {
+ CodecData data;
+ data.codecDescription = QString("GSM AMR Codec");
+ m_audioCodeclist[QString("AMR")]=data;
+ }
+ if (m_controllerIdMap.contains("audio/basic")) {
+ CodecData data;
+ data.fourCC = KMMFFourCCCodeALAW;
+ data.codecDescription = QString("Sun/Next ""Au"" audio codec");
+ m_audioCodeclist[QString("AULAW")]=data;
+ }
+ if (m_controllerIdMap.contains("audio/wav")) {
+ CodecData data;
+ data.fourCC = KMMFFourCCCodePCM16;
+ data.codecDescription = QString("Pulse code modulation");
+ m_audioCodeclist[QString("PCM")]=data;
+ }
+ if (m_controllerIdMap.contains("audio/mp4")) {
+ CodecData data;
+ data.fourCC = KMMFFourCCCodeAAC;
+ data.codecDescription = QString("Advanced Audio Codec");
+ m_audioCodeclist[QString("AAC")]=data;
+ }
+
+ // default samplerates
+ m_supportedSampleRates << 96000 << 88200 << 64000 << 48000 << 44100 << 32000 << 24000 << 22050 << 16000 << 12000 << 11025 << 8000;
+
+ DP0("S60AudioCaptureSession::populateAudioCodecsDataL ---");
+}
+
+void S60AudioCaptureSession::applyAudioSettingsL()
+{
+ DP0("S60AudioCaptureSession::applyAudioSettingsL +++");
+
+ if (!m_recorderUtility)
+ return;
+
+#ifdef AUDIOINPUT_ROUTING
+ //CAudioInput needs to be re-initialized every time recording starts
+ if (m_audioInput) {
+ delete m_audioInput;
+ m_audioInput = NULL;
+ }
+
+ if (m_setActiveEndPoint) {
+ m_audioInput = CAudioInput::NewL(*m_recorderUtility);
+ doSetAudioInputL(m_audioEndpoint);
+ }
+#endif //AUDIOINPUT_ROUTING
+
+ if (m_format.codec() == "AMR")
+ return;
+
+ TFourCC fourCC = m_audioCodeclist.value(m_format.codec()).fourCC;
+
+ if (m_format.codec() == "PCM")
+ fourCC = determinePCMFormat();
+
+ RArray<TFourCC> supportedDataTypes;
+ CleanupClosePushL(supportedDataTypes);
+ TRAPD(err,m_recorderUtility->GetSupportedDestinationDataTypesL(supportedDataTypes));
+ TInt num = supportedDataTypes.Count();
+ if (num > 0 ) {
+ supportedDataTypes.SortUnsigned();
+ int index = supportedDataTypes.Find(fourCC.FourCC());
+ if (index != KErrNotFound) {
+ TRAPD(err,m_recorderUtility->SetDestinationDataTypeL(supportedDataTypes[index]));
+ }
+ }
+
+ supportedDataTypes.Reset();
+ CleanupStack::PopAndDestroy(&supportedDataTypes);
+
+ if (m_recorderUtility->DestinationSampleRateL() != m_format.frequency()) {
+
+ RArray<TUint> supportedSampleRates;
+ CleanupClosePushL(supportedSampleRates);
+ m_recorderUtility->GetSupportedSampleRatesL(supportedSampleRates);
+ for (TInt i = 0; i < supportedSampleRates.Count(); i++ ) {
+ TUint supportedSampleRate = supportedSampleRates[i];
+ if (supportedSampleRate == m_format.frequency()) {
+ m_recorderUtility->SetDestinationSampleRateL(m_format.frequency());
+ break;
+ }
+ }
+ supportedSampleRates.Reset();
+ CleanupStack::PopAndDestroy(&supportedSampleRates);
+ }
+
+ /* If requested channel setting is different than current one */
+ if (m_recorderUtility->DestinationNumberOfChannelsL() != m_format.channels()) {
+ RArray<TUint> supportedChannels;
+ CleanupClosePushL(supportedChannels);
+ m_recorderUtility->GetSupportedNumberOfChannelsL(supportedChannels);
+ for (TInt l = 0; l < supportedChannels.Count(); l++ ) {
+ if (supportedChannels[l] == m_format.channels()) {
+ m_recorderUtility->SetDestinationNumberOfChannelsL(m_format.channels());
+ break;
+ }
+ }
+ supportedChannels.Reset();
+ CleanupStack::PopAndDestroy(&supportedChannels);
+ }
+
+ if (!(m_format.codec().compare("pcm",Qt::CaseInsensitive) == 0)) {
+ if (m_recorderUtility->DestinationBitRateL() != m_audioEncoderSettings.bitRate()) {
+ RArray<TUint> supportedBitRates;
+ CleanupClosePushL(supportedBitRates);
+ m_recorderUtility->GetSupportedBitRatesL(supportedBitRates);
+ for (TInt l = 0; l < supportedBitRates.Count(); l++ ) {
+ if (supportedBitRates[l] == m_audioEncoderSettings.bitRate()) {
+ m_recorderUtility->SetDestinationBitRateL(m_audioEncoderSettings.bitRate());
+ break;
+ }
+ }
+ supportedBitRates.Reset();
+ CleanupStack::PopAndDestroy(&supportedBitRates);
+ }
+ }
+
+ DP0("S60AudioCaptureSession::applyAudioSettingsL ---");
+}
+
+TFourCC S60AudioCaptureSession::determinePCMFormat()
+{
+ DP0("S60AudioCaptureSession::determinePCMFormat +++");
+
+ TFourCC fourCC;
+
+ if (m_format.sampleSize() == 8) {
+ // 8 bit
+ switch (m_format.sampleType()) {
+ case QAudioFormat::SignedInt: {
+ fourCC.Set(KMMFFourCCCodePCM8);
+ break;
+ }
+ case QAudioFormat::UnSignedInt: {
+ fourCC.Set(KMMFFourCCCodePCMU8);
+ break;
+ }
+ case QAudioFormat::Float:
+ case QAudioFormat::Unknown:
+ default: {
+ fourCC.Set(KMMFFourCCCodePCM8);
+ break;
+ }
+ }
+ } else if (m_format.sampleSize() == 16) {
+ // 16 bit
+ switch (m_format.sampleType()) {
+ case QAudioFormat::SignedInt: {
+ fourCC.Set(m_format.byteOrder()==QAudioFormat::BigEndian?
+ KMMFFourCCCodePCM16B:KMMFFourCCCodePCM16);
+ break;
+ }
+ case QAudioFormat::UnSignedInt: {
+ fourCC.Set(m_format.byteOrder()==QAudioFormat::BigEndian?
+ KMMFFourCCCodePCMU16B:KMMFFourCCCodePCMU16);
+ break;
+ }
+ default: {
+ fourCC.Set(KMMFFourCCCodePCM16);
+ break;
+ }
+ }
+ }
+
+ DP0("S60AudioCaptureSession::determinePCMFormat ---");
+
+ return fourCC;
+}
diff --git a/src/plugins/symbian/mmf/audiosource/s60audiocapturesession.h b/src/plugins/symbian/mmf/audiosource/s60audiocapturesession.h
new file mode 100644
index 000000000..a541446e9
--- /dev/null
+++ b/src/plugins/symbian/mmf/audiosource/s60audiocapturesession.h
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60AUDIOCAPTURESESSION_H
+#define S60AUDIOCAPTURESESSION_H
+
+#include <qmobilityglobal.h>
+#include <QtCore/qobject.h>
+#include <QFile>
+#include <QUrl>
+#include <QList>
+#include <QHash>
+#include <QMap>
+#include "qaudioformat.h"
+#include <qmediarecorder.h>
+
+#include <mda/common/audio.h>
+#include <mda/common/resource.h>
+#include <mda/client/utility.h>
+#include <mdaaudiosampleeditor.h>
+#include <mmf/common/mmfutilities.h>
+
+#ifdef AUDIOINPUT_ROUTING
+#include <audioinput.h>
+#endif //AUDIOINPUT_ROUTING
+
+QT_BEGIN_NAMESPACE
+struct ControllerData
+{
+ int controllerUid;
+ int destinationFormatUid;
+ QString destinationFormatDescription;
+ QString fileExtension;
+};
+
+struct CodecData
+{
+ TFourCC fourCC;
+ QString codecDescription;
+};
+QT_END_NAMESPACE
+
+QT_USE_NAMESPACE
+
+class S60AudioCaptureSession : public QObject, public MMdaObjectStateChangeObserver
+{
+ Q_OBJECT
+ Q_PROPERTY(qint64 position READ position NOTIFY positionChanged)
+ Q_ENUMS(TAudioCaptureState)
+public:
+
+ enum TAudioCaptureState
+ {
+ ENotInitialized = 0,
+ EInitialized,
+ EOpenCompelete,
+ ERecording,
+ EPaused,
+ ERecordComplete
+ };
+
+ S60AudioCaptureSession(QObject *parent = 0);
+ ~S60AudioCaptureSession();
+
+ QAudioFormat format() const;
+ bool setFormat(const QAudioFormat &format);
+ QAudioEncoderSettings settings() const;
+ bool setEncoderSettings(const QAudioEncoderSettings &setting);
+ QStringList supportedAudioCodecs() const;
+ QString codecDescription(const QString &codecName);
+ bool setAudioCodec(const QString &codecName);
+ QString audioCodec() const;
+ QString audioContainer() const;
+ QStringList supportedAudioContainers() const;
+ bool setAudioContainer(const QString &containerMimeType);
+ QString audioContainerDescription(const QString &containerName);
+ QList<int> supportedAudioSampleRates(const QAudioEncoderSettings &settings) const;
+ QUrl outputLocation() const;
+ bool setOutputLocation(const QUrl& sink);
+ qint64 position() const;
+ void record();
+ void pause();
+ void stop();
+ void mute(bool muted);
+ bool muted();
+
+ QString activeEndpoint() const;
+ QString defaultEndpoint() const;
+ QList<QString> availableEndpoints() const;
+ QString endpointDescription(const QString& name) const;
+
+#ifdef AUDIOINPUT_ROUTING
+ static const QString microPhone;
+ static const QString voiceCall;
+ static const QString fmRadio;
+#endif //AUDIOINPUT_ROUTING
+private:
+ void initializeSessionL();
+ void setError(TInt aError);
+ QMediaRecorder::Error fromSymbianErrorToMultimediaError(int error);
+ void prepareSinkL();
+ void updateAudioContainersL();
+ void populateAudioCodecsDataL();
+ void retrieveSupportedAudioSampleRatesL();
+ void applyAudioSettingsL();
+ TFourCC determinePCMFormat();
+ void setDefaultSettings();
+ // MMdaObjectStateChangeObserver
+ void MoscoStateChangeEvent(CBase* aObject, TInt aPreviousState,
+ TInt aCurrentState, TInt aErrorCode);
+ void MoscoStateChangeEventL(CBase* aObject, TInt aPreviousState,
+ TInt aCurrentState, TInt aErrorCode);
+
+#ifdef AUDIOINPUT_ROUTING
+ QString qStringFromTAudioInputPreference(CAudioInput::TAudioInputPreference input) const;
+ void initAudioInputs();
+ void doSetAudioInputL(const QString& name);
+#endif //AUDIOINPUT_ROUTING
+
+public Q_SLOTS:
+ void setActiveEndpoint(const QString& audioEndpoint);
+
+
+Q_SIGNALS:
+ void stateChanged(S60AudioCaptureSession::TAudioCaptureState);
+ void positionChanged(qint64 position);
+ void error(int error, const QString &errorString);
+ void activeEndpointChanged(const QString &audioEndpoint);
+private:
+ QString m_container;
+ QUrl m_sink;
+ TTimeIntervalMicroSeconds m_pausedPosition;
+ CMdaAudioRecorderUtility *m_recorderUtility;
+ TAudioCaptureState m_captureState;
+ QAudioFormat m_format;
+ QAudioEncoderSettings m_audioEncoderSettings;
+ QHash<QString, ControllerData> m_controllerIdMap;
+ QHash<QString, CodecData> m_audioCodeclist;
+ QList<int> m_supportedSampleRates;
+ int m_error;
+ bool m_isMuted;
+ RFs m_fsSession;
+
+#ifdef AUDIOINPUT_ROUTING
+ bool m_setActiveEndPoint;
+ CAudioInput *m_audioInput;
+
+#endif //AUDIOINPUT_ROUTING
+ QMap<QString, QString> m_audioInputs;
+ QString m_audioEndpoint;
+
+
+};
+
+#endif // S60AUDIOCAPTURESESSION_H
diff --git a/src/plugins/symbian/mmf/audiosource/s60audiocontainercontrol.cpp b/src/plugins/symbian/mmf/audiosource/s60audiocontainercontrol.cpp
new file mode 100644
index 000000000..d6c2d5db2
--- /dev/null
+++ b/src/plugins/symbian/mmf/audiosource/s60audiocontainercontrol.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60audiocontainercontrol.h"
+#include "s60audiocapturesession.h"
+#include <QtCore/qdebug.h>
+
+S60AudioContainerControl::S60AudioContainerControl(QObject *parent)
+ : QMediaContainerControl(parent)
+{
+ DP0("S60AudioContainerControl::S60AudioContainerControl(QObject *parent) +++");
+
+ DP0("S60AudioContainerControl::S60AudioContainerControl(QObject *parent) ---");
+
+}
+
+S60AudioContainerControl::S60AudioContainerControl(QObject *session, QObject *parent)
+ : QMediaContainerControl(parent)
+{
+ DP0("S60AudioContainerControl::S60AudioContainerControl(QObject *session, QObject *parent) +++");
+
+ m_session = qobject_cast<S60AudioCaptureSession*>(session);
+
+ DP0("S60AudioContainerControl::S60AudioContainerControl(QObject *session, QObject *parent) ---");
+}
+
+QStringList S60AudioContainerControl::supportedContainers() const
+{
+ DP0("S60AudioContainerControl::supportedContainers");
+
+ return m_session->supportedAudioContainers();
+}
+
+QString S60AudioContainerControl::containerMimeType() const
+{
+ DP0("S60AudioContainerControl::containerMimeType");
+
+ return m_session->audioContainer();
+}
+
+void S60AudioContainerControl::setContainerMimeType(const QString &containerMimeType)
+{
+ DP0("S60AudioContainerControl::setContainerMimeType +++");
+
+ m_session->setAudioContainer(containerMimeType);
+
+ DP0("S60AudioContainerControl::setContainerMimeType ---");
+}
+
+QString S60AudioContainerControl::containerDescription(const QString &containerMimeType) const
+{
+ DP0("S60AudioContainerControl::containerDescription");
+
+ return m_session->audioContainerDescription(containerMimeType);
+}
+
diff --git a/src/plugins/symbian/mmf/audiosource/s60audiocontainercontrol.h b/src/plugins/symbian/mmf/audiosource/s60audiocontainercontrol.h
new file mode 100644
index 000000000..4c3498d0f
--- /dev/null
+++ b/src/plugins/symbian/mmf/audiosource/s60audiocontainercontrol.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60AUDIOFORMATCONTROL_H
+#define S60AUDIOFORMATCONTROL_H
+
+#include "qmediacontainercontrol.h"
+#include <QtCore/qstringlist.h>
+
+
+QT_USE_NAMESPACE
+
+class S60AudioCaptureSession;
+
+class S60AudioContainerControl : public QMediaContainerControl
+{
+Q_OBJECT
+public:
+ S60AudioContainerControl(QObject *parent = 0);
+ S60AudioContainerControl(QObject *session, QObject *parent = 0);
+ virtual ~S60AudioContainerControl() {};
+
+ QStringList supportedContainers() const;
+ QString containerMimeType() const;
+ void setContainerMimeType(const QString &containerMimeType);
+ QString containerDescription(const QString &containerMimeType) const;
+
+private:
+ S60AudioCaptureSession* m_session;
+};
+
+#endif // S60AUDIOFORMATCONTROL_H
diff --git a/src/plugins/symbian/mmf/audiosource/s60audioencodercontrol.cpp b/src/plugins/symbian/mmf/audiosource/s60audioencodercontrol.cpp
new file mode 100644
index 000000000..b3d02a94a
--- /dev/null
+++ b/src/plugins/symbian/mmf/audiosource/s60audioencodercontrol.cpp
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60audioencodercontrol.h"
+#include "s60audiocapturesession.h"
+
+#include "qaudioformat.h"
+
+#include <QtCore/qdebug.h>
+
+S60AudioEncoderControl::S60AudioEncoderControl(QObject *session, QObject *parent)
+ :QAudioEncoderControl(parent), m_quality(QtMultimediaKit::NormalQuality)
+{
+ DP0("S60AudioEncoderControl::S60AudioEncoderControl +++");
+
+ m_session = qobject_cast<S60AudioCaptureSession*>(session);
+ QAudioFormat fmt = m_session->format();
+ // medium, 22050Hz mono S16
+ fmt.setSampleType(QAudioFormat::SignedInt);
+ if (fmt.codec().compare("PCM", Qt::CaseInsensitive) == 0) {
+ fmt.setSampleSize(16);
+ fmt.setFrequency(22050);
+ }
+ fmt.setChannels(1);
+ m_session->setFormat(fmt);
+ m_settings.setChannelCount(fmt.channels());
+ m_settings.setCodec(fmt.codec());
+ m_settings.setSampleRate(fmt.sampleRate());
+
+ DP0("S60AudioEncoderControl::S60AudioEncoderControl ---");
+}
+
+S60AudioEncoderControl::~S60AudioEncoderControl()
+{
+ DP0("S60AudioEncoderControl::~S60AudioEncoderControl +++");
+
+ DP0("S60AudioEncoderControl::~S60AudioEncoderControl ---");
+}
+
+QStringList S60AudioEncoderControl::supportedAudioCodecs() const
+{
+ DP0("S60AudioEncoderControl::supportedAudioCodecs");
+
+ return m_session->supportedAudioCodecs();
+}
+
+QString S60AudioEncoderControl::codecDescription(const QString &codecName) const
+{
+ DP0("S60AudioEncoderControl::codecDescription");
+
+ return m_session->codecDescription(codecName);
+}
+
+QtMultimediaKit::EncodingQuality S60AudioEncoderControl::quality() const
+{
+ DP0("S60AudioEncoderControl::quality");
+
+ return m_quality;
+}
+
+void S60AudioEncoderControl::setQuality(QtMultimediaKit::EncodingQuality value, QAudioFormat &fmt)
+{
+ DP0("S60AudioEncoderControl::setQuality +++");
+
+ switch (value) {
+ case QtMultimediaKit::VeryLowQuality:
+ case QtMultimediaKit::LowQuality:
+ // low, 8000Hz mono U8
+ fmt.setSampleType(QAudioFormat::UnSignedInt);
+ fmt.setSampleSize(8);
+ fmt.setFrequency(8000);
+ fmt.setChannels(1);
+ break;
+ case QtMultimediaKit::NormalQuality:
+ // medium, 22050Hz mono S16
+ fmt.setSampleType(QAudioFormat::SignedInt);
+ fmt.setSampleSize(16);
+ fmt.setFrequency(22050);
+ fmt.setChannels(1);
+ break;
+ case QtMultimediaKit::HighQuality:
+ case QtMultimediaKit::VeryHighQuality:
+ // high, 44100Hz mono S16
+ fmt.setSampleType(QAudioFormat::SignedInt);
+ fmt.setSampleSize(16);
+ fmt.setFrequency(44100);
+ fmt.setChannels(2);
+ break;
+ default:
+ break;
+ }
+
+ DP0("S60AudioEncoderControl::setQuality ---");
+}
+
+QStringList S60AudioEncoderControl::supportedEncodingOptions(const QString &codec) const
+{
+ DP0("S60AudioEncoderControl::supportedEncodingOptions");
+
+ Q_UNUSED(codec)
+ QStringList list;
+ if (codec == "PCM")
+ list << "quality" << "channels" << "samplerate";
+ return list;
+}
+
+QVariant S60AudioEncoderControl::encodingOption(const QString &codec, const QString &name) const
+{
+ DP0("S60AudioEncoderControl::encodingOption");
+
+ if (codec == "PCM") {
+ QAudioFormat fmt = m_session->format();
+
+ if(qstrcmp(name.toLocal8Bit().constData(), "quality") == 0) {
+ return QVariant(quality());
+ }
+ else if(qstrcmp(name.toLocal8Bit().constData(), "channels") == 0) {
+ return QVariant(fmt.channels());
+ }
+ else if(qstrcmp(name.toLocal8Bit().constData(), "samplerate") == 0) {
+ return QVariant(fmt.frequency());
+ }
+ }
+ return QVariant();
+}
+
+void S60AudioEncoderControl::setEncodingOption(
+ const QString &codec, const QString &name, const QVariant &value)
+{
+ DP0("S60AudioEncoderControl::setEncodingOption +++");
+
+ if (codec == "PCM") {
+ QAudioFormat fmt = m_session->format();
+
+ if(qstrcmp(name.toLocal8Bit().constData(), "quality") == 0) {
+ setQuality((QtMultimediaKit::EncodingQuality)value.toInt(), fmt);
+ } else if(qstrcmp(name.toLocal8Bit().constData(), "channels") == 0) {
+ fmt.setChannels(value.toInt());
+ } else if(qstrcmp(name.toLocal8Bit().constData(), "samplerate") == 0) {
+ fmt.setFrequency(value.toInt());
+ }
+ m_session->setFormat(fmt);
+ }
+
+ DP0("S60AudioEncoderControl::setEncodingOption ---");
+}
+
+QList<int> S60AudioEncoderControl::supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const
+{
+ DP0("S60AudioEncoderControl::supportedSampleRates");
+
+ if (continuous)
+ *continuous = false;
+
+ return m_session->supportedAudioSampleRates(settings);
+}
+
+QAudioEncoderSettings S60AudioEncoderControl::audioSettings() const
+{
+ DP0("S60AudioEncoderControl::audioSettings");
+
+ return m_settings;
+}
+
+void S60AudioEncoderControl::setAudioSettings(const QAudioEncoderSettings &settings)
+{
+ DP0("S60AudioEncoderControl::setAudioSettings +++");
+
+ QAudioFormat fmt = m_session->format();
+ if (settings.encodingMode() == QtMultimediaKit::ConstantQualityEncoding) {
+ fmt.setCodec(settings.codec());
+ setQuality(settings.quality(), fmt);
+ if (settings.sampleRate() > 0) {
+ fmt.setFrequency(settings.sampleRate());
+ }
+ if (settings.channelCount() > 0)
+ fmt.setChannels(settings.channelCount());
+ }else {
+ if (settings.sampleRate() == 8000) {
+ fmt.setSampleType(QAudioFormat::UnSignedInt);
+ fmt.setSampleSize(8);
+ } else {
+ fmt.setSampleType(QAudioFormat::SignedInt);
+ fmt.setSampleSize(16);
+ }
+ fmt.setCodec(settings.codec());
+ fmt.setFrequency(settings.sampleRate());
+ fmt.setChannels(settings.channelCount());
+ }
+ m_session->setFormat(fmt);
+ m_session->setEncoderSettings(settings);
+ m_settings = settings;
+
+ DP0("S60AudioEncoderControl::setAudioSettings ---");
+}
diff --git a/src/plugins/symbian/mmf/audiosource/s60audioencodercontrol.h b/src/plugins/symbian/mmf/audiosource/s60audioencodercontrol.h
new file mode 100644
index 000000000..236d7d522
--- /dev/null
+++ b/src/plugins/symbian/mmf/audiosource/s60audioencodercontrol.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AUDIOENCODERCONTROL_H
+#define AUDIOENCODERCONTROL_H
+
+#include <qaudioencodercontrol.h>
+#include <QtCore/qstringlist.h>
+#include "qaudioformat.h"
+
+QT_USE_NAMESPACE
+
+class S60AudioCaptureSession;
+
+class S60AudioEncoderControl : public QAudioEncoderControl
+{
+ Q_OBJECT
+public:
+ S60AudioEncoderControl(QObject *session, QObject *parent = 0);
+ virtual ~S60AudioEncoderControl();
+
+ QStringList supportedAudioCodecs() const;
+ QString codecDescription(const QString &codecName) const;
+
+ QList<int> supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous = 0) const;
+
+ QAudioEncoderSettings audioSettings() const;
+ void setAudioSettings(const QAudioEncoderSettings&);
+
+ QStringList supportedEncodingOptions(const QString &codec) const;
+ QVariant encodingOption(const QString &codec, const QString &name) const;
+ void setEncodingOption(const QString &codec, const QString &name, const QVariant &value);
+
+private:
+ QtMultimediaKit::EncodingQuality quality() const;
+ void setQuality(QtMultimediaKit::EncodingQuality, QAudioFormat &format);
+
+private:
+ S60AudioCaptureSession* m_session;
+ QAudioEncoderSettings m_settings;
+ QtMultimediaKit::EncodingQuality m_quality;
+};
+
+#endif
diff --git a/src/plugins/symbian/mmf/audiosource/s60audioendpointselector.cpp b/src/plugins/symbian/mmf/audiosource/s60audioendpointselector.cpp
new file mode 100644
index 000000000..a2f909316
--- /dev/null
+++ b/src/plugins/symbian/mmf/audiosource/s60audioendpointselector.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60audiocapturesession.h"
+#include "s60audioendpointselector.h"
+
+#include <qaudiodeviceinfo.h>
+
+S60AudioEndpointSelector::S60AudioEndpointSelector(QObject *session, QObject *parent)
+ :QAudioEndpointSelector(parent)
+{
+ DP0("S60AudioEndpointSelector::S60AudioEndpointSelector +++");
+ m_session = qobject_cast<S60AudioCaptureSession*>(session);
+
+ connect(m_session, SIGNAL(activeEndpointChanged(const QString &)), this, SIGNAL(activeEndpointChanged(const QString &)));
+
+ DP0("S60AudioEndpointSelector::S60AudioEndpointSelector ---");
+}
+
+S60AudioEndpointSelector::~S60AudioEndpointSelector()
+{
+ DP0("S60AudioEndpointSelector::~S60AudioEndpointSelector +++");
+
+ DP0("S60AudioEndpointSelector::~S60AudioEndpointSelector ---");
+}
+
+QList<QString> S60AudioEndpointSelector::availableEndpoints() const
+{
+ DP0("S60AudioEndpointSelector::availableEndpoints");
+
+ return m_session->availableEndpoints();
+}
+
+QString S60AudioEndpointSelector::endpointDescription(const QString& name) const
+{
+ DP0("S60AudioEndpointSelector::endpointDescription");
+
+ return m_session->endpointDescription(name);
+}
+
+QString S60AudioEndpointSelector::defaultEndpoint() const
+{
+ DP0("S60AudioEndpointSelector::defaultEndpoint");
+
+ return m_session->defaultEndpoint();
+}
+
+QString S60AudioEndpointSelector::activeEndpoint() const
+{
+ DP0("S60AudioEndpointSelector::activeEndpoint");
+
+ return m_session->activeEndpoint();
+}
+
+void S60AudioEndpointSelector::setActiveEndpoint(const QString& name)
+{
+ DP0("S60AudioEndpointSelector::setActiveEndpoint +++");
+ m_session->setActiveEndpoint(name);
+ DP0("S60AudioEndpointSelector::setActiveEndpoint ---");
+}
diff --git a/src/plugins/symbian/mmf/audiosource/s60audioendpointselector.h b/src/plugins/symbian/mmf/audiosource/s60audioendpointselector.h
new file mode 100644
index 000000000..d89ce8765
--- /dev/null
+++ b/src/plugins/symbian/mmf/audiosource/s60audioendpointselector.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60AUDIOENDPOINTSELECTOR_H
+#define S60AUDIOENDPOINTSELECTOR_H
+
+#include <QStringList>
+
+#include <qaudioendpointselector.h>
+
+QT_USE_NAMESPACE
+
+class S60AudioCaptureSession;
+
+class S60AudioEndpointSelector : public QAudioEndpointSelector
+{
+
+Q_OBJECT
+
+public:
+ S60AudioEndpointSelector(QObject *session, QObject *parent = 0);
+ ~S60AudioEndpointSelector();
+
+ QList<QString> availableEndpoints() const;
+ QString endpointDescription(const QString& name) const;
+ QString defaultEndpoint() const;
+ QString activeEndpoint() const;
+
+
+public Q_SLOTS:
+ void setActiveEndpoint(const QString& name);
+
+private:
+
+ S60AudioCaptureSession* m_session;
+};
+
+#endif // S60AUDIOENDPOINTSELECTOR_H
diff --git a/src/plugins/symbian/mmf/audiosource/s60audiomediarecordercontrol.cpp b/src/plugins/symbian/mmf/audiosource/s60audiomediarecordercontrol.cpp
new file mode 100644
index 000000000..5d80033b3
--- /dev/null
+++ b/src/plugins/symbian/mmf/audiosource/s60audiomediarecordercontrol.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60audiomediarecordercontrol.h"
+#include "s60audiocapturesession.h"
+
+#include <QtCore/qdebug.h>
+
+S60AudioMediaRecorderControl::S60AudioMediaRecorderControl(QObject *session, QObject *parent)
+ :QMediaRecorderControl(parent), m_state(QMediaRecorder::StoppedState)
+{
+ DP0("S60AudioMediaRecorderControl::S60AudioMediaRecorderControl +++");
+
+ m_session = qobject_cast<S60AudioCaptureSession*>(session);
+ connect(m_session, SIGNAL(positionChanged(qint64)), this, SIGNAL(durationChanged(qint64)));
+ connect(m_session, SIGNAL(stateChanged(S60AudioCaptureSession::TAudioCaptureState)), this, SLOT(updateState(S60AudioCaptureSession::TAudioCaptureState)));
+ connect(m_session,SIGNAL(error(int,const QString &)),this,SIGNAL(error(int,const QString &)));
+
+ DP0("S60AudioMediaRecorderControl::S60AudioMediaRecorderControl ---");
+}
+
+S60AudioMediaRecorderControl::~S60AudioMediaRecorderControl()
+{
+ DP0("S60AudioMediaRecorderControl::~S60AudioMediaRecorderControl +++");
+
+ DP0("S60AudioMediaRecorderControl::~S60AudioMediaRecorderControl - - ");
+}
+
+QUrl S60AudioMediaRecorderControl::outputLocation() const
+{
+ DP0("S60AudioMediaRecorderControl::outputLocation");
+
+ return m_session->outputLocation();
+}
+
+bool S60AudioMediaRecorderControl::setOutputLocation(const QUrl& sink)
+{
+ DP0("S60AudioMediaRecorderControl::setOutputLocation");
+
+ return m_session->setOutputLocation(sink);
+}
+
+QMediaRecorder::State S60AudioMediaRecorderControl::convertState(S60AudioCaptureSession::TAudioCaptureState aState) const
+{
+ DP0("S60AudioMediaRecorderControl::convertState +++");
+
+ QMediaRecorder::State state = QMediaRecorder::StoppedState;;
+ switch (aState) {
+ case S60AudioCaptureSession::ERecording:
+ state = QMediaRecorder::RecordingState;
+ break;
+ case S60AudioCaptureSession::EPaused:
+ state = QMediaRecorder::PausedState;
+ break;
+ case S60AudioCaptureSession::ERecordComplete:
+ case S60AudioCaptureSession::ENotInitialized:
+ case S60AudioCaptureSession::EOpenCompelete:
+ case S60AudioCaptureSession::EInitialized:
+ state = QMediaRecorder::StoppedState;
+ break;
+ }
+
+ DP1("S60AudioMediaRecorderControl::convertState:", state);
+
+ DP0("S60AudioMediaRecorderControl::convertState ---");
+
+ return state;
+}
+
+void S60AudioMediaRecorderControl::updateState(S60AudioCaptureSession::TAudioCaptureState aState)
+{
+ DP0("S60AudioMediaRecorderControl::updateState +++");
+
+ QMediaRecorder::State newState = convertState(aState);
+ if (m_state != newState) {
+ m_state = newState;
+ emit stateChanged(m_state);
+ }
+
+ DP0("S60AudioMediaRecorderControl::updateState ---");
+}
+
+QMediaRecorder::State S60AudioMediaRecorderControl::state() const
+{
+ DP0("S60AudioMediaRecorderControl::state");
+
+ return m_state;
+}
+
+qint64 S60AudioMediaRecorderControl::duration() const
+{
+ // DP0("S60AudioMediaRecorderControl::duration +++");
+
+ return m_session->position();
+}
+
+void S60AudioMediaRecorderControl::record()
+{
+ DP0("S60AudioMediaRecorderControl::record +++");
+
+ m_session->record();
+
+ DP0("S60AudioMediaRecorderControl::record ---");
+}
+
+void S60AudioMediaRecorderControl::pause()
+{
+ DP0("S60AudioMediaRecorderControl::pause +++");
+
+ m_session->pause();
+
+ DP0("S60AudioMediaRecorderControl::pause ---");
+}
+
+void S60AudioMediaRecorderControl::stop()
+{
+ DP0("S60AudioMediaRecorderControl::stop +++");
+
+ m_session->stop();
+
+ DP0("S60AudioMediaRecorderControl::stop ---");
+}
+
+bool S60AudioMediaRecorderControl::isMuted() const
+{
+ DP0("S60AudioMediaRecorderControl::isMuted");
+
+ return m_session->muted();
+}
+
+void S60AudioMediaRecorderControl::setMuted(bool muted)
+{
+ DP0("S60AudioMediaRecorderControl::setMuted +++");
+
+ DP1("S60AudioMediaRecorderControl::setMuted:", muted);
+
+ m_session->mute(muted);
+
+ DP0("S60AudioMediaRecorderControl::setMuted +++");
+}
diff --git a/src/plugins/symbian/mmf/audiosource/s60audiomediarecordercontrol.h b/src/plugins/symbian/mmf/audiosource/s60audiomediarecordercontrol.h
new file mode 100644
index 000000000..78e8f4870
--- /dev/null
+++ b/src/plugins/symbian/mmf/audiosource/s60audiomediarecordercontrol.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60AUDIOMEDIARECORDERCONTROL_H
+#define S60AUDIOMEDIARECORDERCONTROL_H
+
+#include <QtCore/qobject.h>
+#include <QUrl>
+
+#include "qmediarecorder.h"
+#include "qmediarecordercontrol.h"
+
+#include "s60audiocapturesession.h"
+
+QT_USE_NAMESPACE
+
+//class S60AudioCaptureSession;
+
+class S60AudioMediaRecorderControl : public QMediaRecorderControl
+{
+ Q_OBJECT
+public:
+ S60AudioMediaRecorderControl(QObject *session,QObject *parent = 0);
+ ~S60AudioMediaRecorderControl();
+
+ QUrl outputLocation() const;
+ bool setOutputLocation(const QUrl &sink);
+
+ QMediaRecorder::State state() const;
+
+ qint64 duration() const;
+
+ bool isMuted() const;
+
+ void applySettings() {}
+
+private:
+ QMediaRecorder::State convertState(S60AudioCaptureSession::TAudioCaptureState aState) const;
+
+public slots:
+ void record();
+ void pause();
+ void stop();
+ void setMuted(bool);
+
+private slots:
+ void updateState(S60AudioCaptureSession::TAudioCaptureState aState);
+
+private:
+ S60AudioCaptureSession* m_session;
+ QMediaRecorder::State m_state;
+};
+
+#endif
diff --git a/src/plugins/symbian/mmf/inc/DebugMacros.h b/src/plugins/symbian/mmf/inc/DebugMacros.h
new file mode 100644
index 000000000..449bef088
--- /dev/null
+++ b/src/plugins/symbian/mmf/inc/DebugMacros.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qdebug.h>
+
+#ifndef __DEBUGMACROS_H__
+#define __DEBUGMACROS_H__
+
+// MACROS
+#ifdef _DEBUG
+#define DP0(string) qDebug()<<string
+#define DP1(string,arg1) qDebug()<<string<<arg1
+#define DP2(string,arg1,arg2) qDebug()<<string<<arg1<<arg2
+#define DP3(string,arg1,arg2,arg3) qDebug()<<string<<arg1<<arg2<<arg3
+#define DP4(string,arg1,arg2,arg3,arg4) qDebug()<<string<<arg1<<arg2<<arg3<<arg4
+#define DP5(string,arg1,arg2,arg3,arg4,arg5) qDebug()<<string<<arg1<<arg2<<arg3<<arg4<<arg5
+#define DP6(string,arg1,arg2,arg3,arg4,arg5,arg6) qDebug()<<string<<arg1<<arg2<<arg3<<arg4<<arg5<<arg6
+#else
+#define DP0(string)
+#define DP1(string,arg1)
+#define DP2(string,arg1,arg2)
+#define DP3(string,arg1,arg2,arg3)
+#define DP4(string,arg1,arg2,arg3,arg4)
+#define DP5(string,arg1,arg2,arg3,arg4,arg5)
+#define DP6(string,arg1,arg2,arg3,arg4,arg5,arg6)
+#endif
+
+#endif //__DEBUGMACROS_H__
diff --git a/src/plugins/symbian/mmf/mediaplayer/mediaplayer_s60.pri b/src/plugins/symbian/mmf/mediaplayer/mediaplayer_s60.pri
new file mode 100644
index 000000000..6ec64e2b6
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/mediaplayer_s60.pri
@@ -0,0 +1,92 @@
+INCLUDEPATH += $$PWD
+
+include (../../videooutput/videooutput.pri)
+
+LIBS *= -lmediaclientvideo \
+ -lmediaclientaudio \
+ -lws32 \
+ -lfbscli \
+ -lcone \
+ -lmmfcontrollerframework \
+ -lefsrv \
+ -lbitgdi \
+ -lapgrfx \
+ -lapmime \
+ -lcommdb \
+ -lbafl
+
+# If support to DRM is wanted then comment out the following line
+#CONFIG += drm_supported
+
+# We are building Symbian backend with media player support
+DEFINES += HAS_MEDIA_PLAYER
+# We are building media player with QVideoRendererControl support
+#DEFINES += HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER
+
+drm_supported {
+ LIBS += -ldrmaudioplayutility
+ DEFINES += S60_DRM_SUPPORTED
+}
+
+HEADERS += \
+ $$PWD/s60mediaplayercontrol.h \
+ $$PWD/s60mediaplayerservice.h \
+ $$PWD/s60mediaplayersession.h \
+ $$PWD/s60mediametadataprovider.h \
+ $$PWD/s60videoplayersession.h \
+ $$PWD/s60videosurface.h \
+ $$PWD/s60mediarecognizer.h \
+ $$PWD/s60audioplayersession.h \
+ $$PWD/ms60mediaplayerresolver.h \
+ $$PWD/s60mediaplayeraudioendpointselector.h \
+ $$PWD/s60mediastreamcontrol.h \
+ $$PWD/s60medianetworkaccesscontrol.h
+
+SOURCES += \
+ $$PWD/s60mediaplayercontrol.cpp \
+ $$PWD/s60mediaplayerservice.cpp \
+ $$PWD/s60mediaplayersession.cpp \
+ $$PWD/s60mediametadataprovider.cpp \
+ $$PWD/s60videoplayersession.cpp \
+ $$PWD/s60videosurface.cpp \
+ $$PWD/s60mediarecognizer.cpp \
+ $$PWD/s60audioplayersession.cpp \
+ $$PWD/s60mediaplayeraudioendpointselector.cpp \
+ $$PWD/s60mediastreamcontrol.cpp \
+ $$PWD/s60medianetworkaccesscontrol.cpp
+
+contains(DEFINES, HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER) {
+ HEADERS += $$PWD/s60videorenderer.h
+ SOURCES += $$PWD/s60videorenderer.cpp
+}
+
+contains(S60_VERSION, 3.1) {
+ #3.1 doesn't provide audio routing in videoplayer
+ contains(audiorouting_s60_enabled,yes) {
+ MMP_RULES += "$${LITERAL_HASH}ifndef WINSCW" \
+ "MACRO HAS_AUDIOROUTING" \
+ "LIBRARY audiooutputrouting.lib" \
+ "$${LITERAL_HASH}endif"
+ message("Note: AudioOutput Routing API not supported for 3.1 winscw target and in videoplayer")
+ }
+
+} else {
+ contains(audiorouting_s60_enabled,yes) {
+ #We use audiooutputrouting.lib for directing audio output to speaker/earspeaker
+ DEFINES += HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ DEFINES += HAS_AUDIOROUTING
+ message("Audiorouting_s60 enabled for post 3.1 sdk")
+ LIBS += -laudiooutputrouting
+ }
+
+}
+
+contains(S60_VERSION, 3.1) {
+ DEFINES += PLAY_RATE_NOT_SUPPORTED
+ message("S60 version 3.1 does not support setplaybackrate")
+}
+contains(S60_VERSION, 3.2) {
+ DEFINES += PLAY_RATE_NOT_SUPPORTED
+ message("S60 version 3.2 does not support setplaybackrate")
+}
+
diff --git a/src/plugins/symbian/mmf/mediaplayer/ms60mediaplayerresolver.h b/src/plugins/symbian/mmf/mediaplayer/ms60mediaplayerresolver.h
new file mode 100644
index 000000000..d836dae3e
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/ms60mediaplayerresolver.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef MS60MEDIAPLAYERRESOLVER_H
+#define MS60MEDIAPLAYERRESOLVER_H
+
+class S60MediaPlayerSession;
+
+class MS60MediaPlayerResolver
+{
+ public:
+ virtual S60MediaPlayerSession* PlayerSession() = 0;
+ virtual S60MediaPlayerSession* VideoPlayerSession() = 0;
+ virtual S60MediaPlayerSession* AudioPlayerSession() = 0;
+};
+
+#endif
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60audioplayersession.cpp b/src/plugins/symbian/mmf/mediaplayer/s60audioplayersession.cpp
new file mode 100644
index 000000000..3a5386ce1
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60audioplayersession.cpp
@@ -0,0 +1,577 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60audioplayersession.h"
+#include <QtCore/qdebug.h>
+#include <QtCore/qvariant.h>
+
+/*!
+ Constructs the CMdaAudioPlayerUtility object with given \a parent QObject.
+
+ And Registers for Audio Loading Notifications.
+
+*/
+
+S60AudioPlayerSession::S60AudioPlayerSession(QObject *parent)
+ : S60MediaPlayerSession(parent)
+ , m_player(0)
+ , m_audioEndpoint("Default")
+{
+ DP0("S60AudioPlayerSession::S60AudioPlayerSession +++");
+
+#ifdef HAS_AUDIOROUTING
+ m_audioOutput = 0;
+#endif //HAS_AUDIOROUTING
+ QT_TRAP_THROWING(m_player = CAudioPlayer::NewL(*this, 0, EMdaPriorityPreferenceNone));
+ m_player->RegisterForAudioLoadingNotification(*this);
+
+ DP0("S60AudioPlayerSession::S60AudioPlayerSession ---");
+}
+
+
+/*!
+ Destroys the CMdaAudioPlayerUtility object.
+
+ And Unregister the observer.
+
+*/
+
+S60AudioPlayerSession::~S60AudioPlayerSession()
+{
+ DP0("S60AudioPlayerSession::~S60AudioPlayerSession +++");
+#ifdef HAS_AUDIOROUTING
+ if (m_audioOutput)
+ m_audioOutput->UnregisterObserver(*this);
+ delete m_audioOutput;
+#endif
+ m_player->Close();
+ delete m_player;
+
+ DP0("S60AudioPlayerSession::~S60AudioPlayerSession ---");
+}
+
+/*!
+
+ Opens the a file from \a path.
+
+*/
+
+void S60AudioPlayerSession::doLoadL(const TDesC &path)
+{
+ DP0("S60AudioPlayerSession::doLoadL +++");
+
+#ifdef HAS_AUDIOROUTING
+ // m_audioOutput needs to be reinitialized after MapcInitComplete
+ if (m_audioOutput)
+ m_audioOutput->UnregisterObserver(*this);
+ delete m_audioOutput;
+ m_audioOutput = NULL;
+#endif //HAS_AUDIOROUTING
+ m_player->OpenFileL(path);
+
+ DP0("S60AudioPlayerSession::doLoadL ---");
+}
+
+/*!
+
+ Returns the duration of the audio sample in microseconds.
+
+*/
+
+qint64 S60AudioPlayerSession::doGetDurationL() const
+{
+ // DP0("S60AudioPlayerSession::doGetDurationL");
+
+ return m_player->Duration().Int64() / qint64(1000);
+}
+
+/*!
+ * Returns the current playback position in microseconds from the start of the clip.
+
+*/
+
+qint64 S60AudioPlayerSession::doGetPositionL() const
+{
+ // DP0("S60AudioPlayerSession::doGetPositionL");
+
+ TTimeIntervalMicroSeconds ms = 0;
+ m_player->GetPosition(ms);
+ return ms.Int64() / qint64(1000);
+}
+
+/*!
+ Returns TRUE if Video available or else FALSE
+ */
+
+bool S60AudioPlayerSession::isVideoAvailable()
+{
+ DP0("S60AudioPlayerSession::isVideoAvailable");
+
+ return false;
+}
+
+/*!
+ Returns TRUE if Audio available or else FALSE
+ */
+bool S60AudioPlayerSession::isAudioAvailable()
+{
+ DP0("S60AudioPlayerSession::isAudioAvailable");
+
+ return true; // this is a bit happy scenario, but we do emit error that we can't play
+}
+
+/*!
+ Starts loading Media and sets media status to Buffering.
+
+ */
+
+void S60AudioPlayerSession::MaloLoadingStarted()
+{
+ DP0("S60AudioPlayerSession::MaloLoadingStarted +++");
+
+ buffering();
+
+ DP0("S60AudioPlayerSession::MaloLoadingStarted ---");
+}
+
+
+/*!
+ Indicates loading Media is completed.
+
+ And sets media status to Buffered.
+
+ */
+
+void S60AudioPlayerSession::MaloLoadingComplete()
+{
+ DP0("S60AudioPlayerSession::MaloLoadingComplete +++");
+
+ buffered();
+
+ DP0("S60AudioPlayerSession::MaloLoadingComplete ---");
+}
+
+/*!
+ Start or resume playing the current source.
+*/
+
+void S60AudioPlayerSession::doPlay()
+{
+ DP0("S60AudioPlayerSession::doPlay +++");
+
+ // For some reason loading progress callback are not called on emulator
+ // Same is the case with hardware. Will be fixed as part of QTMOBILITY-782.
+
+ //#ifdef __WINSCW__
+ buffering();
+ //#endif
+ m_player->Play();
+ //#ifdef __WINSCW__
+ buffered();
+ //#endif
+
+ DP0("S60AudioPlayerSession::doPlay ---");
+}
+
+
+/*!
+ Pause playing the current source.
+*/
+
+
+void S60AudioPlayerSession::doPauseL()
+{
+ DP0("S60AudioPlayerSession::doPauseL +++");
+
+ m_player->Pause();
+
+ DP0("S60AudioPlayerSession::doPauseL ---");
+}
+
+
+/*!
+
+ Stop playing, and reset the play position to the beginning.
+*/
+
+void S60AudioPlayerSession::doStop()
+{
+ DP0("S60AudioPlayerSession::doStop +++");
+
+ m_player->Stop();
+
+ DP0("S60AudioPlayerSession::doStop ---");
+}
+
+/*!
+ Closes the current audio clip (allowing another clip to be opened)
+*/
+
+void S60AudioPlayerSession::doClose()
+{
+ DP0("S60AudioPlayerSession::doClose +++");
+
+#ifdef HAS_AUDIOROUTING
+ if (m_audioOutput) {
+ m_audioOutput->UnregisterObserver(*this);
+ delete m_audioOutput;
+ m_audioOutput = NULL;
+ }
+#endif
+ m_player->Close();
+
+ DP0("S60AudioPlayerSession::doClose ---");
+}
+
+/*!
+
+ Changes the current playback volume to specified \a value.
+*/
+
+void S60AudioPlayerSession::doSetVolumeL(int volume)
+{
+ DP0("S60AudioPlayerSession::doSetVolumeL +++");
+
+ DP1("S60AudioPlayerSession::doSetVolumeL, Volume:", volume);
+
+ m_player->SetVolume(volume * m_player->MaxVolume() / 100);
+
+ DP0("S60AudioPlayerSession::doSetVolumeL ---");
+}
+
+/*!
+ Sets the current playback position to \a microSeconds from the start of the clip.
+*/
+
+void S60AudioPlayerSession::doSetPositionL(qint64 microSeconds)
+{
+ DP0("S60AudioPlayerSession::doSetPositionL +++");
+
+ DP1("S60AudioPlayerSession::doSetPositionL, Microseconds:", microSeconds);
+
+ m_player->SetPosition(TTimeIntervalMicroSeconds(microSeconds));
+
+ DP0("S60AudioPlayerSession::doSetPositionL ---");
+}
+
+/*!
+
+ Updates meta data entries in the current audio clip.
+*/
+
+void S60AudioPlayerSession::updateMetaDataEntriesL()
+{
+ DP0("S60AudioPlayerSession::updateMetaDataEntriesL +++");
+
+ metaDataEntries().clear();
+ int numberOfMetaDataEntries = 0;
+
+ //User::LeaveIfError(m_player->GetNumberOfMetaDataEntries(numberOfMetaDataEntries));
+ m_player->GetNumberOfMetaDataEntries(numberOfMetaDataEntries);
+
+ for (int i = 0; i < numberOfMetaDataEntries; i++) {
+ CMMFMetaDataEntry *entry = NULL;
+ entry = m_player->GetMetaDataEntryL(i);
+ metaDataEntries().insert(QString::fromUtf16(entry->Name().Ptr(), entry->Name().Length()), QString::fromUtf16(entry->Value().Ptr(), entry->Value().Length()));
+ delete entry;
+ }
+ emit metaDataChanged();
+
+ DP0("S60AudioPlayerSession::updateMetaDataEntriesL ---");
+}
+
+/*!
+ Sets the playbackRate with \a rate.
+*/
+
+void S60AudioPlayerSession::setPlaybackRate(qreal rate)
+{
+ DP0("S60AudioPlayerSession::setPlaybackRate +++");
+ DP1("S60AudioPlayerSession::setPlaybackRate, Rate:", rate);
+ /*Since AudioPlayerUtility doesn't support set playback rate hence
+ * setPlaybackRate emits playbackRateChanged signal for 1.0x ie normal playback.
+ * For all other playBackRates it sets and emits error signal.
+ */
+ if (rate == 1.0) {
+ emit playbackRateChanged(rate);
+ return;
+ } else {
+ int err = KErrNotSupported;
+ setAndEmitError(err);
+ }
+ DP0("S60AudioPlayerSession::setPlaybackRate ---");
+}
+
+/*!
+
+ Returns the percentage of the audio clip loaded.
+*/
+
+int S60AudioPlayerSession::doGetBufferStatusL() const
+{
+ DP0("S60AudioPlayerSession::doGetBufferStatusL +++");
+
+ int progress = 0;
+ m_player->GetAudioLoadingProgressL(progress);
+
+ DP0("S60AudioPlayerSession::doGetBufferStatusL ---");
+
+ return progress;
+}
+
+/*!
+
+ Defines required client behaviour when an attempt to open and initialise an audio sample has completed,
+ successfully or not.
+
+ \a aError if KErrNone the sample is ready to play or else system wide error.
+
+ \a aDuration The duration of the audio sample.
+*/
+
+#ifdef S60_DRM_SUPPORTED
+void S60AudioPlayerSession::MdapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration)
+#else
+void S60AudioPlayerSession::MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration)
+#endif
+{
+ DP0("S60AudioPlayerSession::MdapcInitComplete +++");
+
+ DP1("S60AudioPlayerSession::MdapcInitComplete - aError", aError);
+
+ Q_UNUSED(aDuration);
+ setError(aError);
+ if (KErrNone != aError)
+ return;
+#ifdef HAS_AUDIOROUTING
+ TRAPD(err,
+ m_audioOutput = CAudioOutput::NewL(*m_player);
+ m_audioOutput->RegisterObserverL(*this);
+ );
+ setActiveEndpoint(m_audioEndpoint);
+ setError(err);
+#endif //HAS_AUDIOROUTING
+ if (KErrNone == aError)
+ loaded();
+
+ DP0("S60AudioPlayerSession::MdapcInitComplete ---");
+}
+
+/*!
+ Defines required client behaviour when an attempt to playback an audio sample has completed,
+ successfully or not.
+
+ \a aError if KErrNone the playback completed or else system wide error.
+*/
+
+
+#ifdef S60_DRM_SUPPORTED
+void S60AudioPlayerSession::MdapcPlayComplete(TInt aError)
+#else
+void S60AudioPlayerSession::MapcPlayComplete(TInt aError)
+#endif
+{
+ DP0("S60AudioPlayerSession::MdapcPlayComplete +++");
+
+ DP1("S60AudioPlayerSession::MdapcPlayComplete", aError);
+
+ if (KErrNone == aError)
+ endOfMedia();
+ else
+ setError(aError);
+
+ DP0("S60AudioPlayerSession::MdapcPlayComplete ---");
+}
+
+/*!
+ Defiens which Audio End point to use.
+
+ \a audioEndpoint audioEndpoint name.
+*/
+
+void S60AudioPlayerSession::doSetAudioEndpoint(const QString& audioEndpoint)
+{
+ DP0("S60AudioPlayerSession::doSetAudioEndpoint +++");
+
+ DP1("S60AudioPlayerSession::doSetAudioEndpoint - ", audioEndpoint);
+
+ m_audioEndpoint = audioEndpoint;
+
+ DP0("S60AudioPlayerSession::doSetAudioEndpoint ---");
+}
+
+/*!
+
+ Returns audioEndpoint name.
+*/
+
+QString S60AudioPlayerSession::activeEndpoint() const
+{
+ DP0("S60AudioPlayerSession::activeEndpoint +++");
+
+ QString outputName = QString("Default");
+#ifdef HAS_AUDIOROUTING
+ if (m_audioOutput) {
+ CAudioOutput::TAudioOutputPreference output = m_audioOutput->AudioOutput();
+ outputName = qStringFromTAudioOutputPreference(output);
+ }
+#endif
+ DP1("S60AudioPlayerSession::activeEndpoint is :", outputName);
+
+ DP0("S60AudioPlayerSession::activeEndpoint ---");
+ return outputName;
+}
+
+/*!
+ * Returns default Audio End point in use.
+*/
+
+QString S60AudioPlayerSession::defaultEndpoint() const
+{
+ DP0("S60AudioPlayerSession::defaultEndpoint +++");
+
+ QString outputName = QString("Default");
+#ifdef HAS_AUDIOROUTING
+ if (m_audioOutput) {
+ CAudioOutput::TAudioOutputPreference output = m_audioOutput->DefaultAudioOutput();
+ outputName = qStringFromTAudioOutputPreference(output);
+ }
+#endif
+ DP1("S60AudioPlayerSession::defaultEndpoint is :", outputName);
+
+ DP0("S60AudioPlayerSession::defaultEndpoint ---");
+ return outputName;
+}
+
+/*!
+ Sets active end \a name as an Audio End point.
+*/
+
+void S60AudioPlayerSession::setActiveEndpoint(const QString& name)
+{
+ DP0("S60AudioPlayerSession::setActiveEndpoint +++");
+
+ DP1("S60AudioPlayerSession::setActiveEndpoint - ", name);
+
+#ifdef HAS_AUDIOROUTING
+ CAudioOutput::TAudioOutputPreference output = CAudioOutput::ENoPreference;
+
+ if (name == QString("Default"))
+ output = CAudioOutput::ENoPreference;
+ else if (name == QString("All"))
+ output = CAudioOutput::EAll;
+ else if (name == QString("None"))
+ output = CAudioOutput::ENoOutput;
+ else if (name == QString("Earphone"))
+ output = CAudioOutput::EPrivate;
+ else if (name == QString("Speaker"))
+ output = CAudioOutput::EPublic;
+
+ if (m_audioOutput) {
+ TRAPD(err, m_audioOutput->SetAudioOutputL(output));
+ setError(err);
+ }
+#endif
+
+ DP0("S60AudioPlayerSession::setActiveEndpoint ---");
+}
+
+/*!
+ The default audio output has been changed.
+
+ \a aAudioOutput Audio Output object.
+
+ \a aNewDefault is CAudioOutput::TAudioOutputPreference.
+*/
+
+
+#ifdef HAS_AUDIOROUTING
+void S60AudioPlayerSession::DefaultAudioOutputChanged(CAudioOutput& aAudioOutput,
+ CAudioOutput::TAudioOutputPreference aNewDefault)
+{
+ DP0("S60AudioPlayerSession::DefaultAudioOutputChanged +++");
+
+ // Emit already implemented in setActiveEndpoint function
+ Q_UNUSED(aAudioOutput)
+ Q_UNUSED(aNewDefault)
+
+ DP0("S60AudioPlayerSession::DefaultAudioOutputChanged ---");
+}
+
+
+/*!
+ Converts CAudioOutput::TAudioOutputPreference enum to QString.
+
+ \a output is CAudioOutput::TAudioOutputPreference enum value.
+
+*/
+
+QString S60AudioPlayerSession::qStringFromTAudioOutputPreference(CAudioOutput::TAudioOutputPreference output) const
+{
+ DP0("S60AudioPlayerSession::qStringFromTAudioOutputPreference");
+
+ if (output == CAudioOutput::ENoPreference)
+ return QString("Default");
+ else if (output == CAudioOutput::EAll)
+ return QString("All");
+ else if (output == CAudioOutput::ENoOutput)
+ return QString("None");
+ else if (output == CAudioOutput::EPrivate)
+ return QString("Earphone");
+ else if (output == CAudioOutput::EPublic)
+ return QString("Speaker");
+ return QString("Default");
+}
+#endif
+
+/*!
+ Return True if its Seekable or else False.
+*/
+
+bool S60AudioPlayerSession::getIsSeekable() const
+{
+ DP0("S60AudioPlayerSession::getIsSeekable");
+
+ return ETrue;
+}
+
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60audioplayersession.h b/src/plugins/symbian/mmf/mediaplayer/s60audioplayersession.h
new file mode 100644
index 000000000..80228ef0a
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60audioplayersession.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60AUDIOPLAYERSESSION_H
+#define S60AUDIOPLAYERSESSION_H
+
+#include <QtCore/qobject.h>
+#include "s60mediaplayersession.h"
+
+#ifdef S60_DRM_SUPPORTED
+#include <drmaudiosampleplayer.h>
+typedef CDrmPlayerUtility CAudioPlayer;
+typedef MDrmAudioPlayerCallback MAudioPlayerObserver;
+#else
+#include <mdaaudiosampleplayer.h>
+typedef CMdaAudioPlayerUtility CAudioPlayer;
+typedef MMdaAudioPlayerCallback MAudioPlayerObserver;
+#endif
+
+#ifdef HAS_AUDIOROUTING
+#include <AudioOutput.h>
+#include <MAudioOutputObserver.h>
+#endif //HAS_AUDIOROUTING
+
+class S60AudioPlayerSession : public S60MediaPlayerSession
+ , public MAudioPlayerObserver
+ , public MAudioLoadingObserver
+#ifdef HAS_AUDIOROUTING
+ , public MAudioOutputObserver
+#endif
+{
+ Q_OBJECT
+public:
+ S60AudioPlayerSession(QObject *parent);
+ ~S60AudioPlayerSession();
+
+ //From S60MediaPlayerSession
+ bool isVideoAvailable();
+ bool isAudioAvailable();
+
+ // From MAudioLoadingObserver
+ void MaloLoadingStarted();
+ void MaloLoadingComplete();
+
+#ifdef HAS_AUDIOROUTING
+ // From MAudioOutputObserver
+ void DefaultAudioOutputChanged( CAudioOutput& aAudioOutput,
+ CAudioOutput::TAudioOutputPreference aNewDefault );
+#endif //HAS_AUDIOROUTING
+
+public:
+ // From S60MediaPlayerAudioEndpointSelector
+ QString activeEndpoint() const;
+ QString defaultEndpoint() const;
+ void setPlaybackRate(qreal rate);
+public Q_SLOTS:
+ void setActiveEndpoint(const QString& name);
+
+protected:
+ //From S60MediaPlayerSession
+ void doLoadL(const TDesC &path);
+ void doLoadUrlL(const TDesC &path){Q_UNUSED(path)/*empty implementation*/}
+ void doPlay();
+ void doStop();
+ void doClose();
+ void doPauseL();
+ void doSetVolumeL(int volume);
+ qint64 doGetPositionL() const;
+ void doSetPositionL(qint64 microSeconds);
+ void updateMetaDataEntriesL();
+ int doGetBufferStatusL() const;
+ qint64 doGetDurationL() const;
+ void doSetAudioEndpoint(const QString& audioEndpoint);
+ bool getIsSeekable() const;
+private:
+#ifdef S60_DRM_SUPPORTED
+ // From MMdaAudioPlayerCallback
+ void MdapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration);
+ void MdapcPlayComplete(TInt aError);
+#else
+ // From MDrmAudioPlayerCallback
+ void MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration);
+ void MapcPlayComplete(TInt aError);
+#endif
+
+#ifdef HAS_AUDIOROUTING
+ QString qStringFromTAudioOutputPreference(CAudioOutput::TAudioOutputPreference output) const;
+#endif //HAS_AUDIOROUTING
+
+private:
+ CAudioPlayer *m_player;
+#ifdef HAS_AUDIOROUTING
+ CAudioOutput *m_audioOutput;
+#endif //HAS_AUDIOROUTING
+ QString m_audioEndpoint;
+};
+
+#endif
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediametadataprovider.cpp b/src/plugins/symbian/mmf/mediaplayer/s60mediametadataprovider.cpp
new file mode 100644
index 000000000..85bfe65a3
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60mediametadataprovider.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60mediametadataprovider.h"
+#include "s60mediaplayercontrol.h"
+#include "s60mediaplayersession.h"
+#include <QtCore/qdebug.h>
+
+/*!
+ * Typecasts the \a control object to S60MediaPlayerControl object.
+*/
+S60MediaMetaDataProvider::S60MediaMetaDataProvider(QObject *control, QObject *parent)
+ : QMetaDataReaderControl(parent)
+ , m_control(NULL)
+{
+ DP0("S60MediaMetaDataProvider::S60MediaMetaDataProvider +++");
+
+ m_control = qobject_cast<S60MediaPlayerControl*>(control);
+
+ DP0("S60MediaMetaDataProvider::S60MediaMetaDataProvider ---");
+}
+
+/*!
+ * Destructor
+*/
+
+S60MediaMetaDataProvider::~S60MediaMetaDataProvider()
+{
+ DP0("S60MediaMetaDataProvider::~S60MediaMetaDataProvider +++");
+ DP0("S60MediaMetaDataProvider::~S60MediaMetaDataProvider ---");
+}
+
+/*!
+ * Returns TRUE if MetaData is Available or else FALSE.
+*/
+
+bool S60MediaMetaDataProvider::isMetaDataAvailable() const
+{
+ DP0("S60MediaMetaDataProvider::isMetaDataAvailable");
+
+ if (m_control->session())
+ return m_control->session()->isMetadataAvailable();
+ return false;
+}
+
+/*!
+ * Always returns FLASE.
+*/
+bool S60MediaMetaDataProvider::isWritable() const
+{
+ DP0("S60MediaMetaDataProvider::isWritable");
+
+ return false;
+}
+
+/*!
+ * Returns when \a key meta data is found in metaData.
+*/
+
+QVariant S60MediaMetaDataProvider::metaData(QtMultimediaKit::MetaData key) const
+{
+ DP0("S60MediaMetaDataProvider::metaData");
+
+ if (m_control->session())
+ return m_control->session()->metaData(key);
+ return QVariant();
+}
+
+/*!
+ * Returns available metaData.
+*/
+
+QList<QtMultimediaKit::MetaData> S60MediaMetaDataProvider::availableMetaData() const
+{
+ DP0("S60MediaMetaDataProvider::availableMetaData");
+
+ if (m_control->session())
+ return m_control->session()->availableMetaData();
+ return QList<QtMultimediaKit::MetaData>();
+}
+
+/*!
+ * Returns when \a key string is found in extended metaData.
+*/
+
+QVariant S60MediaMetaDataProvider::extendedMetaData(const QString &key) const
+{
+ DP0("S60MediaMetaDataProvider::extendedMetaData");
+
+ if (m_control->session())
+ return m_control->session()->metaData(key);
+ return QVariant();
+}
+
+/*!
+ * Returns available Extended MetaData.
+*/
+
+QStringList S60MediaMetaDataProvider::availableExtendedMetaData() const
+{
+ DP0("S60MediaMetaDataProvider::availableExtendedMetaData");
+
+ if (m_control->session())
+ return m_control->session()->availableExtendedMetaData();
+ return QStringList();
+}
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediametadataprovider.h b/src/plugins/symbian/mmf/mediaplayer/s60mediametadataprovider.h
new file mode 100644
index 000000000..eb995080d
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60mediametadataprovider.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60MEDIAMETADATAPROVIDER_H
+#define S60MEDIAMETADATAPROVIDER_H
+
+#include <qmetadatareadercontrol.h>
+#include "s60mediaplayercontrol.h"
+
+QT_USE_NAMESPACE
+
+class S60MediaPlayerControl;
+
+class S60MediaMetaDataProvider : public QMetaDataReaderControl
+{
+ Q_OBJECT
+
+public:
+ S60MediaMetaDataProvider(QObject *control, QObject *parent = 0);
+ ~S60MediaMetaDataProvider();
+
+ bool isMetaDataAvailable() const;
+ bool isWritable() const;
+
+ QVariant metaData(QtMultimediaKit::MetaData key) const;
+ QList<QtMultimediaKit::MetaData> availableMetaData() const;
+ QVariant extendedMetaData(const QString &key) const ;
+ QStringList availableExtendedMetaData() const;
+
+private:
+ S60MediaPlayerControl *m_control;
+};
+
+#endif // S60VIDEOMETADATAPROVIDER_H
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60medianetworkaccesscontrol.cpp b/src/plugins/symbian/mmf/mediaplayer/s60medianetworkaccesscontrol.cpp
new file mode 100644
index 000000000..dad69a691
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60medianetworkaccesscontrol.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "s60medianetworkaccesscontrol.h"
+
+#define KBuffersize 512
+
+S60MediaNetworkAccessControl::S60MediaNetworkAccessControl(QObject *parent)
+ : QMediaNetworkAccessControl(parent)
+ , m_iapId(KUseDefaultIap)
+ , m_currentIndex(0)
+{
+}
+
+void S60MediaNetworkAccessControl::accessPointChanged(int id)
+{
+ if (!m_IapIdList.isEmpty())
+ m_NetworkObject = m_NetworkObjectList.at(m_IapIdList.indexOf(id));
+ emit configurationChanged(m_NetworkObject);
+}
+
+S60MediaNetworkAccessControl::~S60MediaNetworkAccessControl()
+{
+ m_NetworkObjectList.clear();
+ m_IapIdList.clear();
+}
+
+void S60MediaNetworkAccessControl::resetIndex()
+{
+ m_currentIndex = 0;
+}
+
+void S60MediaNetworkAccessControl::setConfigurations(const QList<QNetworkConfiguration> &configurations)
+{
+ if (!configurations.isEmpty()) {
+ m_currentIndex =0;
+ TRAPD(error, retriveAccesspointIDL(configurations));
+ if (error != KErrNone) {
+ m_NetworkObjectList.clear();
+ m_IapIdList.clear();
+ }
+ }
+}
+
+TBool S60MediaNetworkAccessControl::isLastAccessPoint()
+{
+ if (m_currentIndex == m_NetworkObjectList.size())
+ return TRUE;
+ else
+ return FALSE;
+}
+
+int S60MediaNetworkAccessControl::accessPointId()
+{
+ if (m_IapIdList.isEmpty())
+ return m_iapId;
+
+ m_iapId = m_IapIdList.at(m_currentIndex);
+
+ if (isLastAccessPoint())
+ m_currentIndex = 0;
+ else
+ m_currentIndex ++;
+
+ return m_iapId;
+}
+
+QNetworkConfiguration S60MediaNetworkAccessControl::currentConfiguration() const
+{
+ return m_NetworkObject;
+}
+
+void S60MediaNetworkAccessControl::retriveAccesspointIDL(const QList<QNetworkConfiguration> &configurationList)
+{
+ m_NetworkObjectList.clear();
+ m_IapIdList.clear();
+ TBuf<KBuffersize> iapName;
+ TUint32 iapId;
+ TInt err;
+
+ // open the IAP communications database
+ CCommsDatabase* commDB = CCommsDatabase::NewL();
+ CleanupStack::PushL(commDB);
+
+ // Open the IAP table
+ CCommsDbTableView* view = commDB->OpenTableLC(TPtrC(IAP));
+
+ for (int i=0;i<=configurationList.size()- 1;i++) {
+ QString accesspointname = configurationList.at(i).name();
+ TBuf<KBuffersize> accesspointbuffer(accesspointname.utf16());
+ // Point to the first entry
+ if (view->GotoFirstRecord() == KErrNone) {
+ do {
+ view->ReadTextL(TPtrC(COMMDB_NAME), iapName);
+ view->ReadUintL(TPtrC(COMMDB_ID), iapId);
+ if (accesspointbuffer == iapName) {
+ m_NetworkObjectList<<configurationList.at(i);
+ m_IapIdList<<iapId;
+ }
+ // Store name and ID to where you want to
+ } while (err = view->GotoNextRecord(), err == KErrNone);
+ }
+ }
+ CleanupStack::PopAndDestroy(); // view
+ CleanupStack::PopAndDestroy(); // commDB
+}
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60medianetworkaccesscontrol.h b/src/plugins/symbian/mmf/mediaplayer/s60medianetworkaccesscontrol.h
new file mode 100644
index 000000000..aea4dcab5
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60medianetworkaccesscontrol.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60MEDIANETWORKACCESSCONTROL_H_
+#define S60MEDIANETWORKACCESSCONTROL_H_
+
+
+#include <QtCore/qobject.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qstring.h>
+#include <qmetaobject.h>
+#include <QtNetwork/qnetworkconfiguration.h>
+#include <commdbconnpref.h>
+#include <commdb.h>
+#include <mmf/common/mmfcontrollerframeworkbase.h>
+#include <qmedianetworkaccesscontrol.h>
+#include "s60mediaplayercontrol.h"
+
+QT_BEGIN_NAMESPACE
+class QMediaPlayerControl;
+class QMediaNetworkAccessControl;
+class QNetworkConfiguration;
+QT_END_NAMESPACE
+
+class S60MediaNetworkAccessControl : public QMediaNetworkAccessControl
+{
+ Q_OBJECT
+
+public:
+
+ S60MediaNetworkAccessControl(QObject *parent = 0);
+ ~S60MediaNetworkAccessControl();
+
+ virtual void setConfigurations(const QList<QNetworkConfiguration> &configurations);
+ virtual QNetworkConfiguration currentConfiguration() const;
+ int accessPointId();
+ TBool isLastAccessPoint();
+ void resetIndex();
+
+public Q_SLOTS:
+ void accessPointChanged(int);
+
+private:
+ void retriveAccesspointIDL(const QList<QNetworkConfiguration> &);
+ QList<int> m_IapIdList;
+ QList<QNetworkConfiguration> m_NetworkObjectList;
+ QNetworkConfiguration m_NetworkObject;
+ int m_iapId;
+ int m_currentIndex;
+};
+#endif /* S60MEDIANETWORKACCESSCONTROL_H_ */
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayeraudioendpointselector.cpp b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayeraudioendpointselector.cpp
new file mode 100644
index 000000000..3ad64ef3b
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayeraudioendpointselector.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60mediaplayercontrol.h"
+#include "s60mediaplayersession.h"
+#include "s60mediaplayeraudioendpointselector.h"
+
+#include <QtGui/QIcon>
+#include <QtCore/QDebug>
+
+/*!
+ Constructs a new audio endpoint selector with the given \a parent.
+*/
+
+S60MediaPlayerAudioEndpointSelector::S60MediaPlayerAudioEndpointSelector(QObject *control, QObject *parent)
+ :QAudioEndpointSelector(parent)
+ , m_control(0)
+{
+ DP0("S60MediaPlayerAudioEndpointSelector::S60MediaPlayerAudioEndpointSelector +++");
+
+ m_control = qobject_cast<S60MediaPlayerControl*>(control);
+ m_audioEndpointNames.append("Default");
+ m_audioEndpointNames.append("All");
+ m_audioEndpointNames.append("None");
+ m_audioEndpointNames.append("Earphone");
+ m_audioEndpointNames.append("Speaker");
+
+ DP0("S60MediaPlayerAudioEndpointSelector::S60MediaPlayerAudioEndpointSelector ---");
+}
+
+/*!
+ Destroys an audio endpoint selector.
+*/
+
+S60MediaPlayerAudioEndpointSelector::~S60MediaPlayerAudioEndpointSelector()
+{
+ DP0("S60MediaPlayerAudioEndpointSelector::~S60MediaPlayerAudioEndpointSelector +++");
+ DP0("S60MediaPlayerAudioEndpointSelector::~S60MediaPlayerAudioEndpointSelector ---");
+}
+
+/*!
+ \return a list of available audio endpoints.
+*/
+
+QList<QString> S60MediaPlayerAudioEndpointSelector::availableEndpoints() const
+{
+ DP0("S60MediaPlayerAudioEndpointSelector::availableEndpoints");
+
+ return m_audioEndpointNames;
+}
+
+/*!
+ \return the description of the endpoint name.
+*/
+
+QString S60MediaPlayerAudioEndpointSelector::endpointDescription(const QString& name) const
+{
+ DP0("S60MediaPlayerAudioEndpointSelector::endpointDescription");
+
+ if (name == QString("Default")) //ENoPreference
+ return QString("Used to indicate that the playing audio can be routed to"
+ "any speaker. This is the default value for audio.");
+ else if (name == QString("All")) //EAll
+ return QString("Used to indicate that the playing audio should be routed to all speakers.");
+ else if (name == QString("None")) //ENoOutput
+ return QString("Used to indicate that the playing audio should not be routed to any output.");
+ else if (name == QString("Earphone")) //EPrivate
+ return QString("Used to indicate that the playing audio should be routed to"
+ "the default private speaker. A private speaker is one that can only"
+ "be heard by one person.");
+ else if (name == QString("Speaker")) //EPublic
+ return QString("Used to indicate that the playing audio should be routed to"
+ "the default public speaker. A public speaker is one that can "
+ "be heard by multiple people.");
+
+ return QString();
+}
+
+/*!
+ \return the name of the currently selected audio endpoint.
+*/
+
+QString S60MediaPlayerAudioEndpointSelector::activeEndpoint() const
+{
+ DP0("S60MediaPlayerAudioEndpointSelector::activeEndpoint");
+
+ if (m_control->session()) {
+ DP1("S60MediaPlayerAudioEndpointSelector::activeEndpoint - ",
+ m_control->session()->activeEndpoint());
+ return m_control->session()->activeEndpoint();
+ }
+ else {
+ DP1("S60MediaPlayerAudioEndpointSelector::activeEndpoint - ",
+ m_control->mediaControlSettings().audioEndpoint());
+ return m_control->mediaControlSettings().audioEndpoint();
+ }
+}
+
+/*!
+ \return the name of the default audio endpoint.
+*/
+
+QString S60MediaPlayerAudioEndpointSelector::defaultEndpoint() const
+{
+ DP0("S60MediaPlayerAudioEndpointSelector::defaultEndpoint");
+
+ if (m_control->session()) {
+ DP1("S60MediaPlayerAudioEndpointSelector::defaultEndpoint - ",
+ m_control->session()->defaultEndpoint());
+ return m_control->session()->defaultEndpoint();
+ }
+ else {
+ DP1("S60MediaPlayerAudioEndpointSelector::defaultEndpoint - ",
+ m_control->mediaControlSettings().audioEndpoint());
+ return m_control->mediaControlSettings().audioEndpoint();
+ }
+}
+
+/*!
+ Set the audio endpoint to \a name.
+*/
+
+void S60MediaPlayerAudioEndpointSelector::setActiveEndpoint(const QString& name)
+{
+ DP0("S60MediaPlayerAudioEndpointSelector::setActiveEndpoin +++");
+
+ DP1("S60MediaPlayerAudioEndpointSelector::setActiveEndpoint - ", name);
+
+ QString oldEndpoint = m_control->mediaControlSettings().audioEndpoint();
+
+ if (name != oldEndpoint && (name == QString("Default") || name == QString("All") ||
+ name == QString("None") || name == QString("Earphone") || name == QString("Speaker"))) {
+
+ if (m_control->session()) {
+ m_control->session()->setActiveEndpoint(name);
+ emit activeEndpointChanged(name);
+ }
+ m_control->setAudioEndpoint(name);
+ }
+
+ DP0("S60MediaPlayerAudioEndpointSelector::setActiveEndpoin ---");
+}
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayeraudioendpointselector.h b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayeraudioendpointselector.h
new file mode 100644
index 000000000..eff49d47a
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayeraudioendpointselector.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60MEDIAPLAYERAUDIOENDPOINTSELECTOR_H
+#define S60MEDIAPLAYERAUDIOENDPOINTSELECTOR_H
+
+#include <QStringList>
+
+#include <qaudioendpointselector.h>
+
+QT_USE_NAMESPACE
+
+class S60MediaPlayerControl;
+class S60MediaPlayerSession;
+
+class S60MediaPlayerAudioEndpointSelector : public QAudioEndpointSelector
+{
+
+Q_OBJECT
+
+public:
+ S60MediaPlayerAudioEndpointSelector(QObject *control, QObject *parent = 0);
+ ~S60MediaPlayerAudioEndpointSelector();
+
+ QList<QString> availableEndpoints() const ;
+ QString endpointDescription(const QString& name) const;
+ QString defaultEndpoint() const;
+ QString activeEndpoint() const;
+
+public Q_SLOTS:
+ void setActiveEndpoint(const QString& name);
+
+private:
+ S60MediaPlayerControl* m_control;
+ QString m_audioInput;
+ QList<QString> m_audioEndpointNames;
+};
+
+#endif // S60MEDIAPLAYERAUDIOENDPOINTSELECTOR_H
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayercontrol.cpp b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayercontrol.cpp
new file mode 100644
index 000000000..2eeceedd8
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayercontrol.cpp
@@ -0,0 +1,518 @@
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60mediaplayercontrol.h"
+#include "s60mediaplayersession.h"
+
+#include <QtCore/qdir.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qdebug.h>
+
+/*!
+ Constructs a new media player control with the given \a parent.
+*/
+
+S60MediaPlayerControl::S60MediaPlayerControl(MS60MediaPlayerResolver& mediaPlayerResolver, QObject *parent)
+ : QMediaPlayerControl(parent),
+ m_mediaPlayerResolver(mediaPlayerResolver),
+ m_session(NULL),
+ m_stream(NULL)
+{
+ DP0("S60MediaPlayerControl::S60MediaPlayerControl +++");
+
+ DP0("S60MediaPlayerControl::S60MediaPlayerControl ---");
+
+}
+
+/*!
+ Destroys a media player control.
+*/
+
+S60MediaPlayerControl::~S60MediaPlayerControl()
+{
+ DP0("S60MediaPlayerControl::~S60MediaPlayerControl +++");
+ DP0("S60MediaPlayerControl::~S60MediaPlayerControl ---");
+}
+
+/*!
+ \return the current playback position in milliseconds.
+*/
+
+qint64 S60MediaPlayerControl::position() const
+{
+ // DP0("S60MediaPlayerControl::position");
+
+ if (m_session)
+ return m_session->position();
+ return 0;
+}
+
+/*!
+ \return the duration of the current media in milliseconds.
+*/
+
+qint64 S60MediaPlayerControl::duration() const
+{
+ // DP0("S60MediaPlayerControl::duration");
+
+ if (m_session)
+ return m_session->duration();
+ return -1;
+}
+
+/*!
+ \return the state of a player control.
+*/
+
+QMediaPlayer::State S60MediaPlayerControl::state() const
+{
+ DP0("S60MediaPlayerControl::state");
+
+ if (m_session)
+ return m_session->state();
+ return QMediaPlayer::StoppedState;
+}
+
+/*!
+ \return the status of the current media.
+*/
+
+QMediaPlayer::MediaStatus S60MediaPlayerControl::mediaStatus() const
+{
+ DP0("QMediaPlayer::mediaStatus");
+
+ if (m_session)
+ return m_session->mediaStatus();
+ return m_mediaSettings.mediaStatus();
+}
+
+/*!
+ \return the buffering progress of the current media. Progress is measured in the percentage
+ of the buffer filled.
+*/
+
+int S60MediaPlayerControl::bufferStatus() const
+{
+ // DP0("S60MediaPlayerControl::bufferStatus");
+
+ if (m_session)
+ return m_session->bufferStatus();
+ return 0;
+}
+
+/*!
+ \return the audio volume of a player control.
+*/
+
+int S60MediaPlayerControl::volume() const
+{
+ DP0("S60MediaPlayerControl::volume");
+
+ if (m_session)
+ return m_session->volume();
+ return m_mediaSettings.volume();
+}
+
+/*!
+ \return the mute state of a player control.
+*/
+
+bool S60MediaPlayerControl::isMuted() const
+{
+ DP0("S60MediaPlayerControl::isMuted");
+
+ if (m_session)
+ return m_session->isMuted();
+ return m_mediaSettings.isMuted();
+}
+
+/*!
+ Identifies if the current media is seekable.
+
+ \return true if it possible to seek within the current media, and false otherwise.
+*/
+
+bool S60MediaPlayerControl::isSeekable() const
+{
+ DP0("S60MediaPlayerControl::isSeekable");
+
+ if (m_session)
+ return m_session->isSeekable();
+ return false;
+}
+
+/*!
+ \return 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.
+*/
+
+QMediaTimeRange S60MediaPlayerControl::availablePlaybackRanges() const
+{
+ DP0("S60MediaPlayerControl::availablePlaybackRanges");
+
+ QMediaTimeRange ranges;
+
+ if(m_session && m_session->isSeekable())
+ ranges.addInterval(0, m_session->duration());
+
+ return ranges;
+}
+
+/*!
+ \return the rate of playback.
+*/
+
+qreal S60MediaPlayerControl::playbackRate() const
+{
+ DP0("S60MediaPlayerControl::playbackRate");
+
+ return m_mediaSettings.playbackRate();
+}
+
+/*!
+ Sets the \a rate of playback.
+*/
+
+void S60MediaPlayerControl::setPlaybackRate(qreal rate)
+{
+ DP0("S60MediaPlayerControl::setPlaybackRate +++");
+
+ DP1("S60MediaPlayerControl::setPlaybackRate - ", rate);
+
+ //getting the current playbackrate
+ qreal currentPBrate = m_mediaSettings.playbackRate();
+ //checking if we need to change the Playback rate
+ if (!qFuzzyCompare(currentPBrate,rate))
+ {
+ if(m_session)
+ m_session->setPlaybackRate(rate);
+
+ m_mediaSettings.setPlaybackRate(rate);
+ }
+
+ DP0("S60MediaPlayerControl::setPlaybackRate ---");
+}
+
+/*!
+ Sets the playback \a pos of the current media. This will initiate a seek and it may take
+ some time for playback to reach the position set.
+*/
+
+void S60MediaPlayerControl::setPosition(qint64 pos)
+{
+ DP0("S60MediaPlayerControl::setPosition +++");
+
+ DP1("S60MediaPlayerControl::setPosition, Position:", pos);
+
+ if (m_session)
+ m_session->setPosition(pos);
+
+ DP0("S60MediaPlayerControl::setPosition ---");
+}
+
+/*!
+ Starts playback of the current media.
+
+ If successful the player control will immediately enter the \l {QMediaPlayer::PlayingState}
+ {playing} state.
+*/
+
+void S60MediaPlayerControl::play()
+{
+ DP0("S60MediaPlayerControl::play +++");
+
+ if (m_session)
+ m_session->play();
+
+ DP0("S60MediaPlayerControl::play ---");
+}
+
+/*!
+ Pauses playback of the current media.
+
+ If sucessful the player control will immediately enter the \l {QMediaPlayer::PausedState}
+ {paused} state.
+*/
+
+void S60MediaPlayerControl::pause()
+{
+ DP0("S60MediaPlayerControl::pause +++");
+
+ if (m_session)
+ m_session->pause();
+
+ DP0("S60MediaPlayerControl::pause ---");
+}
+
+/*!
+ Stops playback of the current media.
+
+ If successful the player control will immediately enter the \l {QMediaPlayer::StoppedState}
+ {stopped} state.
+*/
+
+void S60MediaPlayerControl::stop()
+{
+ DP0("S60MediaPlayerControl::stop +++");
+
+ if (m_session)
+ m_session->stop();
+
+ DP0("S60MediaPlayerControl::stop ---");
+}
+
+/*!
+ Sets the audio \a volume of a player control.
+*/
+
+void S60MediaPlayerControl::setVolume(int volume)
+{
+ DP0("S60MediaPlayerControl::setVolume +++");
+
+ DP1("S60MediaPlayerControl::setVolume", volume);
+
+ int boundVolume = qBound(0, volume, 100);
+ if (boundVolume == m_mediaSettings.volume())
+ return;
+
+ m_mediaSettings.setVolume(boundVolume);
+
+ if (m_session)
+ m_session->setVolume(boundVolume);
+
+ DP0("S60MediaPlayerControl::setVolume ---");
+}
+
+/*!
+ Sets the \a muted state of a player control.
+*/
+
+void S60MediaPlayerControl::setMuted(bool muted)
+{
+ DP0("S60MediaPlayerControl::setMuted +++");
+
+ DP1("S60MediaPlayerControl::setMuted - ", muted);
+
+ if (m_mediaSettings.isMuted() == muted)
+ return;
+
+ m_mediaSettings.setMuted(muted);
+
+ if (m_session)
+ m_session->setMuted(muted);
+
+ DP0("S60MediaPlayerControl::setMuted ---");
+}
+
+/*!
+ * \return the current media source.
+*/
+
+QMediaContent S60MediaPlayerControl::media() const
+{
+ DP0("S60MediaPlayerControl::media");
+
+ return m_currentResource;
+}
+
+/*!
+ \return the current media stream. This is only a valid if a stream was passed to setMedia().
+
+ \sa setMedia()
+*/
+
+const QIODevice *S60MediaPlayerControl::mediaStream() const
+{
+ DP0("S60MediaPlayerControl::mediaStream");
+
+ return m_stream;
+}
+
+/*!
+ Sets the current \a source 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 QMediaContent 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.
+*/
+
+void S60MediaPlayerControl::setMedia(const QMediaContent &source, QIODevice *stream)
+{
+ DP0("S60MediaPlayerControl::setMedia +++");
+
+ Q_UNUSED(stream)
+
+ if ((m_session && m_currentResource == source) && m_session->isStreaming())
+ {
+ m_session->load(source);
+ return;
+ }
+
+ // we don't want to set & load media again when it is already loaded
+ if (m_session && m_currentResource == source)
+ return;
+
+ // store to variable as session is created based on the content type.
+ m_currentResource = source;
+ S60MediaPlayerSession *newSession = m_mediaPlayerResolver.PlayerSession();
+ m_mediaSettings.setMediaStatus(QMediaPlayer::UnknownMediaStatus);
+
+ if (m_session)
+ m_session->reset();
+ else {
+ emit mediaStatusChanged(QMediaPlayer::UnknownMediaStatus);
+ emit error(QMediaPlayer::NoError, QString());
+ }
+
+ m_session = newSession;
+
+ if (m_session)
+ m_session->load(source);
+ else {
+ QMediaPlayer::MediaStatus status = (source.isNull()) ? QMediaPlayer::NoMedia : QMediaPlayer::InvalidMedia;
+ m_mediaSettings.setMediaStatus(status);
+ emit stateChanged(QMediaPlayer::StoppedState);
+ emit error((source.isNull()) ? QMediaPlayer::NoError : QMediaPlayer::ResourceError,
+ (source.isNull()) ? "" : tr("Media couldn't be resolved"));
+ emit mediaStatusChanged(status);
+ }
+ emit mediaChanged(m_currentResource);
+
+ DP0("S60MediaPlayerControl::setMedia ---");
+}
+
+/*!
+ * \return media player session.
+*/
+S60MediaPlayerSession* S60MediaPlayerControl::session()
+{
+ DP0("S60MediaPlayerControl::session");
+
+ return m_session;
+}
+
+/*!
+ * Sets \a output as a VideoOutput.
+*/
+
+void S60MediaPlayerControl::setVideoOutput(QObject *output)
+{
+ DP0("S60MediaPlayerControl::setVideoOutput +++");
+
+ m_mediaPlayerResolver.VideoPlayerSession()->setVideoRenderer(output);
+
+ DP0("S60MediaPlayerControl::setVideoOutput ---");
+}
+
+/*!
+ * \return TRUE if Audio available or else FALSE.
+*/
+
+bool S60MediaPlayerControl::isAudioAvailable() const
+{
+ DP0("S60MediaPlayerControl::isAudioAvailable");
+
+ if (m_session)
+ return m_session->isAudioAvailable();
+ return false;
+}
+
+/*!
+ * \return TRUE if Video available or else FALSE.
+*/
+
+bool S60MediaPlayerControl::isVideoAvailable() const
+{
+ DP0("S60MediaPlayerControl::isVideoAvailable");
+
+ if (m_session)
+ return m_session->isVideoAvailable();
+ return false;
+}
+
+/*!
+ * \return media settings.
+ *
+ * Media Settings include volume, muted, playbackRate, mediaStatus, audioEndpoint.
+*/
+const S60MediaSettings& S60MediaPlayerControl::mediaControlSettings() const
+{
+ DP0("S60MediaPlayerControl::mediaControlSettings");
+ return m_mediaSettings;
+}
+
+/*!
+ * Set the audio endpoint to \a name.
+*/
+
+void S60MediaPlayerControl::setAudioEndpoint(const QString& name)
+{
+ DP0("S60MediaPlayerControl::setAudioEndpoint +++");
+
+ DP1("S60MediaPlayerControl::setAudioEndpoint - ", name);
+
+ m_mediaSettings.setAudioEndpoint(name);
+
+ DP0("S60MediaPlayerControl::setAudioEndpoint ---");
+}
+
+/*!
+ * Sets media type \a type as Unknown, Video, Audio, Data.
+*/
+
+void S60MediaPlayerControl::setMediaType(S60MediaSettings::TMediaType type)
+{
+ DP0("S60MediaPlayerControl::setMediaType +++");
+
+ DP1("S60MediaPlayerControl::setMediaType - ", type);
+
+ m_mediaSettings.setMediaType(type);
+
+ DP0("S60MediaPlayerControl::setMediaType ---");
+}
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayercontrol.h b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayercontrol.h
new file mode 100644
index 000000000..caf6631a8
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayercontrol.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60MEDIAPLAYERCONTROL_H
+#define S60MEDIAPLAYERCONTROL_H
+
+#include <QtCore/qobject.h>
+
+#include <qmediaplayercontrol.h>
+
+#include "ms60mediaplayerresolver.h"
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+class QMediaPlayer;
+class QMediaTimeRange;
+class QMediaContent;
+QT_END_NAMESPACE
+
+QT_USE_NAMESPACE
+
+class S60MediaPlayerSession;
+class S60MediaPlayerService;
+
+class S60MediaSettings
+{
+
+public:
+ S60MediaSettings()
+ : m_volume(30)
+ , m_muted(false)
+ , m_playbackRate(0)
+ , m_mediaStatus(QMediaPlayer::NoMedia)
+ , m_audioEndpoint(QString("Default"))
+ {
+ }
+
+ enum TMediaType {Unknown, Video, Audio, Data};
+
+ void setVolume(int volume) { m_volume = volume; }
+ void setMuted(bool muted) { m_muted = muted; }
+ void setPlaybackRate(qreal rate) { m_playbackRate = rate; }
+ void setMediaStatus(QMediaPlayer::MediaStatus status) {m_mediaStatus=status;}
+ void setAudioEndpoint(const QString& audioEndpoint) { m_audioEndpoint = audioEndpoint; }
+ void setMediaType(S60MediaSettings::TMediaType type) { m_mediaType = type; }
+
+ int volume() const { return m_volume; }
+ bool isMuted() const { return m_muted; }
+ qreal playbackRate() const { return m_playbackRate; }
+ QMediaPlayer::MediaStatus mediaStatus() const {return m_mediaStatus;}
+ QString audioEndpoint() const { return m_audioEndpoint; }
+ S60MediaSettings::TMediaType mediaType() const { return m_mediaType; }
+
+private:
+ int m_volume;
+ bool m_muted;
+ qreal m_playbackRate;
+ QMediaPlayer::MediaStatus m_mediaStatus;
+ QString m_audioEndpoint;
+ S60MediaSettings::TMediaType m_mediaType;
+};
+
+class S60MediaPlayerControl : public QMediaPlayerControl
+{
+ Q_OBJECT
+
+public:
+ S60MediaPlayerControl(MS60MediaPlayerResolver& mediaPlayerResolver, QObject *parent = 0);
+ ~S60MediaPlayerControl();
+
+ // from QMediaPlayerControl
+ virtual QMediaPlayer::State state() const;
+ virtual QMediaPlayer::MediaStatus mediaStatus() const;
+ virtual qint64 duration() const;
+ virtual qint64 position() const;
+ virtual void setPosition(qint64 pos);
+ virtual int volume() const;
+ virtual void setVolume(int volume);
+ virtual bool isMuted() const;
+ virtual void setMuted(bool muted);
+ virtual int bufferStatus() const;
+ virtual bool isAudioAvailable() const;
+ virtual bool isVideoAvailable() const;
+ virtual bool isSeekable() const;
+ virtual QMediaTimeRange availablePlaybackRanges() const;
+ virtual qreal playbackRate() const;
+ virtual void setPlaybackRate(qreal rate);
+ virtual QMediaContent media() const;
+ virtual const QIODevice *mediaStream() const;
+ virtual void setMedia(const QMediaContent&, QIODevice *);
+ virtual void play();
+ virtual void pause();
+ virtual void stop();
+
+ // Own methods
+ S60MediaPlayerSession* session();
+ void setVideoOutput(QObject *output);
+ const S60MediaSettings& mediaControlSettings() const;
+ void setAudioEndpoint(const QString& name);
+ void setMediaType(S60MediaSettings::TMediaType type);
+
+private:
+ MS60MediaPlayerResolver &m_mediaPlayerResolver;
+ S60MediaPlayerSession *m_session;
+ QMediaContent m_currentResource;
+ QIODevice *m_stream;
+ S60MediaSettings m_mediaSettings;
+};
+
+#endif
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayerservice.cpp b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayerservice.cpp
new file mode 100644
index 000000000..a1aabef90
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayerservice.cpp
@@ -0,0 +1,326 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include <QtCore/qvariant.h>
+#include <QtCore/qdebug.h>
+#include <QtGui/qwidget.h>
+
+#include "s60mediaplayerservice.h"
+#include "s60mediaplayercontrol.h"
+#include "s60videoplayersession.h"
+#include "s60audioplayersession.h"
+#include "s60mediametadataprovider.h"
+#include "s60mediarecognizer.h"
+#include "s60videowidgetcontrol.h"
+#include "s60videowindowcontrol.h"
+#ifdef HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER
+#include "s60videorenderer.h"
+#endif
+#include "s60mediaplayeraudioendpointselector.h"
+#include "s60medianetworkaccesscontrol.h"
+#include "s60mediastreamcontrol.h"
+
+#include <qmediaplaylistnavigator.h>
+#include <qmediaplaylist.h>
+
+/*!
+ Construct a media service with the given \a parent.
+*/
+
+S60MediaPlayerService::S60MediaPlayerService(QObject *parent)
+ : QMediaService(parent)
+ , m_control(NULL)
+ , m_videoPlayerSession(NULL)
+ , m_audioPlayerSession(NULL)
+ , m_metaData(NULL)
+ , m_audioEndpointSelector(NULL)
+ , m_streamControl(NULL)
+ , m_networkAccessControl(NULL)
+ , m_videoOutput(NULL)
+{
+ DP0("S60MediaPlayerService::S60MediaPlayerService +++");
+
+ m_control = new S60MediaPlayerControl(*this, this);
+ m_metaData = new S60MediaMetaDataProvider(m_control, this);
+ m_audioEndpointSelector = new S60MediaPlayerAudioEndpointSelector(m_control, this);
+ m_streamControl = new S60MediaStreamControl(m_control, this);
+ m_networkAccessControl = new S60MediaNetworkAccessControl(this);
+
+ DP0("S60MediaPlayerService::S60MediaPlayerService ---");
+}
+
+/*!
+ Destroys a media service.
+*/
+
+S60MediaPlayerService::~S60MediaPlayerService()
+{
+ DP0("S60MediaPlayerService::~S60MediaPlayerService +++");
+ DP0("S60MediaPlayerService::~S60MediaPlayerService ---");
+}
+
+/*!
+ \return a pointer to the media control, which matches the controller \a name.
+
+ If the service does not implement the control, or if it is unavailable a
+ null pointer is returned instead.
+
+ Controls must be returned to the service when no longer needed using the
+ releaseControl() function.
+*/
+
+QMediaControl *S60MediaPlayerService::requestControl(const char *name)
+{
+ DP0("S60MediaPlayerService::requestControl");
+
+ if (qstrcmp(name, QMediaPlayerControl_iid) == 0)
+ return m_control;
+
+ if (qstrcmp(name, QMediaNetworkAccessControl_iid) == 0)
+ return m_networkAccessControl;
+
+ if (qstrcmp(name, QMetaDataReaderControl_iid) == 0)
+ return m_metaData;
+
+ if (qstrcmp(name, QAudioEndpointSelector_iid) == 0)
+ return m_audioEndpointSelector;
+
+ if (qstrcmp(name, QMediaStreamsControl_iid) == 0)
+ return m_streamControl;
+
+ if (!m_videoOutput) {
+ if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
+ m_videoOutput = new S60VideoWidgetControl(this);
+ }
+#ifdef HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER
+ else if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
+ m_videoOutput = new S60VideoRenderer(this);
+ }
+#endif /* HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER */
+ else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
+ m_videoOutput = new S60VideoWindowControl(this);
+ }
+
+ if (m_videoOutput) {
+ m_control->setVideoOutput(m_videoOutput);
+ return m_videoOutput;
+ }
+ }else {
+ if (qstrcmp(name, QVideoWidgetControl_iid) == 0 ||
+#ifdef HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER
+ qstrcmp(name, QVideoRendererControl_iid) == 0 ||
+#endif /* HAS_VIDEORENDERERCONTROL_IN_VIDEOPLAYER */
+ qstrcmp(name, QVideoWindowControl_iid) == 0){
+ return m_videoOutput;
+ }
+ }
+ return 0;
+}
+
+/*!
+ Releases a \a control back to the service.
+*/
+
+void S60MediaPlayerService::releaseControl(QMediaControl *control)
+{
+ DP0("S60MediaPlayerService::releaseControl ++");
+
+ if (control == m_videoOutput) {
+ m_videoOutput = 0;
+ m_control->setVideoOutput(m_videoOutput);
+ }
+
+ DP0("S60MediaPlayerService::releaseControl --");
+}
+
+/*!
+ * \return media player session(audio playersesion/video playersession)
+ * by recognizing whether media is audio or video and sets it on media type.
+*/
+S60MediaPlayerSession* S60MediaPlayerService::PlayerSession()
+{
+ DP0("S60MediaPlayerService::PlayerSession");
+
+ QUrl url = m_control->media().canonicalUrl();
+
+ if (url.isEmpty() == true) {
+ return NULL;
+ }
+
+ QScopedPointer<S60MediaRecognizer> mediaRecognizer(new S60MediaRecognizer);
+ S60MediaRecognizer::MediaType mediaType = mediaRecognizer->mediaType(url);
+ mediaRecognizer.reset();
+
+ switch (mediaType) {
+ case S60MediaRecognizer::Video:
+ case S60MediaRecognizer::Url: {
+ m_control->setMediaType(S60MediaSettings::Video);
+ return VideoPlayerSession();
+ }
+ case S60MediaRecognizer::Audio: {
+ m_control->setMediaType(S60MediaSettings::Audio);
+ return AudioPlayerSession();
+ }
+ default:
+ m_control->setMediaType(S60MediaSettings::Unknown);
+ break;
+ }
+
+ return NULL;
+}
+
+/*!
+ * \return media playersession (videoplayersession).
+ * constructs the videoplayersession object and connects all the respective signals and slots.
+ * and initialises all the media settings.
+*/
+
+S60MediaPlayerSession* S60MediaPlayerService::VideoPlayerSession()
+{
+ DP0("S60MediaPlayerService::VideoPlayerSession +++");
+
+ if (!m_videoPlayerSession) {
+ m_videoPlayerSession = new S60VideoPlayerSession(this, m_networkAccessControl);
+
+ connect(m_videoPlayerSession, SIGNAL(positionChanged(qint64)),
+ m_control, SIGNAL(positionChanged(qint64)));
+ connect(m_videoPlayerSession, SIGNAL(playbackRateChanged(qreal)),
+ m_control, SIGNAL(playbackRateChanged(qreal)));
+ connect(m_videoPlayerSession, SIGNAL(volumeChanged(int)),
+ m_control, SIGNAL(volumeChanged(int)));
+ connect(m_videoPlayerSession, SIGNAL(mutedChanged(bool)),
+ m_control, SIGNAL(mutedChanged(bool)));
+ connect(m_videoPlayerSession, SIGNAL(durationChanged(qint64)),
+ m_control, SIGNAL(durationChanged(qint64)));
+ connect(m_videoPlayerSession, SIGNAL(stateChanged(QMediaPlayer::State)),
+ m_control, SIGNAL(stateChanged(QMediaPlayer::State)));
+ connect(m_videoPlayerSession, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
+ m_control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+ connect(m_videoPlayerSession,SIGNAL(bufferStatusChanged(int)),
+ m_control, SIGNAL(bufferStatusChanged(int)));
+ connect(m_videoPlayerSession, SIGNAL(videoAvailableChanged(bool)),
+ m_control, SIGNAL(videoAvailableChanged(bool)));
+ connect(m_videoPlayerSession, SIGNAL(audioAvailableChanged(bool)),
+ m_control, SIGNAL(audioAvailableChanged(bool)));
+ connect(m_videoPlayerSession, SIGNAL(seekableChanged(bool)),
+ m_control, SIGNAL(seekableChanged(bool)));
+ connect(m_videoPlayerSession, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)),
+ m_control, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)));
+ connect(m_videoPlayerSession, SIGNAL(error(int, const QString &)),
+ m_control, SIGNAL(error(int, const QString &)));
+ connect(m_videoPlayerSession, SIGNAL(metaDataChanged()),
+ m_metaData, SIGNAL(metaDataChanged()));
+ connect(m_videoPlayerSession, SIGNAL(activeEndpointChanged(const QString&)),
+ m_audioEndpointSelector, SIGNAL(activeEndpointChanged(const QString&)));
+ connect(m_videoPlayerSession, SIGNAL(mediaChanged()),
+ m_streamControl, SLOT(handleStreamsChanged()));
+ connect(m_videoPlayerSession, SIGNAL(accessPointChanged(int)),
+ m_networkAccessControl, SLOT(accessPointChanged(int)));
+
+ }
+
+ m_videoPlayerSession->setVolume(m_control->mediaControlSettings().volume());
+ m_videoPlayerSession->setMuted(m_control->mediaControlSettings().isMuted());
+ m_videoPlayerSession->setAudioEndpoint(m_control->mediaControlSettings().audioEndpoint());
+
+ DP0("S60MediaPlayerService::VideoPlayerSession ---");
+
+ return m_videoPlayerSession;
+}
+
+/*!
+ * \return media playersession (audioplayersession).
+ * constructs the audioplayersession object and connects all the respective signals and slots.
+ * and initialises all the media settings.
+*/
+
+S60MediaPlayerSession* S60MediaPlayerService::AudioPlayerSession()
+{
+ DP0("S60MediaPlayerService::AudioPlayerSession +++");
+
+ if (!m_audioPlayerSession) {
+ m_audioPlayerSession = new S60AudioPlayerSession(this);
+
+ connect(m_audioPlayerSession, SIGNAL(positionChanged(qint64)),
+ m_control, SIGNAL(positionChanged(qint64)));
+ connect(m_audioPlayerSession, SIGNAL(playbackRateChanged(qreal)),
+ m_control, SIGNAL(playbackRateChanged(qreal)));
+ connect(m_audioPlayerSession, SIGNAL(volumeChanged(int)),
+ m_control, SIGNAL(volumeChanged(int)));
+ connect(m_audioPlayerSession, SIGNAL(mutedChanged(bool)),
+ m_control, SIGNAL(mutedChanged(bool)));
+ connect(m_audioPlayerSession, SIGNAL(durationChanged(qint64)),
+ m_control, SIGNAL(durationChanged(qint64)));
+ connect(m_audioPlayerSession, SIGNAL(stateChanged(QMediaPlayer::State)),
+ m_control, SIGNAL(stateChanged(QMediaPlayer::State)));
+ connect(m_audioPlayerSession, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
+ m_control, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+ connect(m_audioPlayerSession,SIGNAL(bufferStatusChanged(int)),
+ m_control, SIGNAL(bufferStatusChanged(int)));
+ connect(m_audioPlayerSession, SIGNAL(videoAvailableChanged(bool)),
+ m_control, SIGNAL(videoAvailableChanged(bool)));
+ connect(m_audioPlayerSession, SIGNAL(audioAvailableChanged(bool)),
+ m_control, SIGNAL(audioAvailableChanged(bool)));
+ connect(m_audioPlayerSession, SIGNAL(seekableChanged(bool)),
+ m_control, SIGNAL(seekableChanged(bool)));
+ connect(m_audioPlayerSession, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)),
+ m_control, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)));
+ connect(m_audioPlayerSession, SIGNAL(error(int, const QString &)),
+ m_control, SIGNAL(error(int, const QString &)));
+ connect(m_audioPlayerSession, SIGNAL(metaDataChanged()),
+ m_metaData, SIGNAL(metaDataChanged()));
+ connect(m_audioPlayerSession, SIGNAL(activeEndpointChanged(const QString&)),
+ m_audioEndpointSelector, SIGNAL(activeEndpointChanged(const QString&)));
+ connect(m_audioPlayerSession, SIGNAL(mediaChanged()),
+ m_streamControl, SLOT(handleStreamsChanged()));
+
+ }
+
+ m_audioPlayerSession->setVolume(m_control->mediaControlSettings().volume());
+ m_audioPlayerSession->setMuted(m_control->mediaControlSettings().isMuted());
+ m_audioPlayerSession->setAudioEndpoint(m_control->mediaControlSettings().audioEndpoint());
+
+ DP0("S60MediaPlayerService::AudioPlayerSession ---");
+
+ return m_audioPlayerSession;
+}
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayerservice.h b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayerservice.h
new file mode 100644
index 000000000..d45ad45cc
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayerservice.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEOPLAYERSERVICE_H
+#define S60VIDEOPLAYERSERVICE_H
+
+#include <QtCore/qobject.h>
+#include <qmediaservice.h>
+
+#include "ms60mediaplayerresolver.h"
+#include "s60mediaplayeraudioendpointselector.h"
+
+QT_BEGIN_NAMESPACE
+class QMediaMetaData;
+class QMediaPlayerControl;
+class QMediaPlaylist;
+QT_END_NAMESPACE
+
+QT_USE_NAMESPACE
+
+class S60VideoPlayerSession;
+class S60AudioPlayerSession;
+class S60MediaPlayerControl;
+class S60MediaMetaDataProvider;
+class S60MediaStreamControl;
+class S60MediaRecognizer;
+
+class QMediaPlaylistNavigator;
+class S60MediaNetworkAccessControl;
+
+class S60MediaPlayerService : public QMediaService, public MS60MediaPlayerResolver
+{
+ Q_OBJECT
+
+public:
+
+ S60MediaPlayerService(QObject *parent = 0);
+ ~S60MediaPlayerService();
+
+ QMediaControl *requestControl(const char *name);
+ void releaseControl(QMediaControl *control);
+
+protected: // From MS60MediaPlayerResolver
+ S60MediaPlayerSession* PlayerSession();
+ S60MediaPlayerSession* VideoPlayerSession();
+ S60MediaPlayerSession* AudioPlayerSession();
+
+private:
+ S60MediaPlayerControl *m_control;
+ S60VideoPlayerSession *m_videoPlayerSession;
+ S60AudioPlayerSession *m_audioPlayerSession;
+ S60MediaMetaDataProvider *m_metaData;
+ S60MediaPlayerAudioEndpointSelector *m_audioEndpointSelector;
+ S60MediaStreamControl *m_streamControl;
+ S60MediaNetworkAccessControl *m_networkAccessControl;
+ QMediaControl *m_videoOutput;
+};
+
+#endif
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayersession.cpp b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayersession.cpp
new file mode 100644
index 000000000..49a840a2d
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayersession.cpp
@@ -0,0 +1,1054 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60mediaplayersession.h"
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qvariant.h>
+#include <QtCore/qtimer.h>
+#include <mmf/common/mmferrors.h>
+#include <qmediatimerange.h>
+
+/*!
+ Construct a media playersession with the given \a parent.
+*/
+
+S60MediaPlayerSession::S60MediaPlayerSession(QObject *parent)
+ : QObject(parent)
+ , m_stream(false)
+ , m_playbackRate(0)
+ , m_muted(false)
+ , m_volume(0)
+ , m_state(QMediaPlayer::StoppedState)
+ , m_mediaStatus(QMediaPlayer::NoMedia)
+ , m_progressTimer(new QTimer(this))
+ , m_stalledTimer(new QTimer(this))
+ , m_error(KErrNone)
+ , m_play_requested(false)
+ , m_seekable(true)
+{
+ DP0("S60MediaPlayerSession::S60MediaPlayerSession +++");
+
+ connect(m_progressTimer, SIGNAL(timeout()), this, SLOT(tick()));
+ connect(m_stalledTimer, SIGNAL(timeout()), this, SLOT(stalled()));
+
+ DP0("S60MediaPlayerSession::S60MediaPlayerSession ---");
+}
+
+/*!
+ Destroys a media playersession.
+*/
+
+S60MediaPlayerSession::~S60MediaPlayerSession()
+{
+ DP0("S60MediaPlayerSession::~S60MediaPlayerSession +++");
+ DP0("S60MediaPlayerSession::~S60MediaPlayerSession ---");
+}
+
+/*!
+ * \return the audio volume of a player session.
+*/
+int S60MediaPlayerSession::volume() const
+{
+ DP1("S60MediaPlayerSession::volume", m_volume);
+
+ return m_volume;
+}
+
+/*!
+ Sets the audio \a volume of a player session.
+*/
+
+void S60MediaPlayerSession::setVolume(int volume)
+{
+ DP0("S60MediaPlayerSession::setVolume +++");
+
+ DP1("S60MediaPlayerSession::setVolume - ", volume);
+
+ if (m_volume == volume)
+ return;
+
+ m_volume = volume;
+ emit volumeChanged(m_volume);
+
+ // Dont set symbian players volume until media loaded.
+ // Leaves with KerrNotReady although documentation says otherwise.
+ if (!m_muted &&
+ ( mediaStatus() == QMediaPlayer::LoadedMedia
+ || (mediaStatus() == QMediaPlayer::StalledMedia && state() != QMediaPlayer::StoppedState)
+ || mediaStatus() == QMediaPlayer::BufferingMedia
+ || mediaStatus() == QMediaPlayer::BufferedMedia
+ || mediaStatus() == QMediaPlayer::EndOfMedia)) {
+ TRAPD(err, doSetVolumeL(m_volume));
+ setError(err);
+ }
+ DP0("S60MediaPlayerSession::setVolume ---");
+}
+
+/*!
+ \return the mute state of a player session.
+*/
+
+bool S60MediaPlayerSession::isMuted() const
+{
+ DP1("S60MediaPlayerSession::isMuted", m_muted);
+
+ return m_muted;
+}
+
+/*!
+ Identifies if the current media is seekable.
+
+ \return true if it possible to seek within the current media, and false otherwise.
+*/
+
+bool S60MediaPlayerSession::isSeekable() const
+{
+ DP1("S60MediaPlayerSession::isSeekable", m_seekable);
+
+ return m_seekable;
+}
+
+/*!
+ Sets the \a status of the current media.
+*/
+
+void S60MediaPlayerSession::setMediaStatus(QMediaPlayer::MediaStatus status)
+{
+ DP0("S60MediaPlayerSession::setMediaStatus +++");
+
+ if (m_mediaStatus == status)
+ return;
+
+ m_mediaStatus = status;
+
+ emit mediaStatusChanged(m_mediaStatus);
+
+ if (m_play_requested && m_mediaStatus == QMediaPlayer::LoadedMedia)
+ play();
+
+ DP0("S60MediaPlayerSession::setMediaStatus ---");
+}
+
+/*!
+ Sets the \a state on media player.
+*/
+
+void S60MediaPlayerSession::setState(QMediaPlayer::State state)
+{
+ DP0("S60MediaPlayerSession::setState +++");
+
+ if (m_state == state)
+ return;
+
+ m_state = state;
+ emit stateChanged(m_state);
+
+ DP0("S60MediaPlayerSession::setState ---");
+}
+
+/*!
+ \return the state of a player session.
+*/
+
+QMediaPlayer::State S60MediaPlayerSession::state() const
+{
+ DP1("S60MediaPlayerSession::state", m_state);
+
+ return m_state;
+}
+
+/*!
+ \return the status of the current media.
+*/
+
+QMediaPlayer::MediaStatus S60MediaPlayerSession::mediaStatus() const
+{
+ DP1("S60MediaPlayerSession::mediaStatus", m_mediaStatus);
+
+ return m_mediaStatus;
+}
+
+/*!
+ * Loads the \a url for playback.
+ * If \a url is local file then it loads audio playersesion if its audio file.
+ * If it is a local video file then loads the video playersession.
+*/
+
+void S60MediaPlayerSession::load(const QMediaContent source)
+{
+ DP0("S60MediaPlayerSession::load +++");
+
+ m_source = source;
+ setMediaStatus(QMediaPlayer::LoadingMedia);
+ startStalledTimer();
+ m_stream = (source.canonicalUrl().scheme() == "file")?false:true;
+ m_UrlPath = source.canonicalUrl();
+ TRAPD(err,
+ if (m_stream)
+ doLoadUrlL(QString2TPtrC(source.canonicalUrl().toString()));
+ else
+ doLoadL(QString2TPtrC(QDir::toNativeSeparators(source.canonicalUrl().toLocalFile()))));
+ setError(err);
+
+ DP0("S60MediaPlayerSession::load ---");
+}
+
+TBool S60MediaPlayerSession::isStreaming()
+{
+ return m_stream;
+}
+
+/*!
+ Start or resume playing the current source.
+*/
+void S60MediaPlayerSession::play()
+{
+ DP0("S60MediaPlayerSession::play +++");
+
+ if ( (state() == QMediaPlayer::PlayingState && m_play_requested == false)
+ || mediaStatus() == QMediaPlayer::UnknownMediaStatus
+ || mediaStatus() == QMediaPlayer::NoMedia
+ || mediaStatus() == QMediaPlayer::InvalidMedia)
+ return;
+
+ setState(QMediaPlayer::PlayingState);
+
+ if (mediaStatus() == QMediaPlayer::LoadingMedia ||
+ (mediaStatus() == QMediaPlayer::StalledMedia &&
+ state() == QMediaPlayer::StoppedState))
+ {
+ m_play_requested = true;
+ return;
+ }
+
+ m_play_requested = false;
+ m_duration = duration();
+ setVolume(m_volume);
+ setMuted(m_muted);
+ startProgressTimer();
+ doPlay();
+
+ DP0("S60MediaPlayerSession::play ---");
+}
+
+/*!
+ Pause playing the current source.
+*/
+
+void S60MediaPlayerSession::pause()
+{
+ DP0("S60MediaPlayerSession::pause +++");
+
+ if (state() != QMediaPlayer::PlayingState)
+ return;
+
+ if (mediaStatus() == QMediaPlayer::NoMedia ||
+ mediaStatus() == QMediaPlayer::InvalidMedia)
+ return;
+
+ setState(QMediaPlayer::PausedState);
+ stopProgressTimer();
+ TRAP_IGNORE(doPauseL());
+ m_play_requested = false;
+
+ DP0("S60MediaPlayerSession::pause ---");
+}
+
+/*!
+ Stop playing, and reset the play position to the beginning.
+*/
+
+void S60MediaPlayerSession::stop()
+{
+ DP0("S60MediaPlayerSession::stop +++");
+
+ if (state() == QMediaPlayer::StoppedState)
+ return;
+
+ m_play_requested = false;
+ m_state = QMediaPlayer::StoppedState;
+ if (mediaStatus() == QMediaPlayer::BufferingMedia ||
+ mediaStatus() == QMediaPlayer::BufferedMedia ||
+ mediaStatus() == QMediaPlayer::StalledMedia)
+ setMediaStatus(QMediaPlayer::LoadedMedia);
+ if (mediaStatus() == QMediaPlayer::LoadingMedia)
+ setMediaStatus(QMediaPlayer::UnknownMediaStatus);
+ stopProgressTimer();
+ stopStalledTimer();
+ doStop();
+ emit positionChanged(0);
+ emit stateChanged(m_state);
+
+ DP0("S60MediaPlayerSession::stop ---");
+}
+
+/*!
+ * Stops the playback and closes the controllers.
+ * And resets all the flags and status, state to default values.
+*/
+
+void S60MediaPlayerSession::reset()
+{
+ DP0("S60MediaPlayerSession::reset +++");
+
+ m_play_requested = false;
+ setError(KErrNone, QString(), true);
+ stopProgressTimer();
+ stopStalledTimer();
+ doStop();
+ doClose();
+ setState(QMediaPlayer::StoppedState);
+ setMediaStatus(QMediaPlayer::UnknownMediaStatus);
+ setPosition(0);
+
+ DP0("S60MediaPlayerSession::reset ---");
+}
+
+/*!
+ * Sets \a renderer as video renderer.
+*/
+
+void S60MediaPlayerSession::setVideoRenderer(QObject *renderer)
+{
+ DP0("S60MediaPlayerSession::setVideoRenderer +++");
+
+ Q_UNUSED(renderer);
+
+ DP0("S60MediaPlayerSession::setVideoRenderer ---");
+}
+
+/*!
+ * the percentage of the temporary buffer filled before playback begins.
+
+ When the player object is buffering; this property holds the percentage of
+ the temporary buffer that is filled. The buffer will need to reach 100%
+ filled before playback can resume, at which time the MediaStatus will be
+ BufferedMedia.
+
+ \sa mediaStatus()
+*/
+
+int S60MediaPlayerSession::bufferStatus()
+{
+ DP0("S60MediaPlayerSession::bufferStatus");
+
+ if (state() ==QMediaPlayer::StoppedState)
+ return 0;
+
+ if( mediaStatus() == QMediaPlayer::LoadingMedia
+ || mediaStatus() == QMediaPlayer::UnknownMediaStatus
+ || mediaStatus() == QMediaPlayer::NoMedia
+ || mediaStatus() == QMediaPlayer::InvalidMedia)
+ return 0;
+
+ int progress = 0;
+ TRAPD(err, progress = doGetBufferStatusL());
+ // If buffer status query not supported by codec return 100
+ // do not set error
+ if(err == KErrNotSupported)
+ return 100;
+
+ setError(err);
+ return progress;
+}
+
+/*!
+ * return TRUE if Meta data is available in current media source.
+*/
+
+bool S60MediaPlayerSession::isMetadataAvailable() const
+{
+ DP0("S60MediaPlayerSession::isMetadataAvailable");
+
+ return !m_metaDataMap.isEmpty();
+}
+
+/*!
+ * \return the \a key meta data.
+*/
+QVariant S60MediaPlayerSession::metaData(const QString &key) const
+{
+ DP0("S60MediaPlayerSession::metaData (const QString &key) const");
+
+ return m_metaDataMap.value(key);
+}
+
+/*!
+ * \return the \a key meta data as QString.
+*/
+
+QVariant S60MediaPlayerSession::metaData(QtMultimediaKit::MetaData key) const
+{
+ DP0("S60MediaPlayerSession::metaData (QtMultimediaKit::MetaData key) const");
+
+ return metaData(metaDataKeyAsString(key));
+}
+
+/*!
+ * \return List of all available meta data from current media source.
+*/
+
+QList<QtMultimediaKit::MetaData> S60MediaPlayerSession::availableMetaData() const
+{
+ DP0("S60MediaPlayerSession::availableMetaData +++");
+
+ QList<QtMultimediaKit::MetaData> metaDataTags;
+ if (isMetadataAvailable()) {
+ for (int i = QtMultimediaKit::Title; i <= QtMultimediaKit::ThumbnailImage; i++) {
+ QString metaDataItem = metaDataKeyAsString((QtMultimediaKit::MetaData)i);
+ if (!metaDataItem.isEmpty()) {
+ if (!metaData(metaDataItem).isNull()) {
+ metaDataTags.append((QtMultimediaKit::MetaData)i);
+ }
+ }
+ }
+ }
+
+ DP0("S60MediaPlayerSession::availableMetaData ---");
+
+ return metaDataTags;
+}
+
+/*!
+ * \return all available extended meta data of current media source.
+*/
+
+QStringList S60MediaPlayerSession::availableExtendedMetaData() const
+{
+ DP0("S60MediaPlayerSession::availableExtendedMetaData");
+
+ return m_metaDataMap.keys();
+}
+
+/*!
+ * \return meta data \a key as QString.
+*/
+
+QString S60MediaPlayerSession::metaDataKeyAsString(QtMultimediaKit::MetaData key) const
+{
+ DP1("S60MediaPlayerSession::metaDataKeyAsString", key);
+
+ switch(key) {
+ case QtMultimediaKit::Title: return "title";
+ case QtMultimediaKit::AlbumArtist: return "artist";
+ case QtMultimediaKit::Comment: return "comment";
+ case QtMultimediaKit::Genre: return "genre";
+ case QtMultimediaKit::Year: return "year";
+ case QtMultimediaKit::Copyright: return "copyright";
+ case QtMultimediaKit::AlbumTitle: return "album";
+ case QtMultimediaKit::Composer: return "composer";
+ case QtMultimediaKit::TrackNumber: return "albumtrack";
+ case QtMultimediaKit::AudioBitRate: return "audiobitrate";
+ case QtMultimediaKit::VideoBitRate: return "videobitrate";
+ case QtMultimediaKit::Duration: return "duration";
+ case QtMultimediaKit::MediaType: return "contenttype";
+ case QtMultimediaKit::CoverArtImage: return "attachedpicture";
+ case QtMultimediaKit::SubTitle: // TODO: Find the matching metadata keys
+ case QtMultimediaKit::Description:
+ case QtMultimediaKit::Category:
+ case QtMultimediaKit::Date:
+ case QtMultimediaKit::UserRating:
+ case QtMultimediaKit::Keywords:
+ case QtMultimediaKit::Language:
+ case QtMultimediaKit::Publisher:
+ case QtMultimediaKit::ParentalRating:
+ case QtMultimediaKit::RatingOrganisation:
+ case QtMultimediaKit::Size:
+ case QtMultimediaKit::AudioCodec:
+ case QtMultimediaKit::AverageLevel:
+ case QtMultimediaKit::ChannelCount:
+ case QtMultimediaKit::PeakValue:
+ case QtMultimediaKit::SampleRate:
+ case QtMultimediaKit::Author:
+ case QtMultimediaKit::ContributingArtist:
+ case QtMultimediaKit::Conductor:
+ case QtMultimediaKit::Lyrics:
+ case QtMultimediaKit::Mood:
+ case QtMultimediaKit::TrackCount:
+ case QtMultimediaKit::CoverArtUrlSmall:
+ case QtMultimediaKit::CoverArtUrlLarge:
+ case QtMultimediaKit::Resolution:
+ case QtMultimediaKit::PixelAspectRatio:
+ case QtMultimediaKit::VideoFrameRate:
+ case QtMultimediaKit::VideoCodec:
+ case QtMultimediaKit::PosterUrl:
+ case QtMultimediaKit::ChapterNumber:
+ case QtMultimediaKit::Director:
+ case QtMultimediaKit::LeadPerformer:
+ case QtMultimediaKit::Writer:
+ case QtMultimediaKit::CameraManufacturer:
+ case QtMultimediaKit::CameraModel:
+ case QtMultimediaKit::Event:
+ case QtMultimediaKit::Subject:
+ default:
+ break;
+ }
+
+ return QString();
+}
+
+/*!
+ Sets the \a muted state of a player session.
+*/
+
+void S60MediaPlayerSession::setMuted(bool muted)
+{
+ DP0("S60MediaPlayerSession::setMuted +++");
+ DP1("S60MediaPlayerSession::setMuted - ", muted);
+
+ m_muted = muted;
+ emit mutedChanged(m_muted);
+
+ if( m_mediaStatus == QMediaPlayer::LoadedMedia
+ || (m_mediaStatus == QMediaPlayer::StalledMedia && state() != QMediaPlayer::StoppedState)
+ || m_mediaStatus == QMediaPlayer::BufferingMedia
+ || m_mediaStatus == QMediaPlayer::BufferedMedia
+ || m_mediaStatus == QMediaPlayer::EndOfMedia) {
+ TRAPD(err, doSetVolumeL((m_muted)?0:m_volume));
+ setError(err);
+ }
+ DP0("S60MediaPlayerSession::setMuted ---");
+}
+
+/*!
+ \return the duration of the current media in milliseconds.
+*/
+
+qint64 S60MediaPlayerSession::duration() const
+{
+ // DP0("S60MediaPlayerSession::duration");
+
+ if( mediaStatus() == QMediaPlayer::LoadingMedia
+ || mediaStatus() == QMediaPlayer::UnknownMediaStatus
+ || mediaStatus() == QMediaPlayer::NoMedia
+ || (mediaStatus() == QMediaPlayer::StalledMedia && state() == QMediaPlayer::StoppedState)
+ || mediaStatus() == QMediaPlayer::InvalidMedia)
+ return -1;
+
+ qint64 pos = 0;
+ TRAP_IGNORE(pos = doGetDurationL());
+ return pos;
+}
+
+/*!
+ \return the current playback position in milliseconds.
+*/
+
+qint64 S60MediaPlayerSession::position() const
+{
+ // DP0("S60MediaPlayerSession::position");
+
+ if( mediaStatus() == QMediaPlayer::LoadingMedia
+ || mediaStatus() == QMediaPlayer::UnknownMediaStatus
+ || mediaStatus() == QMediaPlayer::NoMedia
+ || (mediaStatus() == QMediaPlayer::StalledMedia && state() == QMediaPlayer::StoppedState)
+ || mediaStatus() == QMediaPlayer::InvalidMedia)
+ return 0;
+
+ qint64 pos = 0;
+ TRAP_IGNORE(pos = doGetPositionL());
+ if (!m_play_requested && pos ==0
+ && mediaStatus() != QMediaPlayer::LoadedMedia)
+ return m_duration;
+ return pos;
+}
+
+/*!
+ Sets the playback \a pos of the current media. This will initiate a seek and it may take
+ some time for playback to reach the position set.
+*/
+
+void S60MediaPlayerSession::setPosition(qint64 pos)
+{
+ DP0("S60MediaPlayerSession::setPosition +++");
+
+ DP1("S60MediaPlayerSession::setPosition - ", pos);
+
+ if (position() == pos)
+ return;
+
+ QMediaPlayer::State originalState = state();
+
+ if (originalState == QMediaPlayer::PlayingState)
+ pause();
+
+ TRAPD(err, doSetPositionL(pos * 1000));
+ setError(err);
+
+ if (err == KErrNone) {
+ if (mediaStatus() == QMediaPlayer::EndOfMedia)
+ setMediaStatus(QMediaPlayer::LoadedMedia);
+ }
+ else if (err == KErrNotSupported) {
+ m_seekable = false;
+ emit seekableChanged(m_seekable);
+ }
+
+ if (originalState == QMediaPlayer::PlayingState)
+ play();
+
+ emit positionChanged(position());
+
+ DP0("S60MediaPlayerSession::setPosition ---");
+}
+
+/*!
+ * Set the audio endpoint to \a audioEndpoint.
+*/
+
+void S60MediaPlayerSession::setAudioEndpoint(const QString& audioEndpoint)
+{
+ DP0("S60MediaPlayerSession::setAudioEndpoint +++");
+
+ DP1("S60MediaPlayerSession::setAudioEndpoint - ", audioEndpoint);
+
+ doSetAudioEndpoint(audioEndpoint);
+
+ DP0("S60MediaPlayerSession::setAudioEndpoint ---");
+}
+
+/*!
+ * Loading of media source is completed.
+ * And ready for playback. Updates all the media status, state, settings etc.
+ * And emits the signals.
+*/
+
+void S60MediaPlayerSession::loaded()
+{
+ DP0("S60MediaPlayerSession::loaded +++");
+
+ stopStalledTimer();
+ if (m_error == KErrNone || m_error == KErrMMPartialPlayback) {
+ setMediaStatus(QMediaPlayer::LoadedMedia);
+ TRAPD(err, updateMetaDataEntriesL());
+ setError(err);
+ emit durationChanged(duration());
+ emit positionChanged(0);
+ emit videoAvailableChanged(isVideoAvailable());
+ emit audioAvailableChanged(isAudioAvailable());
+ emit mediaChanged();
+
+ m_seekable = getIsSeekable();
+ }
+
+ DP0("S60MediaPlayerSession::loaded ---");
+}
+
+/*!
+ * Playback is completed as medai source reached end of media.
+*/
+void S60MediaPlayerSession::endOfMedia()
+{
+ DP0("S60MediaPlayerSession::endOfMedia +++");
+
+ m_state = QMediaPlayer::StoppedState;
+ setMediaStatus(QMediaPlayer::EndOfMedia);
+ //there is a chance that user might have called play from EOF callback
+ //if we are already in playing state, do not send state change callback
+ if(m_state == QMediaPlayer::StoppedState)
+ emit stateChanged(QMediaPlayer::StoppedState);
+ emit positionChanged(m_duration);
+
+ DP0("S60MediaPlayerSession::endOfMedia ---");
+}
+
+/*!
+ * The percentage of the temporary buffer filling before playback begins.
+
+ When the player object is buffering; this property holds the percentage of
+ the temporary buffer that is filled. The buffer will need to reach 100%
+ filled before playback can resume, at which time the MediaStatus will be
+ BufferedMedia.
+
+ \sa mediaStatus()
+*/
+
+void S60MediaPlayerSession::buffering()
+{
+ DP0("S60MediaPlayerSession::buffering +++");
+
+ startStalledTimer();
+ setMediaStatus(QMediaPlayer::BufferingMedia);
+
+//Buffering cannot happen in stopped state. Hence update the state
+ if (state() == QMediaPlayer::StoppedState)
+ setState(QMediaPlayer::PausedState);
+
+ DP0("S60MediaPlayerSession::buffering ---");
+}
+
+/*!
+ * Buffer is filled with data and to for continuing/start playback.
+*/
+
+void S60MediaPlayerSession::buffered()
+{
+ DP0("S60MediaPlayerSession::buffered +++");
+
+ stopStalledTimer();
+ setMediaStatus(QMediaPlayer::BufferedMedia);
+
+ DP0("S60MediaPlayerSession::buffered ---");
+}
+
+/*!
+ * Sets media status as stalled as waiting for the buffer to be filled to start playback.
+*/
+
+void S60MediaPlayerSession::stalled()
+{
+ DP0("S60MediaPlayerSession::stalled +++");
+
+ setMediaStatus(QMediaPlayer::StalledMedia);
+
+ DP0("S60MediaPlayerSession::stalled ---");
+}
+
+/*!
+ * \return all the meta data entries in the current media source.
+*/
+
+QMap<QString, QVariant>& S60MediaPlayerSession::metaDataEntries()
+{
+ DP0("S60MediaPlayerSession::metaDataEntries");
+
+ return m_metaDataMap;
+}
+
+/*!
+ * \return Error by converting Symbian specific error to Multimedia error.
+*/
+
+QMediaPlayer::Error S60MediaPlayerSession::fromSymbianErrorToMultimediaError(int error)
+{
+ DP0("S60MediaPlayerSession::fromSymbianErrorToMultimediaError");
+
+ DP1("S60MediaPlayerSession::fromSymbianErrorToMultimediaError - ", error);
+
+ switch(error) {
+ case KErrNoMemory:
+ case KErrNotFound:
+ case KErrBadHandle:
+ case KErrAbort:
+ case KErrNotSupported:
+ case KErrCorrupt:
+ case KErrGeneral:
+ case KErrArgument:
+ case KErrPathNotFound:
+ case KErrDied:
+ case KErrServerTerminated:
+ case KErrServerBusy:
+ case KErrCompletion:
+ case KErrBadPower:
+ case KErrMMInvalidProtocol:
+ case KErrMMInvalidURL:
+ return QMediaPlayer::ResourceError;
+
+ case KErrMMPartialPlayback:
+ return QMediaPlayer::FormatError;
+
+ case KErrMMAudioDevice:
+ case KErrMMVideoDevice:
+ case KErrMMDecoder:
+ case KErrUnknown:
+ return QMediaPlayer::ServiceMissingError;
+
+ case KErrMMNotEnoughBandwidth:
+ case KErrMMSocketServiceNotFound:
+ case KErrMMNetworkRead:
+ case KErrMMNetworkWrite:
+ case KErrMMServerSocket:
+ case KErrMMServerNotSupported:
+ case KErrMMUDPReceive:
+ case KErrMMMulticast:
+ case KErrMMProxyServer:
+ case KErrMMProxyServerNotSupported:
+ case KErrMMProxyServerConnect:
+ case KErrCouldNotConnect:
+ return QMediaPlayer::NetworkError;
+
+ case KErrNotReady:
+ case KErrInUse:
+ case KErrAccessDenied:
+ case KErrLocked:
+ case KErrMMDRMNotAuthorized:
+ case KErrPermissionDenied:
+ case KErrCancel:
+ case KErrAlreadyExists:
+ return QMediaPlayer::AccessDeniedError;
+
+ case KErrNone:
+ return QMediaPlayer::NoError;
+
+ default:
+ return QMediaPlayer::ResourceError;
+ }
+}
+
+/*!
+ * \return error.
+ */
+
+int S60MediaPlayerSession::error() const
+{
+ DP1("S60MediaPlayerSession::error", m_error);
+
+ return m_error;
+}
+
+/*!
+ * Sets the error.
+ * * If playback complete/prepare complete ..., etc with successful then sets error as ZERO
+ * else Multimedia error.
+*/
+
+void S60MediaPlayerSession::setError(int error, const QString &errorString, bool forceReset)
+{
+ DP0("S60MediaPlayerSession::setError +++");
+
+ DP5("S60MediaPlayerSession::setError - error:", error,"errorString:", errorString, "forceReset:", forceReset);
+
+ if( forceReset ) {
+ m_error = KErrNone;
+ emit this->error(QMediaPlayer::NoError, QString());
+ return;
+ }
+
+ // If error does not change and m_error is reseted without forceReset flag
+ if (error == m_error ||
+ (m_error != KErrNone && error == KErrNone))
+ return;
+
+ m_error = error;
+ QMediaPlayer::Error mediaError = fromSymbianErrorToMultimediaError(m_error);
+ QString symbianError = QString(errorString);
+
+ if (mediaError != QMediaPlayer::NoError) {
+ // TODO: fix to user friendly string at some point
+ // These error string are only dev usable
+ symbianError.append("Symbian:");
+ symbianError.append(QString::number(m_error));
+ }
+
+ emit this->error(mediaError, symbianError);
+
+ if (m_error == KErrInUse) {
+ pause();
+ } else if (mediaError != QMediaPlayer::NoError) {
+ m_play_requested = false;
+ setMediaStatus(QMediaPlayer::InvalidMedia);
+ stop();
+ }
+}
+
+void S60MediaPlayerSession::setAndEmitError(int error)
+{
+ m_error = error;
+ QMediaPlayer::Error rateError = fromSymbianErrorToMultimediaError(error);
+ QString symbianError;
+ symbianError.append("Symbian:");
+ symbianError.append(QString::number(error));
+ emit this->error(rateError, symbianError);
+
+ DP0("S60MediaPlayerSession::setError ---");
+}
+
+/*!
+ * emits the signal if there is a changes in position and buffering status.
+ */
+
+void S60MediaPlayerSession::tick()
+{
+ DP0("S60MediaPlayerSession::tick +++");
+
+ emit positionChanged(position());
+
+ if (bufferStatus() < 100)
+ emit bufferStatusChanged(bufferStatus());
+
+ DP0("S60MediaPlayerSession::tick ---");
+}
+
+/*!
+ * Starts the timer once the media source starts buffering.
+*/
+
+void S60MediaPlayerSession::startProgressTimer()
+{
+ DP0("S60MediaPlayerSession::startProgressTimer +++");
+
+ m_progressTimer->start(500);
+
+ DP0("S60MediaPlayerSession::startProgressTimer ---");
+}
+
+/*!
+ * Stops the timer once the media source finished buffering.
+*/
+
+void S60MediaPlayerSession::stopProgressTimer()
+{
+ DP0("S60MediaPlayerSession::stopProgressTimer +++");
+
+ m_progressTimer->stop();
+
+ DP0("S60MediaPlayerSession::stopProgressTimer ---");
+}
+
+/*!
+ * Starts the timer while waiting for some events to happen like source buffering or call backs etc.
+ * So that if the events doesn't occur before stalled timer stops, it'll set the error/media status etc.
+*/
+
+void S60MediaPlayerSession::startStalledTimer()
+{
+ DP0("S60MediaPlayerSession::startStalledTimer +++");
+
+ m_stalledTimer->start(30000);
+
+ DP0("S60MediaPlayerSession::startStalledTimer ---");
+}
+
+/*!
+ * Stops the timer when some events occurred while waiting for them.
+ * media source started buffering or call back is received etc.
+*/
+
+void S60MediaPlayerSession::stopStalledTimer()
+{
+ DP0("S60MediaPlayerSession::stopStalledTimer +++");
+
+ m_stalledTimer->stop();
+
+ DP0("S60MediaPlayerSession::stopStalledTimer ---");
+}
+
+/*!
+ * \return Converted Symbian specific Descriptor to QString.
+*/
+
+QString S60MediaPlayerSession::TDesC2QString(const TDesC& aDescriptor)
+{
+ DP0("S60MediaPlayerSession::TDesC2QString");
+
+ return QString::fromUtf16(aDescriptor.Ptr(), aDescriptor.Length());
+}
+
+/*!
+ * \return Converted QString to non-modifiable pointer Descriptor.
+*/
+
+TPtrC S60MediaPlayerSession::QString2TPtrC( const QString& string )
+{
+ DP0("S60MediaPlayerSession::QString2TPtrC");
+
+ // Returned TPtrC is valid as long as the given parameter is valid and unmodified
+ return TPtrC16(static_cast<const TUint16*>(string.utf16()), string.length());
+}
+
+/*!
+ * \return Converted Symbian TRect object to QRect object.
+*/
+
+QRect S60MediaPlayerSession::TRect2QRect(const TRect& tr)
+{
+ DP0("S60MediaPlayerSession::TRect2QRect");
+
+ return QRect(tr.iTl.iX, tr.iTl.iY, tr.Width(), tr.Height());
+}
+
+/*!
+ * \return converted QRect object to Symbian specific TRec object.
+ */
+
+TRect S60MediaPlayerSession::QRect2TRect(const QRect& qr)
+{
+ DP0("S60MediaPlayerSession::QRect2TRect");
+
+ return TRect(TPoint(qr.left(), qr.top()), TSize(qr.width(), qr.height()));
+}
+
+/*!
+ \fn bool S60MediaPlayerSession::isVideoAvailable();
+
+
+ Returns TRUE if Video is available.
+*/
+
+/*!
+ \fn bool S60MediaPlayerSession::isAudioAvailable();
+
+
+ Returns TRUE if Audio is available.
+*/
+
+/*!
+ \fn void S60MediaPlayerSession::setPlaybackRate (qreal rate);
+
+
+ Sets \a rate play back rate on media source. getIsSeekable
+*/
+
+/*!
+ \fn bool S60MediaPlayerSession::getIsSeekable () const;
+
+
+ \return TRUE if Seekable possible on current media source else FALSE.
+*/
+
+/*!
+ \fn QString S60MediaPlayerSession::activeEndpoint () const;
+
+
+ \return active end point name..
+*/
+
+/*!
+ \fn QString S60MediaPlayerSession::defaultEndpoint () const;
+
+
+ \return default end point name.
+*/
+
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediaplayersession.h b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayersession.h
new file mode 100644
index 000000000..e6889d101
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60mediaplayersession.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60MEDIAPLAYERSESSION_H
+#define S60MEDIAPLAYERSESSION_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qpair.h>
+#include <qmediaplayer.h>
+#include <e32cmn.h> // for TDesC
+#include <QRect>
+#include "s60mediaplayerservice.h"
+
+
+_LIT( KSeekable, "Seekable" );
+_LIT( KFalse, "0");
+
+QT_BEGIN_NAMESPACE
+class QMediaTimeRange;
+QT_END_NAMESPACE
+
+class QTimer;
+
+class S60MediaPlayerSession : public QObject
+{
+ Q_OBJECT
+
+public:
+ S60MediaPlayerSession(QObject *parent);
+ virtual ~S60MediaPlayerSession();
+
+ // for player control interface to use
+ QMediaPlayer::State state() const;
+ QMediaPlayer::MediaStatus mediaStatus() const;
+ qint64 duration() const;
+ qint64 position() const;
+ void setPosition(qint64 pos);
+ int volume() const;
+ void setVolume(int volume);
+ bool isMuted() const;
+ void setMuted(bool muted);
+ virtual bool isVideoAvailable() = 0;
+ virtual bool isAudioAvailable() = 0;
+ bool isSeekable() const;
+ void play();
+ void pause();
+ void stop();
+ void reset();
+ bool isMetadataAvailable() const;
+ QVariant metaData(const QString &key) const;
+ QVariant metaData(QtMultimediaKit::MetaData key) const;
+ QList<QtMultimediaKit::MetaData> availableMetaData() const;
+ QStringList availableExtendedMetaData() const;
+ QString metaDataKeyAsString(QtMultimediaKit::MetaData key) const;
+ void load(const QMediaContent source);
+ int bufferStatus();
+ virtual void setVideoRenderer(QObject *renderer);
+ void setMediaStatus(QMediaPlayer::MediaStatus);
+ void setState(QMediaPlayer::State state);
+ void setAudioEndpoint(const QString& audioEndpoint);
+ virtual void setPlaybackRate(qreal rate) = 0;
+ virtual bool getIsSeekable() const { return ETrue; }
+ TBool isStreaming();
+
+protected:
+ virtual void doLoadL(const TDesC &path) = 0;
+ virtual void doLoadUrlL(const TDesC &path) = 0;
+ virtual void doPlay() = 0;
+ virtual void doStop() = 0;
+ virtual void doClose() = 0;
+ virtual void doPauseL() = 0;
+ virtual void doSetVolumeL(int volume) = 0;
+ virtual void doSetPositionL(qint64 microSeconds) = 0;
+ virtual qint64 doGetPositionL() const = 0;
+ virtual void updateMetaDataEntriesL() = 0;
+ virtual int doGetBufferStatusL() const = 0;
+ virtual qint64 doGetDurationL() const = 0;
+ virtual void doSetAudioEndpoint(const QString& audioEndpoint) = 0;
+
+public:
+ // From S60MediaPlayerAudioEndpointSelector
+ virtual QString activeEndpoint() const = 0;
+ virtual QString defaultEndpoint() const = 0;
+public Q_SLOTS:
+ virtual void setActiveEndpoint(const QString& name) = 0;
+
+protected:
+ int error() const;
+ void setError(int error, const QString &errorString = QString(), bool forceReset = false);
+ void setAndEmitError(int error);
+ void loaded();
+ void buffering();
+ void buffered();
+ void endOfMedia();
+ QMap<QString, QVariant>& metaDataEntries();
+ QMediaPlayer::Error fromSymbianErrorToMultimediaError(int error);
+ void startProgressTimer();
+ void stopProgressTimer();
+ void startStalledTimer();
+ void stopStalledTimer();
+ QString TDesC2QString(const TDesC& aDescriptor);
+ TPtrC QString2TPtrC( const QString& string );
+ QRect TRect2QRect(const TRect& tr);
+ TRect QRect2TRect(const QRect& qr);
+
+protected slots:
+ void tick();
+ void stalled();
+
+signals:
+ void durationChanged(qint64 duration);
+ void positionChanged(qint64 position);
+ void stateChanged(QMediaPlayer::State state);
+ void mediaStatusChanged(QMediaPlayer::MediaStatus mediaStatus);
+ void videoAvailableChanged(bool videoAvailable);
+ void audioAvailableChanged(bool audioAvailable);
+ void bufferStatusChanged(int percentFilled);
+ void seekableChanged(bool);
+ void availablePlaybackRangesChanged(const QMediaTimeRange&);
+ void metaDataChanged();
+ void error(int error, const QString &errorString);
+ void activeEndpointChanged(const QString &name);
+ void mediaChanged();
+ void playbackRateChanged(qreal rate);
+ void volumeChanged(int volume);
+ void mutedChanged(bool muted);
+
+protected:
+ QUrl m_UrlPath;
+ bool m_stream;
+ QMediaContent m_source;
+
+private:
+ qreal m_playbackRate;
+ QMap<QString, QVariant> m_metaDataMap;
+ bool m_muted;
+ int m_volume;
+ QMediaPlayer::State m_state;
+ QMediaPlayer::MediaStatus m_mediaStatus;
+ QTimer *m_progressTimer;
+ QTimer *m_stalledTimer;
+ int m_error;
+ bool m_play_requested;
+ bool m_seekable;
+ qint64 m_duration;
+};
+
+#endif
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediarecognizer.cpp b/src/plugins/symbian/mmf/mediaplayer/s60mediarecognizer.cpp
new file mode 100644
index 000000000..48b565c34
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60mediarecognizer.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60mediarecognizer.h"
+#include <e32def.h>
+#include <e32cmn.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qdebug.h>
+
+#include <apgcli.h>
+
+static const TInt KMimeTypePrefixLength = 6; // "audio/" or "video/"
+
+_LIT(KMimeTypePrefixAudio, "audio/");
+_LIT(KMimeTypePrefixVideo, "video/");
+_LIT(KMimeTypeRingingTone, "application/vnd.nokia.ringing-tone");
+
+/*!
+ Construct a media Recognizer with the given \a parent.
+*/
+
+S60MediaRecognizer::S60MediaRecognizer(QObject *parent) : QObject(parent)
+{
+ DP0("S60MediaRecognizer::S60MediaRecognizer +++");
+ DP0("S60MediaRecognizer::S60MediaRecognizer ---");
+}
+
+/*!
+ Destroys a media Recognizer.
+*/
+
+S60MediaRecognizer::~S60MediaRecognizer()
+{
+ DP0("S60MediaRecognizer::~S60MediaRecognizer +++");
+
+ m_file.Close();
+ m_fileServer.Close();
+ m_recognizer.Close();
+
+ DP0("S60MediaRecognizer::~S60MediaRecognizer ---");
+}
+
+/*!
+ * \return media type of \a url.
+ * \a url may be a streaming link or a local file.
+ * If \a url is local file then identifies the media type and returns it.
+*/
+
+S60MediaRecognizer::MediaType S60MediaRecognizer::mediaType(const QUrl &url)
+{
+ DP0("S60MediaRecognizer::mediaType");
+
+ bool isStream = (url.scheme() == "file")?false:true;
+
+ if (isStream)
+ return Url;
+ else
+ return identifyMediaType(QDir::cleanPath(url.toLocalFile()));
+}
+
+/*!
+ * \return Media type of \a file name by recognizing its mimetype whether its audio or video.
+*/
+
+S60MediaRecognizer::MediaType S60MediaRecognizer::identifyMediaType(const QString& fileName)
+{
+ DP0("S60MediaRecognizer::identifyMediaType +++");
+
+ DP1("S60MediaRecognizer::identifyMediaType - ", fileName);
+
+ S60MediaRecognizer::MediaType result = Video; // default to videoplayer
+ bool recognizerOpened = false;
+
+ TInt err = m_recognizer.Connect();
+ if (err == KErrNone) {
+ recognizerOpened = true;
+ }
+
+ err = m_fileServer.Connect();
+ if (err == KErrNone) {
+ recognizerOpened = true;
+ }
+
+ // This is needed for sharing file handles for the recognizer
+ err = m_fileServer.ShareProtected();
+ if (err == KErrNone) {
+ recognizerOpened = true;
+ }
+
+ if (recognizerOpened) {
+ m_file.Close();
+ err = m_file.Open(m_fileServer, QString2TPtrC(QDir::toNativeSeparators(fileName)), EFileRead |
+ EFileShareReadersOnly);
+
+ if (err == KErrNone) {
+ TDataRecognitionResult recognizerResult;
+ err = m_recognizer.RecognizeData(m_file, recognizerResult);
+ if (err == KErrNone) {
+ const TPtrC mimeType = recognizerResult.iDataType.Des();
+
+ if (mimeType.Left(KMimeTypePrefixLength).Compare(KMimeTypePrefixAudio) == 0 ||
+ mimeType.Compare(KMimeTypeRingingTone) == 0) {
+ result = Audio;
+ } else if (mimeType.Left(KMimeTypePrefixLength).Compare(KMimeTypePrefixVideo) == 0) {
+ result = Video;
+ }
+ }
+ }
+ }
+
+ DP0("S60MediaRecognizer::identifyMediaType ---");
+
+ return result;
+}
+
+/*!
+ * \return Symbian modifiable pointer descriptor from a QString \a string.
+ */
+
+TPtrC S60MediaRecognizer::QString2TPtrC( const QString& string )
+{
+ DP1("S60MediaRecognizer::QString2TPtrC - ", string);
+
+ // Returned TPtrC is valid as long as the given parameter is valid and unmodified
+ return TPtrC16(static_cast<const TUint16*>(string.utf16()), string.length());
+}
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediarecognizer.h b/src/plugins/symbian/mmf/mediaplayer/s60mediarecognizer.h
new file mode 100644
index 000000000..bdd0caabe
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60mediarecognizer.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60MEDIARECOGNIZER_H_
+#define S60MEDIARECOGNIZER_H_
+
+#include <QtCore/qobject.h>
+
+#include <apgcli.h>
+#include <f32file.h>
+
+class QUrl;
+
+class S60MediaRecognizer : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum MediaType {
+ Audio,
+ Video,
+ Url,
+ NotSupported = -1
+ };
+
+ S60MediaRecognizer(QObject *parent = 0);
+ ~S60MediaRecognizer();
+
+ S60MediaRecognizer::MediaType mediaType(const QUrl &url);
+ S60MediaRecognizer::MediaType identifyMediaType(const QString& fileName);
+
+protected:
+ TPtrC QString2TPtrC( const QString& string );
+
+private:
+ RApaLsSession m_recognizer;
+ RFile m_file;
+ RFs m_fileServer;
+};
+
+#endif /* S60MEDIARECOGNIZER_H_ */
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediastreamcontrol.cpp b/src/plugins/symbian/mmf/mediaplayer/s60mediastreamcontrol.cpp
new file mode 100644
index 000000000..9a2ce5c02
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60mediastreamcontrol.cpp
@@ -0,0 +1,201 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60mediastreamcontrol.h"
+#include "s60mediaplayersession.h"
+#include "s60mediaplayercontrol.h"
+#include <qmediastreamscontrol.h>
+
+#include <QtCore/qdir.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qdebug.h>
+
+/*!
+ Constructs a new media streams control with the given \a control.
+*/
+
+S60MediaStreamControl::S60MediaStreamControl(QObject *control, QObject *parent)
+ : QMediaStreamsControl(parent)
+ , m_control(NULL)
+ , m_mediaType(S60MediaSettings::Unknown)
+{
+ DP0("S60MediaStreamControl::S60MediaStreamControl +++");
+
+ m_control = qobject_cast<S60MediaPlayerControl*>(control);
+ m_mediaType = m_control->mediaControlSettings().mediaType();
+
+ DP0("S60MediaStreamControl::S60MediaStreamControl ---");
+}
+
+/*!
+ Destroys a media streams control.
+*/
+
+S60MediaStreamControl::~S60MediaStreamControl()
+{
+ DP0("S60MediaStreamControl::~S60MediaStreamControl +++");
+ DP0("S60MediaStreamControl::~S60MediaStreamControl ---");
+}
+
+/*!
+ \return the number of media streams.
+*/
+
+int S60MediaStreamControl::streamCount()
+{
+ DP0("S60MediaStreamControl::streamCount");
+
+ int streamCount = 0;
+ if (m_control->isAudioAvailable())
+ streamCount++;
+ if (m_control->isVideoAvailable())
+ streamCount++;
+ DP1("S60MediaStreamControl::streamCount", streamCount);
+
+ return streamCount;
+}
+
+/*!
+ \return the type of a media \a streamNumber.
+*/
+
+QMediaStreamsControl::StreamType S60MediaStreamControl::streamType(int streamNumber)
+{
+ DP0("S60MediaStreamControl::streamType +++");
+
+ DP1("S60MediaStreamControl::streamType - ", streamNumber);
+
+ Q_UNUSED(streamNumber);
+
+ QMediaStreamsControl::StreamType type = QMediaStreamsControl::UnknownStream;
+
+ if (m_control->mediaControlSettings().mediaType() == S60MediaSettings::Video)
+ type = QMediaStreamsControl::VideoStream;
+ else
+ type = QMediaStreamsControl::AudioStream;
+
+ DP0("S60MediaStreamControl::streamType ---");
+
+ return type;
+}
+
+/*!
+ \return the meta-data value of \a key for a given \a streamNumber.
+
+ Useful metadata keya are QtMultimediaKit::Title, QtMultimediaKit::Description and QtMultimediaKit::Language.
+*/
+
+QVariant S60MediaStreamControl::metaData(int streamNumber, QtMultimediaKit::MetaData key)
+{
+ DP0("S60MediaStreamControl::metaData");
+
+ Q_UNUSED(streamNumber);
+
+ if (m_control->session()) {
+ if (m_control->session()->isMetadataAvailable())
+ return m_control->session()->metaData(key);
+ }
+ return QVariant();
+}
+
+/*!
+ \return true if the media \a streamNumber is active else false.
+*/
+
+bool S60MediaStreamControl::isActive(int streamNumber)
+{
+ DP0("S60MediaStreamControl::isActive +++");
+
+ DP1("S60MediaStreamControl::isActive - ", streamNumber);
+
+ if (m_control->mediaControlSettings().mediaType() == S60MediaSettings::Video) {
+ switch (streamNumber) {
+ case 1:
+ return m_control->isVideoAvailable();
+ case 2:
+ return m_control->isAudioAvailable();
+ default:
+ break;
+ }
+ }
+
+ DP0("S60MediaStreamControl::isActive ---");
+
+ return m_control->isAudioAvailable();
+}
+
+/*!
+ Sets the active \a streamNumber of a media \a state.
+
+ Symbian MMF does not support enabling or disabling specific media streams.
+
+ Setting the active state of a media stream to true will activate it. If any other stream
+ of the same type was previously active it will be deactivated. Setting the active state fo a
+ media stream to false will deactivate it.
+*/
+
+void S60MediaStreamControl::setActive(int streamNumber, bool state)
+{
+ DP0("S60MediaStreamControl::setActive +++");
+
+ DP2("S60MediaStreamControl::setActive - ", streamNumber, state);
+
+ Q_UNUSED(streamNumber);
+ Q_UNUSED(state);
+ // Symbian MMF does not support enabling or disabling specific media streams
+
+ DP0("S60MediaStreamControl::setActive ---");
+}
+
+/*!
+ The signal is emitted when the available streams list is changed.
+*/
+
+void S60MediaStreamControl::handleStreamsChanged()
+{
+ DP0("S60MediaStreamControl::handleStreamsChanged +++");
+
+ emit streamsChanged();
+
+ DP0("S60MediaStreamControl::handleStreamsChanged ---");
+}
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60mediastreamcontrol.h b/src/plugins/symbian/mmf/mediaplayer/s60mediastreamcontrol.h
new file mode 100644
index 000000000..702ebc7b2
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60mediastreamcontrol.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60MEDIASTREAMCONTROL_H
+#define S60MEDIASTREAMCONTROL_H
+
+#include <QVariant>
+
+#include "s60mediaplayercontrol.h"
+
+#include <qmediastreamscontrol.h>
+#include <qtmedianamespace.h>
+
+QT_USE_NAMESPACE
+
+class S60MediaPlayerControl;
+class S60MediaSettings;
+
+class S60MediaStreamControl : public QMediaStreamsControl
+{
+ Q_OBJECT
+public:
+ S60MediaStreamControl(QObject *session, QObject *parent = 0);
+ ~S60MediaStreamControl();
+
+ // from QMediaStreamsControl
+ int streamCount();
+ QMediaStreamsControl::StreamType streamType(int streamNumber);
+ QVariant metaData(int streamNumber, QtMultimediaKit::MetaData key);
+ bool isActive(int streamNumber);
+ void setActive(int streamNumber, bool state);
+
+public Q_SLOTS:
+ void handleStreamsChanged();
+
+private:
+ S60MediaPlayerControl *m_control;
+ S60MediaSettings::TMediaType m_mediaType;
+};
+
+#endif //S60MEDIASTREAMCONTROL_H
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60videooutputinterface.h b/src/plugins/symbian/mmf/mediaplayer/s60videooutputinterface.h
new file mode 100644
index 000000000..f5388dbbc
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60videooutputinterface.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEOOUTPUTINTERFACE_H
+#define S60VIDEOOUTPUTINTERFACE_H
+
+#include <QtCore/qglobal.h>
+#include <QtGui/qwindowdefs.h>
+#include <coecntrl.h>
+
+class S60VideoOutputInterface
+{
+public:
+ RWindow *videoWindowHandle() const { return videoWinId() ? static_cast<RWindow *>(videoWinId()->DrawableWindow()) : 0 ; }
+ virtual WId videoWinId() const = 0;
+ // If VIDEOOUTPUT_GRAPHICS_SURFACES is defined, the return value is the video
+ // rectangle relative to the video window. If not, the return value is the
+ // absolute screen rectangle.
+ virtual QRect videoDisplayRect() const = 0;
+ virtual Qt::AspectRatioMode videoAspectRatio() const = 0;
+};
+
+#endif // S60VIDEOOUTPUTINTERFACE_H
+
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60videoplayersession.cpp b/src/plugins/symbian/mmf/mediaplayer/s60videoplayersession.cpp
new file mode 100644
index 000000000..49d511ca2
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60videoplayersession.cpp
@@ -0,0 +1,1124 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60videoplayersession.h"
+#include "s60mediaplayerservice.h"
+#include "s60videowidgetcontrol.h"
+#include "s60videowidgetdisplay.h"
+#include "s60videowindowcontrol.h"
+#include "s60videowindowdisplay.h"
+
+#include <QtCore/QTimer>
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QSymbianEvent>
+#include <QtGui/QWidget>
+
+#include <coecntrl.h>
+#include <coemain.h> // For CCoeEnv
+#include <w32std.h>
+#include <mmf/common/mmferrors.h>
+#include <mmf/common/mmfcontrollerframeworkbase.h>
+#include <MMFROPCustomCommandConstants.h>
+#ifdef HTTP_COOKIES_ENABLED
+#include <MMFSessionInfoCustomCommandConstants.h>
+#endif
+
+const QString DefaultAudioEndpoint = QLatin1String("Default");
+const TUid KHelixUID = {0x101F8514};
+
+//Hard-coding the command to support older versions.
+const TInt KMMFROPControllerEnablePausedLoadingStatus = 7;
+
+TVideoRotation videoRotation(qreal angle)
+{
+ // Convert to clockwise
+ angle = 360.0f - angle;
+ while (angle >= 360.0f)
+ angle -= 360.0f;
+ TVideoRotation result = EVideoRotationNone;
+ if (angle >= 45.0f && angle < 135.0f)
+ result = EVideoRotationClockwise90;
+ else if (angle >= 135.0f && angle < 225.0f)
+ result = EVideoRotationClockwise180;
+ else if (angle >= 225.0f && angle < 315.0f)
+ result = EVideoRotationClockwise270;
+ return result;
+}
+
+S60VideoPlayerEventHandler *S60VideoPlayerEventHandler::m_instance = 0;
+QCoreApplication::EventFilter S60VideoPlayerEventHandler::m_eventFilter = 0;
+QList<ApplicationFocusObserver *> S60VideoPlayerEventHandler::m_applicationFocusObservers;
+
+S60VideoPlayerEventHandler *S60VideoPlayerEventHandler::instance()
+{
+ if (!m_instance)
+ m_instance = new S60VideoPlayerEventHandler();
+ return m_instance;
+}
+
+S60VideoPlayerEventHandler::S60VideoPlayerEventHandler()
+{
+ m_eventFilter = QCoreApplication::instance()->setEventFilter(filterEvent);
+}
+
+S60VideoPlayerEventHandler::~S60VideoPlayerEventHandler()
+{
+ QCoreApplication::instance()->setEventFilter(m_eventFilter);
+}
+
+void S60VideoPlayerEventHandler::addApplicationFocusObserver(ApplicationFocusObserver *observer)
+{
+ m_applicationFocusObservers.append(observer);
+}
+
+void S60VideoPlayerEventHandler::removeApplicationFocusObserver(ApplicationFocusObserver *observer)
+{
+ m_applicationFocusObservers.removeAt(m_applicationFocusObservers.indexOf(observer));
+ if (m_applicationFocusObservers.count() == 0) {
+ delete m_instance;
+ m_instance = 0;
+ }
+}
+
+bool S60VideoPlayerEventHandler::filterEvent(void *message, long *result)
+{
+ if (const QSymbianEvent *symbianEvent = reinterpret_cast<const QSymbianEvent*>(message)) {
+ switch (symbianEvent->type()) {
+ case QSymbianEvent::WindowServerEvent:
+ {
+ const TWsEvent *wsEvent = symbianEvent->windowServerEvent();
+ if (EEventFocusLost == wsEvent->Type() || EEventFocusGained == wsEvent->Type()) {
+ for (QList<ApplicationFocusObserver *>::const_iterator it = m_applicationFocusObservers.constBegin();
+ it != m_applicationFocusObservers.constEnd(); ++it) {
+ if (EEventFocusLost == wsEvent->Type())
+ (*it)->applicationLostFocus();
+ else if (EEventFocusGained == wsEvent->Type())
+ (*it)->applicationGainedFocus();
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ bool ret = false;
+ if (m_eventFilter)
+ ret = m_eventFilter(message, result);
+ return ret;
+}
+
+/*!
+ Constructs the CVideoPlayerUtility2 object with given \a service and \a object.
+ And Registers for Video Loading Notifications.
+*/
+S60VideoPlayerSession::S60VideoPlayerSession(QMediaService *service, S60MediaNetworkAccessControl *object)
+ : S60MediaPlayerSession(service)
+ , m_accessPointId(0)
+ , m_wsSession(&CCoeEnv::Static()->WsSession())
+ , m_screenDevice(CCoeEnv::Static()->ScreenDevice())
+ , m_service(service)
+ , m_player(0)
+#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES
+ , m_dsaActive(false)
+ , m_dsaStopped(false)
+#endif
+ , m_videoOutputControl(0)
+ , m_videoOutputDisplay(0)
+ , m_displayWindow(0)
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ , m_audioOutput(0)
+#endif
+ , m_audioEndpoint(DefaultAudioEndpoint)
+ , m_pendingChanges(0)
+ , m_backendInitiatedPause(false)
+#ifdef HTTP_COOKIES_ENABLED
+ , m_destinationPckg(KUidInterfaceMMFControllerSessionInfo)
+#endif
+{
+ DP0("S60VideoPlayerSession::S60VideoPlayerSession +++");
+
+ m_networkAccessControl = object;
+#ifdef VIDEOOUTPUT_GRAPHICS_SURFACES
+ QT_TRAP_THROWING(m_player = CVideoPlayerUtility2::NewL(
+ *this,
+ 0,
+ EMdaPriorityPreferenceNone
+ ));
+ m_player->RegisterForVideoLoadingNotification(*this);
+#else
+ RWindow *window = 0;
+ QRect extentRect;
+ QWidget *widget = QApplication::activeWindow();
+ if (!widget)
+ widget = QApplication::allWidgets().at(0);
+ Q_ASSERT(widget);
+ WId wid = widget->effectiveWinId();
+ if (!wid)
+ wid = widget->winId();
+ window = static_cast<RWindow *>(wid->DrawableWindow());
+ extentRect = QRect(widget->mapToGlobal(widget->pos()), widget->size());
+ TRect clipRect = QRect2TRect(extentRect);
+ const TRect desktopRect = QRect2TRect(QApplication::desktop()->screenGeometry());
+ clipRect.Intersection(desktopRect);
+ QT_TRAP_THROWING(m_player = CVideoPlayerUtility::NewL(
+ *this,
+ 0,
+ EMdaPriorityPreferenceNone,
+ *m_wsSession,
+ *m_screenDevice,
+ *window,
+ QRect2TRect(extentRect),
+ clipRect));
+ m_dsaActive = true;
+ m_player->RegisterForVideoLoadingNotification(*this);
+#endif // VIDEOOUTPUT_GRAPHICS_SURFACES
+ S60VideoPlayerEventHandler::instance()->addApplicationFocusObserver(this);
+ DP0("S60VideoPlayerSession::S60VideoPlayerSession ---");
+}
+
+/*!
+ Destroys the CVideoPlayerUtility2 object.
+
+ And Unregister the observer.
+*/
+
+S60VideoPlayerSession::~S60VideoPlayerSession()
+{
+ DP0("S60VideoPlayerSession::~S60VideoPlayerSession +++");
+ S60VideoPlayerEventHandler::instance()->removeApplicationFocusObserver(this);
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ if (m_audioOutput)
+ m_audioOutput->UnregisterObserver(*this);
+ delete m_audioOutput;
+#endif
+ m_player->Close();
+ delete m_player;
+
+ DP0("S60VideoPlayerSession::~S60VideoPlayerSession ---");
+}
+
+void S60VideoPlayerSession::applicationGainedFocus()
+{
+ if (m_backendInitiatedPause) {
+ m_backendInitiatedPause = false;
+ play();
+ }
+ if (QMediaPlayer::PausedState == state()) {
+ TRAPD(err, m_player->RefreshFrameL());
+ setError(err);
+ }
+}
+
+void S60VideoPlayerSession::applicationLostFocus()
+{
+ if (QMediaPlayer::PlayingState == state()) {
+ m_backendInitiatedPause = true;
+ pause();
+ }
+}
+
+/*!
+
+ Opens the a file from \a path.
+*/
+
+void S60VideoPlayerSession::doLoadL(const TDesC &path)
+{
+ DP0("S60VideoPlayerSession::doLoadL +++");
+
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ // m_audioOutput needs to be reinitialized after MapcInitComplete
+ if (m_audioOutput)
+ m_audioOutput->UnregisterObserver(*this);
+ delete m_audioOutput;
+ m_audioOutput = NULL;
+#endif
+ m_player->OpenFileL(path, KHelixUID);
+
+ DP0("S60VideoPlayerSession::doLoadL ---");
+}
+
+/*!
+ Sets the playbackRate with \a rate.
+*/
+
+void S60VideoPlayerSession::setPlaybackRate(qreal rate)
+{
+ DP0("S60VideoPlayerSession::setPlaybackRate +++");
+
+ DP1("S60VideoPlayerSession::setPlaybackRate - ", rate);
+
+ /*
+ * setPlaybackRate is not supported in S60 3.1 and 3.2
+ * This flag will be defined for 3.1 and 3.2
+ */
+#ifndef PLAY_RATE_NOT_SUPPORTED
+ //setPlayVelocity requires rate in the form of
+ //50 = 0.5x ;100 = 1.x ; 200 = 2.x ; 300 = 3.x
+ //so multiplying rate with 100
+ TRAPD(err, m_player->SetPlayVelocityL((TInt)(rate*100)));
+ if (KErrNone == err)
+ emit playbackRateChanged(rate);
+ else
+ setError(err);
+#endif
+
+ DP0("S60VideoPlayerSession::setPlaybackRate ---");
+}
+
+/*!
+
+ Opens the a Url from \a path for streaming the source.
+*/
+
+void S60VideoPlayerSession::doLoadUrlL(const TDesC &path)
+{
+ DP0("S60VideoPlayerSession::doLoadUrlL +++");
+
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ // m_audioOutput needs to be reinitialized after MapcInitComplete
+ if (m_audioOutput)
+ m_audioOutput->UnregisterObserver(*this);
+ delete m_audioOutput;
+ m_audioOutput = NULL;
+#endif
+ m_accessPointId = m_networkAccessControl->accessPointId();
+ m_player->OpenUrlL(path, m_accessPointId, KNullDesC8, KHelixUID);
+
+ DP0("S60VideoPlayerSession::doLoadUrlL ---");
+}
+
+/*!
+
+ Returns the percentage of the video clip loaded.
+*/
+
+int S60VideoPlayerSession::doGetBufferStatusL() const
+{
+ // DP0("S60VideoPlayerSession::doGetBufferStatusL +++");
+
+ int progress = 0;
+ m_player->GetVideoLoadingProgressL(progress);
+
+ // DP0("S60VideoPlayerSession::doGetBufferStatusL ---");
+
+ return progress;
+}
+
+/*!
+ Returns the duration of the video sample in microseconds.
+*/
+
+qint64 S60VideoPlayerSession::doGetDurationL() const
+{
+ // DP0("S60VideoPlayerSession::doGetDurationL");
+
+ return m_player->DurationL().Int64() / qint64(1000);
+}
+
+/*!
+ * Sets the \a videooutput for video rendering.
+*/
+
+void S60VideoPlayerSession::setVideoRenderer(QObject *videoOutput)
+{
+ DP0("S60VideoPlayerSession::setVideoRenderer +++");
+ if (videoOutput != m_videoOutputControl) {
+ if (m_videoOutputDisplay) {
+ disconnect(m_videoOutputDisplay);
+ m_videoOutputDisplay->disconnect(this);
+ m_videoOutputDisplay = 0;
+ }
+ if (videoOutput) {
+ if (S60VideoWidgetControl *control = qobject_cast<S60VideoWidgetControl *>(videoOutput))
+ m_videoOutputDisplay = control->display();
+ if (!m_videoOutputDisplay)
+ return;
+ m_videoOutputDisplay->setNativeSize(m_nativeSize);
+ connect(this, SIGNAL(nativeSizeChanged(QSize)), m_videoOutputDisplay, SLOT(setNativeSize(QSize)));
+ connect(m_videoOutputDisplay, SIGNAL(windowHandleChanged(RWindow *)), this, SLOT(windowHandleChanged()));
+ connect(m_videoOutputDisplay, SIGNAL(displayRectChanged(QRect, QRect)), this, SLOT(displayRectChanged()));
+ connect(m_videoOutputDisplay, SIGNAL(aspectRatioModeChanged(Qt::AspectRatioMode)), this, SLOT(aspectRatioChanged()));
+ connect(m_videoOutputDisplay, SIGNAL(rotationChanged(qreal)), this, SLOT(rotationChanged()));
+#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES
+ connect(m_videoOutputDisplay, SIGNAL(beginVideoWindowNativePaint()), this, SLOT(suspendDirectScreenAccess()));
+ connect(m_videoOutputDisplay, SIGNAL(endVideoWindowNativePaint()), this, SLOT(resumeDirectScreenAccess()));
+#endif
+ }
+ m_videoOutputControl = videoOutput;
+ windowHandleChanged();
+ }
+
+ DP0("S60VideoPlayerSession::setVideoRenderer ---");
+}
+
+/*!
+ * Apply the pending changes for window.
+*/
+void S60VideoPlayerSession::applyPendingChanges(bool force)
+{
+ DP0("S60VideoPlayerSession::applyPendingChanges +++");
+
+ if ( force
+ || QMediaPlayer::LoadedMedia == mediaStatus()
+ || QMediaPlayer::StalledMedia == mediaStatus()
+ || QMediaPlayer::BufferingMedia == mediaStatus()
+ || QMediaPlayer::BufferedMedia == mediaStatus()
+ || QMediaPlayer::EndOfMedia == mediaStatus()) {
+ int error = KErrNone;
+ RWindow *const window = m_videoOutputDisplay ? m_videoOutputDisplay->windowHandle() : 0;
+ const QRect extentRect = m_videoOutputDisplay ? m_videoOutputDisplay->extentRect() : QRect();
+ const QRect clipRect = m_videoOutputDisplay ? m_videoOutputDisplay->clipRect() : QRect();
+#ifdef VIDEOOUTPUT_GRAPHICS_SURFACES
+ if (m_pendingChanges & WindowHandle) {
+ if (m_displayWindow) {
+ m_player->RemoveDisplayWindow(*m_displayWindow);
+ m_displayWindow = 0;
+ }
+ if (window) {
+ TRAP(error, m_player->AddDisplayWindowL(*m_wsSession, *m_screenDevice,
+ *window,
+ QRect2TRect(extentRect),
+ QRect2TRect(clipRect)));
+ if (KErrNone == error)
+ m_displayWindow = window;
+ }
+ m_pendingChanges = ScaleFactors;
+ }
+ if (KErrNone == error && (m_pendingChanges & DisplayRect) && m_displayWindow) {
+ TRAP(error, m_player->SetVideoExtentL(*m_displayWindow, QRect2TRect(extentRect)));
+ if (KErrNone == error)
+ TRAP(error, m_player->SetWindowClipRectL(*m_displayWindow, QRect2TRect(clipRect)));
+ m_pendingChanges ^= DisplayRect;
+ m_pendingChanges |= ScaleFactors;
+ }
+#else
+ if (m_pendingChanges & WindowHandle || m_pendingChanges & DisplayRect) {
+ if (window) {
+ TRAP(error, m_player->SetDisplayWindowL(*m_wsSession, *m_screenDevice,
+ *window,
+ QRect2TRect(extentRect),
+ QRect2TRect(clipRect)));
+ if (KErrNone == error)
+ m_displayWindow = window;
+ }
+ m_dsaActive = (KErrNone == error);
+ m_dsaStopped = false;
+ m_pendingChanges = ScaleFactors;
+ }
+
+#endif // VIDEOOUTPUT_GRAPHICS_SURFACES
+ if (KErrNone == error && (m_pendingChanges & ScaleFactors) && m_displayWindow && m_videoOutputDisplay) {
+ const TVideoRotation rotation = videoRotation(m_videoOutputDisplay->rotation());
+ const bool swap = (rotation == EVideoRotationClockwise90 || rotation == EVideoRotationClockwise270);
+ const QSize extentSize = swap ? QSize(extentRect.height(), extentRect.width()) : extentRect.size();
+ QSize scaled = m_nativeSize;
+ if (m_videoOutputDisplay->aspectRatioMode() == Qt::IgnoreAspectRatio)
+ scaled.scale(extentSize, Qt::IgnoreAspectRatio);
+ else if (m_videoOutputDisplay->aspectRatioMode() == Qt::KeepAspectRatio)
+ scaled.scale(extentSize, Qt::KeepAspectRatio);
+ else if (m_videoOutputDisplay->aspectRatioMode() == Qt::KeepAspectRatioByExpanding)
+ scaled.scale(extentSize, Qt::KeepAspectRatioByExpanding);
+ const qreal width = qreal(scaled.width()) / qreal(m_nativeSize.width()) * qreal(100);
+ const qreal height = qreal(scaled.height()) / qreal(m_nativeSize.height()) * qreal(100);
+#ifdef VIDEOOUTPUT_GRAPHICS_SURFACES
+ TRAP(error, m_player->SetScaleFactorL(*m_displayWindow, width, height));
+#else
+ static const TBool antialias = ETrue;
+ TRAP(error, m_player->SetScaleFactorL(width, height, antialias));
+#endif // VIDEOOUTPUT_GRAPHICS_SURFACES
+ m_pendingChanges ^= ScaleFactors;
+ }
+ if (KErrNone == error && (m_pendingChanges && Rotation) && m_displayWindow && m_videoOutputDisplay) {
+ const TVideoRotation rotation = videoRotation(m_videoOutputDisplay->rotation());
+#ifdef VIDEOOUTPUT_GRAPHICS_SURFACES
+ TRAP(error, m_player->SetRotationL(*m_displayWindow, rotation));
+#else
+ TRAP(error, m_player->SetRotationL(rotation));
+#endif // VIDEOOUTPUT_GRAPHICS_SURFACES
+ m_pendingChanges ^= Rotation;
+ }
+ setError(error);
+ }
+
+ DP0("S60VideoPlayerSession::applyPendingChanges ---");
+}
+
+/*!
+ * \return TRUE if video is available.
+*/
+
+bool S60VideoPlayerSession::isVideoAvailable()
+{
+ DP0("S60VideoPlayerSession::isVideoAvailable");
+
+#ifdef PRE_S60_50_PLATFORM
+ return true; // this is not supported in pre 5th platforms
+#else
+ if ( mediaStatus() == QMediaPlayer::LoadingMedia
+ || mediaStatus() == QMediaPlayer::UnknownMediaStatus
+ || mediaStatus() == QMediaPlayer::NoMedia
+ || (mediaStatus() == QMediaPlayer::StalledMedia && state() == QMediaPlayer::StoppedState)
+ || mediaStatus() == QMediaPlayer::InvalidMedia)
+ return false;
+
+ if (m_player) {
+ bool videoAvailable = false;
+ TRAPD(err, videoAvailable = m_player->VideoEnabledL());
+ setError(err);
+ return videoAvailable;
+ } else {
+ return false;
+ }
+#endif
+
+}
+
+/*!
+ * \return TRUE if Audio available.
+*/
+
+bool S60VideoPlayerSession::isAudioAvailable()
+{
+ DP0("S60VideoPlayerSession::isAudioAvailable");
+
+ if ( mediaStatus() == QMediaPlayer::LoadingMedia
+ || mediaStatus() == QMediaPlayer::UnknownMediaStatus
+ || mediaStatus() == QMediaPlayer::NoMedia
+ || (mediaStatus() == QMediaPlayer::StalledMedia && state() == QMediaPlayer::StoppedState)
+ || mediaStatus() == QMediaPlayer::InvalidMedia)
+ return false;
+
+ if (m_player) {
+ bool audioAvailable = false;
+ TRAPD(err, audioAvailable = m_player->AudioEnabledL());
+ setError(err);
+ return audioAvailable;
+ } else {
+ return false;
+ }
+}
+
+/*!
+ Start or resume playing the current source.
+*/
+
+void S60VideoPlayerSession::doPlay()
+{
+ DP0("S60VideoPlayerSession::doPlay +++");
+
+ m_player->Play();
+
+ DP0("S60VideoPlayerSession::doPlay ---");
+}
+
+/*!
+ Pause playing the current source.
+*/
+
+void S60VideoPlayerSession::doPauseL()
+{
+ DP0("S60VideoPlayerSession::doPauseL +++");
+
+ m_player->PauseL();
+
+ DP0("S60VideoPlayerSession::doPauseL ---");
+}
+
+/*!
+
+ Stop playing, and reset the play position to the beginning.
+*/
+
+void S60VideoPlayerSession::doStop()
+{
+ DP0("S60VideoPlayerSession::doStop +++");
+
+ if (m_stream)
+ m_networkAccessControl->resetIndex();
+
+ m_player->Stop();
+
+ DP0("S60VideoPlayerSession::doStop ---");
+}
+
+/*!
+ Closes the current audio clip (allowing another clip to be opened)
+*/
+
+void S60VideoPlayerSession::doClose()
+{
+ DP0("S60VideoPlayerSession::doClose +++");
+
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ if (m_audioOutput) {
+ m_audioOutput->UnregisterObserver(*this);
+ delete m_audioOutput;
+ m_audioOutput = NULL;
+ }
+#endif
+
+ m_player->Close();
+
+// close will remove the window handle in media clint video.
+// So mark it in pending changes.
+ m_pendingChanges |= WindowHandle;
+
+ DP0("S60VideoPlayerSession::doClose ---");
+}
+
+/*!
+ * Returns the current playback position in microseconds from the start of the clip.
+
+*/
+
+qint64 S60VideoPlayerSession::doGetPositionL() const
+{
+ // DP0("S60VideoPlayerSession::doGetPositionL");
+
+ return m_player->PositionL().Int64() / qint64(1000);
+}
+
+/*!
+ Sets the current playback position to \a microSeconds from the start of the clip.
+*/
+
+void S60VideoPlayerSession::doSetPositionL(qint64 microSeconds)
+{
+ // DP0("S60VideoPlayerSession::doSetPositionL");
+
+ m_player->SetPositionL(TTimeIntervalMicroSeconds(microSeconds));
+}
+
+/*!
+
+ Changes the current playback volume to specified \a value.
+*/
+
+void S60VideoPlayerSession::doSetVolumeL(int volume)
+{
+ DP0("S60VideoPlayerSession::doSetVolumeL +++");
+
+ DP1("S60VideoPlayerSession::doSetVolumeL - ", volume);
+
+ m_player->SetVolumeL(volume * m_player->MaxVolume() / 100);
+
+ DP0("S60VideoPlayerSession::doSetVolumeL ---");
+}
+
+/*!
+ * Notification to the client that the opening of the video clip has completed.
+ * If successful then an \a aError will be ZERO else system wide error.
+*/
+
+void S60VideoPlayerSession::MvpuoOpenComplete(TInt aError)
+{
+ DP0("S60VideoPlayerSession::MvpuoOpenComplete +++");
+
+ DP1("S60VideoPlayerSession::MvpuoOpenComplete - aError:", aError);
+
+ setError(aError);
+#ifdef HTTP_COOKIES_ENABLED
+ if (KErrNone == aError) {
+ TInt err(KErrNone);
+ const QByteArray userAgentString("User-Agent");
+ TInt uasize = m_source.canonicalRequest().rawHeader(userAgentString).size();
+ TPtrC8 userAgent((const unsigned char*)(m_source.canonicalRequest().rawHeader(userAgentString).constData()), uasize);
+ if (userAgent.Length()) {
+ err = m_player->CustomCommandSync(m_destinationPckg, EMMFSetSessionInfo, _L8("User-Agent"), userAgent);
+ if (err != KErrNone) {
+ setError(err);
+ return;
+ }
+ }
+ const QByteArray refererString("Referer");
+ TInt refsize = m_source.canonicalRequest().rawHeader(refererString).size();
+ TPtrC8 referer((const unsigned char*)m_source.canonicalRequest().rawHeader(refererString).constData(),refsize);
+ if (referer.Length()) {
+ err = m_player->CustomCommandSync(m_destinationPckg, EMMFSetSessionInfo, _L8("Referer"), referer);
+ if (err != KErrNone) {
+ setError(err);
+ return;
+ }
+ }
+ const QByteArray cookieString("Cookie");
+ TInt cksize = m_source.canonicalRequest().rawHeader(cookieString).size();
+ TPtrC8 cookie((const unsigned char*)m_source.canonicalRequest().rawHeader(cookieString).constData(),cksize);
+ if (cookie.Length()) {
+ err = m_player->CustomCommandSync(m_destinationPckg, EMMFSetSessionInfo, _L8("Cookie"), cookie);
+ if (err != KErrNone) {
+ setError(err);
+ return;
+ }
+ }
+ m_player->Prepare();
+ }
+#else
+ if (KErrNone == aError)
+ m_player->Prepare();
+#endif
+ const TMMFMessageDestinationPckg dest( KUidInterfaceMMFROPController );
+ TRAP_IGNORE(m_player->CustomCommandSync(dest, KMMFROPControllerEnablePausedLoadingStatus, KNullDesC8, KNullDesC8));
+
+ DP0("S60VideoPlayerSession::MvpuoOpenComplete ---");
+}
+
+/*!
+ * Notification to the client that the opening of the video clip has been preapred.
+ * If successful then an \a aError will be ZERO else system wide error.
+*/
+
+void S60VideoPlayerSession::MvpuoPrepareComplete(TInt aError)
+{
+ DP0("S60VideoPlayerSession::MvpuoPrepareComplete +++");
+
+ DP1("S60VideoPlayerSession::MvpuoPrepareComplete - aError:", aError);
+
+ if (KErrNone == aError && m_stream) {
+ emit accessPointChanged(m_accessPointId);
+ }
+ if (KErrCouldNotConnect == aError && !(m_networkAccessControl->isLastAccessPoint())) {
+ load(m_source);
+ return;
+ }
+ TInt error = aError;
+ if (KErrNone == error || KErrMMPartialPlayback == error) {
+ TSize originalSize;
+ TRAP(error, m_player->VideoFrameSizeL(originalSize));
+ if (KErrNone == error) {
+ m_nativeSize = QSize(originalSize.iWidth, originalSize.iHeight);
+ emit nativeSizeChanged(m_nativeSize);
+ m_pendingChanges |= ScaleFactors;
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ Q_ASSERT(!m_audioOutput);
+ TRAP(error, m_audioOutput = CAudioOutput::NewL(*m_player));
+ if (KErrNone == error) {
+ TRAP(error, m_audioOutput->RegisterObserverL(*this));
+ if (KErrNone == error)
+ setActiveEndpoint(m_audioEndpoint);
+ }
+#endif
+ }
+ if (KErrNone == error) {
+ applyPendingChanges(true); // force apply even though state is not Loaded
+ if (KErrNone == this->error()) // applyPendingChanges() can call setError()
+ loaded();
+ }
+ } else {
+ setError(error);
+ }
+
+ DP0("S60VideoPlayerSession::MvpuoPrepareComplete ---");
+}
+
+/*!
+ * Notification that frame requested by a call to GetFrameL is ready.
+*/
+
+void S60VideoPlayerSession::MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError)
+{
+ DP0("S60VideoPlayerSession::MvpuoFrameReady +++");
+
+ Q_UNUSED(aFrame);
+ Q_UNUSED(aError);
+
+ DP0("S60VideoPlayerSession::MvpuoFrameReady ---");
+}
+
+/*!
+ * Notification that video playback has completed.
+ * If successful then \a aError will be ZERO else system wide error.
+ * This not called if playback is explicitly stopped by calling stop.
+*/
+
+void S60VideoPlayerSession::MvpuoPlayComplete(TInt aError)
+{
+ DP0("S60VideoPlayerSession::MvpuoPlayComplete +++");
+
+ DP1("S60VideoPlayerSession::MvpuoPlayComplete - aError", aError);
+
+ if (m_stream)
+ m_networkAccessControl->resetIndex();
+
+ if (aError != KErrNone) {
+ setError(aError);
+ doClose();
+ } else {
+ endOfMedia();
+ }
+
+ DP0("S60VideoPlayerSession::MvpuoPlayComplete ---");
+}
+
+
+/*!
+ * General \a event notification from controller.
+ * These events are specified by the supplier of the controller.
+*/
+
+void S60VideoPlayerSession::MvpuoEvent(const TMMFEvent &aEvent)
+{
+ DP0("S60VideoPlayerSession::MvpuoEvent +++");
+
+ Q_UNUSED(aEvent);
+
+ DP0("S60VideoPlayerSession::MvpuoEvent ---");
+}
+
+/*!
+
+ Updates meta data entries in the current video clip.
+*/
+
+void S60VideoPlayerSession::updateMetaDataEntriesL()
+{
+ DP0("S60VideoPlayerSession::updateMetaDataEntriesL +++");
+
+ metaDataEntries().clear();
+ int numberOfMetaDataEntries = 0;
+ numberOfMetaDataEntries = m_player->NumberOfMetaDataEntriesL();
+ for (int i = 0; i < numberOfMetaDataEntries; i++) {
+ CMMFMetaDataEntry *entry = NULL;
+ entry = m_player->MetaDataEntryL(i);
+ metaDataEntries().insert(TDesC2QString(entry->Name()), TDesC2QString(entry->Value()));
+ delete entry;
+ }
+ emit metaDataChanged();
+
+ DP0("S60VideoPlayerSession::updateMetaDataEntriesL ---");
+}
+
+/*!
+ * Apply the window changes when window handle changes.
+*/
+
+void S60VideoPlayerSession::windowHandleChanged()
+{
+ DP0("S60VideoPlayerSession::windowHandleChanged +++");
+
+ m_pendingChanges |= WindowHandle;
+ applyPendingChanges();
+
+ DP0("S60VideoPlayerSession::windowHandleChanged ---");
+}
+
+/*!
+ * Apply the window changes when display Rect changes.
+*/
+
+void S60VideoPlayerSession::displayRectChanged()
+{
+ DP0("S60VideoPlayerSession::displayRectChanged +++");
+
+ m_pendingChanges |= DisplayRect;
+ applyPendingChanges();
+
+ DP0("S60VideoPlayerSession::displayRectChanged ---");
+}
+
+/*!
+ * Apply the window changes when aspect Ratio changes.
+*/
+
+void S60VideoPlayerSession::aspectRatioChanged()
+{
+ DP0("S60VideoPlayerSession::aspectRatioChanged +++");
+
+ m_pendingChanges |= ScaleFactors;
+ applyPendingChanges();
+
+ DP0("S60VideoPlayerSession::aspectRatioChanged ---");
+}
+
+void S60VideoPlayerSession::rotationChanged()
+{
+ m_pendingChanges |= ScaleFactors;
+ m_pendingChanges |= Rotation;
+ applyPendingChanges();
+}
+
+#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES
+void S60VideoPlayerSession::suspendDirectScreenAccess()
+{
+ DP0("S60VideoPlayerSession::suspendDirectScreenAccess +++");
+
+ m_dsaStopped = stopDirectScreenAccess();
+
+ DP0("S60VideoPlayerSession::suspendDirectScreenAccess ---");
+}
+
+void S60VideoPlayerSession::resumeDirectScreenAccess()
+{
+ DP0("S60VideoPlayerSession::resumeDirectScreenAccess +++");
+
+ if (!m_dsaStopped)
+ return;
+ startDirectScreenAccess();
+ m_dsaStopped = false;
+
+ DP0("S60VideoPlayerSession::resumeDirectScreenAccess ---");
+}
+
+void S60VideoPlayerSession::startDirectScreenAccess()
+{
+ DP0("S60VideoPlayerSession::startDirectScreenAccess +++");
+
+ if (m_dsaActive)
+ return;
+ TRAPD(err, m_player->StartDirectScreenAccessL());
+ if (err == KErrNone)
+ m_dsaActive = true;
+ setError(err);
+
+ DP0("S60VideoPlayerSession::startDirectScreenAccess ---");
+}
+
+bool S60VideoPlayerSession::stopDirectScreenAccess()
+{
+ DP0("S60VideoPlayerSession::stopDirectScreenAccess");
+
+ if (!m_dsaActive)
+ return false;
+ TRAPD(err, m_player->StopDirectScreenAccessL());
+ if (err == KErrNone)
+ m_dsaActive = false;
+ setError(err);
+ return true;
+}
+#endif
+
+/*!
+ * The percentage of the temporary buffer filling before playback begins.
+*/
+
+void S60VideoPlayerSession::MvloLoadingStarted()
+{
+ DP0("S60VideoPlayerSession::MvloLoadingStarted +++");
+
+ buffering();
+
+ DP0("S60VideoPlayerSession::MvloLoadingStarted ---");
+}
+
+/*!
+ * Buffer is filled with data and to for continuing/start playback.
+*/
+
+void S60VideoPlayerSession::MvloLoadingComplete()
+{
+ DP0("S60VideoPlayerSession::MvloLoadingComplete +++");
+
+ buffered();
+
+ DP0("S60VideoPlayerSession::MvloLoadingComplete ---");
+}
+
+/*!
+ Defiens which Audio End point to use.
+
+ \a audioEndpoint audioEndpoint name.
+*/
+
+void S60VideoPlayerSession::doSetAudioEndpoint(const QString& audioEndpoint)
+{
+ DP0("S60VideoPlayerSession::doSetAudioEndpoint +++");
+
+ DP1("S60VideoPlayerSession::doSetAudioEndpoint - ", audioEndpoint);
+
+ m_audioEndpoint = audioEndpoint;
+
+ DP0("S60VideoPlayerSession::doSetAudioEndpoint ---");
+}
+
+/*!
+
+ Returns audioEndpoint name.
+*/
+
+QString S60VideoPlayerSession::activeEndpoint() const
+{
+ DP0("S60VideoPlayerSession::activeEndpoint +++");
+
+ QString outputName = m_audioEndpoint;
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ if (m_audioOutput) {
+ CAudioOutput::TAudioOutputPreference output = m_audioOutput->AudioOutput();
+ outputName = qStringFromTAudioOutputPreference(output);
+ }
+#endif
+
+ DP1("S60VideoPlayerSession::activeEndpoint- outputName:", outputName);
+ DP0("S60VideoPlayerSession::activeEndpoint ---");
+ return outputName;
+}
+
+/*!
+ * Returns default Audio End point in use.
+*/
+
+QString S60VideoPlayerSession::defaultEndpoint() const
+{
+ DP0("S60VideoPlayerSession::defaultEndpoint +++");
+
+ QString outputName = DefaultAudioEndpoint;
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ if (m_audioOutput) {
+ CAudioOutput::TAudioOutputPreference output = m_audioOutput->DefaultAudioOutput();
+ outputName = qStringFromTAudioOutputPreference(output);
+ }
+#endif
+
+ DP1("S60VideoPlayerSession::defaultEndpoint, outputName:", outputName);
+ DP0("S60VideoPlayerSession::defaultEndpoint ---");
+
+ return outputName;
+}
+
+/*!
+ Sets active end \a name as an Audio End point.
+*/
+
+void S60VideoPlayerSession::setActiveEndpoint(const QString& name)
+{
+ DP0("S60VideoPlayerSession::setActiveEndpoint +++");
+
+ DP1("S60VideoPlayerSession::setActiveEndpoint - ", name);
+
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ CAudioOutput::TAudioOutputPreference output = CAudioOutput::ENoPreference;
+ if (name == DefaultAudioEndpoint)
+ output = CAudioOutput::ENoPreference;
+ else if (name == QString("All"))
+ output = CAudioOutput::EAll;
+ else if (name == QString("None"))
+ output = CAudioOutput::ENoOutput;
+ else if (name == QString("Earphone"))
+ output = CAudioOutput::EPrivate;
+ else if (name == QString("Speaker"))
+ output = CAudioOutput::EPublic;
+ if (m_audioOutput) {
+ TRAPD(err, m_audioOutput->SetAudioOutputL(output));
+ setError(err);
+ }
+#endif
+
+ DP0("S60VideoPlayerSession::setActiveEndpoint ---");
+}
+
+/*!
+ The default Audio output has been changed.
+
+ \a aAudioOutput Audio Output object.
+
+ \a aNewDefault is CAudioOutput::TAudioOutputPreference.
+*/
+
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+void S60VideoPlayerSession::DefaultAudioOutputChanged( CAudioOutput& aAudioOutput,
+ CAudioOutput::TAudioOutputPreference aNewDefault)
+{
+ DP0("S60VideoPlayerSession::DefaultAudioOutputChanged +++");
+
+ // Emit already implemented in setActiveEndpoint function
+ Q_UNUSED(aAudioOutput)
+ Q_UNUSED(aNewDefault)
+
+ DP0("S60VideoPlayerSession::DefaultAudioOutputChanged ---");
+}
+
+/*!
+ * \return CAudioOutput::ENoOutput by converting it to QString.
+*/
+
+QString S60VideoPlayerSession::qStringFromTAudioOutputPreference(CAudioOutput::TAudioOutputPreference output) const
+{
+ DP0("S60VideoPlayerSession::qStringFromTAudioOutputPreference");
+
+ if (output == CAudioOutput::ENoPreference)
+ return QString("Default");
+ else if (output == CAudioOutput::EAll)
+ return QString("All");
+ else if (output == CAudioOutput::ENoOutput)
+ return QString("None");
+ else if (output == CAudioOutput::EPrivate)
+ return QString("Earphone");
+ else if (output == CAudioOutput::EPublic)
+ return QString("Speaker");
+ return QString("Default");
+}
+#endif //HAS_AUDIOROUTING_IN_VIDEOPLAYER)
+
+/*!
+ * \return TRUE if video is Seekable else FALSE.
+*/
+
+bool S60VideoPlayerSession::getIsSeekable() const
+{
+ DP0("S60VideoPlayerSession::getIsSeekable +++");
+
+ bool seekable = ETrue;
+ int numberOfMetaDataEntries = 0;
+
+ TRAPD(err, numberOfMetaDataEntries = m_player->NumberOfMetaDataEntriesL());
+ if (err)
+ return seekable;
+
+ for (int i = 0; i < numberOfMetaDataEntries; i++) {
+ CMMFMetaDataEntry *entry = NULL;
+ TRAP(err, entry = m_player->MetaDataEntryL(i));
+
+ if (err)
+ return seekable;
+
+ if (!entry->Name().Compare(KSeekable)) {
+ if (!entry->Value().Compare(KFalse))
+ seekable = EFalse;
+ break;
+ }
+ }
+ DP0("S60VideoPlayerSession::getIsSeekable ---");
+
+ return seekable;
+}
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60videoplayersession.h b/src/plugins/symbian/mmf/mediaplayer/s60videoplayersession.h
new file mode 100644
index 000000000..f73683af8
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60videoplayersession.h
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEOPLAYERSESSION_H
+#define S60VIDEOPLAYERSESSION_H
+
+#include "s60mediaplayersession.h"
+#include "s60mediaplayeraudioendpointselector.h"
+#include "s60medianetworkaccesscontrol.h"
+#include "s60videodisplay.h"
+
+#ifdef VIDEOOUTPUT_GRAPHICS_SURFACES
+#include <videoplayer2.h>
+#else
+#include <videoplayer.h>
+#endif // VIDEOOUTPUT_GRAPHICS_SURFACES
+
+#include <QtCore/QCoreApplication>
+#include <QtGui/qwidget.h>
+#include <qvideowidget.h>
+
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+#include <AudioOutput.h>
+#include <MAudioOutputObserver.h>
+#endif // HAS_AUDIOROUTING_IN_VIDEOPLAYER
+
+class QTimer;
+class S60MediaNetworkAccessControl;
+class S60VideoDisplay;
+
+// Helper classes to pass Symbian events from WServ to the S60VideoPlayerSession
+// so it can control video player on certain events if required
+
+class ApplicationFocusObserver
+{
+public:
+ virtual void applicationGainedFocus() = 0;
+ virtual void applicationLostFocus() = 0;
+};
+
+class S60VideoPlayerEventHandler : public QObject
+{
+public:
+ static S60VideoPlayerEventHandler *instance();
+ static bool filterEvent(void *message, long *result);
+ void addApplicationFocusObserver(ApplicationFocusObserver* observer);
+ void removeApplicationFocusObserver(ApplicationFocusObserver* observer);
+private:
+ S60VideoPlayerEventHandler();
+ ~S60VideoPlayerEventHandler();
+private:
+ static S60VideoPlayerEventHandler *m_instance;
+ static QList<ApplicationFocusObserver *> m_applicationFocusObservers;
+ static QCoreApplication::EventFilter m_eventFilter;
+};
+
+class S60VideoPlayerSession : public S60MediaPlayerSession
+ , public MVideoPlayerUtilityObserver
+ , public MVideoLoadingObserver
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ , public MAudioOutputObserver
+#endif // HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ , public ApplicationFocusObserver
+{
+ Q_OBJECT
+public:
+ S60VideoPlayerSession(QMediaService *service, S60MediaNetworkAccessControl *object);
+ ~S60VideoPlayerSession();
+
+ // From S60MediaPlayerSession
+ bool isVideoAvailable();
+ bool isAudioAvailable();
+ void setVideoRenderer(QObject *renderer);
+
+ // From MVideoLoadingObserver
+ void MvloLoadingStarted();
+ void MvloLoadingComplete();
+ void setPlaybackRate(qreal rate);
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ // From MAudioOutputObserver
+ void DefaultAudioOutputChanged(CAudioOutput& aAudioOutput,
+ CAudioOutput::TAudioOutputPreference aNewDefault);
+#endif
+
+ // From S60MediaPlayerAudioEndpointSelector
+ QString activeEndpoint() const;
+ QString defaultEndpoint() const;
+
+ // ApplicationFocusObserver
+ void applicationGainedFocus();
+ void applicationLostFocus();
+
+signals:
+ void nativeSizeChanged(QSize);
+
+public Q_SLOTS:
+ void setActiveEndpoint(const QString& name);
+
+signals:
+ void accessPointChanged(int);
+
+protected:
+ // From S60MediaPlayerSession
+ void doLoadL(const TDesC &path);
+ void doLoadUrlL(const TDesC &path);
+ void doPlay();
+ void doStop();
+ void doClose();
+ void doPauseL();
+ void doSetVolumeL(int volume);
+ qint64 doGetPositionL() const;
+ void doSetPositionL(qint64 microSeconds);
+ void updateMetaDataEntriesL();
+ int doGetBufferStatusL() const;
+ qint64 doGetDurationL() const;
+ void doSetAudioEndpoint(const QString& audioEndpoint);
+ bool getIsSeekable() const;
+
+private slots:
+ void windowHandleChanged();
+ void displayRectChanged();
+ void aspectRatioChanged();
+ void rotationChanged();
+#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES
+ void suspendDirectScreenAccess();
+ void resumeDirectScreenAccess();
+#endif
+
+private:
+ void applyPendingChanges(bool force = false);
+#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES
+ void startDirectScreenAccess();
+ bool stopDirectScreenAccess();
+#endif
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ QString qStringFromTAudioOutputPreference(CAudioOutput::TAudioOutputPreference output) const;
+#endif
+
+ // From MVideoPlayerUtilityObserver
+ void MvpuoOpenComplete(TInt aError);
+ void MvpuoPrepareComplete(TInt aError);
+ void MvpuoFrameReady(CFbsBitmap &aFrame, TInt aError);
+ void MvpuoPlayComplete(TInt aError);
+ void MvpuoEvent(const TMMFEvent &aEvent);
+
+private:
+ int m_accessPointId;
+ S60MediaNetworkAccessControl* m_networkAccessControl;
+ RWsSession *const m_wsSession;
+ CWsScreenDevice *const m_screenDevice;
+ QMediaService *const m_service;
+#ifdef VIDEOOUTPUT_GRAPHICS_SURFACES
+ CVideoPlayerUtility2 *m_player;
+#else
+ CVideoPlayerUtility *m_player;
+ bool m_dsaActive;
+ bool m_dsaStopped;
+#endif // VIDEOOUTPUT_GRAPHICS_SURFACES
+ QObject *m_videoOutputControl;
+ S60VideoDisplay *m_videoOutputDisplay;
+ RWindow *m_displayWindow;
+ QSize m_nativeSize;
+#ifdef HTTP_COOKIES_ENABLED
+ TMMFMessageDestinationPckg m_destinationPckg;
+#endif
+#ifdef HAS_AUDIOROUTING_IN_VIDEOPLAYER
+ CAudioOutput *m_audioOutput;
+#endif
+ QString m_audioEndpoint;
+ enum Parameter {
+ WindowHandle = 0x1,
+ DisplayRect = 0x2,
+ ScaleFactors = 0x4,
+ Rotation = 0x8
+ };
+ QFlags<Parameter> m_pendingChanges;
+ bool m_backendInitiatedPause;
+};
+
+#endif
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60videorenderer.cpp b/src/plugins/symbian/mmf/mediaplayer/s60videorenderer.cpp
new file mode 100644
index 000000000..2de6896a0
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60videorenderer.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60videorenderer.h"
+
+#include <QtCore/qcoreevent.h>
+#include <QtGui/qapplication.h>
+
+/*!
+ Constructs a new video renderer media end point with the given \a parent.
+*/
+
+S60VideoRenderer::S60VideoRenderer(QObject *parent)
+ : QVideoRendererControl(parent)
+{
+ DP0("S60VideoRenderer::S60VideoRenderer +++");
+
+ DP0("S60VideoRenderer::S60VideoRenderer ---");
+
+}
+
+/*!
+ Destroys a video renderer media end point.
+*/
+
+S60VideoRenderer::~S60VideoRenderer()
+{
+ DP0("S60VideoRenderer::~S60VideoRenderer +++");
+ DP0("S60VideoRenderer::~S60VideoRenderer ---");
+}
+
+/*!
+ \return the surface a video producer renders to.
+*/
+
+QAbstractVideoSurface *S60VideoRenderer::surface() const
+{
+ DP0("S60VideoRenderer::surface");
+
+ return m_surface;
+}
+
+/*!
+ Sets the \a surface a video producer renders to.
+*/
+
+void S60VideoRenderer::setSurface(QAbstractVideoSurface *surface)
+{
+ DP0("S60VideoRenderer::setSurface +++");
+
+ m_surface = surface;
+
+ DP0("S60VideoRenderer::setSurface ---");
+}
+
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60videorenderer.h b/src/plugins/symbian/mmf/mediaplayer/s60videorenderer.h
new file mode 100644
index 000000000..6e90d42c3
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60videorenderer.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEORENDERER_H
+#define S60VIDEORENDERER_H
+
+#include <QtCore/qobject.h>
+#include <qvideorenderercontrol.h>
+
+QT_USE_NAMESPACE
+
+class S60VideoRenderer : public QVideoRendererControl
+{
+ Q_OBJECT
+
+public:
+ S60VideoRenderer(QObject *parent = 0);
+ virtual ~S60VideoRenderer();
+
+ QAbstractVideoSurface *surface() const;
+ void setSurface(QAbstractVideoSurface *surface);
+
+private:
+
+ QAbstractVideoSurface *m_surface;
+};
+
+#endif // S60VIDEORENDERER_H
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60videosurface.cpp b/src/plugins/symbian/mmf/mediaplayer/s60videosurface.cpp
new file mode 100644
index 000000000..563d33b40
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60videosurface.cpp
@@ -0,0 +1,372 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include <qvideosurfaceformat.h>
+
+#include "s60videosurface.h"
+/*!
+ * Constructs a video surface with the given \a parent.
+*/
+
+S60VideoSurface::S60VideoSurface(QObject *parent)
+ : QAbstractVideoSurface(parent)
+ , m_winId(0)
+{
+ DP0("S60VideoSurface::S60VideoSurface +++");
+ DP0("S60VideoSurface::S60VideoSurface ---");
+}
+
+/*!
+ * Destroys video surface.
+*/
+
+S60VideoSurface::~S60VideoSurface()
+{
+ DP0("S60VideoSurface::~S60VideoSurface +++");
+ DP0("S60VideoSurface::~S60VideoSurface ---");
+}
+
+/*!
+ \return the ID of the window a video surface end point renders to.
+*/
+
+WId S60VideoSurface::winId() const
+{
+ DP0("S60VideoSurface::winId");
+
+ return m_winId;
+}
+
+/*!
+ Sets the \a id of the window a video surface end point renders to.
+*/
+
+void S60VideoSurface::setWinId(WId id)
+{
+ DP0("S60VideoSurface::setWinId +++");
+
+ m_winId = id;
+
+ DP0("S60VideoSurface::setWinId ---");
+}
+
+/*!
+ \return the sub-rect of a window where video is displayed.
+*/
+
+QRect S60VideoSurface::displayRect() const
+{
+ DP0("S60VideoSurface::displayRect");
+
+ return m_displayRect;
+}
+
+/*!
+ Sets the sub-\a rect of a window where video is displayed.
+*/
+
+void S60VideoSurface::setDisplayRect(const QRect &rect)
+{
+ DP0("S60VideoSurface::setDisplayRect +++");
+
+ m_displayRect = rect;
+
+ DP0("S60VideoSurface::setDisplayRect ---");
+}
+
+/*!
+ \return the brightness adjustment applied to a video surface.
+
+ Valid brightness values range between -100 and 100, the default is 0.
+*/
+
+int S60VideoSurface::brightness() const
+{
+ DP0("S60VideoSurface::brightness");
+
+ return 0;
+}
+
+/*!
+ Sets a \a brightness adjustment for a video surface.
+
+ Valid brightness values range between -100 and 100, the default is 0.
+*/
+
+void S60VideoSurface::setBrightness(int brightness)
+{
+ DP0("S60VideoSurface::setBrightness +++");
+
+ DP1("S60VideoSurface::setBrightness - brightness:", brightness);
+
+ Q_UNUSED(brightness);
+
+ DP0("S60VideoSurface::setBrightness ---");
+}
+
+/*!
+ \return the contrast adjustment applied to a video surface.
+
+ Valid contrast values range between -100 and 100, the default is 0.
+*/
+
+int S60VideoSurface::contrast() const
+{
+ DP0("S60VideoSurface::contrast");
+
+ return 0;
+}
+
+/*!
+ Sets the \a contrast adjustment for a video surface.
+
+ Valid contrast values range between -100 and 100, the default is 0.
+*/
+
+void S60VideoSurface::setContrast(int contrast)
+{
+ DP0("S60VideoSurface::setContrast +++");
+
+ DP1("S60VideoSurface::setContrast - ", contrast);
+
+ Q_UNUSED(contrast);
+
+ DP0("S60VideoSurface::setContrast ---");
+}
+
+/*!
+ \return the hue adjustment applied to a video surface.
+
+ Value hue values range between -100 and 100, the default is 0.
+*/
+
+int S60VideoSurface::hue() const
+{
+ DP0("S60VideoSurface::hue");
+
+ return 0;
+}
+
+/*!
+ Sets a \a hue adjustment for a video surface.
+
+ Valid hue values range between -100 and 100, the default is 0.
+*/
+
+void S60VideoSurface::setHue(int hue)
+{
+ DP0("S60VideoSurface::setHue +++");
+
+ DP1("S60VideoSurface::setHue - ", hue);
+
+ Q_UNUSED(hue);
+
+ DP0("S60VideoSurface::setHue ---");
+}
+
+/*!
+ \return the saturation adjustment applied to a video surface.
+
+ Value saturation values range between -100 and 100, the default is 0.
+*/
+
+int S60VideoSurface::saturation() const
+{
+ DP0("S60VideoSurface::saturation");
+
+ return 0;
+}
+
+/*!
+ Sets a \a saturation adjustment for a video surface.
+
+ Valid saturation values range between -100 and 100, the default is 0.
+*/
+
+void S60VideoSurface::setSaturation(int saturation)
+{
+ DP0("S60VideoSurface::setSaturation +++");
+
+ DP1("S60VideoSurface::setSaturation - ", saturation);
+
+ Q_UNUSED(saturation);
+
+ DP0("S60VideoSurface::setSaturation ---");
+}
+
+/*!
+ * \return ZERO. \a attribute, \a minimum, \a maximum are not used.
+*/
+int S60VideoSurface::getAttribute(const char *attribute, int minimum, int maximum) const
+{
+ DP0("S60VideoSurface::getAttribute +++");
+
+ Q_UNUSED(attribute);
+ Q_UNUSED(minimum);
+ Q_UNUSED(maximum);
+
+ DP0("S60VideoSurface::getAttribute ---");
+
+ return 0;
+}
+
+/*!
+ * Sets the \a attribute, \a minimum, \a maximum.
+ * But never used.
+*/
+
+void S60VideoSurface::setAttribute(const char *attribute, int value, int minimum, int maximum)
+{
+ DP0("S60VideoSurface::setAttribute +++");
+
+ Q_UNUSED(attribute);
+ Q_UNUSED(value);
+ Q_UNUSED(minimum);
+ Q_UNUSED(maximum);
+
+ DP0("S60VideoSurface::setAttribute ---");
+
+}
+
+/*!
+ * \return ZERO.
+ * \a value, \a fromLower, \a fromUpper, \a toLower, \a toUpper are never used.
+*/
+
+int S60VideoSurface::redistribute(
+ int value, int fromLower, int fromUpper, int toLower, int toUpper)
+{
+ DP0("S60VideoSurface::redistribute +++");
+
+ Q_UNUSED(value);
+ Q_UNUSED(fromLower);
+ Q_UNUSED(fromUpper);
+ Q_UNUSED(toLower);
+ Q_UNUSED(toUpper);
+
+ DP0("S60VideoSurface::redistribute ---");
+
+ return 0;
+}
+
+/*!
+ * \return List of video surface supported Pixel Formats.
+*/
+
+QList<QVideoFrame::PixelFormat> S60VideoSurface::supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType) const
+{
+ DP0("S60VideoSurface::supportedPixelFormats +++");
+
+ Q_UNUSED(handleType);
+ QList<QVideoFrame::PixelFormat> list;
+
+ DP0("S60VideoSurface::supportedPixelFormats ---");
+
+ return list;
+}
+
+/*!
+ * \return always FALSE, as \a format never used.
+*/
+
+bool S60VideoSurface::start(const QVideoSurfaceFormat &format)
+{
+ DP0("S60VideoSurface::start");
+
+ Q_UNUSED(format);
+ return false;
+}
+
+/*!
+ * Stops video surface.
+*/
+void S60VideoSurface::stop()
+{
+ DP0("S60VideoSurface::stop +++");
+
+ DP0("S60VideoSurface::stop ---");
+
+}
+
+/*!
+ * \return always FALS, as \a format is never used.
+*/
+bool S60VideoSurface::present(const QVideoFrame &frame)
+{
+ DP0("S60VideoSurface::present");
+
+ Q_UNUSED(frame);
+ return false;
+}
+
+/*!
+ * \return always FALSE.
+*/
+
+bool S60VideoSurface::findPort()
+{
+ DP0("S60VideoSurface::findPort");
+
+ return false;
+}
+
+void S60VideoSurface::querySupportedFormats()
+{
+ DP0("S60VideoSurface::querySupportedFormats +++");
+
+ DP0("S60VideoSurface::querySupportedFormats ---");
+
+}
+
+/*!
+ * \return always FLASE, as \a format never used.
+*/
+
+bool S60VideoSurface::isFormatSupported(const QVideoSurfaceFormat &format) const
+{
+ DP0("S60VideoSurface::isFormatSupported");
+
+ Q_UNUSED(format);
+ return false;
+}
diff --git a/src/plugins/symbian/mmf/mediaplayer/s60videosurface.h b/src/plugins/symbian/mmf/mediaplayer/s60videosurface.h
new file mode 100644
index 000000000..9f13755b7
--- /dev/null
+++ b/src/plugins/symbian/mmf/mediaplayer/s60videosurface.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEOSURFACE_H
+#define S60VIDEOSURFACE_H
+
+#include <QtGui/qwidget.h>
+#include <qabstractvideosurface.h>
+
+class S60VideoSurface : public QAbstractVideoSurface
+{
+ Q_OBJECT
+public:
+ S60VideoSurface(QObject *parent = 0);
+ ~S60VideoSurface();
+
+ WId winId() const;
+ void setWinId(WId id);
+
+ QRect displayRect() const;
+ void setDisplayRect(const QRect &rect);
+
+ int brightness() const;
+ void setBrightness(int brightness);
+
+ int contrast() const;
+ void setContrast(int contrast);
+
+ int hue() const;
+ void setHue(int hue);
+
+ int saturation() const;
+ void setSaturation(int saturation);
+
+ QList<QVideoFrame::PixelFormat> supportedPixelFormats(
+ QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const;
+
+ bool isFormatSupported(const QVideoSurfaceFormat &format) const;
+
+ bool start(const QVideoSurfaceFormat &format);
+ void stop();
+
+ bool present(const QVideoFrame &frame);
+
+private:
+ WId m_winId;
+ //XvPortID m_portId;
+ //GC m_gc;
+ //XvImage *m_image;
+ QList<QVideoFrame::PixelFormat> m_supportedPixelFormats;
+ QVector<int> m_formatIds;
+ QRect m_viewport;
+ QRect m_displayRect;
+ QPair<int, int> m_brightnessRange;
+ QPair<int, int> m_contrastRange;
+ QPair<int, int> m_hueRange;
+ QPair<int, int> m_saturationRange;
+
+ bool findPort();
+ void querySupportedFormats();
+
+ int getAttribute(const char *attribute, int minimum, int maximum) const;
+ void setAttribute(const char *attribute, int value, int minimum, int maximum);
+
+ static int redistribute(int value, int fromLower, int fromUpper, int toLower, int toUpper);
+};
+
+#endif
diff --git a/src/plugins/symbian/mmf/mmf.pro b/src/plugins/symbian/mmf/mmf.pro
new file mode 100644
index 000000000..2bae03e59
--- /dev/null
+++ b/src/plugins/symbian/mmf/mmf.pro
@@ -0,0 +1,58 @@
+TEMPLATE = lib
+
+CONFIG += plugin
+TARGET = $$qtLibraryTarget(qtmultimediakit_mmfengine)
+PLUGIN_TYPE = mediaservice
+include (../../../../common.pri)
+qtAddLibrary(QtMultimediaKit)
+
+#includes here so that all defines are added here also
+include(mediaplayer/mediaplayer_s60.pri)
+include(radio/radio.pri)
+
+QT += network
+
+# we include mmf audiorecording only if we are not building openmaxal based backend
+!contains(openmaxal_symbian_enabled, yes) {
+ message("Enabling mmf mediarecording backend")
+ include(audiosource/audiosource_s60.pri)
+}
+
+DEPENDPATH += .
+INCLUDEPATH += . \
+ $${SOURCE_DIR}/include \
+ $${SOURCE_DIR}/src/multimedia \
+ $${SOURCE_DIR}/src/multimedia/audio \
+ $${SOURCE_DIR}/src/multimedia/video \
+ $${SOURCE_DIR}/plugins/multimedia/symbian/mmf/inc \
+ $${SOURCE_DIR}
+
+
+HEADERS += s60mediaserviceplugin.h \
+ s60formatsupported.h
+
+SOURCES += s60mediaserviceplugin.cpp \
+ s60formatsupported.cpp
+
+contains(S60_VERSION, 3.2)|contains(S60_VERSION, 3.1) {
+ DEFINES += PRE_S60_50_PLATFORM
+}
+contains(mmf_http_cookies_enabled, yes) {
+ DEFINES += HTTP_COOKIES_ENABLED
+}
+load(data_caging_paths)
+TARGET.EPOCALLOWDLLDATA = 1
+TARGET.UID3=0x2002AC76
+TARGET.CAPABILITY = ALL -TCB
+MMP_RULES += EXPORTUNFROZEN
+
+#make a sis package from plugin + api + stub (plugin)
+pluginDep.sources = $${TARGET}.dll
+pluginDep.path = $${QT_PLUGINS_BASE_DIR}/$${PLUGIN_TYPE}
+DEPLOYMENT += pluginDep
+
+#Media API spesific deployment
+QtMediaDeployment.sources = QtMultimediaKit.dll
+QtMediaDeployment.path = /sys/bin
+
+DEPLOYMENT += QtMediaDeployment
diff --git a/src/plugins/symbian/mmf/radio/radio.pri b/src/plugins/symbian/mmf/radio/radio.pri
new file mode 100644
index 000000000..a4703d126
--- /dev/null
+++ b/src/plugins/symbian/mmf/radio/radio.pri
@@ -0,0 +1,24 @@
+INCLUDEPATH += $$PWD
+
+contains(tunerlib_s60_enabled, yes) {
+
+ LIBS += -ltunerutility
+ DEFINES += TUNERLIBUSED
+ INCLUDEPATH += $${EPOCROOT}epoc32/include/mmf/common
+
+ HEADERS += $$PWD/s60radiotunercontrol_31.h
+ SOURCES += $$PWD/s60radiotunercontrol_31.cpp
+}
+
+contains(radioutility_s60_enabled, yes) {
+ LIBS += -lradio_utility
+ DEFINES += RADIOUTILITYLIBUSED
+
+ HEADERS += $$PWD/s60radiotunercontrol_since32.h
+ SOURCES += $$PWD/s60radiotunercontrol_since32.cpp
+}
+
+contains(tunerlib_s60_enabled, yes)|contains(radioutility_s60_enabled, yes) {
+ HEADERS += $$PWD/s60radiotunerservice.h
+ SOURCES += $$PWD/s60radiotunerservice.cpp
+}
diff --git a/src/plugins/symbian/mmf/radio/s60radiotunercontrol_31.cpp b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_31.cpp
new file mode 100644
index 000000000..b7627e312
--- /dev/null
+++ b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_31.cpp
@@ -0,0 +1,603 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60radiotunercontrol_31.h"
+#include "s60radiotunerservice.h"
+
+#include <QtCore/qdebug.h>
+#include <QFile>
+
+// from AudioPreference.h
+const TInt KAudioPriorityFMRadio = 79;
+const TUint KAudioPrefRadioAudioEvent = 0x03000001;
+
+S60RadioTunerControl::S60RadioTunerControl(QObject *parent)
+ : QRadioTunerControl(parent)
+ , m_error(0)
+ , m_tunerState(0)
+ , m_apiTunerState(QRadioTuner::StoppedState)
+ , m_audioInitializationComplete(false)
+ , m_radioError(QRadioTuner::NoError)
+ , m_muted(false)
+ , m_isStereo(true)
+ , m_stereoMode(QRadioTuner::Auto)
+ , m_signal(0)
+ , m_currentBand(QRadioTuner::FM)
+ , m_currentFreq(87500000)
+ , m_scanning(false)
+ , m_vol(50)
+{
+ DP0("S60RadioTunerControl::S60RadioTunerControl +++");
+
+ initRadio();
+
+ DP0("S60RadioTunerControl::S60RadioTunerControl ---");
+}
+
+S60RadioTunerControl::~S60RadioTunerControl()
+{
+ DP0("S60RadioTunerControl::~S60RadioTunerControl +++");
+
+ if (m_tunerUtility) {
+ m_tunerUtility->Close();
+ m_tunerUtility->CancelNotifyChange();
+ m_tunerUtility->CancelNotifySignalStrength();
+ m_tunerUtility->CancelNotifyStereoChange();
+ delete m_tunerUtility;
+ }
+ if (m_audioPlayerUtility) {
+ m_audioPlayerUtility = NULL;
+ }
+
+ DP0("S60RadioTunerControl::~S60RadioTunerControl ---");
+}
+
+bool S60RadioTunerControl::initRadio()
+{
+ DP0("S60RadioTunerControl::initRadio +++");
+
+ m_available = false;
+
+ TRAPD(tunerError, m_tunerUtility = CMMTunerUtility::NewL(*this, CMMTunerUtility::ETunerBandFm, 1,
+ CMMTunerUtility::ETunerAccessPriorityNormal));
+ if (tunerError != KErrNone) {
+ m_radioError = QRadioTuner::OpenError;
+ return m_available;
+ }
+
+ TRAPD(playerError, m_audioPlayerUtility = m_tunerUtility->TunerPlayerUtilityL(*this));
+ if (playerError != KErrNone) {
+ m_radioError = QRadioTuner::OpenError;
+ return m_available;
+ }
+
+ TRAPD(initializeError, m_audioPlayerUtility->InitializeL(KAudioPriorityFMRadio,
+ TMdaPriorityPreference(KAudioPrefRadioAudioEvent)));
+ if (initializeError != KErrNone) {
+ m_radioError = QRadioTuner::OpenError;
+ return m_available;
+ }
+
+ m_tunerUtility->NotifyChange(*this);
+ m_tunerUtility->NotifyStereoChange(*this);
+ m_tunerUtility->NotifySignalStrength(*this);
+
+ TFrequency freq(m_currentFreq);
+ m_tunerUtility->Tune(freq);
+
+ m_available = true;
+
+ DP0("S60RadioTunerControl::initRadio ---");
+
+ return m_available;
+}
+
+void S60RadioTunerControl::start()
+{
+ DP0("S60RadioTunerControl::start +++");
+
+ if (!m_audioInitializationComplete) {
+ TFrequency freq(m_currentFreq);
+ m_tunerUtility->Tune(freq);
+ } else {
+ m_audioPlayerUtility->Play();
+ }
+
+ m_apiTunerState = QRadioTuner::ActiveState;
+ emit stateChanged(m_apiTunerState);
+
+ DP0("S60RadioTunerControl::start ---");
+}
+
+void S60RadioTunerControl::stop()
+{
+ DP0("S60RadioTunerControl::stop +++");
+
+ if (m_audioPlayerUtility) {
+ m_audioPlayerUtility->Stop();
+ m_apiTunerState = QRadioTuner::StoppedState;
+ emit stateChanged(m_apiTunerState);
+ }
+
+ DP0("S60RadioTunerControl::stop ---");
+}
+
+QRadioTuner::State S60RadioTunerControl::state() const
+{
+ DP0("S60RadioTunerControl::state");
+
+ return m_apiTunerState;
+}
+
+QRadioTuner::Band S60RadioTunerControl::band() const
+{
+ DP0("S60RadioTunerControl::band");
+
+ return m_currentBand;
+}
+
+bool S60RadioTunerControl::isBandSupported(QRadioTuner::Band b) const
+{
+ DP0("S60RadioTunerControl::isBandSupported");
+
+ if(b == QRadioTuner::FM)
+ return true;
+ else if(b == QRadioTuner::LW)
+ return false;
+ else if(b == QRadioTuner::AM)
+ return true;
+ else if(b == QRadioTuner::SW)
+ return false;
+ else
+ return false;
+}
+
+void S60RadioTunerControl::setBand(QRadioTuner::Band b)
+{
+ DP0("S60RadioTunerControl::setBand +++");
+
+ QRadioTuner::Band tempBand = b;
+ if (tempBand != m_currentBand) {
+ m_currentBand = b;
+ emit bandChanged(m_currentBand);
+ }
+
+ DP0("S60RadioTunerControl::setBand ---");
+}
+
+int S60RadioTunerControl::frequency() const
+{
+ DP0("S60RadioTunerControl::frequency");
+
+ return m_currentFreq;
+}
+
+void S60RadioTunerControl::setFrequency(int frequency)
+{
+ DP0("S60RadioTunerControl::setFrequency +++");
+
+ m_currentFreq = frequency;
+ TFrequency freq(m_currentFreq);
+ m_tunerUtility->Tune(freq);
+
+ DP0("S60RadioTunerControl::setFrequency ---");
+}
+
+int S60RadioTunerControl::frequencyStep(QRadioTuner::Band b) const
+{
+ DP0("S60RadioTunerControl::frequencyStep +++");
+
+ int step = 0;
+
+ if(b == QRadioTuner::FM)
+ step = 100000; // 100kHz steps
+ else if(b == QRadioTuner::LW)
+ step = 1000; // 1kHz steps
+ else if(b == QRadioTuner::AM)
+ step = 1000; // 1kHz steps
+ else if(b == QRadioTuner::SW)
+ step = 500; // 500Hz steps
+
+ DP1("S60RadioTunerControl::frequencyStep, Step:", step);
+ DP0("S60RadioTunerControl::frequencyStep ---");
+
+ return step;
+}
+
+QPair<int,int> S60RadioTunerControl::frequencyRange(QRadioTuner::Band band) const
+{
+ DP0("S60RadioTunerControl::frequencyRange +++");
+
+ TFrequency bottomFreq;
+ TFrequency topFreq;
+ int bandError = KErrNone;
+
+ if (m_tunerUtility){
+ bandError = m_tunerUtility->GetFrequencyBandRange(bottomFreq, topFreq);
+ if (!bandError) {
+ return qMakePair<int,int>(bottomFreq.iFrequency, topFreq.iFrequency);
+ }
+ }
+
+ DP0("S60RadioTunerControl::frequencyRange ---");
+
+ return qMakePair<int,int>(0,0);
+}
+
+CMMTunerUtility::TTunerBand S60RadioTunerControl::getNativeBand(QRadioTuner::Band b) const
+{
+ DP0("S60RadioTunerControl::getNativeBand");
+
+ // api match to native s60 bands
+ if (b == QRadioTuner::AM)
+ return CMMTunerUtility::ETunerBandAm;
+ else if (b == QRadioTuner::FM)
+ return CMMTunerUtility::ETunerBandFm;
+ else if (b == QRadioTuner::LW)
+ return CMMTunerUtility::ETunerBandLw;
+ else
+ return CMMTunerUtility::ETunerNoBand;
+}
+
+bool S60RadioTunerControl::isStereo() const
+{
+ DP0("S60RadioTunerControl::isStereo");
+
+ return m_isStereo;
+}
+
+QRadioTuner::StereoMode S60RadioTunerControl::stereoMode() const
+{
+ DP0("S60RadioTunerControl::stereoMode");
+
+ return m_stereoMode;
+}
+
+void S60RadioTunerControl::setStereoMode(QRadioTuner::StereoMode mode)
+{
+ DP0("S60RadioTunerControl::setStereoMode +++");
+
+ m_stereoMode = mode;
+ if (m_tunerUtility) {
+ if (QRadioTuner::ForceMono == mode)
+ m_tunerUtility->ForceMonoReception(true);
+ else
+ m_tunerUtility->ForceMonoReception(false);
+ }
+
+ DP0("S60RadioTunerControl::setStereoMode ---");
+}
+
+int S60RadioTunerControl::signalStrength() const
+{
+ DP0("S60RadioTunerControl::signalStrength +++");
+
+ // return value is a percentage value
+ if (m_tunerUtility) {
+ TInt maxSignalStrength;
+ TInt currentSignalStrength;
+ m_error = m_tunerUtility->GetMaxSignalStrength(maxSignalStrength);
+ if (m_error == KErrNone) {
+ m_error = m_tunerUtility->GetSignalStrength(currentSignalStrength);
+ if (m_error == KErrNone) {
+ if (maxSignalStrength == 0 || currentSignalStrength == 0) {
+ return 0;
+ }
+ m_signal = ((TInt64)currentSignalStrength) * 100 / maxSignalStrength;
+ }
+ }
+ }
+
+ DP1("S60RadioTunerControl::signalStrength, m_signal:", m_signal);
+ DP0("S60RadioTunerControl::signalStrength ---");
+
+ return m_signal;
+}
+
+int S60RadioTunerControl::volume() const
+{
+ DP0("S60RadioTunerControl::volume");
+
+ return m_vol;
+}
+
+void S60RadioTunerControl::setVolume(int volume)
+{
+ DP0("S60RadioTunerControl::setVolume +++");
+ DP1("S60RadioTunerControl::setVolume: ", volume);
+
+ if (m_audioPlayerUtility) {
+ m_vol = volume;
+ TInt error = m_audioPlayerUtility->SetVolume(volume/10);
+ emit volumeChanged(m_vol);
+ }
+
+ DP0("S60RadioTunerControl::setVolume ---");
+}
+
+bool S60RadioTunerControl::isMuted() const
+{
+ DP0("S60RadioTunerControl::isMuted");
+
+ return m_muted;
+}
+
+void S60RadioTunerControl::setMuted(bool muted)
+{
+ DP0("S60RadioTunerControl::setMuted +++");
+
+ DP1("S60RadioTunerControl::setMuted:", muted);
+
+ if (m_audioPlayerUtility && m_audioInitializationComplete) {
+ m_muted = muted;
+ m_audioPlayerUtility->Mute(m_muted);
+ emit mutedChanged(m_muted);
+ }
+
+ DP0("S60RadioTunerControl::setMuted ---");
+}
+
+bool S60RadioTunerControl::isSearching() const
+{
+ DP0("S60RadioTunerControl::isSearching");
+
+ if (m_tunerUtility) {
+ TUint32 tempState;
+ m_tunerUtility->GetState(tempState);
+ if (tempState == CMMTunerUtility::ETunerStateRetuning || m_scanning) {
+ return true;
+ } else
+ return false;
+ }
+ return true;
+}
+
+void S60RadioTunerControl::cancelSearch()
+{
+ DP0("S60RadioTunerControl::cancelSearch +++");
+
+ m_tunerUtility->CancelRetune();
+ m_scanning = false;
+ emit searchingChanged(false);
+
+ DP0("S60RadioTunerControl::cancelSearch ---");
+}
+
+void S60RadioTunerControl::searchForward()
+{
+ DP0("S60RadioTunerControl::searchForward +++");
+
+ m_scanning = true;
+ setVolume(m_vol);
+ m_tunerUtility->StationSeek(CMMTunerUtility::ESearchDirectionUp);
+ emit searchingChanged(true);
+
+ DP0("S60RadioTunerControl::searchForward ---");
+}
+
+void S60RadioTunerControl::searchBackward()
+{
+ DP0("S60RadioTunerControl::searchBackward +++");
+
+ m_scanning = true;
+ setVolume(m_vol);
+ m_tunerUtility->StationSeek(CMMTunerUtility::ESearchDirectionDown);
+ emit searchingChanged(true);
+
+ DP0("S60RadioTunerControl::searchBackward ---");
+}
+
+bool S60RadioTunerControl::isValid() const
+{
+ DP0("S60RadioTunerControl::isValid");
+
+ return m_available;
+}
+
+bool S60RadioTunerControl::isAvailable() const
+{
+ DP0("S60RadioTunerControl::isAvailable");
+
+ return m_available;
+}
+
+QtMultimediaKit::AvailabilityError S60RadioTunerControl::availabilityError() const
+{
+ DP0("S60RadioTunerControl::availabilityError");
+
+ if (m_available)
+ return QtMultimediaKit::NoError;
+ else
+ return QtMultimediaKit::ResourceError;
+}
+
+QRadioTuner::Error S60RadioTunerControl::error() const
+{
+ DP1("QtMultimediaKit::NoError", m_radioError);
+
+ return m_radioError;
+}
+
+QString S60RadioTunerControl::errorString() const
+{
+ DP1("S60RadioTunerControl::errorString", m_errorString);
+
+ return m_errorString;
+}
+
+void S60RadioTunerControl::MToTuneComplete(TInt aError)
+{
+ DP0("S60RadioTunerControl::MToTuneComplete +++");
+ DP1("S60RadioTunerControl::MToTuneComplete, aError:",aError);
+
+ if (aError == KErrNone) {
+ m_scanning = false;
+ m_audioPlayerUtility->Play();
+ if (!m_audioInitializationComplete) {
+ TRAPD(initializeError, m_audioPlayerUtility->InitializeL(KAudioPriorityFMRadio,
+ TMdaPriorityPreference(KAudioPrefRadioAudioEvent)));
+ if (initializeError != KErrNone) {
+ m_radioError = QRadioTuner::OpenError;
+ }
+ }
+ }
+
+ DP0("S60RadioTunerControl::MToTuneComplete ---");
+}
+
+void S60RadioTunerControl::MTcoFrequencyChanged(const TFrequency& aOldFrequency, const TFrequency& aNewFrequency)
+{
+ DP0("S60RadioTunerControl::MTcoFrequencyChanged +++");
+
+ m_currentFreq = aNewFrequency.iFrequency;
+ m_scanning = false;
+ emit frequencyChanged(m_currentFreq);
+
+ DP0("S60RadioTunerControl::MTcoFrequencyChanged ---");
+}
+
+void S60RadioTunerControl::MTcoStateChanged(const TUint32& aOldState, const TUint32& aNewState)
+{
+ DP0("S60RadioTunerControl::MTcoStateChanged +++");
+
+ if (aNewState == CMMTunerUtility::ETunerStateActive) {
+ m_apiTunerState = QRadioTuner::ActiveState;
+ }
+ if (aNewState == CMMTunerUtility::ETunerStatePlaying) {
+ m_apiTunerState = QRadioTuner::ActiveState;
+ }
+ if (aOldState != aNewState){
+ emit stateChanged(m_apiTunerState);
+ }
+
+ DP0("S60RadioTunerControl::MTcoStateChanged ---");
+}
+
+void S60RadioTunerControl::MTcoAntennaDetached()
+{
+ DP0("S60RadioTunerControl::MTcoAntennaDetached +++");
+
+ DP0("S60RadioTunerControl::MTcoAntennaDetached ---");
+
+ // no actions
+}
+
+void S60RadioTunerControl::MTcoAntennaAttached()
+{
+ DP0("S60RadioTunerControl::MTcoAntennaAttached +++");
+
+ DP0("S60RadioTunerControl::MTcoAntennaAttached ---");
+
+ // no actions
+}
+
+void S60RadioTunerControl::FlightModeChanged(TBool aFlightMode)
+{
+ DP0("S60RadioTunerControl::FlightModeChanged +++");
+
+ DP0("S60RadioTunerControl::FlightModeChanged ---");
+
+ // no actions
+}
+
+void S60RadioTunerControl::MTsoStereoReceptionChanged(TBool aStereo)
+{
+ DP0("S60RadioTunerControl::MTsoStereoReceptionChanged +++");
+ DP1("S60RadioTunerControl::MTsoStereoReceptionChanged, aStereo:", aStereo);
+ m_isStereo = aStereo;
+ emit stereoStatusChanged(aStereo);
+
+ DP0("S60RadioTunerControl::MTsoStereoReceptionChanged ---");
+}
+
+void S60RadioTunerControl::MTsoForcedMonoChanged(TBool aForcedMono)
+{
+ DP0("S60RadioTunerControl::MTsoForcedMonoChanged +++");
+ DP1("S60RadioTunerControl::MTsoForcedMonoChanged, aForcedMono:", aForcedMono);
+
+ if (aForcedMono) {
+ m_stereoMode = QRadioTuner::ForceMono;
+ }
+
+ DP0("S60RadioTunerControl::MTsoForcedMonoChanged ---");
+}
+
+void S60RadioTunerControl::MssoSignalStrengthChanged(TInt aNewSignalStrength)
+{
+ DP0("S60RadioTunerControl::MssoSignalStrengthChanged +++");
+ DP1("S60RadioTunerControl::MssoSignalStrengthChanged, aNewSignalStrength:", aNewSignalStrength);
+
+ m_signal = aNewSignalStrength;
+ emit signalStrengthChanged(m_signal);
+
+ DP0("S60RadioTunerControl::MssoSignalStrengthChanged ---");
+}
+
+void S60RadioTunerControl::MTapoInitializeComplete(TInt aError)
+{
+ DP0("S60RadioTunerControl::MTapoInitializeComplete +++");
+ DP1("S60RadioTunerControl::MTapoInitializeComplete, aError:", aError);
+ if (aError == KErrNone) {
+ m_audioInitializationComplete = true;
+ m_available = true;
+ m_audioPlayerUtility->Play();
+ m_apiTunerState = QRadioTuner::ActiveState;
+ emit stateChanged(m_apiTunerState);
+ } else if (aError != KErrNone) {
+ m_radioError = QRadioTuner::OpenError;
+ }
+
+ DP0("S60RadioTunerControl::MTapoInitializeComplete ---");
+}
+
+void S60RadioTunerControl::MTapoPlayEvent(TEventType aEvent, TInt aError, TAny* aAdditionalInfo)
+{
+ DP0("S60RadioTunerControl::MTapoPlayEvent +++");
+
+ DP0("S60RadioTunerControl::MTapoPlayEvent ---");
+
+ // no actions
+}
+
+
+
diff --git a/src/plugins/symbian/mmf/radio/s60radiotunercontrol_31.h b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_31.h
new file mode 100644
index 000000000..c8bb8d362
--- /dev/null
+++ b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_31.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60RADIOTUNERCONTROL_H
+#define S60RADIOTUNERCONTROL_H
+
+#include <QtCore/qobject.h>
+#include <qradiotunercontrol.h>
+#include <qradiotuner.h>
+#include <tuner.h>
+
+class S60RadioTunerService;
+
+QT_USE_NAMESPACE
+
+class S60RadioTunerControl
+ : public QRadioTunerControl
+ , public MMMTunerObserver
+ , public MMMTunerStereoObserver
+ , public MMMSignalStrengthObserver
+ , public MMMTunerChangeObserver
+ , public MMMTunerAudioPlayerObserver
+{
+ Q_OBJECT
+public:
+ S60RadioTunerControl(QObject *parent = 0);
+ ~S60RadioTunerControl();
+
+ QRadioTuner::State state() const;
+
+ QRadioTuner::Band band() const;
+ void setBand(QRadioTuner::Band b);
+ bool isBandSupported(QRadioTuner::Band b) const;
+
+ int frequency() const;
+ int frequencyStep(QRadioTuner::Band b) const;
+ QPair<int,int> frequencyRange(QRadioTuner::Band b) const;
+ void setFrequency(int frequency);
+
+ bool isStereo() const;
+ QRadioTuner::StereoMode stereoMode() const;
+ void setStereoMode(QRadioTuner::StereoMode mode);
+
+ int signalStrength() const;
+
+ int volume() const;
+ void setVolume(int volume);
+
+ bool isMuted() const;
+ void setMuted(bool muted);
+
+ bool isSearching() const;
+ void searchForward();
+ void searchBackward();
+ void cancelSearch();
+
+ bool isValid() const;
+
+ bool isAvailable() const;
+ QtMultimediaKit::AvailabilityError availabilityError() const;
+
+ void start();
+ void stop();
+
+ QRadioTuner::Error error() const;
+ QString errorString() const;
+
+ //MMMTunerObserver
+ void MToTuneComplete(TInt aError);
+
+ //MMMTunerChangeObserver
+ void MTcoFrequencyChanged(const TFrequency& aOldFrequency, const TFrequency& aNewFrequency);
+ void MTcoStateChanged(const TUint32& aOldState, const TUint32& aNewState);
+ void MTcoAntennaDetached();
+ void MTcoAntennaAttached();
+ void FlightModeChanged(TBool aFlightMode);
+
+ //MMMTunerStereoObserver
+ void MTsoStereoReceptionChanged(TBool aStereo);
+ void MTsoForcedMonoChanged(TBool aForcedMono);
+
+ //MMMSignalStrengthObserver
+ void MssoSignalStrengthChanged(TInt aNewSignalStrength);
+
+ //MMMTunerAudioPlayerObserver
+ void MTapoInitializeComplete(TInt aError);
+ void MTapoPlayEvent(TEventType aEvent, TInt aError, TAny* aAdditionalInfo);
+
+private slots:
+
+
+private:
+ bool initRadio();
+ CMMTunerUtility::TTunerBand getNativeBand(QRadioTuner::Band b) const;
+
+ mutable int m_error;
+ CMMTunerUtility *m_tunerUtility;
+ CMMTunerAudioPlayerUtility *m_audioPlayerUtility;
+
+ bool m_audioInitializationComplete;
+ bool m_muted;
+ bool m_isStereo;
+ bool m_available;
+ int m_step;
+ int m_vol;
+ mutable int m_signal;
+ bool m_scanning;
+ bool forward;
+ QRadioTuner::Band m_currentBand;
+ qint64 m_currentFreq;
+
+ QRadioTuner::Error m_radioError;
+ QRadioTuner::StereoMode m_stereoMode;
+ QString m_errorString;
+ //caps meaning what the tuner can do.
+ TTunerCapabilities m_currentTunerCapabilities;
+ long m_tunerState;
+ QRadioTuner::State m_apiTunerState;
+
+};
+
+#endif
+
diff --git a/src/plugins/symbian/mmf/radio/s60radiotunercontrol_since32.cpp b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_since32.cpp
new file mode 100644
index 000000000..991c6b8e4
--- /dev/null
+++ b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_since32.cpp
@@ -0,0 +1,685 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60radiotunercontrol_since32.h"
+#include "s60radiotunerservice.h"
+
+#include <QtCore/qdebug.h>
+#include <RadioFmTunerUtility.h>
+
+S60RadioTunerControl::S60RadioTunerControl(QObject *parent)
+ : QRadioTunerControl(parent)
+ , m_error(0)
+ , m_radioUtility(NULL)
+ , m_fmTunerUtility(NULL)
+ , m_playerUtility(NULL)
+ , m_maxVolume(100)
+ , m_audioInitializationComplete(false)
+ , m_muted(false)
+ , m_isStereo(true)
+ , m_vol(50)
+ , m_signal(0)
+ , m_scanning(false)
+ , m_currentBand(QRadioTuner::FM)
+ , m_currentFreq(87500000)
+ , m_radioError(QRadioTuner::NoError)
+ , m_stereoMode(QRadioTuner::Auto)
+ , m_apiTunerState(QRadioTuner::StoppedState)
+ , m_previousSignal(0)
+ , m_volChangeRequired(false)
+ , m_signalStrengthTimer(new QTimer(this))
+{
+ DP0("S60RadioTunerControl::S60RadioTunerControl +++");
+ bool retValue = initRadio();
+ if (!retValue) {
+ m_errorString = QString(tr("Initialize Error."));
+ emit error(QRadioTuner::ResourceError);
+ } else {
+ connect(m_signalStrengthTimer, SIGNAL(timeout()), this, SLOT(changeSignalStrength()));
+ }
+ DP0("S60RadioTunerControl::S60RadioTunerControl ---");
+}
+
+S60RadioTunerControl::~S60RadioTunerControl()
+{
+ DP0("S60RadioTunerControl::~S60RadioTunerControl +++");
+
+ if (m_fmTunerUtility) {
+ m_fmTunerUtility->Close();
+ }
+
+ if (m_playerUtility) {
+ m_playerUtility->Close();
+ }
+
+ delete m_radioUtility;
+
+ DP0("S60RadioTunerControl::~S60RadioTunerControl ---");
+}
+
+QRadioTuner::State S60RadioTunerControl::state() const
+{
+ DP0("S60RadioTunerControl::state");
+
+ return m_apiTunerState;
+}
+
+QRadioTuner::Band S60RadioTunerControl::band() const
+{
+ DP0("S60RadioTunerControl::band");
+
+ return m_currentBand;
+}
+
+bool S60RadioTunerControl::isBandSupported(QRadioTuner::Band b) const
+{
+ DP0("S60RadioTunerControl::isBandSupported");
+ if (b == QRadioTuner::FM)
+ return true;
+ else if (b == QRadioTuner::LW)
+ return false;
+ else if (b == QRadioTuner::AM)
+ return false;
+ else if (b == QRadioTuner::SW)
+ return false;
+ else if (b == QRadioTuner::FM2)
+ return false;
+ else
+ return false;
+}
+
+void S60RadioTunerControl::changeSignalStrength()
+ {
+
+ int currentSignal = signalStrength();
+ if (currentSignal != m_previousSignal)
+ {
+ m_previousSignal = currentSignal;
+ emit signalStrengthChanged(currentSignal);
+ }
+ }
+void S60RadioTunerControl::setBand(QRadioTuner::Band b)
+{
+ DP0("S60RadioTunerControl::setBand +++");
+ QRadioTuner::Band tempBand = b;
+ if (tempBand != m_currentBand ) {
+ if (isBandSupported(tempBand)){
+ m_currentBand = b;
+ emit bandChanged(m_currentBand);
+ }
+ else {
+ switch(tempBand)
+ {
+ case QRadioTuner::FM :
+ m_errorString = QString(tr("Band FM not Supported"));
+ break;
+ case QRadioTuner::AM :
+ m_errorString = QString(tr("Band AM not Supported"));
+ break;
+ case QRadioTuner::SW :
+ m_errorString = QString(tr("Band SW not Supported"));
+ break;
+ case QRadioTuner::LW :
+ m_errorString = QString(tr("Band LW not Supported"));
+ break;
+ case QRadioTuner::FM2 :
+ m_errorString = QString(tr("Band FM2 not Supported"));
+ break;
+ default :
+ m_errorString = QString("Band %1 not Supported").arg(tempBand);
+ break;
+ }
+ emit error(QRadioTuner::OutOfRangeError);
+ }
+ }
+
+ DP0("S60RadioTunerControl::setBand ---");
+}
+
+int S60RadioTunerControl::frequency() const
+{
+ DP0("S60RadioTunerControl::frequency");
+
+ return m_currentFreq;
+}
+
+void S60RadioTunerControl::setFrequency(int frequency)
+{
+ DP0("S60RadioTunerControl::setFrequency +++");
+ DP1("S60RadioTunerControl::setFrequency, frequency:", frequency);
+
+ m_currentFreq = frequency;
+ m_fmTunerUtility->SetFrequency(m_currentFreq);
+
+ DP0("S60RadioTunerControl::setFrequency ---");
+}
+int S60RadioTunerControl::frequencyStep(QRadioTuner::Band b) const
+{
+ DP0("S60RadioTunerControl::frequencyStep +++");
+
+ int step = 0;
+ if (b == QRadioTuner::FM)
+ step = 100000; // 100kHz steps
+ else if(b == QRadioTuner::LW)
+ step = 1000; // 1kHz steps
+ else if (b == QRadioTuner::AM)
+ step = 1000; // 1kHz steps
+ else if(b == QRadioTuner::SW)
+ step = 500; // 500Hz steps
+ DP1("S60RadioTunerControl::frequencyStep, Step:", step);
+ DP0("S60RadioTunerControl::frequencyStep ---");
+
+ return step;
+}
+
+QPair<int,int> S60RadioTunerControl::frequencyRange(QRadioTuner::Band band) const
+{
+ DP0("S60RadioTunerControl::frequencyRange +++");
+
+ int bottomFreq;
+ int topFreq;
+
+ int bandError = KErrNone;
+ TFmRadioFrequencyRange range;
+
+ if (m_fmTunerUtility) {
+ bandError = m_fmTunerUtility->GetFrequencyRange(range, bottomFreq, topFreq);
+ }
+ if (!bandError) {
+ return qMakePair<int,int>(bottomFreq, topFreq);
+ }
+
+ DP0("S60RadioTunerControl::frequencyRange ---");
+
+ return qMakePair<int,int>(0,0);
+}
+
+bool S60RadioTunerControl::isStereo() const
+{
+ DP0("S60RadioTunerControl::isStereo");
+
+ return m_isStereo;
+}
+
+QRadioTuner::StereoMode S60RadioTunerControl::stereoMode() const
+{
+ DP0("S60RadioTunerControl::stereoMode");
+
+ return m_stereoMode;
+}
+
+void S60RadioTunerControl::setStereoMode(QRadioTuner::StereoMode mode)
+{
+ DP0("S60RadioTunerControl::setStereoMode +++");
+
+ if (m_fmTunerUtility) {
+ if (QRadioTuner::ForceMono == mode) {
+ m_fmTunerUtility->ForceMonoReception(true);
+ m_stereoMode = QRadioTuner::ForceMono;
+ m_isStereo = false;
+ } else {
+ m_fmTunerUtility->ForceMonoReception(false);
+ m_isStereo = true;
+ m_stereoMode = QRadioTuner::ForceStereo;
+ }
+ }
+
+ DP0("S60RadioTunerControl::setStereoMode ---");
+}
+
+int S60RadioTunerControl::signalStrength() const
+{
+ DP0("S60RadioTunerControl::signalStrength +++");
+
+ // return value is a percentage value
+ if (m_fmTunerUtility) {
+ TInt maxSignalStrength;
+ TInt currentSignalStrength;
+ m_error = m_fmTunerUtility->GetMaxSignalStrength(maxSignalStrength);
+
+ if (m_error == KErrNone) {
+ m_error = m_fmTunerUtility->GetSignalStrength(currentSignalStrength);
+ if (m_error == KErrNone) {
+ if (currentSignalStrength == 0 || maxSignalStrength == 0) {
+ return currentSignalStrength;
+ }
+ m_signal = ((TInt64)currentSignalStrength) * 100 / maxSignalStrength;
+ }
+ }
+ }
+
+ DP1("S60RadioTunerControl::signalStrength, m_signal:", m_signal);
+ DP0("S60RadioTunerControl::signalStrength ---");
+
+ return m_signal;
+}
+
+int S60RadioTunerControl::volume() const
+{
+ DP0("S60RadioTunerControl::volume");
+
+ return m_vol;
+}
+
+void S60RadioTunerControl::setVolume(int volume)
+{
+ DP0("S60RadioTunerControl::setVolume +++");
+ DP1("S60RadioTunerControl::setVolume, Volume:", volume);
+
+ int boundVolume = qBound(0, volume, 100);
+
+ if (m_vol == boundVolume )
+ return;
+
+ if (!m_muted && m_playerUtility) {
+ m_vol = boundVolume;
+ // Don't set volume until State is in Active State.
+ if (state() == QRadioTuner::ActiveState ) {
+ m_playerUtility->SetVolume(m_vol*m_volMultiplier);
+
+ } else {
+ m_volChangeRequired = TRUE;
+ emit volumeChanged(boundVolume);
+ }
+ }
+ DP0("S60RadioTunerControl::setVolume ---");
+}
+
+bool S60RadioTunerControl::isMuted() const
+{
+ DP0("S60RadioTunerControl::isMuted");
+
+ return m_muted;
+}
+
+void S60RadioTunerControl::setMuted(bool muted)
+{
+ DP0("S60RadioTunerControl::setMuted +++");
+ DP1("S60RadioTunerControl::setMuted, Muted:", muted);
+ if (m_playerUtility) {
+ m_muted = muted;
+ m_playerUtility->Mute(m_muted);
+ }
+ DP0("S60RadioTunerControl::setMuted ---");
+}
+
+bool S60RadioTunerControl::isSearching() const
+{
+ DP0("S60RadioTunerControl::isSearching");
+
+ return m_scanning;
+}
+
+void S60RadioTunerControl::cancelSearch()
+{
+ DP0("S60RadioTunerControl::cancelSearch +++");
+
+ m_fmTunerUtility->CancelStationSeek();
+ m_scanning = false;
+ emit searchingChanged(false);
+
+ DP0("S60RadioTunerControl::cancelSearch ---");
+}
+
+void S60RadioTunerControl::searchForward()
+{
+ DP0("S60RadioTunerControl::searchForward +++");
+ m_fmTunerUtility->StationSeek(true);
+ m_scanning = true;
+ emit searchingChanged(m_scanning);
+ DP0("S60RadioTunerControl::searchForward ---");
+}
+
+void S60RadioTunerControl::searchBackward()
+{
+ DP0("S60RadioTunerControl::searchBackward +++");
+ m_fmTunerUtility->StationSeek(false);
+ m_scanning = true;
+ emit searchingChanged(m_scanning);
+ DP0("S60RadioTunerControl::searchBackward ---");
+}
+
+bool S60RadioTunerControl::isValid() const
+{
+ DP0("S60RadioTunerControl::isValid");
+
+ return m_available;
+}
+
+bool S60RadioTunerControl::initRadio()
+{
+ DP0("S60RadioTunerControl::initRadio +++");
+ m_available = false;
+ // create an instance of Radio Utility factory and indicate
+ // FM Radio is a primary client
+ TRAPD(utilityError,
+ m_radioUtility = CRadioUtility::NewL(ETrue);
+ // Get a tuner utility
+ m_fmTunerUtility = &m_radioUtility->RadioFmTunerUtilityL(*this);
+ // we want to listen radio in offline mode too
+ m_fmTunerUtility->EnableTunerInOfflineMode(ETrue);
+ // Get a player utility
+ m_playerUtility = &m_radioUtility->RadioPlayerUtilityL(*this);
+ );
+ if (utilityError != KErrNone) {
+ m_radioError = QRadioTuner::ResourceError;
+ return m_available;
+ }
+
+ m_tunerControl = false;
+
+ m_available = true;
+ DP1("S60RadioTunerControl::initRadio, m_available:", m_available);
+ DP0("S60RadioTunerControl::initRadio ---");
+ return m_available;
+}
+
+bool S60RadioTunerControl::isAvailable() const
+{
+ DP0("S60RadioTunerControl::isAvailable");
+
+ return m_available;
+}
+
+QtMultimediaKit::AvailabilityError S60RadioTunerControl::availabilityError() const
+{
+ DP0("S60RadioTunerControl::availabilityError");
+ if (m_available)
+ return QtMultimediaKit::NoError;
+ else
+ return QtMultimediaKit::ResourceError;
+}
+
+void S60RadioTunerControl::start()
+{
+ DP0("S60RadioTunerControl::start +++");
+ if (!m_tunerControl) {
+ m_fmTunerUtility->RequestTunerControl();
+ } else {
+ m_playerUtility->Play();
+ }
+ m_signalStrengthTimer->start(3000);
+
+ DP0("S60RadioTunerControl::start ---");
+}
+
+void S60RadioTunerControl::stop()
+{
+ DP0("S60RadioTunerControl::stop +++");
+ if (m_playerUtility) {
+ m_playerUtility->Stop();
+ }
+ m_signalStrengthTimer->stop();
+ DP0("S60RadioTunerControl::stop ---");
+}
+
+QRadioTuner::Error S60RadioTunerControl::error() const
+{
+ DP1("S60RadioTunerControl::error", m_radioError);
+
+ return m_radioError;
+}
+QString S60RadioTunerControl::errorString() const
+{
+ DP1("S60RadioTunerControl::errorString", m_errorString);
+
+ return m_errorString;
+}
+
+void S60RadioTunerControl::MrpoStateChange(TPlayerState aState, TInt aError)
+{
+ DP0("S60RadioTunerControl::MrpoStateChange +++");
+ if (aError == KErrNone){
+ m_radioError = QRadioTuner::NoError;
+ if (aState == ERadioPlayerIdle) {
+ m_apiTunerState = QRadioTuner::StoppedState;
+ } else if (aState == ERadioPlayerPlaying) {
+ m_apiTunerState = QRadioTuner::ActiveState;
+ //Apply pending volume changes.
+ if(m_volChangeRequired){
+ setVolume(m_vol);
+ }
+ }
+ } else {
+ m_apiTunerState = QRadioTuner::StoppedState;
+ }
+ emit stateChanged(m_apiTunerState);
+ DP0("S60RadioTunerControl::MrpoStateChange ---");
+}
+
+void S60RadioTunerControl::MrpoVolumeChange(TInt aVolume)
+{
+ DP0("S60RadioTunerControl::MrpoVolumeChange +++");
+ DP1("S60RadioTunerControl::MrpoVolumeChange, aVolume:", aVolume);
+ m_vol = (aVolume/m_volMultiplier);
+ if (!m_volChangeRequired) {
+ emit volumeChanged(m_vol);
+
+ } else {
+ m_volChangeRequired = false;
+ }
+ DP0("S60RadioTunerControl::MrpoVolumeChange ---");
+}
+
+void S60RadioTunerControl::MrpoMuteChange(TBool aMute)
+{
+ DP0("S60RadioTunerControl::MrpoMuteChange +++");
+ DP1("S60RadioTunerControl::MrpoMuteChange, aMute:", aMute);
+ m_muted = aMute;
+ emit mutedChanged(m_muted);
+ DP0("S60RadioTunerControl::MrpoMuteChange ---");
+}
+
+void S60RadioTunerControl::MrpoBalanceChange(TInt aLeftPercentage, TInt aRightPercentage)
+{
+ DP0("S60RadioTunerControl::MrpoBalanceChange +++");
+
+ DP0("S60RadioTunerControl::MrpoBalanceChange ---");
+
+ // no actions
+}
+
+void S60RadioTunerControl::MrftoRequestTunerControlComplete(TInt aError)
+{
+ DP0("S60RadioTunerControl::MrftoRequestTunerControlComplete +++");
+ DP1("S60RadioTunerControl::MrftoRequestTunerControlComplete, aError:", aError);
+ if (aError == KErrNone) {
+ m_playerUtility->GetMaxVolume(m_maxVolume);
+ m_volMultiplier = float(m_maxVolume)/float(100);
+ m_radioError = QRadioTuner::NoError;
+ m_tunerControl = true;
+ m_available = true;
+ m_fmTunerUtility->SetFrequency(m_currentFreq);
+ m_playerUtility->Play();
+ int signal = signalStrength();
+ if (m_signal != signal) {
+ emit signalStrengthChanged(signal);
+ m_signal = signal;
+ }
+
+ } else if (aError == KFmRadioErrAntennaNotConnected) {
+ m_radioError = QRadioTuner::OpenError;
+ m_errorString = QString(tr("Antenna Not Connected"));
+ emit error(m_radioError);
+ } else if (aError == KErrAlreadyExists){
+ m_radioError = QRadioTuner::ResourceError;
+ m_errorString = QString(tr("Resource Error."));
+ emit error(m_radioError);
+ } else if (aError == KFmRadioErrFrequencyOutOfBandRange) {
+ m_radioError = QRadioTuner::OutOfRangeError;
+ m_errorString = QString(tr("Frequency out of band range"));
+ emit error(m_radioError);
+ }else{
+ m_radioError = QRadioTuner::OpenError;
+ m_errorString = QString(tr("Unknown Error."));
+ emit error(m_radioError);
+ }
+
+ DP0("S60RadioTunerControl::MrftoRequestTunerControlComplete ---");
+}
+
+void S60RadioTunerControl::MrftoSetFrequencyRangeComplete(TInt aError)
+{
+ DP0("S60RadioTunerControl::MrftoSetFrequencyRangeComplete +++");
+ DP1("S60RadioTunerControl::MrftoSetFrequencyRangeComplete, aError:", aError);
+ if (aError == KFmRadioErrFrequencyOutOfBandRange || KFmRadioErrFrequencyNotValid) {
+ m_radioError = QRadioTuner::OutOfRangeError;
+ m_errorString = QString(tr("Frequency Out of Band Range or Frequency Not Valid"));
+ emit error(m_radioError);
+ } else if (aError == KFmRadioErrHardwareFaulty || KFmRadioErrOfflineMode) {
+ m_radioError = QRadioTuner::OpenError;
+ m_errorString = QString(tr("Hardware failure or RadioInOfflineMode"));
+ emit error(m_radioError);
+ }
+ DP0("S60RadioTunerControl::MrftoSetFrequencyRangeComplete ---");
+}
+
+void S60RadioTunerControl::MrftoSetFrequencyComplete(TInt aError)
+{
+ DP0("S60RadioTunerControl::MrftoSetFrequencyComplete +++");
+ DP1("S60RadioTunerControl::MrftoSetFrequencyComplete, aError", aError);
+ if (aError == KErrNone) {
+ m_radioError = QRadioTuner::NoError;
+ } else if (aError == KFmRadioErrFrequencyOutOfBandRange || KFmRadioErrFrequencyNotValid) {
+ m_radioError = QRadioTuner::OutOfRangeError;
+ m_errorString = QString(tr("Frequency Out of range or not Valid."));
+ emit error(m_radioError);
+ } else if (aError == KFmRadioErrHardwareFaulty || KFmRadioErrOfflineMode) {
+ m_radioError = QRadioTuner::OpenError;
+ m_errorString = QString("Hardware failure or Radio In Offline Mode");
+ emit error(m_radioError);
+ }
+ DP0("S60RadioTunerControl::MrftoSetFrequencyComplete ---");
+}
+
+void S60RadioTunerControl::MrftoStationSeekComplete(TInt aError, TInt aFrequency)
+{
+ DP0("S60RadioTunerControl::MrftoStationSeekComplete +++");
+ DP3("S60RadioTunerControl::MrftoStationSeekComplete, aError:", aError, " Frequency:", aFrequency);
+ m_scanning = false;
+ if (aError == KErrNone) {
+ m_radioError = QRadioTuner::NoError;
+ m_currentFreq = aFrequency;
+ emit searchingChanged(m_scanning);
+ } else {
+ m_radioError = QRadioTuner::OpenError;
+ emit searchingChanged(m_scanning);
+ m_errorString = QString("Scanning Error");
+ emit error(m_radioError);
+ }
+ DP0("S60RadioTunerControl::MrftoStationSeekComplete ---");
+}
+
+void S60RadioTunerControl::MrftoFmTransmitterStatusChange(TBool aActive)
+{
+ DP0("S60RadioTunerControl::MrftoFmTransmitterStatusChange +++");
+
+ DP0("S60RadioTunerControl::MrftoFmTransmitterStatusChange ---");
+
+ //no actions
+}
+
+void S60RadioTunerControl::MrftoAntennaStatusChange(TBool aAttached)
+{
+ DP0("S60RadioTunerControl::MrftoAntennaStatusChange +++");
+ DP1("S60RadioTunerControl::MrftoAntennaStatusChange, aAttached:", aAttached);
+ if (aAttached && m_tunerControl) {
+ m_playerUtility->Play();
+ }
+ DP0("S60RadioTunerControl::MrftoAntennaStatusChange ---");
+}
+
+void S60RadioTunerControl::MrftoOfflineModeStatusChange(TBool /*aOfflineMode*/)
+{
+ DP0("S60RadioTunerControl::MrftoOfflineModeStatusChange +++");
+
+ DP0("S60RadioTunerControl::MrftoOfflineModeStatusChange ---");
+
+
+}
+
+void S60RadioTunerControl::MrftoFrequencyRangeChange(TFmRadioFrequencyRange aBand /*, TInt aMinFreq, TInt aMaxFreq*/)
+{
+ DP0("S60RadioTunerControl::MrftoFrequencyRangeChange +++");
+ if (aBand == EFmRangeEuroAmerica) {
+ setBand(QRadioTuner::FM);
+ }
+ DP0("S60RadioTunerControl::MrftoFrequencyRangeChange ---");
+}
+
+void S60RadioTunerControl::MrftoFrequencyChange(TInt aNewFrequency)
+{
+ DP0("S60RadioTunerControl::MrftoFrequencyChange +++");
+ DP1("S60RadioTunerControl::MrftoFrequencyChange, aNewFrequency:", aNewFrequency);
+ m_currentFreq = aNewFrequency;
+ emit frequencyChanged(m_currentFreq);
+
+ int signal = signalStrength();
+ if (m_signal != signal) {
+ emit signalStrengthChanged(signal);
+ m_signal = signal;
+ }
+ DP0("S60RadioTunerControl::MrftoFrequencyChange ---");
+}
+
+void S60RadioTunerControl::MrftoForcedMonoChange(TBool aForcedMono)
+{
+ DP0("S60RadioTunerControl::MrftoForcedMonoChange +++");
+ DP1("S60RadioTunerControl::MrftoForcedMonoChange, aForcedMono:", aForcedMono);
+ if (aForcedMono) {
+ m_stereoMode = QRadioTuner::ForceMono;
+ } else {
+ m_stereoMode = QRadioTuner::ForceStereo;
+ }
+ emit stereoStatusChanged(!aForcedMono);
+ DP0("S60RadioTunerControl::MrftoForcedMonoChange ---");
+}
+
+void S60RadioTunerControl::MrftoSquelchChange(TBool aSquelch)
+{
+ DP0("S60RadioTunerControl::MrftoSquelchChange");
+
+ DP1("S60RadioTunerControl::MrftoSquelchChange, aSquelch:", aSquelch);
+
+ // no actions
+}
diff --git a/src/plugins/symbian/mmf/radio/s60radiotunercontrol_since32.h b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_since32.h
new file mode 100644
index 000000000..481d64c67
--- /dev/null
+++ b/src/plugins/symbian/mmf/radio/s60radiotunercontrol_since32.h
@@ -0,0 +1,296 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60RADIOTUNERCONTROL_H
+#define S60RADIOTUNERCONTROL_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qtimer.h>
+#include <qradiotunercontrol.h>
+#include <qradiotuner.h>
+
+#include <RadioUtility.h>
+#include <RadioFmTunerUtility.h>
+#include <RadioPlayerUtility.h>
+
+class S60RadioTunerService;
+class CFMRadioEngineCallObserver;
+
+QT_USE_NAMESPACE
+
+class S60RadioTunerControl
+ : public QRadioTunerControl
+ , public MRadioPlayerObserver
+ , public MRadioFmTunerObserver
+{
+ Q_OBJECT
+public:
+ S60RadioTunerControl(QObject *parent = 0);
+ ~S60RadioTunerControl();
+
+ QRadioTuner::State state() const;
+
+ QRadioTuner::Band band() const;
+ void setBand(QRadioTuner::Band b);
+ bool isBandSupported(QRadioTuner::Band b) const;
+
+ int frequency() const;
+ int frequencyStep(QRadioTuner::Band b) const;
+ QPair<int,int> frequencyRange(QRadioTuner::Band b) const;
+ void setFrequency(int frequency);
+
+ bool isStereo() const;
+ QRadioTuner::StereoMode stereoMode() const;
+ void setStereoMode(QRadioTuner::StereoMode mode);
+
+ int signalStrength() const;
+
+ int volume() const;
+ void setVolume(int volume);
+
+ bool isMuted() const;
+ void setMuted(bool muted);
+
+ bool isSearching() const;
+ void searchForward();
+ void searchBackward();
+ void cancelSearch();
+
+ bool isValid() const;
+
+ bool isAvailable() const;
+ QtMultimediaKit::AvailabilityError availabilityError() const;
+
+ void start();
+ void stop();
+
+ QRadioTuner::Error error() const;
+ QString errorString() const;
+
+ /**
+ * From MRadioPlayerObserver.
+ * Called when Radio state changed.
+ *
+ * @since S60 3.2
+ * @param aState Radio player state
+ * @param aError A standard system error code, only used when aState is ERadioPlayerIdle
+ */
+ void MrpoStateChange(TPlayerState aState, TInt aError);
+
+ /**
+ * From MRadioPlayerObserver.
+ * Called when volume changes. This may be caused by other applications.
+ *
+ * @since S60 3.2
+ * @param aVolume Current volume.
+ */
+ void MrpoVolumeChange(TInt aVolume);
+
+ /**
+ * From MRadioPlayerObserver.
+ * Called when mute setting changes. This may be caused by other applications.
+ *
+ * @since S60 3.2
+ * @param aMute ETrue indicates audio is muted.
+ */
+ void MrpoMuteChange(TBool aMute);
+
+ /**
+ * From MRadioPlayerObserver.
+ * Called when mute setting changes. This may be caused by other applications.
+ *
+ * Called when balance setting changes. This may be caused by other applications.
+ *
+ * @since S60 3.2
+ * Left speaker volume percentage. This can be any value from zero to 100.
+ * Zero value means left speaker is muted.
+ * @param aRightPercentage
+ * Right speaker volume percentage. This can be any value from zero to 100.
+ * Zero value means right speaker is muted.
+ */
+ void MrpoBalanceChange(TInt aLeftPercentage, TInt aRightPercentage);
+
+
+ /**
+ * From MRadioFmTunerObserver.
+ * Called when Request for tuner control completes.
+ *
+ * @since S60 3.2
+ * @param aError A standard system error code or FM tuner error (TFmRadioTunerError).
+ */
+ void MrftoRequestTunerControlComplete(TInt aError);
+
+ /**
+ * From MRadioFmTunerObserver.
+ * Set frequency range complete event. This event is asynchronous and is received after
+ * a call to CRadioFmTunerUtility::SetFrequencyRange.
+ *
+ * @since S60 3.2
+ * @param aError A standard system error code or FM tuner error (TFmRadioTunerError).
+ */
+ void MrftoSetFrequencyRangeComplete(TInt aError);
+
+ /**
+ * From MRadioFmTunerObserver.
+ * Set frequency complete event. This event is asynchronous and is received after a call to
+ * CRadioFmTunerUtility::SetFrequency.
+ *
+ * @since S60 3.2
+ * @param aError A standard system error code or FM tuner error (TFmRadioTunerError).
+ */
+ void MrftoSetFrequencyComplete(TInt aError);
+
+ /**
+ * From MRadioFmTunerObserver.
+ * Station seek complete event. This event is asynchronous and is received after a call to
+ * CRadioFmTunerUtility::StationSeek.
+ *
+ * @since S60 3.2
+ * @param aError A standard system error code or FM tuner error (TFmRadioTunerError).
+ * @param aFrequency The frequency(Hz) of the radio station that was found.
+ */
+ void MrftoStationSeekComplete(TInt aError, TInt aFrequency);
+
+ /**
+ * From MRadioFmTunerObserver.
+ * Called when FM Transmitter status changes (if one is present in the device). Tuner receiver
+ * is forced to be turned off due to hardware conflicts when FM transmitter is activated.
+ *
+ * @since S60 3.2
+ * @param aActive ETrue if FM transmitter is active; EFalse otherwise.
+ */
+ void MrftoFmTransmitterStatusChange(TBool aActive);
+
+ /**
+ * From MRadioFmTunerObserver.
+ * Called when antenna status changes.
+ *
+ * @since S60 3.2
+ * @param aAttached ETrue if antenna is attached; EFalse otherwise.
+ */
+ void MrftoAntennaStatusChange(TBool aAttached);
+
+ /**
+ * From MRadioFmTunerObserver.
+ * Called when offline mode status changes.
+ * @since S60 3.2
+ *
+ ** @param aAttached ETrue if offline mode is enabled; EFalse otherwise.
+ */
+ void MrftoOfflineModeStatusChange(TBool aOfflineMode);
+
+ /**
+ * From MRadioFmTunerObserver.
+ * Called when the frequency range changes. This may be caused by other applications.
+ *
+ * @since S60 3.2
+ * @param aNewRange New frequency range.
+ */
+ void MrftoFrequencyRangeChange(TFmRadioFrequencyRange aBand /*, TInt aMinFreq, TInt aMaxFreq*/);
+
+ /**
+ * From MRadioFmTunerObserver.
+ * Called when the tuned frequency changes. This may be caused by other
+ * applications or RDS if AF/TA is enabled.
+ *
+ * @since S60 3.2
+ * @param aNewFrequency The new tuned frequency(Hz).
+ */
+ void MrftoFrequencyChange(TInt aNewFrequency);
+
+ /**
+ * From MRadioFmTunerObserver.
+ * Called when the forced mono status change. This may be caused by other applications.
+ *
+ * @since S60 3.2
+ * @param aForcedMono ETrue if forced mono mode is enabled; EFalse otherwise.
+ */
+ void MrftoForcedMonoChange(TBool aForcedMono);
+
+ /**
+ * From MRadioFmTunerObserver.
+ * Called when the squelch (muting the frequencies without broadcast) status change.
+ * This may be caused by other applications.
+ *
+ * @since S60 3.2
+ * @param aSquelch ETrue if squelch is enabled; EFalse otherwise.
+ */
+ void MrftoSquelchChange(TBool aSquelch);
+
+private:
+ bool initRadio();
+
+ mutable int m_error;
+
+ CRadioUtility* m_radioUtility;
+ CRadioFmTunerUtility* m_fmTunerUtility;
+ CRadioPlayerUtility* m_playerUtility;
+ TInt m_maxVolume;
+ TReal m_volMultiplier;
+
+ bool m_tunerControl;
+ bool m_audioInitializationComplete;
+ bool m_muted;
+ bool m_isStereo;
+ bool m_available;
+ int m_vol;
+ bool m_volChangeRequired;
+ mutable int m_signal;
+ int m_previousSignal;
+ bool m_scanning;
+ QRadioTuner::Band m_currentBand;
+ qint64 m_currentFreq;
+
+ QRadioTuner::Error m_radioError;
+ QRadioTuner::StereoMode m_stereoMode;
+ QString m_errorString;
+ QRadioTuner::State m_apiTunerState;
+ QTimer *m_signalStrengthTimer;
+
+Q_SIGNALS:
+ void error(QRadioTuner::Error) const;
+
+protected slots:
+ void changeSignalStrength();
+};
+
+#endif
+
diff --git a/src/plugins/symbian/mmf/radio/s60radiotunerservice.cpp b/src/plugins/symbian/mmf/radio/s60radiotunerservice.cpp
new file mode 100644
index 000000000..99b0bf0d2
--- /dev/null
+++ b/src/plugins/symbian/mmf/radio/s60radiotunerservice.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "DebugMacros.h"
+
+#include "s60radiotunerservice.h"
+
+
+S60RadioTunerService::S60RadioTunerService(QObject *parent)
+ : QMediaService(parent)
+{
+ DP0("S60RadioTunerService::S60RadioTunerService +++");
+
+ m_playerControl = new S60RadioTunerControl(this);
+
+ DP0("S60RadioTunerService::S60RadioTunerService ---");
+}
+
+S60RadioTunerService::~S60RadioTunerService()
+{
+ DP0("S60RadioTunerService::~S60RadioTunerService +++");
+
+ delete m_playerControl;
+
+ DP0("S60RadioTunerService::~S60RadioTunerService ---");
+}
+
+QMediaControl *S60RadioTunerService::requestControl(const char* name)
+{
+ DP0("S60RadioTunerService::requestControl");
+
+ if (qstrcmp(name, QRadioTunerControl_iid) == 0)
+ return m_playerControl;
+
+ return 0;
+}
+
+void S60RadioTunerService::releaseControl(QMediaControl *control)
+{
+ DP0("S60RadioTunerService::releaseControl +++");
+
+ Q_UNUSED(control);
+
+ DP0("S60RadioTunerService::releaseControl ---");
+}
diff --git a/src/plugins/symbian/mmf/radio/s60radiotunerservice.h b/src/plugins/symbian/mmf/radio/s60radiotunerservice.h
new file mode 100644
index 000000000..92e3eb7f8
--- /dev/null
+++ b/src/plugins/symbian/mmf/radio/s60radiotunerservice.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60RADIOTUNERSERVICE_H
+#define S60RADIOTUNERSERVICE_H
+
+#include <QtCore/qobject.h>
+
+#include <qmediaservice.h>
+
+#ifdef TUNERLIBUSED
+#include "s60radiotunercontrol_31.h"
+#else
+#include "s60radiotunercontrol_since32.h"
+#endif
+
+QT_USE_NAMESPACE
+
+class S60RadioTunerService : public QMediaService
+{
+ Q_OBJECT
+public:
+ S60RadioTunerService(QObject *parent = 0);
+ ~S60RadioTunerService();
+
+ QMediaControl *requestControl(const char* name);
+ void releaseControl(QMediaControl *control);
+
+private:
+ S60RadioTunerControl *m_playerControl;
+};
+
+#endif
diff --git a/src/plugins/symbian/mmf/s60formatsupported.cpp b/src/plugins/symbian/mmf/s60formatsupported.cpp
new file mode 100644
index 000000000..e892008ab
--- /dev/null
+++ b/src/plugins/symbian/mmf/s60formatsupported.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "s60formatsupported.h"
+
+
+
+S60FormatSupported::S60FormatSupported()
+{}
+
+S60FormatSupported::~S60FormatSupported()
+{
+ if (m_controllerparam) {
+ delete m_controllerparam;
+ m_controllerparam = NULL;
+ }
+}
+
+QStringList S60FormatSupported::supportedPlayMimeTypesL()
+{
+
+ RArray<TUid> mediaIds; //search for both audio and video
+
+ RMMFControllerImplInfoArray iControllers;
+
+ m_controllerparam = CMMFControllerPluginSelectionParameters::NewL();
+
+ m_playformatparam = CMMFFormatSelectionParameters::NewL();
+
+ mediaIds.Append(KUidMediaTypeAudio);
+
+ mediaIds.Append(KUidMediaTypeVideo);
+
+ m_controllerparam->SetMediaIdsL(mediaIds, CMMFPluginSelectionParameters::EAllowOtherMediaIds);
+
+ m_controllerparam->SetRequiredPlayFormatSupportL(*m_playformatparam);
+
+ m_controllerparam->ListImplementationsL(iControllers);
+
+ CDesC8ArrayFlat* controllerArray = new (ELeave) CDesC8ArrayFlat(1);
+
+ for (TInt i = 0; i < iControllers.Count(); i++) {
+ for (TInt j = 0; j < (iControllers[i]->PlayFormats()).Count(); j++) {
+ const CDesC8Array& iarr = (iControllers[i]->PlayFormats()[j]->SupportedMimeTypes());
+
+ TInt count = iarr.Count();
+
+ for (TInt k = 0; k < count; k++) {
+ TPtrC8 ptr = iarr.MdcaPoint(k);
+
+ HBufC8* n = HBufC8::NewL(ptr.Length());
+
+ TPtr8 ptr1 = n->Des();
+
+ ptr1.Copy((TUint8*) ptr.Ptr(), ptr.Length());
+
+ controllerArray->AppendL(ptr1);
+ }
+ }
+ }
+
+// converting CDesC8Array to QStringList
+ for (TInt x = 0; x < controllerArray->Count(); x++) {
+ m_supportedplaymime.append(QString::fromUtf8(
+ (const char*) (controllerArray->MdcaPoint(x).Ptr()),
+ controllerArray->MdcaPoint(x).Length()));
+ }
+
+ // populating the list with only audio and controller mime types
+ QStringList tempaudio = m_supportedplaymime.filter(QString("audio"));
+ QStringList tempvideo = m_supportedplaymime.filter(QString("video"));
+
+ m_supportedplaymime.clear();
+
+ m_supportedplaymime = tempaudio + tempvideo;
+
+ mediaIds.Close();
+ delete controllerArray;
+ iControllers.ResetAndDestroy();
+
+ return m_supportedplaymime;
+}
diff --git a/src/plugins/symbian/mmf/s60formatsupported.h b/src/plugins/symbian/mmf/s60formatsupported.h
new file mode 100644
index 000000000..3b5a3ffe6
--- /dev/null
+++ b/src/plugins/symbian/mmf/s60formatsupported.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60FORMATSUPPORTED_H_
+#define S60FORMATSUPPORTED_H_
+
+#include <mmf/common/mmfcontrollerpluginresolver.h>
+#include <mmf/server/mmfdatasourcesink.hrh>
+#include <qstringlist.h>
+#include <badesca.h>
+#include <qstring.h>
+
+class S60FormatSupported
+{
+public:
+ S60FormatSupported();
+ ~S60FormatSupported();
+
+ QStringList supportedPlayMimeTypesL();
+
+private:
+
+ CMMFFormatSelectionParameters* m_playformatparam;
+ CMMFControllerPluginSelectionParameters* m_controllerparam;
+ QStringList m_supportedplaymime;
+};
+#endif /* S60FORMATSUPPORTED_H_ */
diff --git a/src/plugins/symbian/mmf/s60mediaserviceplugin.cpp b/src/plugins/symbian/mmf/s60mediaserviceplugin.cpp
new file mode 100644
index 000000000..cfb77255f
--- /dev/null
+++ b/src/plugins/symbian/mmf/s60mediaserviceplugin.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+#include <QtCore/qdebug.h>
+
+#include "s60mediaserviceplugin.h"
+#if defined(TUNERLIBUSED) || defined(RADIOUTILITYLIBUSED)
+#include "s60radiotunerservice.h"
+#endif
+#ifdef HAS_MEDIA_PLAYER
+#include "s60mediaplayerservice.h"
+#endif
+#ifdef AUDIOSOURCEUSED
+#include "s60audiocaptureservice.h"
+#endif /* AUDIOSOURCEUSED */
+
+QStringList S60MediaServicePlugin::keys() const
+{
+ QStringList list;
+#if defined(TUNERLIBUSED) || defined(RADIOUTILITYLIBUSED)
+ list << QLatin1String(Q_MEDIASERVICE_RADIO);
+#endif
+
+#ifdef HAS_MEDIA_PLAYER
+ list << QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER);
+#endif
+#ifdef AUDIOSOURCEUSED
+ list << QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE);
+#endif /* AUDIOSOURCEUSED */
+ return list;
+}
+
+QMediaService* S60MediaServicePlugin::create(QString const& key)
+{
+#ifdef HAS_MEDIA_PLAYER
+ if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
+ return new S60MediaPlayerService;
+#endif
+#ifdef AUDIOSOURCEUSED
+ if (key == QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE))
+ return new S60AudioCaptureService;
+#endif /* AUDIOSOURCEUSED */
+#if defined(TUNERLIBUSED) || defined(RADIOUTILITYLIBUSED)
+ if (key == QLatin1String(Q_MEDIASERVICE_RADIO))
+ return new S60RadioTunerService;
+#endif
+
+ return 0;
+}
+
+void S60MediaServicePlugin::release(QMediaService *service)
+{
+ delete service;
+}
+
+QtMultimediaKit::SupportEstimate S60MediaServicePlugin::hasSupport(const QString &mimeType, const QStringList& codecs) const
+{
+ Q_UNUSED(mimeType);
+ Q_UNUSED(codecs);
+ return QtMultimediaKit::PreferredService;
+}
+
+QStringList S60MediaServicePlugin::supportedMimeTypes() const
+{
+ if (m_supportedmimetypes.isEmpty()) {
+ TInt err;
+ S60FormatSupported* formats = new (ELeave) S60FormatSupported();
+ if (formats) {
+ TRAP(err, m_supportedmimetypes = formats->supportedPlayMimeTypesL());
+ delete formats;
+ }
+ }
+ return m_supportedmimetypes;
+}
+
+Q_EXPORT_PLUGIN2(qtmultimediakit_mmfengine, S60MediaServicePlugin);
diff --git a/src/plugins/symbian/mmf/s60mediaserviceplugin.h b/src/plugins/symbian/mmf/s60mediaserviceplugin.h
new file mode 100644
index 000000000..b2140dd6f
--- /dev/null
+++ b/src/plugins/symbian/mmf/s60mediaserviceplugin.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef S60SERVICEPLUGIN_H
+#define S60SERVICEPLUGIN_H
+
+#include <QtCore/qobject.h>
+#include <qmediaservice.h>
+#include <qmediaserviceproviderplugin.h>
+#include "s60formatsupported.h"
+
+QT_USE_NAMESPACE
+
+class S60MediaServicePlugin : public QMediaServiceProviderPlugin,public QMediaServiceSupportedFormatsInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QMediaServiceSupportedFormatsInterface)
+public:
+
+ QStringList keys() const;
+ QMediaService* create(QString const& key);
+ void release(QMediaService *service);
+
+ QtMultimediaKit::SupportEstimate hasSupport(const QString &mimeType, const QStringList& codecs) const;
+ QStringList supportedMimeTypes() const;
+private:
+ mutable QStringList m_supportedmimetypes;
+};
+
+#endif // S60SERVICEPLUGIN_H
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/mediaplayer.pri b/src/plugins/symbian/openmaxal/mediaplayer/mediaplayer.pri
new file mode 100644
index 000000000..7c6843e19
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/mediaplayer.pri
@@ -0,0 +1,36 @@
+INCLUDEPATH += $$PWD
+
+LIBS += \
+ -lws32 \
+ -lcone
+
+#DEFINES += USE_VIDEOPLAYERUTILITY
+
+HEADERS += \
+ $$PWD/qxametadatacontrol.h \
+ $$PWD/qxamediastreamscontrol.h \
+ $$PWD/qxamediaplayercontrol.h \
+ $$PWD/qxaplaymediaservice.h \
+ $$PWD/qxaplaysession.h \
+ $$PWD/xaplaysessioncommon.h \
+ $$PWD/qxavideowidgetcontrol.h \
+ $$PWD/qxavideowindowcontrol.h \
+ $$PWD/qxawidget.h \
+ $$PWD/xaplaysessionimpl.h
+
+SOURCES += \
+ $$PWD/qxamediaplayercontrol.cpp \
+ $$PWD/qxametadatacontrol.cpp \
+ $$PWD/qxamediastreamscontrol.cpp \
+ $$PWD/qxaplaymediaservice.cpp \
+ $$PWD/qxaplaysession.cpp \
+ $$PWD/qxavideowidgetcontrol.cpp \
+ $$PWD/qxavideowindowcontrol.cpp \
+ $$PWD/qxawidget.cpp \
+ $$PWD/xaplaysessionimpl.cpp
+
+# check for USE_VIDEOPLAYERUTILITY
+contains(DEFINES, USE_VIDEOPLAYERUTILITY) {
+ message("Using VideoPlayerUtility instead of OpenMAX AL.")
+ LIBS += -lmediaclientvideo
+}
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxamediaplayercontrol.cpp b/src/plugins/symbian/openmaxal/mediaplayer/qxamediaplayercontrol.cpp
new file mode 100644
index 000000000..ee192105b
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxamediaplayercontrol.cpp
@@ -0,0 +1,288 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtCore/qurl.h>
+#include "qxamediaplayercontrol.h"
+#include "qxaplaysession.h"
+#include "qxacommon.h"
+
+QXAMediaPlayerControl::QXAMediaPlayerControl(QXAPlaySession *session, QObject *parent)
+ :QMediaPlayerControl(parent), mSession(session)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ connect(mSession, SIGNAL(mediaChanged(const QMediaContent &)),
+ this, SIGNAL(mediaChanged(const QMediaContent& )));
+ connect(mSession, SIGNAL(durationChanged(qint64)),
+ this, SIGNAL(durationChanged(qint64)));
+ connect(mSession, SIGNAL(positionChanged(qint64)),
+ this, SIGNAL(positionChanged(qint64)));
+ connect(mSession, SIGNAL(stateChanged(QMediaPlayer::State)),
+ this, SIGNAL(stateChanged(QMediaPlayer::State)));
+ connect(mSession, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
+ this, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)));
+ connect(mSession, SIGNAL(volumeChanged(int)),
+ this, SIGNAL(volumeChanged(int)));
+ connect(mSession, SIGNAL(mutedChanged(bool)),
+ this, SIGNAL(mutedChanged(bool)));
+ connect(mSession, SIGNAL(audioAvailableChanged(bool)),
+ this, SIGNAL(audioAvailableChanged(bool)));
+ connect(mSession, SIGNAL(videoAvailableChanged(bool)),
+ this, SIGNAL(videoAvailableChanged(bool)));
+ connect(mSession,SIGNAL(bufferStatusChanged(int)),
+ this, SIGNAL(bufferStatusChanged(int)));
+ connect(mSession, SIGNAL(seekableChanged(bool)),
+ this, SIGNAL(seekableChanged(bool)));
+ connect(mSession, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)),
+ this, SIGNAL(availablePlaybackRangesChanged(const QMediaTimeRange&)));
+ connect(mSession, SIGNAL(playbackRateChanged(qreal)),
+ this, SIGNAL(playbackRateChanged(qreal)));
+ connect(mSession, SIGNAL(error(int, const QString &)),
+ this, SIGNAL(error(int, const QString &)));
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+QXAMediaPlayerControl::~QXAMediaPlayerControl()
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+QMediaPlayer::State QXAMediaPlayerControl::state() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ QMediaPlayer::State retVal = QMediaPlayer::StoppedState;
+ RET_s_IF_p_IS_NULL(mSession, retVal);
+ retVal = mSession->state();
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+QMediaPlayer::MediaStatus QXAMediaPlayerControl::mediaStatus() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ QMediaPlayer::MediaStatus retVal = QMediaPlayer::NoMedia;
+ RET_s_IF_p_IS_NULL(mSession, retVal);
+ retVal = mSession->mediaStatus();
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+qint64 QXAMediaPlayerControl::duration() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ qint64 retVal = 0;
+ RET_s_IF_p_IS_NULL(mSession, retVal);
+ retVal = mSession->duration();
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+qint64 QXAMediaPlayerControl::position() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ qint64 retVal = 0;
+ RET_s_IF_p_IS_NULL(mSession, retVal);
+ retVal = mSession->position();
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+void QXAMediaPlayerControl::setPosition(qint64 pos)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ RET_IF_p_IS_NULL(mSession);
+ mSession->setPosition(pos);
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+int QXAMediaPlayerControl::volume() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ int retVal = 0;
+ RET_s_IF_p_IS_NULL(mSession, retVal);
+ retVal = mSession->volume();
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+void QXAMediaPlayerControl::setVolume(int volume)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ RET_IF_p_IS_NULL(mSession);
+ mSession->setVolume(volume);
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+bool QXAMediaPlayerControl::isMuted() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ bool retVal = false;
+ RET_s_IF_p_IS_NULL(mSession, retVal);
+ retVal = mSession->isMuted();
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+void QXAMediaPlayerControl::setMuted(bool muted)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ RET_IF_p_IS_NULL(mSession);
+ mSession->setMuted(muted);
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+int QXAMediaPlayerControl::bufferStatus() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ int retVal = 0;
+ RET_s_IF_p_IS_NULL(mSession, retVal);
+ retVal = mSession->bufferStatus();
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+bool QXAMediaPlayerControl::isAudioAvailable() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ bool retVal = false;
+ RET_s_IF_p_IS_NULL(mSession, retVal);
+ retVal = mSession->isAudioAvailable();
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+bool QXAMediaPlayerControl::isVideoAvailable() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ bool retVal = false;
+ RET_s_IF_p_IS_NULL(mSession, retVal);
+ retVal = mSession->isVideoAvailable();
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+bool QXAMediaPlayerControl::isSeekable() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ bool retVal = false;
+ RET_s_IF_p_IS_NULL(mSession, retVal);
+ retVal = mSession->isSeekable();
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+QMediaTimeRange QXAMediaPlayerControl::availablePlaybackRanges() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ QMediaTimeRange retVal;
+ RET_s_IF_p_IS_NULL(mSession, retVal);
+ if (mSession->isSeekable())
+ retVal.addInterval(0, mSession->duration());
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+float QXAMediaPlayerControl::playbackRate() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ float retVal = 0;
+ RET_s_IF_p_IS_NULL(mSession, retVal);
+ retVal = mSession->playbackRate();
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+void QXAMediaPlayerControl::setPlaybackRate(float rate)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ RET_IF_p_IS_NULL(mSession);
+ mSession->setPlaybackRate(rate);
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+QMediaContent QXAMediaPlayerControl::media() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ QMediaContent retVal;
+ RET_s_IF_p_IS_NULL(mSession, retVal);
+ retVal = mSession->media();
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+const QIODevice *QXAMediaPlayerControl::mediaStream() const
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return mStream;
+}
+
+void QXAMediaPlayerControl::setMedia(const QMediaContent &content, QIODevice *stream)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ RET_IF_p_IS_NULL(mSession);
+ mSession->setMedia(content);
+ mStream = stream;
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXAMediaPlayerControl::play()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ RET_IF_p_IS_NULL(mSession);
+ mSession->play();
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXAMediaPlayerControl::pause()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ RET_IF_p_IS_NULL(mSession);
+ mSession->pause();
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXAMediaPlayerControl::stop()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ RET_IF_p_IS_NULL(mSession);
+ mSession->stop();
+ QT_TRACE_FUNCTION_EXIT;
+}
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxamediaplayercontrol.h b/src/plugins/symbian/openmaxal/mediaplayer/qxamediaplayercontrol.h
new file mode 100644
index 000000000..b9d7802bd
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxamediaplayercontrol.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXAMEDIAPLAYERCONTROL_H
+#define QXAMEDIAPLAYERCONTROL_H
+
+#include "qmediaplayercontrol.h"
+#include "qmediaplayer.h"
+
+QT_USE_NAMESPACE
+
+class QXAPlaySession;
+
+class QXAMediaPlayerControl : public QMediaPlayerControl
+{
+ Q_OBJECT
+public:
+ QXAMediaPlayerControl(QXAPlaySession *session, QObject *parent = 0);
+ ~QXAMediaPlayerControl();
+
+ QMediaPlayer::State state() const;
+ QMediaPlayer::MediaStatus mediaStatus() const;
+
+ qint64 duration() const;
+
+ qint64 position() const;
+ void setPosition(qint64 position);
+
+ int volume() const;
+ void setVolume(int volume);
+
+ bool isMuted() const;
+ void setMuted(bool muted);
+
+ int bufferStatus() const;
+
+ bool isAudioAvailable() const;
+ bool isVideoAvailable() const;
+
+ bool isSeekable() const;
+
+ QMediaTimeRange availablePlaybackRanges() const;
+
+ float playbackRate() const;
+ void setPlaybackRate(float rate);
+
+ QMediaContent media() const;
+ const QIODevice *mediaStream() const;
+ void setMedia(const QMediaContent&, QIODevice *);
+
+ void play();
+ void pause();
+ void stop();
+
+
+private:
+ QXAPlaySession *mSession;
+ QIODevice *mStream;
+};
+
+#endif /* QXAMEDIAPLAYERCONTROL_H */
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxamediastreamscontrol.cpp b/src/plugins/symbian/openmaxal/mediaplayer/qxamediastreamscontrol.cpp
new file mode 100644
index 000000000..528fb1837
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxamediastreamscontrol.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtCore/qurl.h>
+
+#include "qxamediastreamscontrol.h"
+#include "qxaplaysession.h"
+#include "qxacommon.h"
+
+QXAMediaStreamsControl::QXAMediaStreamsControl(QXAPlaySession *session, QObject *parent)
+ :QMediaStreamsControl(parent), mSession(session)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ connect(mSession, SIGNAL(activeStreamsChanged()),
+ this, SIGNAL(activeStreamsChanged()));
+ connect(mSession, SIGNAL(streamsChanged()),
+ this, SIGNAL(streamsChanged()));
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+QXAMediaStreamsControl::~QXAMediaStreamsControl()
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+bool QXAMediaStreamsControl::isActive (int stream)
+{
+ RET_s_IF_p_IS_NULL(mSession, false);
+ return mSession->isStreamActive(stream);
+}
+
+QVariant QXAMediaStreamsControl::metaData (int stream, QtMultimediaKit::MetaData key)
+{
+ QVariant var;
+ RET_s_IF_p_IS_NULL(mSession, var);
+ QT_TRACE_FUNCTION_ENTRY;
+ var = mSession->metaData(stream, key);
+ QT_TRACE_FUNCTION_EXIT;
+ return var;
+}
+
+void QXAMediaStreamsControl::setActive (int stream, bool state)
+{
+ Q_UNUSED(stream);
+ Q_UNUSED(state);
+}
+
+int QXAMediaStreamsControl::streamCount()
+{
+ RET_s_IF_p_IS_NULL(mSession, 0);
+ return mSession->streamCount();
+}
+
+QMediaStreamsControl::StreamType QXAMediaStreamsControl::streamType (int stream)
+{
+ RET_s_IF_p_IS_NULL(mSession, QMediaStreamsControl::UnknownStream);
+ return mSession->streamType(stream);
+}
+
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxamediastreamscontrol.h b/src/plugins/symbian/openmaxal/mediaplayer/qxamediastreamscontrol.h
new file mode 100644
index 000000000..d77b89ca5
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxamediastreamscontrol.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QXAMEDIASTREAMSCONTROL_H
+#define QXAMEDIASTREAMSCONTROL_H
+
+
+
+#include <QStringList>
+#include <QList>
+#include <QVariant>
+#include <QString>
+
+#include <qtmedianamespace.h>
+
+#include <qmediastreamscontrol.h>
+
+QT_USE_NAMESPACE
+
+class QXAPlaySession;
+
+class QXAMediaStreamsControl : public QMediaStreamsControl
+{
+ Q_OBJECT
+public:
+ QXAMediaStreamsControl(QXAPlaySession *session, QObject *parent = 0);
+ ~QXAMediaStreamsControl();
+
+ bool isActive (int stream);
+ QVariant metaData (int stream, QtMultimediaKit::MetaData key);
+ void setActive (int stream, bool state);
+ int streamCount();
+ QMediaStreamsControl::StreamType streamType (int stream);
+private:
+ QXAPlaySession *mSession;
+};
+
+#endif //QXAMEDIASTREAMSCONTROL_H
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxametadatacontrol.cpp b/src/plugins/symbian/openmaxal/mediaplayer/qxametadatacontrol.cpp
new file mode 100644
index 000000000..9c6b906cf
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxametadatacontrol.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qurl.h>
+
+#include "qxametadatacontrol.h"
+#include "qxaplaysession.h"
+#include "qxacommon.h"
+
+QXAMetaDataControl::QXAMetaDataControl(QXAPlaySession *session, QObject *parent)
+ :QMetaDataReaderControl(parent), mSession(session)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ connect(mSession, SIGNAL(metaDataAvailableChanged(bool)),
+ this, SIGNAL(metaDataAvailableChanged(bool)));
+ connect(mSession, SIGNAL(metaDataChanged()),
+ this, SIGNAL(metaDataChanged()));
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+QXAMetaDataControl::~QXAMetaDataControl()
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+QStringList QXAMetaDataControl::availableExtendedMetaData ()const
+{
+ QStringList list;
+ RET_s_IF_p_IS_NULL(mSession, list);
+ QT_TRACE_FUNCTION_ENTRY;
+ list = mSession->availableExtendedMetaData();
+ QT_TRACE_FUNCTION_EXIT;
+ return list;
+}
+
+QList<QtMultimediaKit::MetaData> QXAMetaDataControl::availableMetaData () const
+{
+ QList<QtMultimediaKit::MetaData> list;
+ RET_s_IF_p_IS_NULL(mSession, list);
+ QT_TRACE_FUNCTION_ENTRY;
+ list = mSession->availableMetaData();
+ QT_TRACE_FUNCTION_EXIT;
+ return list;
+}
+
+QVariant QXAMetaDataControl::extendedMetaData(const QString & key ) const
+{
+ QVariant var;
+ RET_s_IF_p_IS_NULL(mSession, var);
+ QT_TRACE_FUNCTION_ENTRY;
+ var = mSession->extendedMetaData(key);
+ QT_TRACE_FUNCTION_EXIT;
+ return var;
+}
+
+bool QXAMetaDataControl::isMetaDataAvailable() const
+{
+ RET_s_IF_p_IS_NULL(mSession, false);
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return mSession->isMetaDataAvailable();
+}
+
+bool QXAMetaDataControl::isWritable() const
+{
+ RET_s_IF_p_IS_NULL(mSession, false);
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return mSession->isWritable();
+}
+
+QVariant QXAMetaDataControl::metaData( QtMultimediaKit::MetaData key ) const
+{
+ QVariant var;
+ RET_s_IF_p_IS_NULL(mSession, var);
+ QT_TRACE_FUNCTION_ENTRY;
+ var = mSession->metaData(key);
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return var;
+}
+
+void QXAMetaDataControl::setExtendedMetaData( const QString & key, const QVariant & value )
+{
+ RET_IF_p_IS_NULL(mSession);
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return mSession->setExtendedMetaData(key,value);
+}
+
+void QXAMetaDataControl::setMetaData( QtMultimediaKit::MetaData key, const QVariant & value )
+{
+ RET_IF_p_IS_NULL(mSession);
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return mSession->setMetaData(key,value);
+}
+
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxametadatacontrol.h b/src/plugins/symbian/openmaxal/mediaplayer/qxametadatacontrol.h
new file mode 100644
index 000000000..8904a5ff4
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxametadatacontrol.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXAMETADATACONTROL_H
+#define QXAMETADATACONTROL_H
+
+
+
+#include <QStringList>
+#include <QList>
+#include <QVariant>
+#include <QString>
+
+#include <qmetadatareadercontrol.h>
+#include <qtmedianamespace.h>
+QT_USE_NAMESPACE
+
+class QXAPlaySession;
+
+class QXAMetaDataControl : public QMetaDataReaderControl
+{
+ Q_OBJECT
+public:
+ QXAMetaDataControl(QXAPlaySession *session, QObject *parent = 0);
+ ~QXAMetaDataControl();
+
+ QStringList availableExtendedMetaData () const;
+ QList<QtMultimediaKit::MetaData> availableMetaData () const;
+ QVariant extendedMetaData(const QString & key ) const;
+ bool isMetaDataAvailable() const;
+ bool isWritable() const;
+ QVariant metaData( QtMultimediaKit::MetaData key ) const;
+ void setExtendedMetaData( const QString & key, const QVariant & value );
+ void setMetaData( QtMultimediaKit::MetaData key, const QVariant & value );
+
+private:
+ QXAPlaySession *mSession;
+};
+
+#endif //QXAMETADATACONTROL_H
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxaplaymediaservice.cpp b/src/plugins/symbian/openmaxal/mediaplayer/qxaplaymediaservice.cpp
new file mode 100644
index 000000000..f2d3c4b15
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxaplaymediaservice.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QString>
+#include "qxaplaymediaservice.h"
+#include "qxaplaysession.h"
+#include "qxamediaplayercontrol.h"
+#include "qxacommon.h"
+#include "qxavideowidgetcontrol.h"
+#include "qxavideowindowcontrol.h"
+#include "qxametadatacontrol.h"
+#include "qxamediastreamscontrol.h"
+
+QXAPlayMediaService::QXAPlayMediaService(QObject *parent) : QMediaService(parent)
+{
+ mSession = NULL;
+ mMediaPlayerControl = NULL;
+ mVideowidgetControl = NULL;
+ mVideoWindowControl = NULL;
+ mMetaDataControl = NULL;
+ mMediaStreamsControl = NULL;
+
+ mSession = new QXAPlaySession(this);
+ mMediaPlayerControl = new QXAMediaPlayerControl(mSession, this);
+ mMetaDataControl = new QXAMetaDataControl(mSession, this);
+ mMediaStreamsControl = new QXAMediaStreamsControl(mSession, this);
+}
+
+QXAPlayMediaService::~QXAPlayMediaService()
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+QMediaControl *QXAPlayMediaService::requestControl(const char *name)
+{
+ if (qstrcmp(name, QMediaPlayerControl_iid) == 0) {
+ return mMediaPlayerControl;
+ }
+ else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
+ if (!mVideowidgetControl) {
+ mVideowidgetControl = new QXAVideoWidgetControl(mSession, this);
+ if (mSession && mVideowidgetControl)
+ mSession->setVideoWidgetControl(mVideowidgetControl);
+ }
+ return mVideowidgetControl;
+ }
+ else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
+ if (!mVideoWindowControl) {
+ mVideoWindowControl = new QXAVideoWindowControl(mSession, this);
+ if (mSession && mVideoWindowControl)
+ mSession->setVideoWindowControl(mVideoWindowControl);
+ }
+ return mVideoWindowControl;
+ }
+ else if (qstrcmp(name,QMetaDataReaderControl_iid) == 0) {
+ return mMetaDataControl;
+ }
+ else if (qstrcmp(name,QMediaStreamsControl_iid) == 0) {
+ return mMediaStreamsControl;
+ }
+
+ return 0;
+}
+
+void QXAPlayMediaService::releaseControl(QMediaControl *control)
+{
+ if (control == mVideowidgetControl) {
+ if (mSession)
+ mSession->unsetVideoWidgetControl(qobject_cast<QXAVideoWidgetControl*>(control));
+ mVideowidgetControl = NULL;
+ }
+ else if (control == mVideoWindowControl) {
+ if (mSession)
+ mSession->unsetVideoWindowControl(qobject_cast<QXAVideoWindowControl*>(control));
+ mVideoWindowControl = NULL;
+ }
+}
+
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxaplaymediaservice.h b/src/plugins/symbian/openmaxal/mediaplayer/qxaplaymediaservice.h
new file mode 100644
index 000000000..4a344b087
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxaplaymediaservice.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXAPLAYMEDIASERVICE_H
+#define QXAPLAYMEDIASERVICE_H
+
+#include <QtCore/qobject.h>
+#include <qmediaservice.h>
+
+QT_USE_NAMESPACE
+
+class QXAPlaySession;
+class QXAMediaPlayerControl;
+class QXAVideoWidgetControl;
+class QXAVideoWindowControl;
+class QXAMetaDataControl;
+class QXAMediaStreamsControl;
+
+class QXAPlayMediaService : public QMediaService
+{
+ Q_OBJECT
+public:
+ QXAPlayMediaService(QObject *parent = 0);
+ ~QXAPlayMediaService();
+ QMediaControl *requestControl(const char *name);
+ void releaseControl( QMediaControl *control);
+private:
+ QXAPlaySession *mSession;
+ QXAMediaPlayerControl *mMediaPlayerControl;
+ QXAVideoWidgetControl *mVideowidgetControl;
+ QXAVideoWindowControl *mVideoWindowControl;
+ QXAMetaDataControl *mMetaDataControl;
+ QXAMediaStreamsControl *mMediaStreamsControl;
+};
+
+#endif /* QXAPLAYMEDIASERVICE_H */
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxaplaysession.cpp b/src/plugins/symbian/openmaxal/mediaplayer/qxaplaysession.cpp
new file mode 100644
index 000000000..2254a9363
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxaplaysession.cpp
@@ -0,0 +1,610 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QMetaType>
+#include "qxaplaysession.h"
+#include "xaplaysessionimpl.h"
+#include "qxacommon.h"
+#include <COECNTRL.H>
+
+QXAPlaySession::QXAPlaySession(QObject *parent):QObject(parent),
+m_state(QMediaPlayer::StoppedState),
+m_mediaStatus(QMediaPlayer::NoMedia),
+mSeekable(-1),
+mNumStreams(0),
+mbAudioAvailable(EFalse),
+mbVideoAvailable(EFalse),
+mImpl(NULL),
+mVideowidgetControl(NULL),
+mWidgetCtrlWindow(NULL),
+mWidgetCtrlWindowId(NULL),
+mVideoWindowControl(NULL),
+mWindowCtrlWindow(NULL),
+mWindowCtrlWindowId(NULL),
+mWsSession(&(CCoeEnv::Static()->WsSession()))
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ mImpl = new XAPlaySessionImpl(*this);
+
+ if (mImpl && (mImpl->postConstruct() != KErrNone)) {
+ delete mImpl;
+ mImpl = NULL;
+ QT_TRACE1("Error initializing implementation");
+ }
+
+ if (!mImpl)
+ emit error(QMediaPlayer::ResourceError, tr("Service has not been started"));
+
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+QXAPlaySession::~QXAPlaySession()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ delete mImpl;
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXAPlaySession::setVideoWidgetControl( QXAVideoWidgetControl * videoWidgetControl )
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ if (mVideowidgetControl) {
+ disconnect(mVideowidgetControl, SIGNAL(widgetUpdated()),
+ this, SLOT(videoWidgetControlWidgetUpdated()));
+ RWindow* window = static_cast<RWindow*>(mVideowidgetControl->videoWidgetWId()->DrawableWindow());
+ mImpl->removeNativeDisplay(window, mWsSession);
+ }
+ mVideowidgetControl = videoWidgetControl;
+ if (mVideowidgetControl)
+ connect(mVideowidgetControl, SIGNAL(widgetUpdated()),
+ this, SLOT(videoWidgetControlWidgetUpdated()));
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXAPlaySession::unsetVideoWidgetControl( QXAVideoWidgetControl * videoWidgetControl )
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ if ((mVideowidgetControl == videoWidgetControl) && (mImpl)) {
+ disconnect(mVideowidgetControl, SIGNAL(widgetUpdated()),
+ this, SLOT(videoWidgetControlWidgetUpdated()));
+ RWindow* window = static_cast<RWindow*>(mVideowidgetControl->videoWidgetWId()->DrawableWindow());
+ mImpl->removeNativeDisplay(window, mWsSession);
+ }
+ mVideowidgetControl = NULL;
+ mWidgetCtrlWindow = NULL;
+ mWidgetCtrlWindowId = NULL;
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXAPlaySession::setVideoWindowControl( QXAVideoWindowControl * videoWindowControl )
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ if (mVideoWindowControl) {
+ disconnect(mVideoWindowControl, SIGNAL(windowUpdated()),
+ this, SLOT(videoWindowControlWindowUpdated()));
+ RWindow* window = static_cast<RWindow*>(mVideoWindowControl->winId()->DrawableWindow());
+ mImpl->removeNativeDisplay(window, mWsSession);
+ }
+ mVideoWindowControl = videoWindowControl;
+ if (mVideoWindowControl) {
+ connect(mVideoWindowControl, SIGNAL(windowUpdated()),
+ this, SLOT(videoWindowControlWindowUpdated()));
+ videoWindowControlWindowUpdated();
+ }
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXAPlaySession::unsetVideoWindowControl( QXAVideoWindowControl * videoWindowControl )
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ if ((mVideoWindowControl == videoWindowControl) && (mImpl)) {
+ disconnect(mVideoWindowControl, SIGNAL(windowUpdated()),
+ this, SLOT(videoWindowControlWindowUpdated()));
+ RWindow* window = static_cast<RWindow*>(mVideoWindowControl->winId()->DrawableWindow());
+ mImpl->removeNativeDisplay(window, mWsSession);
+ }
+ mVideoWindowControl = NULL;
+ mWindowCtrlWindow = NULL;
+ mWindowCtrlWindowId = NULL;
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+qint64 QXAPlaySession::duration()
+{
+ TInt64 dur(0);
+ if (mImpl)
+ mImpl->duration(dur);
+
+ return (qint64)dur;
+}
+
+qint64 QXAPlaySession::position()
+{
+ TInt64 pos(0);
+ if (mImpl)
+ mImpl->position(pos);
+
+ return (qint64)pos;
+}
+
+void QXAPlaySession::setPosition(qint64 ms)
+{
+ if (mImpl) {
+ qint64 currPos = position();
+ mImpl->seek(ms);
+
+ if(currPos != position()) {
+ emit positionChanged(position());
+
+ if(position()>=duration()) {
+ setMediaStatus(QMediaPlayer::EndOfMedia);
+ stop();
+ }
+ }
+ }
+}
+
+int QXAPlaySession::volume()
+{
+ if(mImpl) {
+ TInt v(0);
+
+ TInt err = mImpl->volume(v);
+ if(KErrNone == err)
+ return v;
+ }
+
+ return 50;
+}
+
+void QXAPlaySession::setVolume(int v)
+{
+ if(mImpl) {
+ if(v != volume()) {
+ TInt err = mImpl->setVolume(v);
+ if(KErrNone == err)
+ emit volumeChanged(volume());
+ }
+ }
+}
+
+
+bool QXAPlaySession::isMuted()
+{
+ if(mImpl) {
+ TBool bCurrMute = EFalse;
+ TInt err = mImpl->getMute(bCurrMute);
+ if(err == KErrNone)
+ return bCurrMute;
+ }
+
+ return EFalse;
+}
+
+void QXAPlaySession::setMuted(bool muted)
+{
+ if(muted != isMuted())
+ {
+ if(mImpl)
+ {
+ TInt err = mImpl->setMute(muted);
+
+ if(KErrNone == err)
+ {
+ emit mutedChanged(muted);
+ }
+ }
+ }
+}
+
+int QXAPlaySession::bufferStatus()
+{
+ if(mImpl) {
+ TInt fillLevel = 0;
+ TInt err = mImpl->bufferStatus(fillLevel);
+ if(err == KErrNone)
+ return fillLevel;
+ }
+
+ return 100;//default
+}
+
+bool QXAPlaySession::isAudioAvailable()
+{
+ return mbAudioAvailable;
+}
+
+bool QXAPlaySession::isVideoAvailable()
+{
+ return mbVideoAvailable;
+}
+
+bool QXAPlaySession::isSeekable()
+{
+ return ((mSeekable==1) || (mSeekable==-1));//default seekable
+}
+
+float QXAPlaySession::playbackRate()
+{
+ if(mImpl) {
+ TReal32 currPBRate = 0.0;
+ TInt ret = mImpl->getPlaybackRate(currPBRate);
+ if(ret == KErrNone)
+ return currPBRate;
+ }
+
+ return 1.0;
+}
+
+void QXAPlaySession::setPlaybackRate(float rate)
+{
+ if(mImpl) {
+ TReal32 currPBRate = 0.0;
+ TInt ret = mImpl->getPlaybackRate(currPBRate);
+ if( (ret == KErrNone) &&
+ (rate!=currPBRate)) {
+ ret = mImpl->setPlaybackRate(rate);
+ if(ret == KErrNone)
+ emit playbackRateChanged(rate);
+ }
+ }
+}
+
+QMediaContent QXAPlaySession::media()
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return mMediaContent;
+}
+
+void QXAPlaySession::setMedia(const QMediaContent& media)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ RET_IF_p_IS_NULL_EMIT_PLAYER_RESOURCE_ERROR(mImpl);
+
+ if (media.isNull() ||
+ mMediaContent == media) {
+ return;
+ }
+
+ setMediaStatus(QMediaPlayer::NoMedia);
+
+ QString urlStr = media.canonicalUrl().toString();
+ TPtrC16 urlPtr(reinterpret_cast<const TUint16*>(urlStr.utf16()));
+
+ setMediaStatus(QMediaPlayer::LoadingMedia);
+ if (mImpl->load(urlPtr) == 0) {
+ setMediaStatus(QMediaPlayer::LoadedMedia);
+ emit error(QMediaPlayer::NoError, "");
+ mMediaContent = media;
+ setPlayerState(QMediaPlayer::StoppedState);
+ emit mediaChanged(mMediaContent);
+
+ if(mImpl->isMetaDataAvailable()) {
+ emit metaDataAvailableChanged(true);
+ emit metaDataChanged();
+ }
+ else {
+ emit metaDataAvailableChanged(false);
+ }
+ }
+ else {
+ setMediaStatus(QMediaPlayer::NoMedia);
+ emit error(QMediaPlayer::ResourceError, tr("Unable to load media"));
+ }
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXAPlaySession::play()
+{
+ if (mImpl) {
+ setMediaStatus(QMediaPlayer::BufferingMedia);
+
+ TInt err = mImpl->play();
+ if (err != KErrNone) {
+ setMediaStatus(QMediaPlayer::NoMedia);
+ RET_IF_ERROR(err);
+ }
+ setPlayerState(QMediaPlayer::PlayingState);
+
+ TInt fillLevel = 0;
+ err = mImpl->bufferStatus(fillLevel);
+ RET_IF_ERROR(err);
+ if (fillLevel == 100) {
+ setMediaStatus(QMediaPlayer::BufferedMedia);
+ }
+ }
+}
+
+void QXAPlaySession::pause()
+{
+ if (mImpl) {
+ TInt err = mImpl->pause();
+ RET_IF_ERROR(err);
+ setPlayerState(QMediaPlayer::PausedState);
+ }
+}
+
+void QXAPlaySession::stop()
+{
+ if (mImpl) {
+ TInt err = mImpl->stop();
+ RET_IF_ERROR(err);
+ setPlayerState(QMediaPlayer::StoppedState);
+ }
+}
+
+void QXAPlaySession::cbDurationChanged(TInt64 new_dur)
+{
+ emit durationChanged((qint64)new_dur);
+}
+
+void QXAPlaySession::cbPositionChanged(TInt64 new_pos)
+{
+ emit positionChanged((qint64)new_pos);
+}
+
+void QXAPlaySession::cbSeekableChanged(TBool seekable)
+{
+ if( (mSeekable==-1) ||
+ (seekable != (TBool)mSeekable)) {
+ mSeekable = seekable?1:0;
+ emit seekableChanged((bool)seekable);
+ }
+}
+
+void QXAPlaySession::cbPlaybackStopped(TInt err)
+{
+ if (err) {
+ emit error(QMediaPlayer::ResourceError, tr("Resources Unavailable"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaPlayer::ResourceError, tr(\"Resources Unavailable\"))");
+ emit positionChanged(position());
+ setPlayerState(QMediaPlayer::StoppedState);
+ setMediaStatus(QMediaPlayer::NoMedia);
+ }
+ else {
+ setMediaStatus(QMediaPlayer::EndOfMedia);
+ /* Set player state to Stopped */
+ stop();
+ }
+}
+
+void QXAPlaySession::cbPrefetchStatusChanged()
+{
+ if(mImpl) {
+ TInt fillLevel = 0;
+ TInt err = mImpl->bufferStatus(fillLevel);
+ if(err == KErrNone) {
+ emit bufferStatusChanged(fillLevel);
+
+ if(fillLevel == 100)
+ setMediaStatus(QMediaPlayer::BufferedMedia);
+ else if(fillLevel ==0)
+ setMediaStatus(QMediaPlayer::StalledMedia);
+ }
+ }
+}
+
+void QXAPlaySession::cbStreamInformation(TBool bFirstTime)
+{
+ updateStreamInfo(bFirstTime);
+}
+
+
+
+void QXAPlaySession::videoWidgetControlWidgetUpdated()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ if (mVideowidgetControl) {
+ WId newId = mVideowidgetControl->videoWidgetWId();
+ if ((newId != NULL) && (newId != mWidgetCtrlWindowId)) {
+ mWidgetCtrlWindow = static_cast<RWindow*>(newId->DrawableWindow());
+ if (mWidgetCtrlWindowId == NULL)
+ mImpl->addNativeDisplay(mWidgetCtrlWindow, mWsSession);
+ else
+ mImpl->updateNativeDisplay(mWidgetCtrlWindow, mWsSession);
+ mWidgetCtrlWindowId = newId;
+ }
+ }
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXAPlaySession::videoWindowControlWindowUpdated()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ if (mVideoWindowControl) {
+ WId newId = mVideoWindowControl->winId();
+ if ((newId != NULL) && (newId != mWindowCtrlWindowId)) {
+ mWidgetCtrlWindow = static_cast<RWindow*>(newId->DrawableWindow());
+ if (mWindowCtrlWindowId == NULL)
+ mImpl->addNativeDisplay(mWidgetCtrlWindow, mWsSession);
+ else
+ mImpl->updateNativeDisplay(mWidgetCtrlWindow, mWsSession);
+ mWindowCtrlWindowId = newId;
+ }
+ }
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXAPlaySession::setMediaStatus(QMediaPlayer::MediaStatus status)
+{
+ if (m_mediaStatus != status) {
+ m_mediaStatus = status;
+ emit mediaStatusChanged(status);
+ }
+}
+
+void QXAPlaySession::setPlayerState(QMediaPlayer::State state)
+{
+ if (m_state != state) {
+ m_state = state;
+ emit stateChanged(m_state);
+ }
+}
+
+QStringList QXAPlaySession::availableExtendedMetaData () const
+{
+ QStringList list;
+ RET_s_IF_p_IS_NULL(mImpl, list);
+ list = mImpl->availableExtendedMetaData();
+ return list;
+}
+
+QList<QtMultimediaKit::MetaData> QXAPlaySession::availableMetaData () const
+{
+ QList<QtMultimediaKit::MetaData> list;
+ RET_s_IF_p_IS_NULL(mImpl, list);
+ return mImpl->availableMetaData();
+}
+
+QVariant QXAPlaySession::extendedMetaData(const QString & key ) const
+{
+ QVariant var;
+ RET_s_IF_p_IS_NULL(mImpl, var);
+ return mImpl->extendedMetaData(key);
+}
+
+bool QXAPlaySession::isMetaDataAvailable() const
+{
+ RET_s_IF_p_IS_NULL(mImpl, false);
+ return mImpl->isMetaDataAvailable();
+}
+
+bool QXAPlaySession::isWritable() const
+{
+ RET_s_IF_p_IS_NULL(mImpl, false);
+ return mImpl->isWritable();
+}
+
+QVariant QXAPlaySession::metaData( QtMultimediaKit::MetaData key ) const
+{
+ QVariant var;
+ RET_s_IF_p_IS_NULL(mImpl, var);
+ return mImpl->metaData(key);
+}
+
+void QXAPlaySession::setExtendedMetaData( const QString & key, const QVariant & value )
+{
+ RET_IF_p_IS_NULL(mImpl);
+ mImpl->setExtendedMetaData(key, value);
+}
+
+void QXAPlaySession::setMetaData( QtMultimediaKit::MetaData key, const QVariant & value )
+{
+ RET_IF_p_IS_NULL(mImpl);
+ mImpl->setMetaData(key, value);
+}
+
+void QXAPlaySession::updateStreamInfo(TBool emitSignal)
+{
+ if(mImpl) {
+ mNumStreams = 0;
+ TInt ret = mImpl->numMediaStreams(mNumStreams);
+ if(ret == KErrNone) {
+ TBool bAudioAvailable = EFalse;//lcoal variable
+ TBool bVideoAvailable = EFalse;//lcvoal variable
+
+ for(TUint i = 0; i < mNumStreams; i++) {
+ QMediaStreamsControl::StreamType strType;
+ mImpl->streamType(i, strType);
+ if(strType == QMediaStreamsControl::AudioStream)
+ bAudioAvailable = ETrue;
+ else if(strType == QMediaStreamsControl::VideoStream)
+ bVideoAvailable = ETrue;
+ }
+
+ if(emitSignal || (bAudioAvailable != mbAudioAvailable)) {
+ emit audioAvailableChanged(bAudioAvailable);
+ mbAudioAvailable = bAudioAvailable;
+ }
+
+ if(emitSignal || (bVideoAvailable != mbVideoAvailable)) {
+ emit videoAvailableChanged(bVideoAvailable);
+ mbVideoAvailable = bVideoAvailable;
+ }
+
+ emit streamsChanged();
+ }
+ }
+}
+
+bool QXAPlaySession::isStreamActive ( int stream )
+{
+ RET_s_IF_p_IS_NULL(mImpl, false);
+ TBool isActive = EFalse;
+ mImpl->isStreamActive(stream,isActive);
+ return isActive;
+}
+
+QVariant QXAPlaySession::metaData ( int /*stream*/, QtMultimediaKit::MetaData key )
+{
+ return this->metaData(key);
+}
+
+int QXAPlaySession::streamCount()
+{
+ return mNumStreams;
+}
+
+QMediaStreamsControl::StreamType QXAPlaySession::streamType ( int stream )
+{
+ QMediaStreamsControl::StreamType strType = QMediaStreamsControl::UnknownStream;
+ RET_s_IF_p_IS_NULL(mImpl, strType);
+ if(mImpl->streamType(stream, strType) == KErrNone) {
+ return strType;
+ }
+
+ return QMediaStreamsControl::UnknownStream;
+}
+
+////AspectRatioMode
+void QXAPlaySession::setAspectRatioMode(Qt::AspectRatioMode aspectRatioMode)
+{
+ RET_IF_p_IS_NULL(mImpl);
+ mImpl->setAspectRatioMode(aspectRatioMode);
+}
+
+Qt::AspectRatioMode QXAPlaySession::getAspectRatioMode()
+{
+ RET_s_IF_p_IS_NULL(mImpl, Qt::KeepAspectRatio);
+ return mImpl->getAspectRatioMode();
+}
+
+
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxaplaysession.h b/src/plugins/symbian/openmaxal/mediaplayer/qxaplaysession.h
new file mode 100644
index 000000000..0d366518f
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxaplaysession.h
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXAPLAYSESSION_H
+#define QXAPLAYSESSION_H
+
+#include <QObject>
+#include <QUrl>
+#include <qtmedianamespace.h>
+
+#include "qxamediaplayercontrol.h"
+#include "qxametadatacontrol.h"
+#include "qmediaplayer.h"
+#include "xaplaysessioncommon.h"
+#include "qxavideowidgetcontrol.h"
+#include "qxavideowindowcontrol.h"
+#include "qmediastreamscontrol.h"
+
+
+QT_USE_NAMESPACE
+
+class XAPlaySessionImpl;
+class RWindow;
+class RWsSession;
+class QXAVideoWidgetControl;
+
+class QXAPlaySession : public QObject,
+ public XAPlayObserver
+{
+ Q_OBJECT
+public:
+ QXAPlaySession(QObject *parent);
+ virtual ~QXAPlaySession();
+
+ void setVideoWidgetControl( QXAVideoWidgetControl * videoWidgetControl );
+ void unsetVideoWidgetControl( QXAVideoWidgetControl * videoWidgetControl );
+ void setVideoWindowControl( QXAVideoWindowControl * videoWindowControl );
+ void unsetVideoWindowControl( QXAVideoWindowControl * videoWindowControl );
+
+ //QXAMediaPlayerControl
+ QMediaPlayer::State state() const { return m_state; }
+ QMediaPlayer::MediaStatus mediaStatus() const { return m_mediaStatus; }
+ qint64 duration();
+ qint64 position();
+ void setPosition(qint64 position);
+ int volume();
+ void setVolume(int volume);
+ bool isMuted();
+ void setMuted(bool muted);
+ int bufferStatus();
+ bool isAudioAvailable();
+ bool isVideoAvailable();
+ bool isSeekable();
+ float playbackRate();
+ void setPlaybackRate(float rate);
+ QMediaContent media();
+ void setMedia(const QMediaContent& media);
+ void play();
+ void pause();
+ void stop();
+
+ // Callback from XAPlaySessionImpl
+ void cbDurationChanged(TInt64 new_dur);
+ void cbPositionChanged(TInt64 new_pos);
+ void cbSeekableChanged(TBool seekable);
+ void cbPlaybackStopped(TInt error);
+ void cbPrefetchStatusChanged();
+ void cbStreamInformation(TBool);
+
+ //MetadataControl methods
+ QStringList availableExtendedMetaData () const;
+ QList<QtMultimediaKit::MetaData> availableMetaData () const;
+ QVariant extendedMetaData(const QString & key ) const;
+ bool isMetaDataAvailable() const;
+ bool isWritable() const;
+ QVariant metaData( QtMultimediaKit::MetaData key ) const;
+ void setExtendedMetaData( const QString & key, const QVariant & value );
+ void setMetaData( QtMultimediaKit::MetaData key, const QVariant & value );
+
+ //QMediaStreamsControl
+ bool isStreamActive ( int stream ) ;
+ QVariant metaData ( int stream, QtMultimediaKit::MetaData key );
+ int streamCount();
+ QMediaStreamsControl::StreamType streamType ( int stream );
+
+ //QVideoWidgetControl
+ void setAspectRatioMode(Qt::AspectRatioMode);
+ Qt::AspectRatioMode getAspectRatioMode();
+
+public Q_SLOTS:
+ void videoWidgetControlWidgetUpdated();
+ void videoWindowControlWindowUpdated();
+
+Q_SIGNALS:
+ void mediaChanged(const QMediaContent& content);
+ void durationChanged(qint64 duration);
+ void positionChanged(qint64 position);
+ void stateChanged(QMediaPlayer::State newState);
+ void mediaStatusChanged(QMediaPlayer::MediaStatus status);
+ void volumeChanged(int volume);
+ void mutedChanged(bool muted);
+ void audioAvailableChanged(bool audioAvailable);
+ void videoAvailableChanged(bool videoAvailable);
+ void bufferStatusChanged(int percentFilled);
+ void seekableChanged(bool);
+ void availablePlaybackRangesChanged(const QMediaTimeRange&);
+ void error(int errorCode, const QString &errorString);
+ void playbackRateChanged(qreal rate);
+
+ //metadata
+ void metaDataAvailableChanged(bool);
+ void metaDataChanged();
+ void writableChanged(bool);
+
+ //QMediaStreamsControl
+ void streamsChanged();
+ void activeStreamsChanged();
+
+private:
+ void setMediaStatus(QMediaPlayer::MediaStatus);
+ void setPlayerState(QMediaPlayer::State state);
+ void updateStreamInfo(TBool emitSignal = EFalse);
+
+private:
+ QMediaPlayer::State m_state;
+ QMediaPlayer::MediaStatus m_mediaStatus;
+
+ QMap<QString,QVariant> m_tags;
+ QList< QMap<QString,QVariant> > m_streamProperties;
+
+ //seekable
+ int mSeekable; //-1 =unintialized, 0=nonseekable, 1=seekable
+
+ //StreamInfo
+ TUint mNumStreams;
+ TBool mbAudioAvailable;
+ TBool mbVideoAvailable;
+
+ //Own
+ XAPlaySessionImpl* mImpl;
+
+ // Does not own
+ QXAVideoWidgetControl *mVideowidgetControl;
+ RWindow *mWidgetCtrlWindow;
+ WId mWidgetCtrlWindowId;
+ QXAVideoWindowControl *mVideoWindowControl;
+ RWindow *mWindowCtrlWindow;
+ WId mWindowCtrlWindowId;
+ RWsSession *mWsSession;
+
+ QMediaContent mMediaContent;
+};
+
+#endif /* QXAPLAYSESSION_H */
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxavideowidgetcontrol.cpp b/src/plugins/symbian/openmaxal/mediaplayer/qxavideowidgetcontrol.cpp
new file mode 100644
index 000000000..6e9c833fd
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxavideowidgetcontrol.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxavideowidgetcontrol.h"
+#include "qxacommon.h"
+#include "qxawidget.h"
+#include <QEvent>
+
+QXAVideoWidgetControl::QXAVideoWidgetControl(QXAPlaySession *session, QObject *parent)
+ : QVideoWidgetControl(parent), mSession(session)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ mWidget = new QXAWidget;
+ if (mWidget)
+ mWidget->installEventFilter(this);
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+QXAVideoWidgetControl::~QXAVideoWidgetControl()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ delete mWidget;
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+QWidget* QXAVideoWidgetControl::videoWidget()
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return mWidget;
+}
+
+Qt::AspectRatioMode QXAVideoWidgetControl::aspectRatioMode() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ RET_s_IF_p_IS_NULL(mSession, Qt::IgnoreAspectRatio);
+ QT_TRACE_FUNCTION_EXIT;
+ return mSession->getAspectRatioMode();
+}
+
+void QXAVideoWidgetControl::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ RET_IF_p_IS_NULL(mSession);
+ mSession->setAspectRatioMode(mode);
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+bool QXAVideoWidgetControl::isFullScreen() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ bool retVal = false;
+ RET_s_IF_p_IS_NULL(mWidget, retVal);
+ retVal = mWidget->isFullScreen();
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+void QXAVideoWidgetControl::setFullScreen(bool fullScreen)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ RET_IF_p_IS_NULL(mWidget);
+ if (fullScreen == mWidget->isFullScreen())
+ return;
+ else if (fullScreen)
+ mWidget->showFullScreen();
+ else
+ mWidget->showNormal();
+
+ emit fullScreenChanged(fullScreen);
+
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+int QXAVideoWidgetControl::brightness() const
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return 0;
+}
+
+void QXAVideoWidgetControl::setBrightness(int brightness)
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ Q_UNUSED(brightness);
+}
+
+int QXAVideoWidgetControl::contrast() const
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return 0;
+}
+
+void QXAVideoWidgetControl::setContrast(int contrast)
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ Q_UNUSED(contrast);
+}
+
+int QXAVideoWidgetControl::hue() const
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return 0;
+}
+
+void QXAVideoWidgetControl::setHue(int hue)
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ Q_UNUSED(hue);
+}
+
+int QXAVideoWidgetControl::saturation() const
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return 0;
+}
+
+void QXAVideoWidgetControl::setSaturation(int saturation)
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ Q_UNUSED(saturation);
+}
+
+bool QXAVideoWidgetControl::eventFilter(QObject *object, QEvent *event)
+{
+ if (object == mWidget) {
+ if ( event->type() == QEvent::Resize
+ || event->type() == QEvent::Move
+ || event->type() == QEvent::WinIdChange
+ || event->type() == QEvent::ParentChange
+ || event->type() == QEvent::Show) {
+ emit widgetUpdated();
+ }
+ }
+ return false;
+}
+
+WId QXAVideoWidgetControl::videoWidgetWId()
+{
+ if (mWidget->internalWinId())
+ return mWidget->internalWinId();
+ else if (mWidget->effectiveWinId())
+ return mWidget->effectiveWinId();
+
+ return NULL;
+}
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxavideowidgetcontrol.h b/src/plugins/symbian/openmaxal/mediaplayer/qxavideowidgetcontrol.h
new file mode 100644
index 000000000..7a0eda765
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxavideowidgetcontrol.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXAVIDEOWIDGETCONTROL_H
+#define QXAVIDEOWIDGETCONTROL_H
+
+#include <QObject>
+#include <qvideowidgetcontrol.h>
+#include "qxaplaysession.h"
+
+QT_USE_NAMESPACE
+
+class QXAWidget;
+
+class QXAVideoWidgetControl : public QVideoWidgetControl
+{
+ Q_OBJECT
+public:
+ QXAVideoWidgetControl(QXAPlaySession *session, QObject *parent = 0);
+ ~QXAVideoWidgetControl();
+
+ QWidget *videoWidget();
+
+ Qt::AspectRatioMode aspectRatioMode() const;
+ void setAspectRatioMode(Qt::AspectRatioMode mode);
+
+ bool isFullScreen() const;
+ void setFullScreen(bool fullScreen);
+
+ int brightness() const;
+ void setBrightness(int brightness);
+
+ int contrast() const;
+ void setContrast(int contrast);
+
+ int hue() const;
+ void setHue(int hue);
+
+ int saturation() const;
+ void setSaturation(int saturation);
+
+ bool eventFilter(QObject *object, QEvent *event);
+
+ WId videoWidgetWId();
+
+Q_SIGNALS:
+ void widgetUpdated();
+
+private:
+ QXAPlaySession *mSession;
+ QXAWidget *mWidget;
+
+};
+
+#endif // QXAVIDEOWIDGETCONTROL_H
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxavideowindowcontrol.cpp b/src/plugins/symbian/openmaxal/mediaplayer/qxavideowindowcontrol.cpp
new file mode 100644
index 000000000..c19b949ac
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxavideowindowcontrol.cpp
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxavideowindowcontrol.h"
+#include "qxacommon.h"
+#include <QEvent>
+#include "qxaplaysession.h"
+
+QXAVideoWindowControl::QXAVideoWindowControl(QXAPlaySession* session, QObject *parent)
+ :QVideoWindowControl(parent),
+ mWid(NULL),
+ mWidget(NULL),
+ mAspectRatioMode(Qt::IgnoreAspectRatio),
+ mSession(session)
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+QXAVideoWindowControl::~QXAVideoWindowControl()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ if (mWidget)
+ mWidget->removeEventFilter(this);
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+WId QXAVideoWindowControl::winId() const
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return mWid;
+}
+
+void QXAVideoWindowControl::setWinId(WId id)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ if (mWid != id) {
+ if (mWidget)
+ mWidget->removeEventFilter(this);
+ mWid = id;
+ mWidget = QWidget::find(mWid);
+ if (mWidget)
+ mWidget->installEventFilter(this);
+ emit windowUpdated();
+ }
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+QRect QXAVideoWindowControl::displayRect() const
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return mDisplayRect;
+}
+
+void QXAVideoWindowControl::setDisplayRect(const QRect &rect)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ mDisplayRect = rect;
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+bool QXAVideoWindowControl::isFullScreen() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ bool retVal(false);
+ if (mWidget)
+ retVal = mWidget->isFullScreen();
+ QT_TRACE_FUNCTION_EXIT;
+ return retVal;
+}
+
+void QXAVideoWindowControl::setFullScreen(bool fullScreen)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ if (mWidget && (fullScreen != mWidget->isFullScreen())) {
+ if (fullScreen)
+ mWidget->showFullScreen();
+ else
+ mWidget->showNormal();
+ emit fullScreenChanged(fullScreen);
+ }
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXAVideoWindowControl::repaint()
+{
+}
+
+QSize QXAVideoWindowControl::nativeSize() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ QSize size(0, 0);
+ RET_s_IF_p_IS_NULL(mSession, size);
+ QVariant sizeBundle = mSession->metaData(QtMultimediaKit::Resolution);
+ QString metadata = sizeBundle.toString();
+ if (!metadata.isNull() && !metadata.isEmpty()) {
+ int xIndex = metadata.indexOf('x');
+ if (xIndex > 0) {
+ size.setWidth(metadata.left(xIndex).toInt());
+ xIndex = metadata.length() - (xIndex + 1);
+ if (xIndex > 0)
+ size.setHeight(metadata.right(xIndex).toInt());
+ }
+ }
+ QT_TRACE_FUNCTION_EXIT;
+ return size;
+}
+
+Qt::AspectRatioMode QXAVideoWindowControl::aspectRatioMode() const
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ RET_s_IF_p_IS_NULL(mSession, Qt::IgnoreAspectRatio);
+ QT_TRACE_FUNCTION_EXIT;
+ return mSession->getAspectRatioMode();
+}
+
+void QXAVideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ RET_IF_p_IS_NULL(mSession);
+ mSession->setAspectRatioMode(mode);
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+int QXAVideoWindowControl::brightness() const
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return 0;
+}
+
+void QXAVideoWindowControl::setBrightness(int brightness)
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ Q_UNUSED(brightness);
+}
+
+int QXAVideoWindowControl::contrast() const
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return 0;
+}
+
+void QXAVideoWindowControl::setContrast(int contrast)
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ Q_UNUSED(contrast);
+}
+
+int QXAVideoWindowControl::hue() const
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return 0;
+}
+
+void QXAVideoWindowControl::setHue(int hue)
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ Q_UNUSED(hue);
+}
+
+int QXAVideoWindowControl::saturation() const
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ return 0;
+}
+
+void QXAVideoWindowControl::setSaturation(int saturation)
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+ Q_UNUSED(saturation);
+}
+
+bool QXAVideoWindowControl::eventFilter(QObject *object, QEvent *event)
+{
+ if (object == mWidget) {
+ if (event->type() == QEvent::Resize
+ || event->type() == QEvent::Move
+ || event->type() == QEvent::WinIdChange
+ || event->type() == QEvent::ParentChange
+ || event->type() == QEvent::Show) {
+ emit windowUpdated();
+ }
+ }
+ return false;
+}
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxavideowindowcontrol.h b/src/plugins/symbian/openmaxal/mediaplayer/qxavideowindowcontrol.h
new file mode 100644
index 000000000..879349822
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxavideowindowcontrol.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXAVIDEOWINDOWCONTROL_H
+#define QXAVIDEOWINDOWCONTROL_H
+
+#include <QObject>
+#include <QVideoWindowControl>
+
+QT_USE_NAMESPACE
+
+class QXAPlaySession;
+
+class QXAVideoWindowControl : public QVideoWindowControl
+{
+ Q_OBJECT
+
+public:
+ QXAVideoWindowControl(QXAPlaySession* session, QObject *parent = 0);
+ ~QXAVideoWindowControl();
+
+ // QVideoWindowControl virtual functions
+ WId winId() const;
+ void setWinId(WId id);
+
+ QRect displayRect() const;
+ void setDisplayRect(const QRect &rect);
+
+ bool isFullScreen() const;
+ void setFullScreen(bool fullScreen);
+
+ void repaint();
+
+ QSize nativeSize() const;
+
+ Qt::AspectRatioMode aspectRatioMode() const;
+ void setAspectRatioMode(Qt::AspectRatioMode mode);
+
+ int brightness() const;
+ void setBrightness(int brightness);
+
+ int contrast() const;
+ void setContrast(int contrast);
+
+ int hue() const;
+ void setHue(int hue);
+
+ int saturation() const;
+ void setSaturation(int saturation);
+
+ //Callback function to receive event from Qt framework
+ //for object represented by mWid
+ bool eventFilter(QObject *object, QEvent *event);
+
+Q_SIGNALS:
+ void windowUpdated();
+
+private:
+ WId mWid;
+ QWidget* mWidget; /* QWidget represented by mWid */
+ QRect mDisplayRect;
+ Qt::AspectRatioMode mAspectRatioMode;
+
+ QXAPlaySession* mSession;
+};
+
+#endif /* QXAVIDEOWINDOWCONTROL_H */
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxawidget.cpp b/src/plugins/symbian/openmaxal/mediaplayer/qxawidget.cpp
new file mode 100644
index 000000000..4685226fd
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxawidget.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxawidget.h"
+#include <coemain.h>
+
+QXAWidget::QXAWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ setAttribute(Qt::WA_OpaquePaintEvent, true);
+ setAttribute(Qt::WA_NoSystemBackground, true);
+ setAutoFillBackground(false);
+ setPalette(QPalette(Qt::black));
+ /* Initialize the native window*/
+ winId();
+}
+
+QXAWidget::~QXAWidget()
+{
+}
+
+void QXAWidget::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+}
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/qxawidget.h b/src/plugins/symbian/openmaxal/mediaplayer/qxawidget.h
new file mode 100644
index 000000000..d36be1fa4
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/qxawidget.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXAWIDGET_H
+#define QXAWIDGET_H
+
+#include <QObject>
+#include <qwidget.h>
+
+QT_USE_NAMESPACE
+
+class QXAWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ QXAWidget(QWidget *parent = 0);
+ virtual ~QXAWidget();
+
+protected:
+ void paintEvent(QPaintEvent *event);
+};
+
+
+#endif /* QXAWIDGET_H */
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/xaplaysessioncommon.h b/src/plugins/symbian/openmaxal/mediaplayer/xaplaysessioncommon.h
new file mode 100644
index 000000000..a9497e475
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/xaplaysessioncommon.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XAPLAYSESSIONCOMMON_H
+#define XAPLAYSESSIONCOMMON_H
+
+#include <e32base.h>
+
+class XAPlayObserver
+ {
+public:
+ virtual void cbDurationChanged(TInt64 new_dur) = 0;
+ virtual void cbPositionChanged(TInt64 new_pos) = 0;
+ virtual void cbSeekableChanged(TBool seekable) = 0;
+ virtual void cbPlaybackStopped(TInt error) = 0;
+ virtual void cbPrefetchStatusChanged() = 0;
+ virtual void cbStreamInformation(TBool bFirstTime) = 0;
+ };
+
+#endif /*XAPLAYSESSIONCOMMON_H*/
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/xaplaysessionimpl.cpp b/src/plugins/symbian/openmaxal/mediaplayer/xaplaysessionimpl.cpp
new file mode 100644
index 000000000..88a06807f
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/xaplaysessionimpl.cpp
@@ -0,0 +1,1259 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QString>
+#include <QVariant>
+#include <QList>
+#include <QStringList>
+#include <QImage>
+
+#include "xaplaysessionimpl.h"
+#include "xaplaysessioncommon.h"
+#include "xacommon.h"
+
+#ifdef USE_VIDEOPLAYERUTILITY
+#include <COECNTRL.H>
+#endif
+
+_LIT8(K8WAVMIMETYPE, "audio/wav");
+
+#define RET_ERR_IF_ERR(e) \
+ if (e != 0) {\
+ return e; \
+ } \
+
+#define MAX_NUMBER_INTERFACES 20
+const TUint KPlayPosUpdatePeriod = 1000;
+
+/* Local functions for callback registation */
+void MediaPlayerCallback( XAObjectItf caller,
+ const void *pContext,
+ XAuint32 event,
+ XAresult result,
+ XAuint32 param,
+ void *pInterface);
+
+void PlayItfCallback( XAPlayItf caller,
+ void *pContext,
+ XAuint32 event);
+
+void PrefetchItfCallback( XAPrefetchStatusItf caller,
+ void * pContext,
+ XAuint32 event);
+
+void StreamInformationItfCallback( XAStreamInformationItf caller,
+ XAuint32 eventId,
+ XAuint32 streamIndex,
+ void * pEventData,
+ void * pContext);
+
+XAPlaySessionImpl::XAPlaySessionImpl(XAPlayObserver& parent)
+:mParent(parent),
+mEOEngine(NULL),
+mMOPlayer(NULL),
+mPlayItf(NULL),
+mSeekItf(NULL),
+mURIName(NULL),
+mWAVMime(NULL),
+mbMetadataAvailable(EFalse),
+mbVolEnabled(EFalse),
+mbMuteEnabled(EFalse),
+mbPrefetchStatusChange(EFalse),
+mbStreamInfoAvailable(EFalse),
+mbPlaybackRateItfAvailable(EFalse),
+mbScalable(EFalse),
+mCurrAspectRatioMode(Qt::KeepAspectRatio)
+#ifdef USE_VIDEOPLAYERUTILITY
+, mVideoPlayUtil(NULL)
+, mActiveSchedulerWait(NULL)
+#endif
+{
+}
+
+XAPlaySessionImpl::~XAPlaySessionImpl()
+{
+ if (mMOPlayer)
+ (*mMOPlayer)->Destroy(mMOPlayer);
+
+ if (mEOEngine)
+ (*mEOEngine)->Destroy(mEOEngine);
+
+ delete mURIName;
+ delete mWAVMime;
+
+ //clear metadata datastructures
+ alKeyMap.clear();
+ keyMap.clear();
+ extendedKeyMap.clear();
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ delete mVideoPlayUtil;
+ if (mActiveSchedulerWait && \
+ mActiveSchedulerWait->IsStarted()) {
+ mActiveSchedulerWait->AsyncStop();
+ }
+
+ delete mActiveSchedulerWait;
+#endif
+
+}
+
+TInt XAPlaySessionImpl::postConstruct()
+{
+ TInt retVal;
+ XAresult xaRes;
+ XAEngineOption engineOption[] = { (XAuint32) XA_ENGINEOPTION_THREADSAFE,
+ (XAuint32) XA_BOOLEAN_TRUE
+ };
+ XAEngineItf engineItf;
+
+ mNativeDisplay.locatorType = XA_DATALOCATOR_NATIVEDISPLAY;
+ mNativeDisplay.hWindow = NULL;
+ mNativeDisplay.hDisplay = NULL;
+ mVideoSink.pLocator = (void*)&mNativeDisplay;
+ mVideoSink.pFormat = NULL;
+
+ // Create and realize Engine object
+ xaRes = xaCreateEngine (&mEOEngine, 1, engineOption, 0, NULL, NULL);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+ xaRes = (*mEOEngine)->Realize(mEOEngine, XA_BOOLEAN_FALSE);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ // Create and realize Output Mix object to be used by player
+ xaRes = (*mEOEngine)->GetInterface(mEOEngine, XA_IID_ENGINE, (void**) &engineItf);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ TRAP(retVal, mWAVMime = HBufC8::NewL(K8WAVMIMETYPE().Length() + 1));
+ RET_ERR_IF_ERR(retVal);
+ TPtr8 ptr = mWAVMime->Des();
+ ptr = K8WAVMIMETYPE(); // copy uri name into local variable
+ ptr.PtrZ(); // append zero terminator to end of URI
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ TRAP(retVal, mVideoPlayUtil =
+ CVideoPlayerUtility2::NewL( *this,
+ EMdaPriorityNormal,
+ EMdaPriorityPreferenceTimeAndQuality)
+ );
+ mActiveSchedulerWait = new CActiveSchedulerWait;
+#endif
+
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::addNativeDisplay(RWindow* window, RWsSession* wssession)
+ {
+ TInt retVal(KErrNotReady);
+
+ if (!mMOPlayer && !mPlayItf) {
+ // window can only be set before player creation
+ mNativeDisplay.locatorType = XA_DATALOCATOR_NATIVEDISPLAY;
+ mNativeDisplay.hWindow = (void*)window;
+ mNativeDisplay.hDisplay = (void*)wssession;
+ retVal = KErrNone;
+ }
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::updateNativeDisplay(RWindow* /*window*/, RWsSession* /*wssession*/)
+{
+ return KErrNone;
+}
+
+TInt XAPlaySessionImpl::removeNativeDisplay(RWindow* /*window*/, RWsSession* /*wssession*/)
+{
+ return KErrNone;
+}
+
+TInt XAPlaySessionImpl::load(const TDesC& aURI)
+{
+ TInt retVal;
+ XAresult xaRes;
+ XAEngineItf engineItf;
+ XADynamicSourceItf dynamicSourceItf;
+ XAboolean required[MAX_NUMBER_INTERFACES];
+ XAInterfaceID iidArray[MAX_NUMBER_INTERFACES];
+ XAuint32 noOfInterfaces = 0;
+ TInt i;
+
+ XAmillisecond dur(0);
+ TPtr8 uriPtr(0,0,0);
+ TPtr8 mimeTypePtr(0,0,0);
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ TRAP(m_VPError, mVideoPlayUtil->OpenFileL(_L("C:\\data\\test.3gp")));
+ if (m_VPError)
+ return 0;
+
+ if(!mActiveSchedulerWait->IsStarted())
+ mActiveSchedulerWait->Start();
+
+ if (m_VPError)
+ return 0;
+
+ mVideoPlayUtil->Prepare();
+
+ if(!mActiveSchedulerWait->IsStarted())
+ mActiveSchedulerWait->Start();
+
+ return 0;
+#endif
+
+ delete mURIName;
+ mURIName = NULL;
+ TRAP(retVal, mURIName = HBufC8::NewL(aURI.Length()+1));
+ RET_ERR_IF_ERR(retVal);
+ uriPtr.Set(mURIName->Des());
+
+ // This has to be done here since we can not destroy the Player
+ // in the Resource Lost callback.
+ if (mbMediaPlayerUnrealized) {
+ if (mMOPlayer) {
+ (*mMOPlayer)->Destroy(mMOPlayer);
+ mMOPlayer = NULL;
+ }
+ }
+
+ //py uri name into local variable
+ //TODO fix copy issue from 16 bit to 8 bit
+ uriPtr.Copy(aURI);
+
+ //If media player object already exists, just switch source
+ //using dynamic source interface
+ if (mMOPlayer && mPlayItf) {
+ dynamicSourceItf = NULL;
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_DYNAMICSOURCE, &dynamicSourceItf);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ //Setup the data source
+ //TODO Hard coded locator type
+ mUri.locatorType = XA_DATALOCATOR_URI;
+
+ //append zero terminator to end of URI
+ mUri.URI = (XAchar*) uriPtr.PtrZ();
+
+ //TODO Hard coded locator type
+ mMime.containerType = XA_CONTAINERTYPE_WAV;
+
+ //TODO Hard coded locator type
+ mMime.formatType = XA_DATAFORMAT_MIME;
+ mimeTypePtr.Set(mWAVMime->Des());
+ mMime.mimeType = (XAchar*)mimeTypePtr.Ptr();
+ mDataSource.pFormat = (void*)&mMime;
+ mDataSource.pLocator = (void*)&mUri;
+
+ xaRes = (*dynamicSourceItf)->SetSource(dynamicSourceItf, &mDataSource);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+ }
+ else { // Create media player object
+
+ // Setup the data source
+ // TODO Hard coded locator type
+ mUri.locatorType = XA_DATALOCATOR_URI;
+
+ //append zero terminator to end of URI
+ mUri.URI = (XAchar*) uriPtr.PtrZ();
+
+ //TODO Hard coded locator type
+ mMime.containerType = XA_CONTAINERTYPE_WAV;
+
+ //TODO Hard coded locator type
+ mMime.formatType = XA_DATAFORMAT_MIME;
+ mimeTypePtr.Set(mWAVMime->Des());
+ mMime.mimeType = (XAchar*)mimeTypePtr.Ptr();
+ mDataSource.pFormat = (void*)&mMime;
+ mDataSource.pLocator = (void*)&mUri;
+
+ //Setup the audio data sink
+ mLocatorOutputDevice.locatorType = XA_DATALOCATOR_IODEVICE;
+ mLocatorOutputDevice.deviceType = 6;
+ mAudioSink.pLocator = (void*) &mLocatorOutputDevice;
+ mAudioSink.pFormat = NULL;
+
+ //Init arrays required[] and iidArray[]
+ for (i = 0; i < MAX_NUMBER_INTERFACES; i++) {
+ required[i] = XA_BOOLEAN_FALSE;
+ iidArray[i] = XA_IID_NULL;
+ }
+
+ noOfInterfaces = 0;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_SEEK;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_DYNAMICSOURCE;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_METADATAEXTRACTION;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_NOKIALINEARVOLUME;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_NOKIAVOLUMEEXT;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_PREFETCHSTATUS;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_STREAMINFORMATION;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_PLAYBACKRATE;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_VIDEOPOSTPROCESSING;
+ noOfInterfaces++;
+
+ xaRes = (*mEOEngine)->GetInterface(mEOEngine, XA_IID_ENGINE, (void**) &engineItf);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ xaRes = (*engineItf)->CreateMediaPlayer(engineItf,
+ &mMOPlayer,
+ &mDataSource,
+ NULL,
+ &mAudioSink,
+ &mVideoSink,
+ NULL,
+ NULL,
+ noOfInterfaces,
+ iidArray,
+ required);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ xaRes = (*mMOPlayer)->Realize(mMOPlayer, XA_BOOLEAN_FALSE);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ mbMediaPlayerUnrealized = FALSE;
+
+ xaRes = (*mMOPlayer)->RegisterCallback(mMOPlayer, MediaPlayerCallback, (void*)this);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_PLAY, &mPlayItf);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ xaRes = (*mPlayItf)->RegisterCallback(mPlayItf, PlayItfCallback, (void*)this);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ xaRes = (*mPlayItf)->SetPositionUpdatePeriod(mPlayItf, (XAmillisecond)KPlayPosUpdatePeriod);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ xaRes = (*mPlayItf)->SetCallbackEventsMask( mPlayItf,
+ ( XA_PLAYEVENT_HEADATEND |
+ XA_PLAYEVENT_HEADATNEWPOS |
+ XA_PLAYEVENT_HEADMOVING )
+ );
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_SEEK, &mSeekItf);
+ retVal = mapError(xaRes, ETrue);
+
+ //Metadata
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_METADATAEXTRACTION, &mMetadataExtItf);
+ if(mapError(xaRes, ETrue)==KErrNone) {
+ mbMetadataAvailable = ETrue;
+ setupALKeyMap(); //done only once at creation of meadia player
+ }
+
+ //volume
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_NOKIALINEARVOLUME, &mNokiaLinearVolumeItf);
+ if(mapError(xaRes, ETrue)==KErrNone)
+ mbVolEnabled = ETrue;
+
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_NOKIAVOLUMEEXT, &mNokiaVolumeExtItf);
+ if(mapError(xaRes, ETrue)==KErrNone)
+ mbMuteEnabled = ETrue;
+
+ //buffer status
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_PREFETCHSTATUS, &mPrefetchStatusItf);
+ if(mapError(xaRes, ETrue)==KErrNone) {
+ mbPrefetchStatusChange = ETrue;
+ (*mPrefetchStatusItf)->RegisterCallback(mPrefetchStatusItf, PrefetchItfCallback, (void*)this);
+ (*mPrefetchStatusItf)->SetCallbackEventsMask(mPrefetchStatusItf, XA_PREFETCHEVENT_FILLLEVELCHANGE);
+ }
+
+ //stream information
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_STREAMINFORMATION, &mStreamInformationItf);
+ if(mapError(xaRes, ETrue)==KErrNone) {
+ mbStreamInfoAvailable = ETrue;
+ mParent.cbStreamInformation(ETrue); //indicate first time
+ (*mStreamInformationItf)->RegisterStreamChangeCallback(mStreamInformationItf, StreamInformationItfCallback, (void*)this);
+ }
+
+ //playback rate
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_PLAYBACKRATE, &mPlaybackRateItf);
+ if(mapError(xaRes, ETrue)==KErrNone)
+ mbPlaybackRateItfAvailable = ETrue;
+
+
+ //videopostprocessing
+ xaRes = (*mMOPlayer)->GetInterface(mMOPlayer, XA_IID_VIDEOPOSTPROCESSING, &mVideoPostProcessingItf);
+ if(mapError(xaRes, ETrue)==KErrNone)
+ mbScalable = ETrue;
+
+ }
+
+ if(mbMetadataAvailable) {
+ keyMap.clear();
+ extendedKeyMap.clear();
+ setupMetaData(); //done every time source is changed
+ }
+ else { //send signal for seekable
+ mParent.cbSeekableChanged(ETrue);
+ }
+
+ mCurPosition = 0;
+ mParent.cbPositionChanged(mCurPosition);
+
+ xaRes = (*mPlayItf)->GetDuration(mPlayItf, &dur);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ mDuration = dur;
+ mParent.cbDurationChanged(mDuration);
+
+ return retVal;
+}
+
+void XAPlaySessionImpl::unload()
+{
+ mPlayItf = NULL;
+ mSeekItf = NULL;
+
+ //Metadata
+ mbMetadataAvailable = FALSE;
+ mMetadataExtItf = NULL;
+ alKeyMap.clear();
+ keyMap.clear();
+ extendedKeyMap.clear();
+ //Volume
+ mNokiaLinearVolumeItf = NULL;
+ mbVolEnabled = FALSE;
+ mNokiaVolumeExtItf = NULL;
+ mbMuteEnabled = NULL;
+
+ //buffer status
+ mPrefetchStatusItf = NULL;
+ mbPrefetchStatusChange = FALSE;
+
+ //stream information
+ mStreamInformationItf = NULL;
+ mbStreamInfoAvailable = FALSE;
+ mbAudioStream = FALSE;
+ mbVideoStream = FALSE;
+ mNumStreams = 0;
+
+ //Playbackrate
+ mPlaybackRateItf = NULL;
+ mbPlaybackRateItfAvailable = FALSE;
+
+ mVideoPostProcessingItf = NULL;
+ mbScalable = FALSE;
+ mCurrAspectRatioMode = Qt::KeepAspectRatio;
+
+ //internal
+ mCurPosition = 0; // in milliseconds
+ mDuration = 0; // in milliseconds
+
+
+ mbMediaPlayerUnrealized = TRUE;
+
+ delete mURIName;
+ mURIName = NULL;
+
+}
+
+TInt XAPlaySessionImpl::play()
+{
+ TInt retVal(KErrGeneral);
+ XAresult xaRes;
+ XAuint32 state;
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ mVideoPlayUtil->Play();
+ return 0;
+#endif
+
+ if (!mMOPlayer || !mPlayItf)
+ return retVal;
+
+ xaRes = (*mPlayItf)->GetPlayState(mPlayItf, &state);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ if ((state == XA_PLAYSTATE_STOPPED) ||
+ (state == XA_PLAYSTATE_PAUSED)) {
+ xaRes = (*mPlayItf)->SetPlayState(mPlayItf, XA_PLAYSTATE_PLAYING);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+ }
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::pause()
+{
+ TInt retVal(KErrGeneral);
+ XAresult xaRes;
+ XAuint32 state;
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ TRAPD(err, mVideoPlayUtil->PauseL());
+ return 0;
+#endif
+
+ if (!mMOPlayer || !mPlayItf)
+ return retVal;
+
+ xaRes = (*mPlayItf)->GetPlayState(mPlayItf, &state);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ if ((state == XA_PLAYSTATE_STOPPED) ||
+ (state == XA_PLAYSTATE_PLAYING)) {
+ xaRes = (*mPlayItf)->SetPlayState(mPlayItf, XA_PLAYSTATE_PAUSED);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+ }
+
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::stop()
+{
+ TInt retVal(KErrGeneral);
+ XAresult xaRes;
+ XAuint32 state;
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ mVideoPlayUtil->Stop();
+ return 0;
+#endif
+
+ if (!mMOPlayer || !mPlayItf)
+ return retVal;
+
+ xaRes = (*mPlayItf)->GetPlayState(mPlayItf, &state);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+
+ if ((state == XA_PLAYSTATE_PAUSED) ||
+ (state == XA_PLAYSTATE_PLAYING)) {
+ xaRes = (*mPlayItf)->SetPlayState(mPlayItf, XA_PLAYSTATE_STOPPED);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+ mCurPosition += KPlayPosUpdatePeriod;
+ mParent.cbPositionChanged(mCurPosition);
+ }
+
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::duration(TInt64& aDur)
+{
+ TInt retVal(KErrGeneral);
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ TTimeIntervalMicroSeconds dur(0);
+ TRAPD(err, mVideoPlayUtil->DurationL());
+ if (!err)
+ aDur = dur.Int64() / 1000;
+ return 0;
+#endif
+ if (!mMOPlayer || !mPlayItf)
+ return retVal;
+ aDur = mDuration;
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::position(TInt64& aPos)
+{
+ TInt retVal(KErrGeneral);
+#ifdef USE_VIDEOPLAYERUTILITY
+ TTimeIntervalMicroSeconds dur(0);
+ TRAPD(err, mVideoPlayUtil->PositionL());
+ if (!err)
+ aPos = dur.Int64() / 1000;
+ return 0;
+#endif
+
+/* XAresult xaRes;
+ XAmillisecond pos(0);*/
+
+ if (!mMOPlayer || !mPlayItf)
+ return retVal;
+
+ aPos = mCurPosition;
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::getSeekable(TBool& seekable)
+{
+ TInt retVal(KErrGeneral);
+
+ if (!mMOPlayer || !mSeekItf)
+ return retVal;
+
+ retVal = ETrue;
+ seekable = ETrue;
+
+ return retVal;
+}
+
+TInt XAPlaySessionImpl::seek(TInt64 pos)
+{
+ TInt retVal(KErrGeneral);
+ XAresult xaRes;
+
+ if (!mMOPlayer || !mSeekItf)
+ return retVal;
+
+ xaRes = (*mSeekItf)->SetPosition(mSeekItf, (XAmillisecond)pos, XA_SEEKMODE_FAST);
+ retVal = mapError(xaRes, ETrue);
+ RET_ERR_IF_ERR(retVal);
+ mCurPosition = pos;
+
+ return retVal;
+}
+
+void XAPlaySessionImpl::cbMediaPlayer(XAObjectItf /*caller*/,
+ const void */*pContext*/,
+ XAuint32 event,
+ XAresult result,
+ XAuint32 /*param*/,
+ void */*pInterface*/)
+
+{
+ switch (event) {
+ case XA_OBJECT_EVENT_RESOURCES_LOST:
+ unload();
+ mParent.cbPlaybackStopped(result);
+ break;
+ case XA_OBJECT_EVENT_RUNTIME_ERROR:
+ {
+ switch (result) {
+ case XA_RESULT_RESOURCE_LOST:
+ unload();
+ mParent.cbPlaybackStopped(result);
+ break;
+ default:
+ break;
+ }; /* of switch (result) */
+ }
+ default:
+ break;
+ } /* of switch (event) */
+}
+
+void XAPlaySessionImpl::cbPlayItf(XAPlayItf /*caller*/,
+ void */*pContext*/,
+ XAuint32 event)
+{
+ switch(event) {
+ case XA_PLAYEVENT_HEADATEND:
+ mParent.cbPlaybackStopped(KErrNone);
+ break;
+ case XA_PLAYEVENT_HEADATMARKER:
+ break;
+ case XA_PLAYEVENT_HEADATNEWPOS:
+ mCurPosition += KPlayPosUpdatePeriod;
+ mParent.cbPositionChanged(mCurPosition);
+ break;
+ case XA_PLAYEVENT_HEADMOVING:
+ break;
+ case XA_PLAYEVENT_HEADSTALLED:
+ break;
+ default:
+ break;
+ }
+}
+
+void XAPlaySessionImpl::cbPrefetchItf(XAuint32 event)
+{
+ if(event == XA_PREFETCHEVENT_FILLLEVELCHANGE)
+ mParent.cbPrefetchStatusChanged();
+}
+
+void XAPlaySessionImpl::cbStreamInformationItf( XAuint32 /*eventId*/,
+ XAuint32 /*streamIndex*/,
+ void * /*pEventData*/)
+{
+ mParent.cbStreamInformation(EFalse);
+}
+
+void XAPlaySessionImpl::setAspectRatioMode(Qt::AspectRatioMode aspectRatioMode)
+{
+ if( !mbScalable ||
+ (mCurrAspectRatioMode == aspectRatioMode)) {
+ return;
+ }
+
+ XAuint32 scaleOptions;;
+ XAuint32 backgrndColor = 1;
+ XAuint32 renderingHints = 1;
+
+ switch(aspectRatioMode) {
+ case Qt::IgnoreAspectRatio:
+ scaleOptions = XA_VIDEOSCALE_STRETCH;
+ break;
+ case Qt::KeepAspectRatio:
+ scaleOptions = XA_VIDEOSCALE_FIT;
+ break;
+ case Qt::KeepAspectRatioByExpanding:
+ scaleOptions = XA_VIDEOSCALE_CROP;
+ break;
+ default:
+ return;
+ }
+
+ XAresult xaRes = (*mVideoPostProcessingItf)->SetScaleOptions(mVideoPostProcessingItf, \
+ scaleOptions, backgrndColor, renderingHints);
+ if(mapError(xaRes, ETrue) == KErrNone)
+ xaRes = (*mVideoPostProcessingItf)->Commit(mVideoPostProcessingItf);
+
+ if(mapError(xaRes, ETrue) == KErrNone)
+ mCurrAspectRatioMode = aspectRatioMode;
+}
+
+Qt::AspectRatioMode XAPlaySessionImpl::getAspectRatioMode()
+{
+ return mCurrAspectRatioMode;
+}
+
+
+#ifdef USE_VIDEOPLAYERUTILITY
+void XAPlaySessionImpl::MvpuoOpenComplete(TInt aError)
+{
+ TRACE_FUNCTION_ENTRY;
+ m_VPError = aError;
+ if (mActiveSchedulerWait->IsStarted())
+ mActiveSchedulerWait->AsyncStop();
+ TRACE_FUNCTION_EXIT;
+}
+
+void XAPlaySessionImpl::MvpuoPrepareComplete(TInt aError)
+{
+ TRACE_FUNCTION_ENTRY;
+ m_VPError = aError;
+ if (mActiveSchedulerWait->IsStarted())
+ mActiveSchedulerWait->AsyncStop();
+
+ RWindow* window = (RWindow*)mNativeDisplay.hWindow;
+ RWsSession* wssession = (RWsSession*)mNativeDisplay.hDisplay;
+
+ if (window) {
+ TRect videoExtent = TRect(window->Size());
+ TRect clipRect = TRect(window->Size());
+ TRAP_IGNORE(mVideoPlayUtil->AddDisplayWindowL(*wssession, *(CCoeEnv::Static()->ScreenDevice()), *window, videoExtent, clipRect));
+ TRAP_IGNORE(mVideoPlayUtil->SetAutoScaleL(*window, EAutoScaleBestFit));
+ }
+ TRACE_FUNCTION_EXIT;
+}
+
+void XAPlaySessionImpl::MvpuoFrameReady(CFbsBitmap& /*aFrame*/,TInt /*aError*/)
+{
+ TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+void XAPlaySessionImpl::MvpuoPlayComplete(TInt /*aError*/)
+{
+ TRACE_FUNCTION_ENTRY;
+ mParent.cbPlaybackStopped_EOS();
+ TRACE_FUNCTION_EXIT;
+}
+
+void XAPlaySessionImpl::MvpuoEvent(const TMMFEvent& /*aEvent*/)
+{
+ TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+#endif
+
+TInt XAPlaySessionImpl::mapError(XAresult xa_err, TBool /*debPrn*/)
+{
+ TInt retVal(KErrGeneral);
+
+ switch(xa_err) {
+ case XA_RESULT_SUCCESS:
+ retVal = KErrNone;
+ break;
+ case XA_RESULT_PRECONDITIONS_VIOLATED:
+ break;
+ case XA_RESULT_PARAMETER_INVALID:
+ break;
+ case XA_RESULT_MEMORY_FAILURE:
+ break;
+ case XA_RESULT_RESOURCE_ERROR:
+ break;
+ case XA_RESULT_RESOURCE_LOST:
+ break;
+ case XA_RESULT_IO_ERROR:
+ break;
+ case XA_RESULT_BUFFER_INSUFFICIENT:
+ break;
+ case XA_RESULT_CONTENT_CORRUPTED:
+ break;
+ case XA_RESULT_CONTENT_UNSUPPORTED:
+ break;
+ case XA_RESULT_CONTENT_NOT_FOUND:
+ break;
+ case XA_RESULT_PERMISSION_DENIED:
+ break;
+ case XA_RESULT_FEATURE_UNSUPPORTED:
+ break;
+ case XA_RESULT_INTERNAL_ERROR:
+ break;
+ case XA_RESULT_UNKNOWN_ERROR:
+ break;
+ case XA_RESULT_OPERATION_ABORTED:
+ break;
+ case XA_RESULT_CONTROL_LOST:
+ break;
+ default:
+ break;
+ }
+
+ return retVal;
+}
+
+
+QStringList XAPlaySessionImpl::availableExtendedMetaData () const
+{
+ QStringList retList;
+
+ //create a qlist with all keys in keyMap hash
+ QHashIterator<QString, int> it(extendedKeyMap);
+ while(it.hasNext()) {
+ it.next();
+ retList << it.key();
+ }
+
+ return retList;
+}
+
+QList<QtMultimediaKit::MetaData> XAPlaySessionImpl::availableMetaData () const
+{
+ QList<QtMultimediaKit::MetaData> retList;
+
+ //create a qlist with all keys in keyMap hash
+ QHashIterator<QtMultimediaKit::MetaData, int> it(keyMap);
+ while( it.hasNext() ) {
+ it.next();
+ retList << it.key();
+ }
+
+ return retList;
+}
+
+QVariant XAPlaySessionImpl::getMetaData( int alIndex ) const
+{
+ QVariant ret; //invalid variant
+
+ //find index for the given key
+ if(mMetadataExtItf) {
+ XAuint32 valueSize = 0;
+ XAresult res = (*mMetadataExtItf)->GetValueSize(mMetadataExtItf, alIndex, &valueSize);
+ if(res == XA_RESULT_SUCCESS) {
+ XAMetadataInfo * value = (XAMetadataInfo*)calloc(valueSize, 1);
+ if(value) {
+ res = (*mMetadataExtItf)->GetValue(mMetadataExtItf, alIndex, valueSize, value);
+ if(res == XA_RESULT_SUCCESS) {
+ if(value->encoding == XA_CHARACTERENCODING_ASCII)
+ ret = QVariant ((const char*)value->data);
+ else if(value->encoding == XA_CHARACTERENCODING_UTF16LE)
+ ret = QVariant(QString::fromUtf16((ushort*)value->data, (value->size/2)-1)); //dont include null terminating character
+ else if(value->encoding == XA_CHARACTERENCODING_BINARY)
+ ret = QVariant(QImage::fromData(value->data, value->size));
+ }
+
+ free(value);
+ }
+ }
+ }
+
+ return ret;
+}
+
+QVariant XAPlaySessionImpl::metaData( QtMultimediaKit::MetaData key ) const
+{
+ QVariant ret;
+ if(keyMap.contains(key))
+ ret = getMetaData(keyMap[key]);
+ return ret;
+}
+
+QVariant XAPlaySessionImpl::extendedMetaData(const QString & key ) const
+{
+ QVariant ret;
+ if(extendedKeyMap.contains(key))
+ ret = getMetaData(extendedKeyMap[key]);
+
+ return ret;
+}
+
+bool XAPlaySessionImpl::isMetaDataAvailable() const
+{
+ return ((keyMap.size()>0) || (extendedKeyMap.size()>0));
+}
+
+bool XAPlaySessionImpl::isWritable() const
+{
+ return false;
+}
+
+void XAPlaySessionImpl::setExtendedMetaData( const QString&, const QVariant&)
+{
+ //Do Nothing
+}
+
+void XAPlaySessionImpl::setMetaData( QtMultimediaKit::MetaData, const QVariant& )
+{
+ //Do Nothing
+}
+
+void XAPlaySessionImpl::setupALKeyMap()
+{
+ alKeyMap["KhronosTitle"] = QtMultimediaKit::Title;
+ alKeyMap["KhronosComment"] = QtMultimediaKit::Comment;
+ alKeyMap["KhronosTrackNumber"] = QtMultimediaKit::TrackNumber;
+ alKeyMap["KhronosAlbumArtJPEG"] = QtMultimediaKit::CoverArtImage;
+ alKeyMap["KhronosAlbumArtPNG"] = QtMultimediaKit::CoverArtImage;
+ alKeyMap["KhronosAlbum"] = QtMultimediaKit::AlbumTitle;
+ alKeyMap["KhronosArtist"] = QtMultimediaKit::AlbumArtist;
+ alKeyMap["KhronosGenre"] = QtMultimediaKit::Genre;
+ alKeyMap["KhronosYear"] = QtMultimediaKit::Year;
+ alKeyMap["KhronosYear"] = QtMultimediaKit::Date;
+ alKeyMap["KhronosRating"] = QtMultimediaKit::UserRating;
+ alKeyMap["KhronosCopyright"] = QtMultimediaKit::Copyright;
+ alKeyMap["Author"] = QtMultimediaKit::Author;
+ alKeyMap["Duration"] = QtMultimediaKit::Duration;
+ alKeyMap["Stream Count"] = QtMultimediaKit::ChannelCount;
+ alKeyMap["Composer"] = QtMultimediaKit::Composer;
+ alKeyMap["Resolution"] = QtMultimediaKit::Resolution;
+ alKeyMap["FrameRate"] = QtMultimediaKit::VideoFrameRate;
+ alKeyMap["ClipBitRate"] = QtMultimediaKit::VideoBitRate;
+ alKeyMap["Codec"] = QtMultimediaKit::VideoCodec;
+ alKeyMap["attachedpicture"] = QtMultimediaKit::CoverArtImage;
+
+ /*Keys not available
+ QtMedia::SubTitle
+ QtMedia::Description
+ QtMedia::Category
+ QtMedia::Keywords
+ QtMedia::Language
+ QtMedia::Publisher
+ QtMedia::ParentalRating
+ QtMedia::RatingOrganisation
+ QtMedia::Size
+ QtMedia::MediaType
+ QtMedia::AudioBitrate
+ QtMedia::AudioCodec
+ QtMedia::AverageLevel
+ QtMedia::PeakValue
+ QtMedia::Frequency
+ QtMedia::ContributingArtist
+ QtMedia::Conductor
+ QtMedia::Lyrics
+ QtMedia::Mood
+ QtMedia::TrackCount
+ QtMedia::PixelAspectRatio
+ QtMedia::PosterUri
+ QtMedia::ChapterNumber
+ QtMedia::Director
+ QtMedia::LeadPerformer
+ QtMedia::Writer */
+}
+
+TInt XAPlaySessionImpl::mapMetaDataKey(const char* asckey, QtMultimediaKit::MetaData& key)
+{
+ if(alKeyMap.contains(asckey)) {
+ key = alKeyMap[asckey];
+ return KErrNone;
+ }
+
+ return KErrNotFound;
+}
+
+TInt XAPlaySessionImpl::setupMetaData()
+{
+ XAresult res;
+ if(mMetadataExtItf) {
+ XAuint32 numItems = 0;
+ res = (*mMetadataExtItf)->GetItemCount(mMetadataExtItf, &numItems);
+ RET_ERR_IF_ERR(mapError(res, ETrue));
+
+ for(int i=0; i<numItems; ++i) {
+ XAuint32 keySize;
+ res = (*mMetadataExtItf)->GetKeySize(mMetadataExtItf, i, &keySize);
+ RET_ERR_IF_ERR(mapError(res, ETrue));
+
+ XAMetadataInfo *key = (XAMetadataInfo *)calloc(keySize,1);
+ if(key) {
+ res = (*mMetadataExtItf)->GetKey(mMetadataExtItf, i, keySize, key);
+ RET_ERR_IF_ERR(mapError(res, ETrue));
+
+ if(key->encoding == XA_CHARACTERENCODING_ASCII) { //only handle ASCII keys ignore others
+ QtMultimediaKit::MetaData qtKey;
+ if(mapMetaDataKey((const char*)key->data, qtKey) == KErrNone)//qt metadata
+ keyMap[qtKey] = i;
+ else //extended metadata
+ extendedKeyMap[(const char*)key->data] = i;
+ }
+
+ free(key);
+ }
+ }
+
+ //check for seek property to generate seekable signal
+ QVariant var = extendedMetaData("Seekable");
+ if(!var.isValid() || (var.toString() == "1"))
+ mParent.cbSeekableChanged(ETrue);
+ else
+ mParent.cbSeekableChanged(EFalse);
+
+ }
+
+ return KErrGeneral;
+}
+
+//Volume
+TInt XAPlaySessionImpl::volume(TInt& v)
+{
+ if(mbVolEnabled) {
+ XAresult res = (*mNokiaLinearVolumeItf)->GetVolumeLevel(mNokiaLinearVolumeItf, (XAuint32 *)&v);
+ return mapError(res, ETrue);
+ }
+
+ return KErrNotFound;
+}
+
+TInt XAPlaySessionImpl::setVolume(TInt v)
+{
+ if(mbVolEnabled) {
+ XAresult res = (*mNokiaLinearVolumeItf)->SetVolumeLevel(mNokiaLinearVolumeItf, (XAuint32*)&v);
+ return mapError(res, ETrue);
+ }
+
+ return KErrNotFound;
+}
+
+TInt XAPlaySessionImpl::setMute(TBool bMute)
+{
+ if(mbMuteEnabled) {
+ XAresult res = (*mNokiaVolumeExtItf)->SetMute(mNokiaVolumeExtItf, (XAboolean)bMute);
+ return mapError(res, ETrue);
+ }
+
+ return KErrNotFound;
+
+}
+
+TInt XAPlaySessionImpl::getMute(TBool& bIsMute)
+{
+ if(mbMuteEnabled) {
+ XAboolean xaMute;
+ XAresult res = (*mNokiaVolumeExtItf)->GetMute(mNokiaVolumeExtItf, &xaMute);
+ bIsMute = xaMute;
+ return mapError(res, ETrue);
+ }
+
+ return KErrNotFound;
+}
+
+
+TInt XAPlaySessionImpl::bufferStatus(TInt &bs)
+{
+ TInt ret = KErrNotFound;
+
+ if(mbPrefetchStatusChange) {
+ XApermille satusPerThousand;
+ XAresult res = (*mPrefetchStatusItf)->GetFillLevel(mPrefetchStatusItf, &satusPerThousand);
+ ret = mapError(res, ETrue);
+ if(ret == KErrNone)
+ bs = satusPerThousand/10.0; //convert to parts per hundred
+ }
+ return ret;
+}
+
+QMediaStreamsControl::StreamType XAPlaySessionImpl::mapStreamType(XAuint32& alStreamType)
+{
+ switch(alStreamType) {
+ case XA_DOMAINTYPE_AUDIO:
+ return QMediaStreamsControl::AudioStream;
+ case XA_DOMAINTYPE_VIDEO:
+ return QMediaStreamsControl::VideoStream;
+ case XA_DOMAINTYPE_IMAGE:
+ return QMediaStreamsControl::DataStream;
+ }
+ return QMediaStreamsControl::UnknownStream;
+}
+
+
+TInt XAPlaySessionImpl::numMediaStreams(TUint& numStreams)
+{
+ TInt ret = KErrNotFound;
+ numStreams = 0;
+ if(mbStreamInfoAvailable) {
+ XAMediaContainerInformation mediaContainerInfo;
+ XAresult res = (*mStreamInformationItf)->QueryMediaContainerInformation(mStreamInformationItf, &mediaContainerInfo);
+ ret = mapError(res, ETrue);
+ if(ret == KErrNone)
+ numStreams = mediaContainerInfo.numStreams;
+ }
+ return ret;
+}
+
+TInt XAPlaySessionImpl::streamType(TUint index, QMediaStreamsControl::StreamType& type)
+{
+ TInt ret = KErrNotFound;
+ type = QMediaStreamsControl::UnknownStream;
+ if(mbStreamInfoAvailable) {
+ XAuint32 strType;
+ XAresult res = (*mStreamInformationItf)->QueryStreamType(mStreamInformationItf, (XAuint32)(index+1), &strType);
+ ret = mapError(res, ETrue);
+ if(ret == KErrNone)
+ type = mapStreamType(strType);
+ }
+ return ret;
+}
+
+TInt XAPlaySessionImpl::isStreamActive(TUint index, TBool& isActive)
+{
+ TUint numStreams;
+ TInt ret = numMediaStreams(numStreams);
+ if((ret == KErrNone) && (index < numStreams)) {
+ isActive = EFalse;
+ if(numStreams > 0) {
+ //create array of bools
+ XAboolean *activeStreams = new XAboolean[numStreams+1];
+ XAresult res = (*mStreamInformationItf)->QueryActiveStreams(mStreamInformationItf, (XAuint32*)&numStreams, activeStreams);
+ ret = mapError(res, ETrue);
+ if(ret == KErrNone)
+ isActive = activeStreams[index+1];
+ delete[] activeStreams;
+ }
+ }
+ return ret;
+}
+
+TInt XAPlaySessionImpl::getPlaybackRate(TReal32 &rate)
+{
+ TInt ret = KErrNotFound;
+
+ if(mbPlaybackRateItfAvailable) {
+ XApermille perMilleRate = 0;
+ ret = (*mPlaybackRateItf)->GetRate(mPlaybackRateItf, &perMilleRate);
+ rate = perMilleRate / 1000.0;
+ }
+ return ret;
+}
+
+TInt XAPlaySessionImpl::setPlaybackRate(TReal32 rate)
+{
+ TInt ret = KErrNotFound;
+ if(mbPlaybackRateItfAvailable)
+ ret = (*mPlaybackRateItf)->SetRate(mPlaybackRateItf, (XApermille)(rate * 1000.0));
+ return ret;
+}
+
+
+/* Local function implementation */
+void MediaPlayerCallback( XAObjectItf caller,
+ const void *pContext,
+ XAuint32 event,
+ XAresult result,
+ XAuint32 param,
+ void *pInterface)
+{
+ if (pContext)
+ ((XAPlaySessionImpl*)pContext)->cbMediaPlayer( caller,
+ pContext,
+ event,
+ result,
+ param,
+ pInterface);
+}
+
+void PlayItfCallback( XAPlayItf caller,
+ void *pContext,
+ XAuint32 event)
+{
+ if (pContext)
+ ((XAPlaySessionImpl*)pContext)->cbPlayItf(caller,
+ pContext,
+ event);
+}
+
+void PrefetchItfCallback( XAPrefetchStatusItf /*caller*/,
+ void *pContext,
+ XAuint32 event)
+{
+ if (pContext)
+ ((XAPlaySessionImpl*)pContext)->cbPrefetchItf(event);
+}
+
+void StreamInformationItfCallback( XAStreamInformationItf /*caller*/,
+ XAuint32 eventId,
+ XAuint32 streamIndex,
+ void * pEventData,
+ void * pContext)
+{
+ if (pContext)
+ ((XAPlaySessionImpl*)pContext)->cbStreamInformationItf( eventId,
+ streamIndex,
+ pEventData);
+}
+
+
+
+// End of file
diff --git a/src/plugins/symbian/openmaxal/mediaplayer/xaplaysessionimpl.h b/src/plugins/symbian/openmaxal/mediaplayer/xaplaysessionimpl.h
new file mode 100644
index 000000000..30144712a
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediaplayer/xaplaysessionimpl.h
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XAPLAYSESSIONIMPL_H
+#define XAPLAYSESSIONIMPL_H
+
+#include <OpenMAXAL.h>
+#include <xanokiavolumeextitf.h>
+#include <xanokialinearvolumeitf.h>
+#ifdef USE_VIDEOPLAYERUTILITY
+#include <VideoPlayer2.h>
+#endif
+
+#include "qtmedianamespace.h"
+#include "qmediastreamscontrol.h"
+
+class XAPlayObserver;
+class RWindow;
+class RWsSession;
+
+class XAPlaySessionImpl
+#ifdef USE_VIDEOPLAYERUTILITY
+ : public MVideoPlayerUtilityObserver
+#endif
+{
+public:
+ XAPlaySessionImpl(XAPlayObserver& parent);
+ ~XAPlaySessionImpl();
+ TInt postConstruct();
+ TInt addNativeDisplay(RWindow* window, RWsSession* wssession);
+ TInt updateNativeDisplay(RWindow* window, RWsSession* wssession);
+ TInt removeNativeDisplay(RWindow* window, RWsSession* wssession);
+ TInt load(const TDesC& aURI);
+ void unload();
+ TInt play();
+ TInt pause();
+ TInt stop();
+ TInt duration(TInt64& aDur);
+ TInt position(TInt64& aPos);
+ TInt getSeekable(TBool& seekable);
+ TInt seek(TInt64 pos);
+
+ //Metadata
+ QStringList availableExtendedMetaData () const;
+ QList<QtMultimediaKit::MetaData> availableMetaData () const;
+ QVariant extendedMetaData(const QString & key ) const;
+ bool isMetaDataAvailable() const;
+ bool isWritable() const;
+ QVariant metaData( QtMultimediaKit::MetaData key ) const;
+ void setExtendedMetaData( const QString & key, const QVariant & value );
+ void setMetaData( QtMultimediaKit::MetaData key, const QVariant & value );
+
+ TInt volume(TInt&);
+ TInt setVolume(TInt);
+ TInt setMute(TBool);
+ TInt getMute(TBool&);
+
+ TInt bufferStatus(TInt &);
+
+
+ TInt numMediaStreams(TUint& numStreams);
+ TInt streamType(TUint index, QMediaStreamsControl::StreamType& type);
+ TInt isStreamActive(TUint index, TBool& isActive);
+
+ TInt getPlaybackRate(TReal32 &rate);
+ TInt setPlaybackRate(TReal32 rate);
+
+ //AspectRatioMode
+ void setAspectRatioMode(Qt::AspectRatioMode);
+ Qt::AspectRatioMode getAspectRatioMode();
+
+public:
+ void cbMediaPlayer( XAObjectItf caller,
+ const void *pContext,
+ XAuint32 event,
+ XAresult result,
+ XAuint32 param,
+ void *pInterface);
+
+ void cbPlayItf(XAPlayItf caller,
+ void *pContext,
+ XAuint32 event);
+
+
+ void cbPrefetchItf(XAuint32);
+
+ void cbStreamInformationItf(XAuint32, XAuint32, void*);
+
+#ifdef USE_VIDEOPLAYERUTILITY
+ //MVideoPlayerUtilityObserver
+ void MvpuoOpenComplete(TInt aError);
+ void MvpuoPrepareComplete(TInt aError);
+ void MvpuoFrameReady(CFbsBitmap& aFrame,TInt aError);
+ void MvpuoPlayComplete(TInt aError);
+ void MvpuoEvent(const TMMFEvent& aEvent);
+#endif
+
+private:
+ TInt mapError(XAresult xa_err,
+ TBool debPrn);
+ void setupALKeyMap();
+ TInt setupMetaData();
+ TInt mapMetaDataKey(const char* asckey, QtMultimediaKit::MetaData& key);
+ QVariant getMetaData( int alIndex ) const;
+
+ QMediaStreamsControl::StreamType mapStreamType(XAuint32& alStreamType);
+
+
+private:
+ XAPlayObserver& mParent;
+ XAObjectItf mEOEngine;
+ XAObjectItf mMOPlayer;
+ XAPlayItf mPlayItf;
+ XASeekItf mSeekItf;
+ HBufC8* mURIName;
+ HBufC8* mWAVMime;
+ // Audio Source
+ XADataSource mDataSource;
+ XADataFormat_MIME mMime;
+ XADataLocator_URI mUri;
+ //Audio Sink
+ XADataSink mAudioSink;
+ XADataLocator_IODevice mLocatorOutputDevice;
+ //Video Sink
+ XADataSink mVideoSink;
+ XADataLocator_NativeDisplay mNativeDisplay;
+
+ //Metadata
+ TBool mbMetadataAvailable;
+ XAMetadataExtractionItf mMetadataExtItf;
+ QHash<QString, QtMultimediaKit::MetaData> alKeyMap;
+ QHash<QtMultimediaKit::MetaData, int> keyMap;
+ QHash<QString,int> extendedKeyMap;
+
+ //Volume
+ XANokiaLinearVolumeItf mNokiaLinearVolumeItf;
+ TBool mbVolEnabled;
+ XANokiaVolumeExtItf mNokiaVolumeExtItf;
+ TBool mbMuteEnabled;
+
+ //buffer status
+ XAPrefetchStatusItf mPrefetchStatusItf;
+ TBool mbPrefetchStatusChange;
+
+ //stream information
+ XAStreamInformationItf mStreamInformationItf;
+ TBool mbStreamInfoAvailable;
+ TBool mbAudioStream;
+ TBool mbVideoStream;
+ TInt mNumStreams;
+
+ //Playbackrate
+ XAPlaybackRateItf mPlaybackRateItf;
+ TBool mbPlaybackRateItfAvailable;
+
+ XAVideoPostProcessingItf mVideoPostProcessingItf;
+ TBool mbScalable;
+ Qt::AspectRatioMode mCurrAspectRatioMode;
+
+ //internal
+ TInt64 mCurPosition; // in milliseconds
+ TInt64 mDuration; // in milliseconds
+
+ TBool mbMediaPlayerUnrealized;
+#ifdef USE_VIDEOPLAYERUTILITY
+ CVideoPlayerUtility2* mVideoPlayUtil;
+ CActiveSchedulerWait* mActiveSchedulerWait;
+ TInt m_VPError;
+#endif
+};
+
+#endif /* XAPLAYSESSIONIMPL_H */
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/mediarecorder.pri b/src/plugins/symbian/openmaxal/mediarecorder/mediarecorder.pri
new file mode 100644
index 000000000..ee78e8348
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/mediarecorder.pri
@@ -0,0 +1,24 @@
+INCLUDEPATH += $$PWD
+
+# Input
+HEADERS += \
+ $$PWD/qxarecordmediaservice.h \
+ $$PWD/qxarecordsession.h \
+ $$PWD/qxaaudioendpointselector.h \
+ $$PWD/qxaaudioencodercontrol.h \
+ $$PWD/qxamediacontainercontrol.h \
+ $$PWD/qxamediarecordercontrol.h \
+ $$PWD/xarecordsessionimpl.h \
+ $$PWD/xarecordsessioncommon.h
+
+SOURCES += \
+ $$PWD/qxarecordmediaservice.cpp \
+ $$PWD/qxarecordsession.cpp \
+ $$PWD/qxaaudioendpointselector.cpp \
+ $$PWD/qxaaudioencodercontrol.cpp \
+ $$PWD/qxamediacontainercontrol.cpp \
+ $$PWD/qxamediarecordercontrol.cpp \
+ $$PWD/xarecordsessionimpl.cpp
+
+LIBS += \
+ -lbafl
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/qxaaudioencodercontrol.cpp b/src/plugins/symbian/openmaxal/mediarecorder/qxaaudioencodercontrol.cpp
new file mode 100644
index 000000000..2826f79a2
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/qxaaudioencodercontrol.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxaaudioencodercontrol.h"
+#include "qxarecordsession.h"
+#include "qxacommon.h"
+
+QXAAudioEncoderControl::QXAAudioEncoderControl(QXARecordSession *session, QObject *parent)
+:QAudioEncoderControl(parent), m_session(session)
+{
+}
+
+QXAAudioEncoderControl::~QXAAudioEncoderControl()
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+QStringList QXAAudioEncoderControl::supportedAudioCodecs() const
+{
+ if (m_session)
+ return m_session->supportedAudioCodecs();
+ return QStringList();
+}
+
+QString QXAAudioEncoderControl::codecDescription(const QString &codecName) const
+{
+ if (m_session)
+ return m_session->codecDescription(codecName);
+ return QString();
+}
+
+QList<int> QXAAudioEncoderControl::supportedSampleRates(
+ const QAudioEncoderSettings &settings,
+ bool *continuous) const
+{
+ if (m_session)
+ return m_session->supportedSampleRates(settings, continuous);
+ return QList<int>();
+}
+
+QAudioEncoderSettings QXAAudioEncoderControl::audioSettings() const
+{
+ if (m_session)
+ return m_session->audioSettings();
+ return QAudioEncoderSettings();
+}
+
+void QXAAudioEncoderControl::setAudioSettings(const QAudioEncoderSettings &settings)
+{
+ if (m_session)
+ m_session->setAudioSettings(settings);
+}
+
+QStringList QXAAudioEncoderControl::supportedEncodingOptions(const QString &codec) const
+{
+ if (m_session)
+ return m_session->supportedEncodingOptions(codec);
+ return QStringList();
+}
+
+QVariant QXAAudioEncoderControl::encodingOption(const QString &codec, const QString &name) const
+{
+ if (m_session)
+ return m_session->encodingOption(codec, name);
+ return QVariant();
+}
+
+void QXAAudioEncoderControl::setEncodingOption(
+ const QString &codec, const QString &name, const QVariant &value)
+{
+ if (m_session)
+ m_session->setEncodingOption(codec, name, value);
+}
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/qxaaudioencodercontrol.h b/src/plugins/symbian/openmaxal/mediarecorder/qxaaudioencodercontrol.h
new file mode 100644
index 000000000..117d36fdc
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/qxaaudioencodercontrol.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXAAUDIOENCODERCONTROL_H
+#define QXAAUDIOENCODERCONTROL_H
+
+#include <qaudioencodercontrol.h>
+
+QT_USE_NAMESPACE
+
+/*
+ * This class implements QAudioEncoderControl interface.
+ */
+class QXARecordSession;
+
+class QXAAudioEncoderControl : public QAudioEncoderControl
+{
+ Q_OBJECT
+
+public:
+ QXAAudioEncoderControl(QXARecordSession *session, QObject *parent = 0);
+ virtual ~QXAAudioEncoderControl();
+
+ QStringList supportedAudioCodecs() const;
+ QString codecDescription(const QString &codecName) const;
+
+ QList<int> supportedSampleRates(const QAudioEncoderSettings &settings,
+ bool *continuous = 0) const;
+
+ QAudioEncoderSettings audioSettings() const;
+ void setAudioSettings(const QAudioEncoderSettings &settings);
+
+ QStringList supportedEncodingOptions(const QString &codec) const;
+ QVariant encodingOption(const QString &codec, const QString &name) const;
+ void setEncodingOption(const QString &codec, const QString &name, const QVariant &value);
+
+private:
+ QXARecordSession *m_session;
+};
+
+#endif /* QXAAUDIOENCODERCONTROL_H */
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/qxaaudioendpointselector.cpp b/src/plugins/symbian/openmaxal/mediarecorder/qxaaudioendpointselector.cpp
new file mode 100644
index 000000000..7e546595c
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/qxaaudioendpointselector.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxaaudioendpointselector.h"
+#include "qxarecordsession.h"
+#include "qxacommon.h"
+
+QXAAudioEndpointSelector::QXAAudioEndpointSelector(QXARecordSession *session, QObject *parent)
+:QAudioEndpointSelector(parent), m_session(session)
+{
+ connect(m_session, SIGNAL(availableAudioInputsChanged()),
+ this, SLOT(availableAudioInputsChanged()));
+ connect(m_session, SIGNAL(activeEndpointChanged(QString)),
+ this, SIGNAL(activeEndpointChanged(QString)));
+}
+
+QXAAudioEndpointSelector::~QXAAudioEndpointSelector()
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+QList<QString> QXAAudioEndpointSelector::availableEndpoints() const
+{
+ if (m_session)
+ return m_session->availableEndpoints();
+ return QList<QString>();
+}
+
+QString QXAAudioEndpointSelector::endpointDescription(const QString &name) const
+{
+ if (m_session)
+ return m_session->endpointDescription(name);
+ return QString();
+}
+
+QString QXAAudioEndpointSelector::defaultEndpoint() const
+{
+ if (m_session)
+ return m_session->defaultEndpoint();
+ return QString();
+}
+
+QString QXAAudioEndpointSelector::activeEndpoint() const
+{
+ if (m_session)
+ return m_session->activeEndpoint();
+ return QString();
+}
+
+void QXAAudioEndpointSelector::setActiveEndpoint(const QString &name)
+{
+ if (m_session)
+ m_session->setActiveEndpoint(name);
+}
+
+void QXAAudioEndpointSelector::availableAudioInputsChanged()
+ {
+ emit availableEndpointsChanged();
+ }
+
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/qxaaudioendpointselector.h b/src/plugins/symbian/openmaxal/mediarecorder/qxaaudioendpointselector.h
new file mode 100644
index 000000000..5fbadbc64
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/qxaaudioendpointselector.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXAAUDIOENDPOINTSELECTOR_H
+#define QXAAUDIOENDPOINTSELECTOR_H
+
+#include <qaudioendpointselector.h>
+
+QT_USE_NAMESPACE
+
+/*
+ * This class implements QAudioEncoderControl interface.
+ */
+class QXARecordSession;
+
+class QXAAudioEndpointSelector : public QAudioEndpointSelector
+{
+ Q_OBJECT
+
+public:
+ QXAAudioEndpointSelector(QXARecordSession *session, QObject *parent);
+ ~QXAAudioEndpointSelector();
+
+ QList<QString> availableEndpoints() const;
+ QString endpointDescription(const QString &name) const;
+ QString defaultEndpoint() const;
+ QString activeEndpoint() const;
+
+public Q_SLOTS:
+ void setActiveEndpoint(const QString &name);
+
+private Q_SLOTS:
+ void availableAudioInputsChanged();
+
+private:
+ QXARecordSession *m_session;
+};
+
+#endif /* QXAAUDIOENDPOINTSELECTOR_H */
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/qxamediacontainercontrol.cpp b/src/plugins/symbian/openmaxal/mediarecorder/qxamediacontainercontrol.cpp
new file mode 100644
index 000000000..0d97fd5e5
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/qxamediacontainercontrol.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxamediacontainercontrol.h"
+#include "qxarecordsession.h"
+#include "qxacommon.h"
+
+QXAMediaContainerControl::QXAMediaContainerControl(QXARecordSession *session, QObject *parent)
+:QMediaContainerControl(parent), m_session(session)
+{
+}
+
+QXAMediaContainerControl::~QXAMediaContainerControl()
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+QStringList QXAMediaContainerControl::supportedContainers() const
+{
+ if (m_session)
+ return m_session->supportedContainers();
+ return QStringList();
+}
+
+QString QXAMediaContainerControl::containerMimeType() const
+{
+ if (m_session)
+ return m_session->containerMimeType();
+ return QString();
+}
+
+void QXAMediaContainerControl::setContainerMimeType(const QString &formatMimeType)
+{
+ if (m_session)
+ m_session->setContainerMimeType(formatMimeType);
+}
+
+QString QXAMediaContainerControl::containerDescription(const QString &formatMimeType) const
+{
+ if (m_session)
+ return m_session->containerDescription(formatMimeType);
+ return QString();
+}
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/qxamediacontainercontrol.h b/src/plugins/symbian/openmaxal/mediarecorder/qxamediacontainercontrol.h
new file mode 100644
index 000000000..4b05fc190
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/qxamediacontainercontrol.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXAMEDIACONTAINERCONTROL_H
+#define QXAMEDIACONTAINERCONTROL_H
+
+#include <qmediacontainercontrol.h>
+
+QT_USE_NAMESPACE
+
+/*
+ * This class implements QMediaContainerControl interface.
+ */
+class QXARecordSession;
+
+class QXAMediaContainerControl : public QMediaContainerControl
+{
+ Q_OBJECT
+
+public:
+ QXAMediaContainerControl(QXARecordSession *session, QObject *parent = 0);
+ virtual ~QXAMediaContainerControl();
+
+ QStringList supportedContainers() const;
+ QString containerMimeType() const;
+ void setContainerMimeType(const QString &formatMimeType);
+ QString containerDescription(const QString &formatMimeType) const;
+
+private:
+ QXARecordSession *m_session;
+};
+
+#endif /* QXAMEDIACONTAINERCONTROL_H */
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/qxamediarecordercontrol.cpp b/src/plugins/symbian/openmaxal/mediarecorder/qxamediarecordercontrol.cpp
new file mode 100644
index 000000000..330edf008
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/qxamediarecordercontrol.cpp
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxamediarecordercontrol.h"
+#include "qxarecordsession.h"
+#include "qxacommon.h"
+
+QXAMediaRecoderControl::QXAMediaRecoderControl(QXARecordSession *session, QObject *parent)
+:QMediaRecorderControl(parent), m_session(session)
+{
+ connect(m_session, SIGNAL(stateChanged(QMediaRecorder::State)),
+ this, SIGNAL(stateChanged(QMediaRecorder::State)));
+ connect(m_session, SIGNAL(error(int,QString)),
+ this,SIGNAL(error(int,QString)));
+ connect(m_session, SIGNAL(durationChanged(qint64)),
+ this, SIGNAL(durationChanged(qint64)));
+}
+
+QXAMediaRecoderControl::~QXAMediaRecoderControl()
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+QUrl QXAMediaRecoderControl::outputLocation() const
+{
+ if (m_session)
+ return m_session->outputLocation();
+ return QUrl();
+}
+
+bool QXAMediaRecoderControl::setOutputLocation(const QUrl &location)
+{
+ if (m_session)
+ return m_session->setOutputLocation(location);
+ return false;
+}
+
+QMediaRecorder::State QXAMediaRecoderControl::state() const
+{
+ if (m_session)
+ return m_session->state();
+ return QMediaRecorder::StoppedState;
+}
+
+qint64 QXAMediaRecoderControl::duration() const
+{
+ if (m_session)
+ return m_session->duration();
+ return 0;
+}
+
+void QXAMediaRecoderControl::record()
+{
+ if (m_session)
+ m_session->record();
+}
+
+void QXAMediaRecoderControl::pause()
+{
+ if (m_session)
+ m_session->pause();
+}
+
+void QXAMediaRecoderControl::stop()
+{
+ if (m_session)
+ m_session->stop();
+}
+
+void QXAMediaRecoderControl::applySettings()
+{
+ if (m_session)
+ m_session->applySettings();
+}
+
+bool QXAMediaRecoderControl::isMuted() const
+{
+ return false;
+}
+
+void QXAMediaRecoderControl::setMuted(bool)
+{
+
+}
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/qxamediarecordercontrol.h b/src/plugins/symbian/openmaxal/mediarecorder/qxamediarecordercontrol.h
new file mode 100644
index 000000000..c6495f2e4
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/qxamediarecordercontrol.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXAMEDIARECORDERCONTROL_H
+#define QXAMEDIARECORDERCONTROL_H
+
+#include <qmediarecorder.h>
+#include <qmediarecordercontrol.h>
+
+QT_USE_NAMESPACE
+
+/*
+ * This class implements QMediaRecorderControl interface.
+ */
+
+class QXARecordSession;
+
+class QXAMediaRecoderControl : public QMediaRecorderControl
+{
+ Q_OBJECT
+
+public:
+ QXAMediaRecoderControl(QXARecordSession *session, QObject *parent = 0);
+ virtual ~QXAMediaRecoderControl();
+
+ QUrl outputLocation() const;
+ bool setOutputLocation(const QUrl &location);
+
+ QMediaRecorder::State state() const;
+
+ qint64 duration() const;
+ bool isMuted() const;
+ void applySettings();
+
+public Q_SLOTS:
+ void record();
+ void pause();
+ void stop();
+ void setMuted(bool);
+
+private:
+ QXARecordSession *m_session;
+};
+
+#endif /* QXAMEDIARECORDERCONTROL_H */
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/qxarecordmediaservice.cpp b/src/plugins/symbian/openmaxal/mediarecorder/qxarecordmediaservice.cpp
new file mode 100644
index 000000000..05c57feb7
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/qxarecordmediaservice.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QString>
+
+#include "qxarecordmediaservice.h"
+#include "qxarecordsession.h"
+#include "qxamediarecordercontrol.h"
+#include "qxaaudioendpointselector.h"
+#include "qxaaudioencodercontrol.h"
+#include "qxamediacontainercontrol.h"
+#include "qxacommon.h"
+
+QXARecodMediaService::QXARecodMediaService(QObject *parent)
+:QMediaService(parent)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ m_session = new QXARecordSession(this);
+ m_control = new QXAMediaRecoderControl(m_session, this);
+ m_endpoint = new QXAAudioEndpointSelector(m_session, this);
+ m_encoder = new QXAAudioEncoderControl(m_session, this);
+ m_container = new QXAMediaContainerControl(m_session, this);
+}
+
+QXARecodMediaService::~QXARecodMediaService()
+{
+ QT_TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+QMediaControl* QXARecodMediaService::requestControl(const char *name)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ if (qstrcmp(name, QMediaRecorderControl_iid) == 0)
+ return m_control;
+ else if (qstrcmp(name, QAudioEndpointSelector_iid) == 0)
+ return m_endpoint;
+ else if (qstrcmp(name, QAudioEncoderControl_iid) == 0)
+ return m_encoder;
+ else if (qstrcmp(name, QMediaContainerControl_iid) == 0)
+ return m_container;
+ QT_TRACE_FUNCTION_EXIT;
+ return 0;
+}
+
+void QXARecodMediaService::releaseControl(QMediaControl *control)
+{
+ Q_UNUSED(control)
+}
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/qxarecordmediaservice.h b/src/plugins/symbian/openmaxal/mediarecorder/qxarecordmediaservice.h
new file mode 100644
index 000000000..98f5136e8
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/qxarecordmediaservice.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXARECORDMEDIASERVICE_H
+#define QXARECORDMEDIASERVICE_H
+
+#include <QtCore/qobject.h>
+#include <qmediaservice.h>
+
+QT_USE_NAMESPACE
+
+/*
+ * This class implements QMediaService interface.
+ */
+
+class QXARecordSession;
+class QXAMediaRecoderControl;
+class QXAAudioEndpointSelector;
+class QXAAudioEncoderControl;
+class QXAMediaContainerControl;
+
+class QXARecodMediaService : public QMediaService
+{
+
+ Q_OBJECT
+
+public:
+ QXARecodMediaService(QObject *parent = 0);
+ ~QXARecodMediaService();
+ QMediaControl *requestControl(const char *name);
+ void releaseControl( QMediaControl *control);
+private:
+ QXARecordSession *m_session;
+ QXAMediaRecoderControl *m_control;
+ QXAAudioEndpointSelector *m_endpoint;
+ QXAAudioEncoderControl *m_encoder;
+ QXAMediaContainerControl *m_container;
+};
+
+#endif /* QXARECORDMEDIASERVICE_H */
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/qxarecordsession.cpp b/src/plugins/symbian/openmaxal/mediarecorder/qxarecordsession.cpp
new file mode 100644
index 000000000..76cdfc3da
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/qxarecordsession.cpp
@@ -0,0 +1,766 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QVariant>
+#include <QtCore/qdir.h>
+#include <qtmedianamespace.h>
+#include "qxarecordsession.h"
+#include "xarecordsessionimpl.h"
+#include "qxacommon.h"
+
+/* The following declaration is required to allow QList<int> to be added to
+ * QVariant
+ */
+Q_DECLARE_METATYPE(QList<uint>)
+
+/* This macro checks for m_impl null pointer. If it is, emits an error signal
+ * error(QMediaRecorder::ResourceError, tr("Service has not been started"));
+ * and returns from function immediately with value 's'.
+ */
+
+#define RETURN_s_IF_m_impl_IS_NULL(s) \
+ if (!m_impl) { \
+ emit error(QMediaRecorder::ResourceError, QXARecordSession::tr("Service has not been started")); \
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::ResourceError, tr(\"Service has not been started\"))"); \
+ return s; \
+ }
+
+/* This macro checks for m_impl null pointer. If it is, emits an error signal
+ * error(QMediaRecorder::ResourceError, tr("Service has not been started"));
+ * and returns from function immediately.
+ */
+#define RETURN_IF_m_impl_IS_NULL \
+ if (!m_impl) { \
+ emit error(QMediaRecorder::ResourceError, QXARecordSession::tr("Service has not been started")); \
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::ResourceError, tr(\"Service has not been started\"))"); \
+ return; \
+ }
+
+QXARecordSession::QXARecordSession(QObject *parent)
+:QObject(parent),
+m_state(QMediaRecorder::StoppedState),
+m_previousState(QMediaRecorder::StoppedState)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ m_impl = NULL;
+ m_impl = new XARecordSessionImpl(*this);
+ if (m_impl) {
+ if (m_impl->postConstruct() == KErrNone) {
+ initCodecsList();
+ initContainersList();
+ m_containerMimeType = QString("audio/wav");
+ m_audioencodersettings.setCodec("pcm");
+ m_audioencodersettings.setBitRate(0);
+ m_audioencodersettings.setChannelCount(-1);
+ m_audioencodersettings.setEncodingMode(QtMultimediaKit::ConstantQualityEncoding);
+ m_audioencodersettings.setQuality(QtMultimediaKit::NormalQuality);
+ m_audioencodersettings.setSampleRate(-1);
+ setEncoderSettingsToImpl();
+ m_URItoImplSet = false;
+ QT_TRACE1("Initialized implementation");
+ }
+ else {
+ delete m_impl;
+ m_impl = NULL;
+ QT_TRACE1("Error initializing implementation");
+ }
+ }
+ else {
+ emit error(QMediaRecorder::ResourceError, tr("Unable to start Service"));
+ }
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+QXARecordSession::~QXARecordSession()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ delete m_impl;
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+QUrl QXARecordSession::outputLocation()
+{
+ return m_outputLocation;
+}
+
+bool QXARecordSession::setOutputLocation(const QUrl &location)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ RETURN_s_IF_m_impl_IS_NULL(false);
+
+ // Location can be set only when recorder is in stopped state.
+ if (state() != QMediaRecorder::StoppedState)
+ return false;
+
+ // Validate URL
+ if (!location.isValid())
+ return false;
+
+ // If old and new locations are same, do nothing.
+ QString newUrlStr = (QUrl::fromUserInput(location.toString())).toString();
+ QString curUrlStr = (QUrl::fromUserInput(m_outputLocation.toString())).toString();
+ if (curUrlStr.compare(newUrlStr) == KErrNone)
+ return true;
+
+ QT_TRACE2("Location:", newUrlStr);
+ m_outputLocation = location;
+ /* New file, so user can set new settings */
+ m_previousState = QMediaRecorder::StoppedState;
+ m_URItoImplSet = false;
+
+ QT_TRACE_FUNCTION_EXIT;
+ return true;
+}
+
+QMediaRecorder::State QXARecordSession::state()
+{
+ return m_state;
+}
+
+qint64 QXARecordSession::duration()
+{
+ TInt64 dur(0);
+
+ QT_TRACE_FUNCTION_ENTRY;
+
+ RETURN_s_IF_m_impl_IS_NULL(dur);
+
+ m_impl->duration(dur);
+
+ QT_TRACE_FUNCTION_EXIT;
+ return (qint64)dur;
+}
+
+void QXARecordSession::applySettings()
+{
+ /* Settings can only be applied when the recorder is in the stopped
+ * state after creation. */
+ if ((state() == QMediaRecorder::StoppedState) && (m_state == m_previousState)) {
+ if (m_appliedaudioencodersettings != m_audioencodersettings)
+ setEncoderSettingsToImpl();
+ }
+ else {
+ emit error(QMediaRecorder::FormatError, tr("Settings cannot be changed once recording started"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::FormatError, tr(\"Settings cannot be changed once recording started\"))");
+ }
+}
+
+void QXARecordSession::record()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ RETURN_IF_m_impl_IS_NULL;
+
+ /* No op if object is already in recording state */
+ if (state() == QMediaRecorder::RecordingState)
+ return;
+
+ /* 1. Set encoder settings here */
+ if (m_appliedaudioencodersettings != m_audioencodersettings)
+ RET_IF_FALSE(setEncoderSettingsToImpl());
+
+ /* 2. Set URI to impl */
+ RET_IF_FALSE(setURIToImpl());
+
+ /* 3. Start recording...
+ * If successful, setRecorderState(QMediaRecorder::RecordingState);
+ * will be called from the callback cbRecordingStarted()
+ */
+ if (m_impl->record() != KErrNone) {
+ emit error(QMediaRecorder::ResourceError, tr("Generic error"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::ResourceError, tr(\"Generic error\"))");
+ }
+
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXARecordSession::pause()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ RETURN_IF_m_impl_IS_NULL;
+
+ /* No op if object is already in paused/stopped state */
+ if ((state() == QMediaRecorder::PausedState) || (state() == QMediaRecorder::StoppedState)) {
+ return;
+ }
+
+ if (m_impl->pause() == KErrNone) {
+ setRecorderState(QMediaRecorder::PausedState);
+ }
+ else {
+ emit error(QMediaRecorder::ResourceError, tr("Unable to pause"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::ResourceError, tr(\"Unable to pause\"))");
+ }
+
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXARecordSession::stop()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ RETURN_IF_m_impl_IS_NULL;
+
+ /* No op if object is already in paused state */
+ if (state() == QMediaRecorder::StoppedState)
+ return;
+
+ if ((m_impl->stop() == KErrNone)) {
+ setRecorderState(QMediaRecorder::StoppedState);
+ }
+ else {
+ emit error(QMediaRecorder::ResourceError, tr("Unable to stop"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::ResourceError, tr(\"Unable to stop\"))");
+ }
+
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXARecordSession::cbDurationChanged(TInt64 new_pos)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ emit durationChanged((qint64)new_pos);
+ SIGNAL_EMIT_TRACE1("emit durationChanged((qint64)new_pos);");
+
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXARecordSession::cbAvailableAudioInputsChanged()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ emit availableAudioInputsChanged();
+ SIGNAL_EMIT_TRACE1("emit availableAudioInputsChanged();");
+
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXARecordSession::cbRecordingStarted()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ setRecorderState(QMediaRecorder::RecordingState);
+
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXARecordSession::cbRecordingStopped()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ emit error(QMediaRecorder::ResourceError, tr("Resources Unavailable"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::ResourceError, tr(\"Resources Unavailable\"))");
+ setRecorderState(QMediaRecorder::StoppedState);
+ /* Set record state to Stopped */
+ if (m_impl)
+ m_impl->stop();
+
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+/* For QAudioEndpointSelector begin */
+QList<QString> QXARecordSession::availableEndpoints()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ QList<QString> strList;
+
+ RETURN_s_IF_m_impl_IS_NULL(strList);
+
+ QString str;
+ RArray<TPtrC> names;
+ m_impl->getAudioInputDeviceNames(names);
+ for (TInt index = 0; index < names.Count(); index++) {
+ str = QString((QChar*)names[index].Ptr(), names[index].Length());
+ strList.append(str);
+ }
+
+ QT_TRACE_FUNCTION_EXIT;
+ return strList;
+}
+
+QString QXARecordSession::endpointDescription(const QString &name)
+{
+ /* From AL we get only device name */
+ return name;
+}
+
+QString QXARecordSession::defaultEndpoint()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ QString str;
+
+ RETURN_s_IF_m_impl_IS_NULL(str);
+
+ TPtrC name;
+ if(m_impl->defaultAudioInputDevice(name) == KErrNone)
+ str = QString((QChar*)name.Ptr(), name.Length());
+
+ QT_TRACE_FUNCTION_EXIT;
+ return str;
+}
+
+QString QXARecordSession::activeEndpoint()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ QString str;
+
+ RETURN_s_IF_m_impl_IS_NULL(str);
+
+ TPtrC name;
+ if(m_impl->activeAudioInputDevice(name) == KErrNone)
+ str = QString((QChar*)name.Ptr(), name.Length());
+
+ QT_TRACE_FUNCTION_EXIT;
+ return str;
+}
+
+void QXARecordSession::setActiveEndpoint(const QString &name)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ RETURN_IF_m_impl_IS_NULL;
+
+ if (name.isNull() || name.isEmpty())
+ return;
+
+ TPtrC16 tempPtr(reinterpret_cast<const TUint16*>(name.utf16()));
+ if (m_impl->setAudioInputDevice(tempPtr) == true) {
+ emit activeEndpointChanged(name);
+ SIGNAL_EMIT_TRACE1("emit activeEndpointChanged(name)");
+ }
+ else {
+ emit error(QMediaRecorder::ResourceError, tr("Invalid endpoint"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::ResourceError, tr(\"Invalid endpoint\"))");
+ }
+
+ QT_TRACE_FUNCTION_EXIT;
+}
+/* For QAudioEndpointSelector end */
+
+/* For QAudioEncoderControl begin */
+QStringList QXARecordSession::supportedAudioCodecs()
+{
+ return m_codecs;
+}
+
+QString QXARecordSession::codecDescription(const QString &codecName)
+{
+ if (m_codecs.contains(codecName))
+ return QString(codecName);
+ return QString();
+}
+
+QList<int> QXARecordSession::supportedSampleRates(
+ const QAudioEncoderSettings &settings,
+ bool *continuous)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ QList<int> srList;
+
+ RETURN_s_IF_m_impl_IS_NULL(srList);
+
+ QString selectedCodec = settings.codec();
+ if (selectedCodec.isNull() || selectedCodec.isEmpty())
+ selectedCodec = QString("pcm");
+
+ if (m_codecs.indexOf(selectedCodec) >= 0) {
+ RArray<TInt32> sampleRates;
+ TBool isContinuous;
+ TPtrC16 tempPtr(reinterpret_cast<const TUint16*>(selectedCodec.utf16()));
+ if (m_impl->getSampleRates(tempPtr, sampleRates, isContinuous) == KErrNone) {
+ for (TInt index = 0; index < sampleRates.Count(); index++)
+ srList.append(sampleRates[index]);
+ sampleRates.Close();
+ if (continuous)
+ {
+ *continuous = false;
+ if (isContinuous == true)
+ *continuous = true;
+ }
+ }
+ }
+
+ QT_TRACE_FUNCTION_EXIT;
+ return srList;
+}
+
+QAudioEncoderSettings QXARecordSession::audioSettings()
+{
+ return m_appliedaudioencodersettings;
+}
+
+void QXARecordSession::setAudioSettings(const QAudioEncoderSettings &settings)
+{
+ /* Settings can only be set when the recorder is in the stopped
+ * state after creation. */
+ if ((state() == QMediaRecorder::StoppedState) && (m_state == m_previousState)) {
+ /* Validate and ignore rest of the settings */
+ m_audioencodersettings = settings;
+ }
+ else {
+ emit error(QMediaRecorder::FormatError, tr("Settings cannot be changed once recording started"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::FormatError, tr(\"Settings cannot be changed once recording started\"))");
+ }
+}
+
+QStringList QXARecordSession::supportedEncodingOptions(const QString &codec)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ Q_UNUSED(codec);
+ QStringList options;
+ if ((codec.compare("aac") == 0) ||
+ (codec.compare("amr") == 0))
+ {
+ options << "bitrate" << "quality";
+ }
+
+
+ QT_TRACE_FUNCTION_EXIT;
+ return options;
+}
+
+QVariant QXARecordSession::encodingOption(const QString &codec, const QString &name)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ QVariant encodingOption;
+ QMap<QString, QVariant> map;
+ RETURN_s_IF_m_impl_IS_NULL(encodingOption);
+
+ if (name.compare("bitrate") == 0) {
+ TPtrC16 tempPtr(reinterpret_cast<const TUint16*>(codec.utf16()));
+ QList<uint> bitrateList;
+ RArray<TUint32> bitrates;
+ TBool continuous;
+ if (m_impl->getBitrates(tempPtr, bitrates, continuous) == KErrNone) {
+ for (TInt index = 0; index < bitrates.Count(); index++)
+ bitrateList.append(bitrates[index]);
+ bitrates.Close();
+ }
+ encodingOption.setValue(bitrateList);
+ map.insert("continuous", QVariant(continuous));
+ map.insert("bitrates", encodingOption);
+ }
+
+ QT_TRACE_FUNCTION_EXIT;
+ return map;
+}
+
+void QXARecordSession::setEncodingOption(
+ const QString &codec,
+ const QString &name,
+ const QVariant &value)
+{
+ /*
+ * Currently nothing can be set via this function.
+ * Bitrate is set via QAudioEncoderSettings::setBitrate().
+ */
+ Q_UNUSED(codec);
+ Q_UNUSED(name);
+ Q_UNUSED(value);
+}
+/* For QAudioEncoderControl end */
+
+QStringList QXARecordSession::supportedContainers()
+{
+ return m_containers;
+}
+
+QString QXARecordSession::containerMimeType()
+{
+ return m_containerMimeType;
+}
+
+void QXARecordSession::setContainerMimeType(const QString &formatMimeType)
+{
+ if (formatMimeType.isNull() || formatMimeType.isEmpty())
+ return;
+ else if (m_containers.indexOf(formatMimeType) >= 0 )
+ m_containerMimeType = formatMimeType;
+ else {
+ emit error(QMediaRecorder::FormatError, tr("Invalid container"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::FormatError, tr(\"Invalid container\"))");
+ }
+}
+
+QString QXARecordSession::containerDescription(const QString &formatMimeType)
+{
+ int index = m_containers.indexOf(formatMimeType);
+ if (index >= 0) {
+ return m_containersDesc.at(index);
+ }
+ else {
+ emit error(QMediaRecorder::FormatError, tr("Invalid container"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::FormatError, tr(\"Invalid container\"))");
+ }
+ return QString();
+}
+
+void QXARecordSession::setRecorderState(QMediaRecorder::State state)
+{
+ if (state != m_state) {
+ m_previousState = m_state;
+ m_state = state;
+ emit stateChanged(m_state);
+ SIGNAL_EMIT_TRACE1("emit stateChanged(m_state);");
+ }
+}
+
+void QXARecordSession::initCodecsList()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ RETURN_IF_m_impl_IS_NULL;
+
+ m_codecs.clear();
+
+ const RArray<TPtrC>& names = m_impl->getAudioEncoderNames();
+ QString str;
+
+ for (TInt index = 0; index < names.Count(); index++) {
+ str = QString((QChar*)names[index].Ptr(), names[index].Length());
+ m_codecs.append(str);
+ }
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+void QXARecordSession::initContainersList()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ RETURN_IF_m_impl_IS_NULL;
+
+ m_containers.clear();
+ m_containersDesc.clear();
+
+ const RArray<TPtrC>& names = m_impl->getContainerNames();
+ const RArray<TPtrC>& descs = m_impl->getContainerDescs();
+ QString str;
+
+ for (TInt32 index = 0; index < names.Count(); index++) {
+ str = QString((QChar*)names[index].Ptr(), names[index].Length());
+ m_containers.append(str);
+ str = QString((QChar*)descs[index].Ptr(), descs[index].Length());
+ m_containersDesc.append(str);
+ }
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+bool QXARecordSession::setEncoderSettingsToImpl()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+
+ RETURN_s_IF_m_impl_IS_NULL(false);
+
+ m_impl->resetEncoderAttributes();
+
+ /* m_containerMimeType is alredy validated in ::setContainerMimeType() */
+ QString tempStr = m_containerMimeType;
+ TPtrC16 tempPtr(reinterpret_cast<const TUint16 *>(tempStr.utf16()));
+ m_impl->setContainerType(tempPtr);
+
+ /* vaidate and assign codec */
+ if (m_audioencodersettings.codec().isNull() || m_audioencodersettings.codec().isEmpty()) {
+ m_audioencodersettings.setCodec(m_appliedaudioencodersettings.codec());
+ }
+ tempStr = m_audioencodersettings.codec();
+ if (m_codecs.indexOf(tempStr) >= 0) {
+ tempPtr.Set(reinterpret_cast<const TUint16*>(tempStr.utf16()));
+ /* We already did validation above, so function always returns true */
+ m_impl->setCodec(tempPtr);
+ }
+ else {
+ QT_TRACE2("Codec selected is :", m_audioencodersettings.codec());
+ emit error(QMediaRecorder::FormatError, tr("Invalid codec"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::FormatError, tr(\"Invalid codec\"));");
+ return false;
+ }
+
+ /* Validate and set bitrate only if encoding mode is other than quality encoding and container type is not wav*/
+ if ((m_audioencodersettings.encodingMode() != QtMultimediaKit::ConstantQualityEncoding) &&
+ (m_containerMimeType.compare("audio/wav") != 0)) {
+ m_impl->setBitRate(m_audioencodersettings.bitRate());
+ m_audioencodersettings.setBitRate(m_impl->getBitRate());
+ }
+
+ if (m_audioencodersettings.channelCount() == -1) {
+ m_impl->setOptimalChannelCount();
+ }
+ else {
+ m_impl->setChannels(m_audioencodersettings.channelCount());
+ m_audioencodersettings.setChannelCount(m_impl->getChannels());
+ }
+
+ switch (m_audioencodersettings.encodingMode()) {
+ case QtMultimediaKit::ConstantQualityEncoding: {
+ switch (m_audioencodersettings.quality()) {
+ case QtMultimediaKit::VeryLowQuality:
+ m_impl->setVeryLowQuality();
+ m_audioencodersettings.setBitRate(m_impl->getBitRate());
+ break;
+ case QtMultimediaKit::LowQuality:
+ m_impl->setLowQuality();
+ m_audioencodersettings.setBitRate(m_impl->getBitRate());
+ break;
+ case QtMultimediaKit::NormalQuality:
+ m_impl->setNormalQuality();
+ m_audioencodersettings.setBitRate(m_impl->getBitRate());
+ break;
+ case QtMultimediaKit::HighQuality:
+ m_impl->setHighQuality();
+ m_audioencodersettings.setBitRate(m_impl->getBitRate());
+ break;
+ case QtMultimediaKit::VeryHighQuality:
+ m_impl->setVeryHighQuality();
+ m_audioencodersettings.setBitRate(m_impl->getBitRate());
+ break;
+ default:
+ break;
+ }; /* end of switch (m_audioencodersettings.quality())*/
+ }
+ break;
+ case QtMultimediaKit::ConstantBitRateEncoding: {
+ TInt32 status = m_impl->setCBRMode();
+ if (status == KErrNotSupported) {
+ emit error(QMediaRecorder::FormatError, tr("Invalid encoding mode setting"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::FormatError, tr(\"Invalid encoding mode setting\"));");
+ return false;
+ }
+ else if (status != KErrNone) {
+ emit error(QMediaRecorder::ResourceError, tr("Internal error"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::ResourceError, tr(\"Internal error\"));");
+ return false;
+ }
+ }
+ break;
+ case QtMultimediaKit::AverageBitRateEncoding: {
+ TInt32 status = m_impl->setVBRMode();
+ if (status == KErrNotSupported) {
+ emit error(QMediaRecorder::FormatError, tr("Invalid encoding mode setting"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::FormatError, tr(\"Invalid encoding mode setting\"));");
+ return false;
+ }
+ else if (status != KErrNone) {
+ emit error(QMediaRecorder::ResourceError, tr("Internal error"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::ResourceError, tr(\"Internal error\"));");
+ return false;
+ }
+ }
+ break;
+ case QtMultimediaKit::TwoPassEncoding:
+ // fall through
+ default: {
+ emit error(QMediaRecorder::FormatError, tr("Invalid encoding mode setting"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::FormatError, tr(\"Invalid encoding mode setting\"));");
+ return false;
+ }
+ }; /* switch (m_audioencodersettings.encodingMode()) */
+
+ if (m_audioencodersettings.sampleRate() == -1) {
+ m_impl->setOptimalSampleRate();
+ }
+ else {
+ m_impl->setSampleRate(m_audioencodersettings.sampleRate());
+ m_audioencodersettings.setSampleRate(m_impl->getSampleRate());
+ }
+ m_appliedaudioencodersettings = m_audioencodersettings;
+
+ QT_TRACE_FUNCTION_EXIT;
+ return true;
+}
+
+bool QXARecordSession::setURIToImpl()
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ if (m_URItoImplSet)
+ return true;
+
+ /* If m_outputLocation is null, set a default location */
+ if (m_outputLocation.isEmpty()) {
+ QDir outputDir(QDir::rootPath());
+
+ int lastImage = 0;
+ int fileCount = 0;
+ foreach(QString fileName, outputDir.entryList(QStringList() << "recordclip_*")) {
+ int imgNumber = fileName.mid(5, fileName.size() - 9).toInt();
+ lastImage = qMax(lastImage, imgNumber);
+ if (outputDir.exists(fileName))
+ fileCount += 1;
+ }
+ lastImage += fileCount;
+ m_outputLocation = QUrl(QDir::toNativeSeparators(outputDir.canonicalPath() + QString("/recordclip_%1").arg(lastImage + 1, 4, 10, QLatin1Char('0'))));
+ }
+
+ QString newUrlStr = (QUrl::fromUserInput(m_outputLocation.toString())).toString();
+ // append file prefix if required
+ if (newUrlStr.lastIndexOf('.') == -1) {
+ QString fileExtension;
+ if ((m_containerMimeType.compare("audio/wav")) == KErrNone) {
+ fileExtension = QString(".wav");
+ }
+ else if ((m_containerMimeType.compare("audio/amr")) == KErrNone) {
+ fileExtension = QString(".amr");
+ }
+ else if ((m_containerMimeType.compare("audio/mpeg")) == KErrNone) {
+ fileExtension = QString(".mp4");
+ }
+ newUrlStr.append(fileExtension);
+ }
+
+ QT_TRACE2("Filename selected is :", newUrlStr);
+ TPtrC16 tempPtr(reinterpret_cast<const TUint16 *>(newUrlStr.utf16()));
+ if (m_impl->setURI(tempPtr) != 0) {
+ emit error(QMediaRecorder::ResourceError, tr("Generic error"));
+ SIGNAL_EMIT_TRACE1("emit error(QMediaRecorder::ResourceError, tr(\"Generic error\"))");
+ return false;
+ }
+ m_URItoImplSet = true;
+ m_outputLocation = QUrl(newUrlStr);
+ QT_TRACE_FUNCTION_EXIT;
+ return true;
+}
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/qxarecordsession.h b/src/plugins/symbian/openmaxal/mediarecorder/qxarecordsession.h
new file mode 100644
index 000000000..cabe58fc9
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/qxarecordsession.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXARECORDSESSION_H
+#define QXARECORDSESSION_H
+
+#include <QObject>
+#include <QUrl>
+#include "qmediarecorder.h"
+#include "xarecordsessioncommon.h"
+
+QT_USE_NAMESPACE
+
+class XARecordSessionImpl;
+
+/*
+ * This is a backend class for all QXXXControl objects.
+ * This class contains actual implementation of recording functionality
+ * from the control object's perspective.
+ */
+
+
+class QXARecordSession : public QObject,
+ public XARecordObserver
+{
+Q_OBJECT
+
+public:
+ QXARecordSession(QObject *parent);
+ virtual ~QXARecordSession();
+
+ /* For QMediaRecorderControl begin */
+ QUrl outputLocation();
+ bool setOutputLocation(const QUrl &location);
+ QMediaRecorder::State state();
+ qint64 duration();
+ void applySettings();
+
+ void record();
+ void pause();
+ void stop();
+
+ void cbDurationChanged(TInt64 new_pos);
+ void cbAvailableAudioInputsChanged();
+ void cbRecordingStarted();
+ void cbRecordingStopped();
+ /* For QMediaRecorderControl end */
+
+ /* For QAudioEndpointSelector begin */
+ QList<QString> availableEndpoints();
+ QString endpointDescription(const QString &name);
+ QString defaultEndpoint();
+ QString activeEndpoint();
+ void setActiveEndpoint(const QString &name);
+ /* For QAudioEndpointSelector end */
+
+ /* For QAudioEncoderControl begin */
+ QStringList supportedAudioCodecs();
+ QString codecDescription(const QString &codecName);
+ QList<int> supportedSampleRates(
+ const QAudioEncoderSettings &settings,
+ bool *continuous);
+ QAudioEncoderSettings audioSettings();
+ void setAudioSettings(const QAudioEncoderSettings &settings);
+ QStringList supportedEncodingOptions(const QString &codec);
+ QVariant encodingOption(const QString &codec, const QString &name);
+ void setEncodingOption(const QString &codec, const QString &name, const QVariant &value);
+ /* For QAudioEncoderControl end */
+
+ /* For QMediaContainerControl begin */
+ QStringList supportedContainers();
+ QString containerMimeType();
+ void setContainerMimeType(const QString &formatMimeType);
+ QString containerDescription(const QString &formatMimeType);
+ /* For QMediaContainerControl end */
+
+Q_SIGNALS:
+ void stateChanged(QMediaRecorder::State state);
+ void durationChanged(qint64 duration);
+ void error(int error, const QString &errorString);
+ void activeEndpointChanged(const QString& name);
+ void availableAudioInputsChanged();
+
+private:
+ void setRecorderState(QMediaRecorder::State state);
+ void initCodecsList();
+ void initContainersList();
+ bool setEncoderSettingsToImpl();
+ bool setURIToImpl();
+
+private:
+ /* Own */
+ XARecordSessionImpl *m_impl;
+ QUrl m_outputLocation;
+ bool m_URItoImplSet;
+ QMediaRecorder::State m_state;
+ QMediaRecorder::State m_previousState;
+ QStringList m_codecs;
+ QAudioEncoderSettings m_audioencodersettings;
+ QAudioEncoderSettings m_appliedaudioencodersettings;
+ QStringList m_containers;
+ QStringList m_containersDesc;
+ QString m_containerMimeType;
+};
+
+#endif /* QXARECORDSESSION_H */
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/xarecordsessioncommon.h b/src/plugins/symbian/openmaxal/mediarecorder/xarecordsessioncommon.h
new file mode 100644
index 000000000..cdf8c1886
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/xarecordsessioncommon.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XARECORDSESSIONCOMMON_H
+#define XARECORDSESSIONCOMMON_H
+
+#include <e32base.h>
+#include "xacommon.h"
+
+#define MAX_NUMBER_INTERFACES 20
+#define MAX_NUMBER_INPUT_DEVICES 10
+#define MAX_NUMBER_ENCODERS 10
+
+//const TInt32 KExtErr = (TInt32)(-2147483648);
+const TInt32 KExtErr = -32768;
+const TInt32 KExtErrUnspecifiedCodecForContainer = (KExtErr+1);
+const TInt32 KExtErrUnsupportedCodecForContainer = (KExtErr+2);
+const TInt32 KExtErrUnsupportedURISuffixForContainer = (KExtErr+3);
+
+class XARecordObserver
+{
+public:
+ virtual void cbDurationChanged(TInt64 new_pos) = 0;
+ virtual void cbAvailableAudioInputsChanged() = 0;
+ virtual void cbRecordingStarted() = 0;
+ virtual void cbRecordingStopped() = 0;
+};
+
+#endif /* XARECORDSESSIONCOMMON_H */
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/xarecordsessionimpl.cpp b/src/plugins/symbian/openmaxal/mediarecorder/xarecordsessionimpl.cpp
new file mode 100644
index 000000000..d18c781d4
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/xarecordsessionimpl.cpp
@@ -0,0 +1,1378 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info@nokia.com)
+ **
+ ** This file is part of the Qt Mobility Components.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** No Commercial Usage
+ ** This file contains pre-release code and may not be distributed.
+ ** You may use this file in accordance with the terms and conditions
+ ** contained in the Technology Preview License Agreement accompanying
+ ** this package.
+ **
+ ** GNU Lesser General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU Lesser
+ ** General Public License version 2.1 as published by the Free Software
+ ** Foundation and appearing in the file LICENSE.LGPL included in the
+ ** packaging of this file. Please review the following information to
+ ** ensure the GNU Lesser General Public License version 2.1 requirements
+ ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** In addition, as a special exception, Nokia gives you certain additional
+ ** rights. These rights are described in the Nokia Qt LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** If you have questions regarding the use of this file, please contact
+ ** Nokia at qt-info@nokia.com.
+ **
+ **
+ **
+ **
+ **
+ **
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+#include "xarecordsessionimpl.h"
+#include "xarecordsessioncommon.h"
+_LIT8(K8WAVMIMETYPE, "audio/x-wav");
+/*
+ * These codec names are not part of AL. Hence we need to define names here.
+ * */
+_LIT(KAUDIOCODECPCM, "pcm");
+_LIT(KAUDIOCODECAMR, "amr");
+_LIT(KAUDIOCODECAAC, "aac");
+_LIT(KCONTAINERWAV, "audio/wav");
+_LIT(KCONTAINERWAVDESC, "wav container");
+_LIT(KCONTAINERAMR, "audio/amr");
+_LIT(KCONTAINERAMRDESC, "amr File format");
+_LIT(KCONTAINERMP4, "audio/mpeg");
+_LIT(KCONTAINERMP4DESC, "mpeg container");
+
+const TUint KRecordPosUpdatePeriod = 1000;
+const TUint KMilliToHz = 1000;
+const TUint KMaxNameLength = 256;
+
+/* Local functions for callback registation */
+void cbXAObjectItf(
+ XAObjectItf caller,
+ const void *pContext,
+ XAuint32 event,
+ XAresult result,
+ XAuint32 param,
+ void *pInterface);
+
+void cbXARecordItf(
+ XARecordItf caller,
+ void *pContext,
+ XAuint32 event);
+
+void cbXAAvailableAudioInputsChanged(
+ XAAudioIODeviceCapabilitiesItf caller,
+ void *pContext,
+ XAuint32 deviceID,
+ XAint32 numInputs,
+ XAboolean isNew);
+
+XARecordSessionImpl::XARecordSessionImpl(XARecordObserver &parent) :
+ m_Parent(parent),
+ m_EOEngine(NULL),
+ m_MORecorder(NULL),
+ m_RecordItf(NULL),
+ m_AudioEncItf(NULL),
+ m_WAVMime(NULL),
+ m_URIName(NULL),
+ m_InputDeviceId(0),
+ m_ContainerType(0),
+ m_BitRate(0),
+ m_RateControl(0),
+ m_ChannelsOut(1),
+ m_SampleRate(0),
+ m_AudioIODevCapsItf(NULL),
+ m_AudioInputDeviceNames(NULL),
+ m_DefaultAudioInputDeviceNames(NULL),
+ m_AudioEncCapsItf(NULL)
+{
+ TRACE_FUNCTION_ENTRY_EXIT;
+}
+
+XARecordSessionImpl::~XARecordSessionImpl()
+{
+ TRACE_FUNCTION_ENTRY;
+
+ if (m_MORecorder)
+ (*m_MORecorder)->Destroy(m_MORecorder);
+
+ if (m_EOEngine)
+ (*m_EOEngine)->Destroy(m_EOEngine);
+
+ delete m_WAVMime;
+ delete m_URIName;
+
+ m_InputDeviceIDs.Close();
+ if (m_AudioInputDeviceNames)
+ m_AudioInputDeviceNames->Reset();
+ delete m_AudioInputDeviceNames;
+ m_DefaultInputDeviceIDs.Close();
+ if (m_DefaultAudioInputDeviceNames)
+ m_DefaultAudioInputDeviceNames->Reset();
+ delete m_DefaultAudioInputDeviceNames;
+ m_EncoderIds.Close();
+ m_EncoderNames.Close();
+ m_ContainerNames.Close();
+ m_ContainerDescs.Close();
+
+ TRACE_FUNCTION_EXIT;
+}
+
+TInt32 XARecordSessionImpl::postConstruct()
+{
+ TRACE_FUNCTION_ENTRY;
+
+ XAEngineOption engineOption[] = { (XAuint32) XA_ENGINEOPTION_THREADSAFE, (XAuint32) XA_BOOLEAN_TRUE};
+
+ /* Create and realize Engine object */
+ TRACE_LOG(_L("XARecordSessionImpl: Creating Engine..."));
+ XAresult xa_result = xaCreateEngine(&m_EOEngine, 1, engineOption, 0, NULL, NULL);
+ TInt returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+ TRACE_LOG(_L("XARecordSessionImpl: Realizing engine..."));
+ xa_result = (*m_EOEngine)->Realize(m_EOEngine, XA_BOOLEAN_FALSE);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+ TRACE_LOG(_L("XARecordSessionImpl: OMX AL Engine realized successfully"));
+
+ XAEngineItf engineItf;
+ xa_result = (*m_EOEngine)->GetInterface(m_EOEngine, XA_IID_ENGINE, (void**) &engineItf);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ xa_result = (*m_EOEngine)->GetInterface(m_EOEngine,
+ XA_IID_AUDIOIODEVICECAPABILITIES,
+ (void**) &m_AudioIODevCapsItf);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+ xa_result = (*m_AudioIODevCapsItf)->RegisterAvailableAudioInputsChangedCallback(
+ m_AudioIODevCapsItf,
+ cbXAAvailableAudioInputsChanged,
+ (void*)this);
+
+ xa_result = (*m_EOEngine)->GetInterface(
+ m_EOEngine,
+ XA_IID_AUDIOENCODERCAPABILITIES,
+ (void**) &m_AudioEncCapsItf);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ TRAP(returnValue, m_WAVMime = HBufC8::NewL(K8WAVMIMETYPE().Length() + 1));
+ RET_ERR_IF_ERR(returnValue);
+ TPtr8 ptr = m_WAVMime->Des();
+ ptr = K8WAVMIMETYPE(); // copy uri name into local variable
+ ptr.PtrZ(); // append zero terminator to end of URI
+
+ m_AudioInputDeviceNames = new CDesC16ArrayFlat(2);
+ if (m_AudioInputDeviceNames == NULL)
+ returnValue = KErrNoMemory;
+ RET_ERR_IF_ERR(returnValue);
+
+ m_DefaultAudioInputDeviceNames = new CDesC16ArrayFlat(2);
+ if (m_DefaultAudioInputDeviceNames == NULL)
+ returnValue = KErrNoMemory;
+ RET_ERR_IF_ERR(returnValue);
+
+ returnValue = initContainersList();
+ RET_ERR_IF_ERR(returnValue);
+ returnValue = initAudioEncodersList();
+ RET_ERR_IF_ERR(returnValue);
+ returnValue = initAudioInputDevicesList();
+ RET_ERR_IF_ERR(returnValue);
+
+ TRACE_FUNCTION_EXIT;
+ return returnValue;
+}
+
+TInt32 XARecordSessionImpl::setURI(const TDesC &aURI)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ /* This function will only get called when aURI is different than m_URIName
+ * and only when recorder is in stopped state.
+ * If the recorder object was created for a different URI (than aURI), we
+ * need to tear it down here.
+ */
+ if (m_MORecorder) {
+ (*m_MORecorder)->Destroy(m_MORecorder);
+ m_MORecorder = NULL;
+ m_RecordItf = NULL;
+ }
+
+ delete m_URIName;
+ m_URIName = NULL;
+ TRAPD(returnValue, m_URIName = HBufC8::NewL(aURI.Length()+1));
+ RET_ERR_IF_ERR(returnValue);
+
+ TPtr8 uriPtr = m_URIName->Des();
+ /* copy uri name into local variable */
+ uriPtr.Copy(aURI);
+
+ TRACE_FUNCTION_EXIT;
+ return returnValue;
+}
+
+TInt32 XARecordSessionImpl::record()
+{
+ TRACE_FUNCTION_ENTRY;
+
+ TInt32 returnValue(KErrGeneral);
+ if (!m_MORecorder || !m_RecordItf) {
+ TRACE_LOG(_L("XARecordSessionImpl::Record: MORecorder/RecordItf is not created"));
+ returnValue = createMediaRecorderObject();
+ RET_ERR_IF_ERR(returnValue);
+
+ returnValue = setEncoderSettingsToMediaRecorder();
+ RET_ERR_IF_ERR(returnValue);
+ }
+
+ XAuint32 state;
+ XAresult xa_result = (*m_RecordItf)->GetRecordState(m_RecordItf, &state);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ if ((state == XA_RECORDSTATE_STOPPED)
+ || (state == XA_RECORDSTATE_PAUSED)) {
+ TRACE_LOG(_L("XARecordSessionImpl::Record: Setting State to Recording..."));
+ xa_result = (*m_RecordItf)->SetRecordState(m_RecordItf, XA_RECORDSTATE_RECORDING);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+ TRACE_LOG(_L("XARecordSessionImpl::Record: SetState to Recording"));
+ }
+
+ TRACE_FUNCTION_EXIT;
+ return returnValue;
+}
+
+TInt32 XARecordSessionImpl::pause()
+{
+ TRACE_FUNCTION_ENTRY;
+
+ TInt32 returnValue(KErrGeneral);
+ if (!m_MORecorder || !m_RecordItf) {
+ TRACE_LOG(_L("XARecordSessionImpl::Record: MORecorder/RecordItf is not created"));
+ return returnValue;
+ }
+
+ XAuint32 state;
+ XAresult xa_result = (*m_RecordItf)->GetRecordState(m_RecordItf, &state);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ if ((state == XA_RECORDSTATE_STOPPED)
+ || (state == XA_RECORDSTATE_RECORDING)) {
+ TRACE_LOG(_L("XARecordSessionImpl::Record: Setting State to Paused..."));
+ xa_result = (*m_RecordItf)->SetRecordState(m_RecordItf, XA_RECORDSTATE_PAUSED);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+ TRACE_LOG(_L("XARecordSessionImpl::Record: SetState to Paused"));
+ }
+
+ TRACE_FUNCTION_EXIT;
+ return returnValue;
+}
+
+TInt32 XARecordSessionImpl::stop()
+{
+ TRACE_FUNCTION_ENTRY;
+
+ TInt32 returnValue(KErrGeneral);
+ if (!m_MORecorder || !m_RecordItf) {
+ TRACE_LOG(_L("XARecordSessionImpl::Record: MORecorder/RecordItf is not created"));
+ return returnValue;
+ }
+
+ XAuint32 state;
+ XAresult xa_result = (*m_RecordItf)->GetRecordState(m_RecordItf, &state);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ if ((state == XA_RECORDSTATE_PAUSED)
+ || (state == XA_RECORDSTATE_RECORDING)) {
+ TRACE_LOG(_L("XARecordSessionImpl::Record: Setting State to Stopped..."));
+ xa_result = (*m_RecordItf)->SetRecordState(m_RecordItf, XA_RECORDSTATE_STOPPED);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+ TRACE_LOG(_L("XARecordSessionImpl::Record: SetState to Stopped"));
+ }
+
+ TRACE_FUNCTION_EXIT;
+ return returnValue;
+}
+
+TInt32 XARecordSessionImpl::duration(TInt64 &aDur)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ TInt32 returnValue(KErrGeneral);
+
+ if (!m_MORecorder || !m_RecordItf) {
+ TRACE_LOG(_L("XARecordSessionImpl::Duration: MORecoder/RecordItf is not created"));
+ return returnValue;
+ }
+
+ XAmillisecond milliSec;
+ XAresult xa_result = (*m_RecordItf)->GetPosition(m_RecordItf, &milliSec);
+ returnValue = mapError(xa_result, ETrue);
+ if (returnValue == KErrNone)
+ aDur = (TInt64)milliSec;
+
+ TRACE_FUNCTION_EXIT;
+ return returnValue;
+}
+
+void XARecordSessionImpl::cbMediaRecorder(
+ XAObjectItf /*caller*/,
+ const void */*pContext*/,
+ XAuint32 event,
+ XAresult result,
+ XAuint32 /*param*/,
+ void */*pInterface*/)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ switch (event) {
+ case XA_OBJECT_EVENT_RESOURCES_LOST:
+ m_Parent.cbRecordingStopped();
+ break;
+ case XA_OBJECT_EVENT_RUNTIME_ERROR: {
+ switch (result) {
+ case XA_RESULT_RESOURCE_LOST:
+ m_Parent.cbRecordingStopped();
+ break;
+ default:
+ break;
+ }; /* of switch (result) */
+ }
+ default:
+ break;
+ } /* of switch (event) */
+
+ TRACE_FUNCTION_EXIT;
+}
+
+void XARecordSessionImpl::cbRecordItf(
+ XARecordItf /*caller*/,
+ void */*pContext*/,
+ XAuint32 event)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ switch(event) {
+ case XA_RECORDEVENT_HEADATLIMIT:
+ TRACE_LOG(_L("XA_RECORDEVENT_HEADATLIMIT"));
+ break;
+ case XA_RECORDEVENT_HEADATMARKER:
+ TRACE_LOG(_L("XA_RECORDEVENT_HEADATMARKER"));
+ break;
+ case XA_RECORDEVENT_HEADATNEWPOS: {
+ TInt32 returnValue;
+ XAresult xa_result;
+ XAmillisecond milliSec;
+ xa_result = (*m_RecordItf)->GetPosition(m_RecordItf, &milliSec);
+ returnValue = mapError(xa_result, ETrue);
+ if (returnValue == KErrNone)
+ m_Parent.cbDurationChanged((TInt64) milliSec);
+ }
+ break;
+ case XA_RECORDEVENT_HEADMOVING:
+ TRACE_LOG(_L("XA_RECORDEVENT_HEADMOVING"));
+ m_Parent.cbRecordingStarted();
+ break;
+ case XA_RECORDEVENT_HEADSTALLED:
+ TRACE_LOG(_L("XA_RECORDEVENT_HEADSTALLED"));
+ break;
+ case XA_RECORDEVENT_BUFFER_FULL:
+ TRACE_LOG(_L("XA_RECORDEVENT_BUFFER_FULL"));
+ break;
+ default:
+ TRACE_LOG(_L("UNKNOWN RECORDEVENT EVENT"));
+ break;
+ } /* of switch(event) */
+
+ TRACE_FUNCTION_EXIT;
+}
+
+/* For QAudioEndpointSelector begin */
+void XARecordSessionImpl::getAudioInputDeviceNames(RArray<TPtrC> &aArray)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ for (TInt index = 0; index < m_AudioInputDeviceNames->MdcaCount(); index++)
+ aArray.Append(m_AudioInputDeviceNames->MdcaPoint(index));
+ TRACE_FUNCTION_EXIT;
+}
+
+TInt32 XARecordSessionImpl::defaultAudioInputDevice(TPtrC &endPoint)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ TInt32 err(KErrGeneral);
+ if (m_DefaultAudioInputDeviceNames->MdcaCount() >= 0) {
+ endPoint.Set(m_DefaultAudioInputDeviceNames->MdcaPoint(0));
+ err = KErrNone;
+ }
+
+ TRACE_FUNCTION_EXIT;
+ return err;
+}
+
+TInt32 XARecordSessionImpl::activeAudioInputDevice(TPtrC &endPoint)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ TInt32 returnValue(KErrGeneral);
+ TBool found(EFalse);
+ TInt index = 0;
+ for (; index < m_InputDeviceIDs.Count(); index++) {
+ if (m_InputDeviceIDs[index] == m_InputDeviceId) {
+ found = ETrue;
+ break;
+ }
+ }
+
+ /* Comparing found with ETrue produces linker error */
+ if (found == true) {
+ endPoint.Set(m_AudioInputDeviceNames->MdcaPoint(index));
+ returnValue = KErrNone;
+ }
+
+ TRACE_FUNCTION_EXIT;
+ return returnValue;
+}
+
+TBool XARecordSessionImpl::setAudioInputDevice(const TDesC &aDevice)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ /* validate if we can set input device id */
+ TBool found(EFalse);
+ m_InputDeviceId = 0;
+ TInt index = 0;
+ for (; index < m_AudioInputDeviceNames->MdcaCount(); index++) {
+ if (m_AudioInputDeviceNames->MdcaPoint(index).Compare(aDevice) == 0) {
+ found = ETrue;
+ break;
+ }
+ }
+ if (found == true) {
+ m_InputDeviceId = m_InputDeviceIDs[index];
+ }
+
+ TRACE_FUNCTION_EXIT;
+ return found;
+}
+
+void XARecordSessionImpl::cbAvailableAudioInputsChanged(
+ XAAudioIODeviceCapabilitiesItf /*caller*/,
+ void */*pContext*/,
+ XAuint32 deviceID,
+ XAint32 /*numInputs*/,
+ XAboolean isNew)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ /* If a new device is added into the system, append it to available input list */
+ if (isNew == XA_BOOLEAN_TRUE) {
+ XAAudioInputDescriptor audioInputDescriptor;
+ m_InputDeviceIDs.Append(deviceID);
+
+ XAresult xa_result = (*m_AudioIODevCapsItf)->QueryAudioInputCapabilities(
+ m_AudioIODevCapsItf,
+ deviceID,
+ &audioInputDescriptor);
+
+ if ((mapError(xa_result, ETrue)) == KErrNone) {
+ TUint8* inDevNamePtr = audioInputDescriptor.deviceName;
+ TUint8* tempPtr = audioInputDescriptor.deviceName;
+ TInt32 inDevNameLength = 0;
+ while (*tempPtr++)
+ inDevNameLength++;
+ TPtrC8 ptr(inDevNamePtr, inDevNameLength);
+ /* Convert 8 bit to 16 bit */
+ TBuf16<KMaxNameLength> name;
+ name.Copy(ptr);
+ /* Using TRAP with returnValue results in compiler error */
+ TRAP_IGNORE(m_AudioInputDeviceNames->AppendL(name));
+ }
+ }
+ else {
+ /* an available device has been removed from the the system, remove it from
+ * available input list and also default list */
+ TBool found(EFalse);
+ TInt index = 0;
+ for (; index < m_InputDeviceIDs.Count(); index++) {
+ if (deviceID == m_InputDeviceIDs[index]) {
+ found = ETrue;
+ break;
+ }
+ }
+ if (found == true) {
+ m_InputDeviceIDs.Remove(index);
+ m_AudioInputDeviceNames->Delete(index);
+ }
+ if (deviceID == m_InputDeviceId)
+ m_InputDeviceId = 0;
+
+ found = EFalse;
+ for (index = 0; index < m_DefaultInputDeviceIDs.Count(); index++) {
+ if (deviceID == m_DefaultInputDeviceIDs[index]) {
+ found = ETrue;
+ break;
+ }
+ }
+ if (found == true) {
+ m_DefaultInputDeviceIDs.Remove(index);
+ m_DefaultAudioInputDeviceNames->Delete(index);
+ }
+ }
+ m_Parent.cbAvailableAudioInputsChanged();
+
+ TRACE_FUNCTION_EXIT;
+}
+/* For QAudioEndpointSelector end */
+
+/* For QAudioEncoderControl begin */
+const RArray<TPtrC>& XARecordSessionImpl::getAudioEncoderNames()
+{
+ TRACE_FUNCTION_ENTRY_EXIT;
+ return m_EncoderNames;
+}
+
+TInt32 XARecordSessionImpl::getSampleRates(
+ const TDesC& aEncoder,
+ RArray<TInt32> &aSampleRates,
+ TBool &aIsContinuous)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ aSampleRates.Reset();
+ aIsContinuous = EFalse;
+
+ XAuint32 encoderId = 0;
+ TBool found(EFalse);
+ for (TInt index = 0; index < m_EncoderIds.Count(); index++) {
+ if (m_EncoderNames[index].Compare(aEncoder) == 0) {
+ found = ETrue;
+ encoderId = m_EncoderIds[index];
+ break;
+ }
+ }
+
+ TInt32 returnValue(KErrGeneral);
+ if (found == false)
+ return returnValue;
+
+ returnValue = getSampleRatesByAudioCodecID(encoderId, aSampleRates);
+
+ TRACE_FUNCTION_EXIT;
+ return returnValue;
+}
+
+TInt32 XARecordSessionImpl::getBitrates(
+ const TDesC& aEncoder,
+ RArray<TUint32> &aBitrates,
+ TBool& aContinuous)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ aBitrates.Reset();
+
+ XAuint32 encoderId = 0;
+ TBool found(EFalse);
+ for (TInt index = 0; index < m_EncoderIds.Count(); index++) {
+ if (m_EncoderNames[index].Compare(aEncoder) == 0) {
+ found = ETrue;
+ encoderId = m_EncoderIds[index];
+ break;
+ }
+ }
+
+ TInt32 returnValue(KErrNotSupported);
+ XAboolean cont;
+ if (found == false)
+ return returnValue;
+
+ returnValue = getBitratesByAudioCodecID(encoderId, aBitrates, cont);
+ aContinuous = cont;
+
+ TRACE_FUNCTION_EXIT;
+ return returnValue;
+}
+
+/* For QAudioEncoderControl end */
+
+/* For QMediaContainerControl begin */
+const RArray<TPtrC>& XARecordSessionImpl::getContainerNames()
+{
+ TRACE_FUNCTION_ENTRY_EXIT;
+ return m_ContainerNames;
+}
+
+const RArray<TPtrC>& XARecordSessionImpl::getContainerDescs()
+{
+ TRACE_FUNCTION_ENTRY_EXIT;
+ return m_ContainerDescs;
+}
+
+/* For QMediaContainerControl end */
+
+void XARecordSessionImpl::resetEncoderAttributes()
+{
+ m_ContainerType = 0;
+ m_AudioEncoderId = 0;
+ m_ProfileSetting = 0;
+ m_BitRate = 0;
+ m_ChannelsOut = 1;
+ m_SampleRate = 0;
+ m_RateControl = 0;
+}
+
+void XARecordSessionImpl::setContainerType(const TDesC &aURI)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ if (aURI.Compare(KCONTAINERWAV()) == 0)
+ m_ContainerType = XA_CONTAINERTYPE_WAV;
+ else if (aURI.Compare(KCONTAINERAMR()) == 0)
+ m_ContainerType = XA_CONTAINERTYPE_AMR;
+ else if (aURI.Compare(KCONTAINERMP4()) == 0)
+ m_ContainerType = XA_CONTAINERTYPE_MP4;
+
+ TRACE_FUNCTION_EXIT;
+}
+
+TBool XARecordSessionImpl::setCodec(const TDesC &aCodec)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ TBool returnValue(EFalse);
+ if (aCodec.Compare(KAUDIOCODECPCM()) == 0) {
+ m_AudioEncoderId = XA_AUDIOCODEC_PCM;
+ m_ProfileSetting = XA_AUDIOPROFILE_PCM;
+ returnValue = ETrue;
+ }
+ else if (aCodec.Compare(KAUDIOCODECAAC()) == 0) {
+ m_AudioEncoderId = XA_AUDIOCODEC_AAC;
+ m_ProfileSetting = XA_AUDIOPROFILE_AAC_AAC;
+ returnValue = ETrue;
+ }
+ else if (aCodec.Compare(KAUDIOCODECAMR()) == 0) {
+ m_AudioEncoderId = XA_AUDIOCODEC_AMR;
+ m_ProfileSetting = XA_AUDIOPROFILE_AMR;
+ returnValue = ETrue;
+ }
+
+ TRACE_FUNCTION_EXIT;
+ return returnValue;
+}
+
+TUint32 XARecordSessionImpl::getBitRate()
+{
+ return m_BitRate;
+}
+
+void XARecordSessionImpl::setBitRate(TUint32 aBitRate)
+{
+ TRACE_FUNCTION_ENTRY;
+ RArray<TUint32> bitrates;
+ XAboolean isContinuous;
+ m_BitRate = 0;
+ if (getBitratesByAudioCodecID(m_AudioEncoderId, bitrates, isContinuous) == KErrNone) {
+ bitrates.SortUnsigned();
+ TInt loopIndex(0);
+ while (loopIndex < bitrates.Count()
+ && aBitRate <= bitrates[loopIndex]) {
+ m_BitRate = bitrates[loopIndex];
+ loopIndex++;
+ }
+ bitrates.Close();
+ }
+ TRACE_LOG((_L("BitRate[%d]"), m_BitRate));
+ TRACE_FUNCTION_EXIT;
+}
+
+TUint32 XARecordSessionImpl::getChannels()
+{
+ return m_ChannelsOut;
+}
+
+void XARecordSessionImpl::setChannels(TUint32 aChannels)
+{
+ TRACE_FUNCTION_ENTRY;
+ switch (m_AudioEncoderId) {
+ case XA_AUDIOCODEC_PCM:
+ case XA_AUDIOCODEC_AAC:
+ m_ChannelsOut = 1;
+ if ((aChannels >= 1) && (aChannels <= 2))
+ m_ChannelsOut = aChannels;
+ break;
+ case XA_AUDIOCODEC_AMR:
+ m_ChannelsOut = 1;
+ break;
+ default:
+ break;
+ }
+ TRACE_LOG((_L("ChannelCount[%d]"), m_ChannelsOut));
+ TRACE_FUNCTION_EXIT;
+}
+
+void XARecordSessionImpl::setOptimalChannelCount()
+{
+ TRACE_FUNCTION_ENTRY;
+ m_ChannelsOut = 1;
+ TRACE_FUNCTION_EXIT;
+}
+
+TUint32 XARecordSessionImpl::getSampleRate()
+{
+ return m_SampleRate;
+}
+
+void XARecordSessionImpl::setSampleRate(TUint32 aSampleRate)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ m_SampleRate = 0;
+
+ RArray<TInt32> samplerates;
+ if (getSampleRatesByAudioCodecID(m_AudioEncoderId, samplerates) == KErrNone) {
+ samplerates.SortUnsigned();
+ TInt loopIndex(0);
+ while (loopIndex < samplerates.Count()) {
+ m_SampleRate = samplerates[loopIndex];
+ if (samplerates[loopIndex] > aSampleRate)
+ break;
+ loopIndex++;
+ }
+ samplerates.Close();
+ }
+
+ /* convert Hz to MilliHz */
+ m_SampleRate *= KMilliToHz;
+ TRACE_LOG((_L("SampleRate[%d]"), m_SampleRate));
+ TRACE_FUNCTION_EXIT;
+}
+
+void XARecordSessionImpl::setOptimalSampleRate()
+{
+ TRACE_FUNCTION_ENTRY;
+ m_SampleRate = 0;
+
+ if (m_AudioEncoderId == XA_AUDIOCODEC_AAC) {
+ m_SampleRate = 32000 * KMilliToHz;
+ }
+ else if (m_AudioEncoderId == XA_AUDIOCODEC_AMR) {
+ m_SampleRate = 8000 * KMilliToHz;
+ }
+ else {
+ RArray<TInt32> sampleRates;
+ TInt res = getSampleRatesByAudioCodecID(m_AudioEncoderId, sampleRates);
+ if ((res == KErrNone) && (sampleRates.Count() > 0)) {
+ /* Sort the array and pick the middle range sample rate */
+ sampleRates.SortUnsigned();
+ m_SampleRate = sampleRates[sampleRates.Count() / 2] * KMilliToHz;
+ }
+ sampleRates.Close();
+ }
+
+ TRACE_FUNCTION_EXIT;
+}
+
+TInt32 XARecordSessionImpl::setCBRMode()
+{
+ TRACE_FUNCTION_ENTRY;
+
+ m_RateControl = XA_RATECONTROLMODE_CONSTANTBITRATE;
+
+ TRACE_FUNCTION_EXIT;
+ return KErrNone;
+}
+
+TInt32 XARecordSessionImpl::setVBRMode()
+{
+ TRACE_FUNCTION_ENTRY;
+
+ m_RateControl = XA_RATECONTROLMODE_VARIABLEBITRATE;
+
+ TRACE_FUNCTION_EXIT;
+ return KErrNone;
+}
+
+void XARecordSessionImpl::setVeryLowQuality()
+{
+ /* Set to very low quality encoder preset */
+ RArray<TUint32> bitrates;
+ XAboolean continuous;
+ TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates, continuous);
+ if ((res == KErrNone) && (bitrates.Count() > 0)) {
+ /* Sort the array and pick the lowest bit rate */
+ bitrates.SortUnsigned();
+ m_BitRate = bitrates[0];
+ }
+ bitrates.Close();
+}
+
+void XARecordSessionImpl::setLowQuality()
+{
+ /* Set to low quality encoder preset */
+ RArray<TUint32> bitrates;
+ XAboolean continuous;
+ TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates, continuous);
+ if ((res == KErrNone) && (bitrates.Count() > 0)) {
+ /* Sort the array and pick the low quality bit rate */
+ bitrates.SortUnsigned();
+ if (continuous == XA_BOOLEAN_FALSE)
+ m_BitRate = bitrates[bitrates.Count() / 4];
+ else
+ m_BitRate = (bitrates[1] - bitrates[0]) / 4;
+ }
+ bitrates.Close();
+}
+
+void XARecordSessionImpl::setNormalQuality()
+{
+ /* Set to normal quality encoder preset */
+ RArray<TUint32> bitrates;
+ XAboolean continuous;
+ TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates, continuous);
+ if ((res == KErrNone) && (bitrates.Count() > 0)) {
+ /* Sort the array and pick the middle range bit rate */
+ bitrates.SortUnsigned();
+ if (continuous == XA_BOOLEAN_FALSE)
+ m_BitRate = bitrates[bitrates.Count() / 2];
+ else
+ m_BitRate = (bitrates[1] - bitrates[0]) / 2;
+ }
+ bitrates.Close();
+}
+
+void XARecordSessionImpl::setHighQuality()
+{
+ /* Set to high quality encoder preset */
+ RArray<TUint32> bitrates;
+ XAboolean continuous;
+ TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates, continuous);
+ if ((res == KErrNone) && (bitrates.Count() > 0)) {
+ /* Sort the array and pick the high quality bit rate */
+ bitrates.SortUnsigned();
+ if (continuous == XA_BOOLEAN_FALSE)
+ m_BitRate = bitrates[bitrates.Count() * 3 / 4];
+ else
+ m_BitRate = (bitrates[1] - bitrates[0]) * 3 / 4;
+ }
+ bitrates.Close();
+}
+
+void XARecordSessionImpl::setVeryHighQuality()
+{
+ /* Set to very high quality encoder preset */
+ RArray<TUint32> bitrates;
+ XAboolean continuous;
+ TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates, continuous);
+ if ((res == KErrNone) && (bitrates.Count() > 0)) {
+ /* Sort the array and pick the highest bit rate */
+ bitrates.SortUnsigned();
+ m_BitRate = bitrates[bitrates.Count() - 1];
+ }
+ bitrates.Close();
+}
+
+/* Internal function */
+TInt32 XARecordSessionImpl::createMediaRecorderObject()
+{
+ TRACE_FUNCTION_ENTRY;
+
+ if (!m_EOEngine)
+ return KErrGeneral;
+
+ TInt32 returnValue(KErrNone);
+
+ TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject"));
+ if (!m_MORecorder && !m_RecordItf) {
+
+ /* Setup the data source */
+ m_LocatorMic.locatorType = XA_DATALOCATOR_IODEVICE;
+ m_LocatorMic.deviceType = XA_IODEVICE_AUDIOINPUT;
+ m_LocatorMic.deviceID = m_InputDeviceId;
+ m_LocatorMic.device = NULL;
+ m_DataSource.pLocator = (void*) &m_LocatorMic;
+ m_DataSource.pFormat = NULL;
+
+ /* Setup the data sink structure */
+ m_Uri.locatorType = XA_DATALOCATOR_URI;
+ /* append zero terminator to end of URI */
+ TPtr8 uriPtr = m_URIName->Des();
+ m_Uri.URI = (XAchar*) uriPtr.PtrZ();
+ m_Mime.formatType = XA_DATAFORMAT_MIME;
+ m_Mime.containerType = m_ContainerType;
+ TPtr8 mimeTypePtr(m_WAVMime->Des());
+ m_Mime.mimeType = (XAchar*) mimeTypePtr.Ptr();
+ m_DataSink.pLocator = (void*) &m_Uri;
+ m_DataSink.pFormat = (void*) &m_Mime;
+
+ /* Init arrays required[] and iidArray[] */
+ XAboolean required[MAX_NUMBER_INTERFACES];
+ XAInterfaceID iidArray[MAX_NUMBER_INTERFACES];
+ for (TInt32 i = 0; i < MAX_NUMBER_INTERFACES; i++) {
+ required[i] = XA_BOOLEAN_FALSE;
+ iidArray[i] = XA_IID_NULL;
+ }
+ XAuint32 noOfInterfaces = 0;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_RECORD;
+ noOfInterfaces++;
+ required[noOfInterfaces] = XA_BOOLEAN_FALSE;
+ iidArray[noOfInterfaces] = XA_IID_AUDIOENCODER;
+ noOfInterfaces++;
+
+ XAEngineItf engineItf;
+ XAresult xa_result = (*m_EOEngine)->GetInterface(m_EOEngine, XA_IID_ENGINE, (void**) &engineItf);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Create Media Recorder..."));
+
+ /* Create recorder with NULL for a the image/video source, since this is for audio-only recording */
+ xa_result = (*engineItf)->CreateMediaRecorder(
+ engineItf,
+ &m_MORecorder,
+ &m_DataSource,
+ NULL,
+ &m_DataSink,
+ noOfInterfaces,
+ iidArray,
+ required);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Realize Media Recorder..."));
+ xa_result = (*m_MORecorder)->Realize(m_MORecorder, XA_BOOLEAN_FALSE);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Register Callback on recorder..."));
+ xa_result = (*m_MORecorder)->RegisterCallback(m_MORecorder, cbXAObjectItf, (void*) this);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Getting Record Interface..."));
+ xa_result = (*m_MORecorder)->GetInterface(m_MORecorder, XA_IID_RECORD, &m_RecordItf);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Registering Callback on record Interface..."));
+ xa_result = (*m_RecordItf)->RegisterCallback(m_RecordItf, cbXARecordItf, (void*) this);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: SetPositionUpdatePeriod on record Interface..."));
+ xa_result = (*m_RecordItf)->SetPositionUpdatePeriod(m_RecordItf, (XAmillisecond)KRecordPosUpdatePeriod);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: SetCallbackEventsMask on record Interface..."));
+ xa_result = (*m_RecordItf)->SetCallbackEventsMask(m_RecordItf, XA_RECORDEVENT_HEADATNEWPOS |
+ XA_RECORDEVENT_HEADMOVING |
+ XA_RECORDEVENT_HEADSTALLED);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Getting Audio Encoder Interface..."));
+ xa_result = (*m_MORecorder)->GetInterface(m_MORecorder, XA_IID_AUDIOENCODER, &m_AudioEncItf);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+ }
+
+ TRACE_FUNCTION_EXIT;
+ return returnValue;
+}
+
+TInt32 XARecordSessionImpl::mapError(XAresult xa_err, TBool debPrn)
+{
+ TInt32 returnValue(KErrGeneral);
+ switch (xa_err) {
+ case XA_RESULT_SUCCESS:
+ returnValue = KErrNone;
+ break;
+ case XA_RESULT_PRECONDITIONS_VIOLATED:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_PRECONDITIONS_VIOLATED"));
+ break;
+ case XA_RESULT_PARAMETER_INVALID:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_PARAMETER_INVALID"));
+ break;
+ case XA_RESULT_MEMORY_FAILURE:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_MEMORY_FAILURE"));
+ break;
+ case XA_RESULT_RESOURCE_ERROR:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_RESOURCE_ERROR"));
+ break;
+ case XA_RESULT_RESOURCE_LOST:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_RESOURCE_LOST"));
+ break;
+ case XA_RESULT_IO_ERROR:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_IO_ERROR"));
+ break;
+ case XA_RESULT_BUFFER_INSUFFICIENT:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_BUFFER_INSUFFICIENT"));
+ break;
+ case XA_RESULT_CONTENT_CORRUPTED:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_CONTENT_CORRUPTED"));
+ break;
+ case XA_RESULT_CONTENT_UNSUPPORTED:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_CONTENT_UNSUPPORTED"));
+ break;
+ case XA_RESULT_CONTENT_NOT_FOUND:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_CONTENT_NOT_FOUND"));
+ break;
+ case XA_RESULT_PERMISSION_DENIED:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_PERMISSION_DENIED"));
+ break;
+ case XA_RESULT_FEATURE_UNSUPPORTED:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_FEATURE_UNSUPPORTED"));
+ break;
+ case XA_RESULT_INTERNAL_ERROR:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_INTERNAL_ERROR"));
+ break;
+ case XA_RESULT_UNKNOWN_ERROR:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_UNKNOWN_ERROR"));
+ break;
+ case XA_RESULT_OPERATION_ABORTED:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_OPERATION_ABORTED"));
+ break;
+ case XA_RESULT_CONTROL_LOST:
+ if (debPrn)
+ TRACE_LOG(_L("XA_RESULT_CONTROL_LOST"));
+ break;
+ default:
+ if (debPrn)
+ TRACE_LOG(_L("Unknown Error!!!"));
+ break;
+ }
+ return returnValue;
+}
+
+TInt32 XARecordSessionImpl::initContainersList()
+{
+ TRACE_FUNCTION_ENTRY;
+
+ m_ContainerNames.Reset();
+ m_ContainerDescs.Reset();
+
+ m_ContainerNames.Append(KCONTAINERWAV());
+ m_ContainerNames.Append(KCONTAINERAMR());
+ m_ContainerNames.Append(KCONTAINERMP4());
+
+ m_ContainerDescs.Append(KCONTAINERWAVDESC());
+ m_ContainerDescs.Append(KCONTAINERAMRDESC());
+ m_ContainerDescs.Append(KCONTAINERMP4DESC());
+
+ TRACE_FUNCTION_EXIT;
+ return KErrNone;
+}
+
+TInt32 XARecordSessionImpl::initAudioEncodersList()
+{
+ TRACE_FUNCTION_ENTRY;
+
+ m_EncoderIds.Reset();
+ m_EncoderNames.Reset();
+
+ XAuint32 encoderIds[MAX_NUMBER_ENCODERS];
+
+ for (TInt index = 0; index < MAX_NUMBER_ENCODERS; index++)
+ encoderIds[index] = 0;
+
+ XAuint32 numEncoders = MAX_NUMBER_ENCODERS;
+ XAresult xa_result = (*m_AudioEncCapsItf)->GetAudioEncoders(
+ m_AudioEncCapsItf,
+ &numEncoders,
+ encoderIds);
+ TInt32 returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ for (TInt index = 0; index < numEncoders; index++) {
+ m_EncoderIds.Append(encoderIds[index]);
+ switch (encoderIds[index]) {
+ case XA_AUDIOCODEC_PCM:
+ m_EncoderNames.Append(KAUDIOCODECPCM());
+ break;
+ case XA_AUDIOCODEC_AMR:
+ m_EncoderNames.Append(KAUDIOCODECAMR());
+ break;
+ case XA_AUDIOCODEC_AAC:
+ m_EncoderNames.Append(KAUDIOCODECAAC());
+ break;
+ default:
+ break;
+ };
+ }
+
+ TRACE_FUNCTION_EXIT;
+ return returnValue;
+}
+
+TInt32 XARecordSessionImpl::initAudioInputDevicesList()
+{
+ TRACE_FUNCTION_ENTRY;
+
+ m_InputDeviceIDs.Reset();
+
+ XAuint32 deviceIds[MAX_NUMBER_INPUT_DEVICES];
+ for (TInt index = 0; index < MAX_NUMBER_INPUT_DEVICES; index++)
+ deviceIds[index] = 0;
+
+ XAint32 numInputs = MAX_NUMBER_INPUT_DEVICES;
+ XAresult xa_result = (*m_AudioIODevCapsItf)->GetAvailableAudioInputs(
+ m_AudioIODevCapsItf,
+ &numInputs,
+ deviceIds);
+ TInt32 returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ XAAudioInputDescriptor audioInputDescriptor;
+ for (TInt index = 0; index < numInputs; index++) {
+ xa_result = (*m_AudioIODevCapsItf)->QueryAudioInputCapabilities(
+ m_AudioIODevCapsItf,
+ deviceIds[index],
+ &audioInputDescriptor);
+ returnValue = mapError(xa_result, ETrue);
+ if (returnValue != KErrNone)
+ continue;
+
+ TUint8 * inDevNamePtr = audioInputDescriptor.deviceName;
+ TUint8 * tempPtr = audioInputDescriptor.deviceName;
+ TInt32 inDevNameLength = 0;
+ while (*tempPtr++)
+ inDevNameLength++;
+ TPtrC8 ptr(inDevNamePtr, inDevNameLength);
+ /* Convert 8 bit to 16 bit */
+ TBuf16<KMaxNameLength> name;
+ name.Copy(ptr);
+ /* Using TRAP with returnValue results in compiler error */
+ TRAPD(err2, m_AudioInputDeviceNames->AppendL(name));
+ returnValue = err2;
+ if (returnValue != KErrNone)
+ continue;
+ m_InputDeviceIDs.Append(deviceIds[index]);
+ }
+
+ numInputs = MAX_NUMBER_INPUT_DEVICES;
+ for (TInt index = 0; index < MAX_NUMBER_INPUT_DEVICES; index++)
+ deviceIds[index] = 0;
+ xa_result = (*m_AudioIODevCapsItf)->GetDefaultAudioDevices(
+ m_AudioIODevCapsItf,
+ XA_DEFAULTDEVICEID_AUDIOINPUT,
+ &numInputs,
+ deviceIds);
+ returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ for (TInt index = 0; index < numInputs; index++) {
+ xa_result = (*m_AudioIODevCapsItf)->QueryAudioInputCapabilities(
+ m_AudioIODevCapsItf,
+ deviceIds[index],
+ &audioInputDescriptor);
+ returnValue = mapError(xa_result, ETrue);
+ if (returnValue != KErrNone)
+ continue;
+ TUint8* inDevNamePtr = audioInputDescriptor.deviceName;
+ TUint8* tempPtr = audioInputDescriptor.deviceName;
+ TInt32 inDevNameLength = 0;
+ while (*tempPtr++)
+ inDevNameLength++;
+ TPtrC8 ptr(inDevNamePtr, inDevNameLength);
+ /* Convert 8 bit to 16 bit */
+ TBuf16<KMaxNameLength> name;
+ name.Copy(ptr);
+ /* Using TRAP with returnValue results in compiler error */
+ TRAPD(err2, m_DefaultAudioInputDeviceNames->AppendL(name));
+ returnValue = err2;
+ if (returnValue != KErrNone)
+ continue;
+ m_DefaultInputDeviceIDs.Append(deviceIds[index]);
+ m_InputDeviceId = deviceIds[index];
+ }
+
+ TRACE_FUNCTION_EXIT;
+ return returnValue;
+}
+
+TInt32 XARecordSessionImpl::setEncoderSettingsToMediaRecorder()
+{
+ TRACE_FUNCTION_EXIT;
+
+ /* Get current settings */
+ XAAudioEncoderSettings settings;
+ XAresult xa_result = (*m_AudioEncItf)->GetEncoderSettings(
+ m_AudioEncItf,
+ &settings);
+ TInt32 returnValue = mapError(xa_result, ETrue);
+
+ settings.encoderId = m_AudioEncoderId;
+ settings.channelsOut = m_ChannelsOut;
+ if ((m_SampleRate != 0) && (m_SampleRate != 0xffffffff))
+ settings.sampleRate = m_SampleRate;
+ if ((m_BitRate != 0) && (m_BitRate != 0xffffffff))
+ settings.bitRate = m_BitRate;
+ if (m_RateControl != 0)
+ settings.rateControl = m_RateControl;
+ settings.profileSetting = m_ProfileSetting;
+ xa_result = (*m_AudioEncItf)->SetEncoderSettings(
+ m_AudioEncItf,
+ &settings);
+ returnValue = mapError(xa_result, ETrue);
+
+ TRACE_FUNCTION_EXIT;
+ return returnValue;
+}
+
+TInt32 XARecordSessionImpl::getBitratesByAudioCodecID(
+ XAuint32 encoderId,
+ RArray<TUint32> &aBitrates,
+ XAboolean& aContinuous)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ if (!m_AudioEncCapsItf)
+ return KErrGeneral;
+
+ XAuint32 numCaps = 0;
+ XAAudioCodecDescriptor codecDesc;
+ XAresult xa_result = (*m_AudioEncCapsItf)->GetAudioEncoderCapabilities(
+ m_AudioEncCapsItf,
+ encoderId,
+ &numCaps,
+ &codecDesc);
+ TInt32 returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+ aContinuous = codecDesc.isBitrateRangeContinuous;
+ /* TODO What do we do if we have more than one caps?? */
+ if (codecDesc.isBitrateRangeContinuous == XA_BOOLEAN_TRUE) {
+ aBitrates.Append(codecDesc.minBitRate);
+ aBitrates.Append(codecDesc.maxBitRate);
+ }
+ else {
+ XAuint32 numBrSupported = codecDesc.numBitratesSupported;
+ XAuint32 * pBitratesSupported(NULL);
+ pBitratesSupported = codecDesc.pBitratesSupported;
+ TInt32 index = 0;
+ for (index = 0; index < numBrSupported; index++)
+ aBitrates.Append(*(pBitratesSupported + index));
+ }
+
+ TRACE_FUNCTION_ENTRY;
+ return returnValue;
+}
+
+TInt32 XARecordSessionImpl::getSampleRatesByAudioCodecID(XAuint32 encoderId,
+ RArray<TInt32> &aSampleRates)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ if (!m_AudioEncCapsItf)
+ return KErrGeneral;
+
+ XAuint32 numCaps = 0;
+ XAAudioCodecDescriptor codecDesc;
+ XAresult xa_result = (*m_AudioEncCapsItf)->GetAudioEncoderCapabilities(
+ m_AudioEncCapsItf,
+ encoderId,
+ &numCaps,
+ &codecDesc);
+ TInt returnValue = mapError(xa_result, ETrue);
+ RET_ERR_IF_ERR(returnValue);
+
+ /* TODO What do we do if we have more than one caps?? */
+ if (codecDesc.isFreqRangeContinuous == XA_BOOLEAN_TRUE) {
+ aSampleRates.Append(codecDesc.minSampleRate / KMilliToHz);
+ aSampleRates.Append(codecDesc.maxSampleRate / KMilliToHz);
+ }
+ else {
+ XAuint32 numSRSupported = codecDesc.numSampleRatesSupported;
+ XAmilliHertz *pSampleRatesSupported(NULL);
+ pSampleRatesSupported = codecDesc.pSampleRatesSupported;
+ for (TInt index = 0; index < numSRSupported; index++)
+ aSampleRates.Append((*(pSampleRatesSupported + index)) / KMilliToHz);
+ }
+
+ TRACE_FUNCTION_ENTRY;
+ return returnValue;
+}
+
+/* Local function implementation */
+void cbXAObjectItf(
+ XAObjectItf caller,
+ const void *pContext,
+ XAuint32 event,
+ XAresult result,
+ XAuint32 param,
+ void *pInterface)
+{
+ if (pContext) {
+ ((XARecordSessionImpl*)pContext)->cbMediaRecorder(
+ caller,
+ pContext,
+ event,
+ result,
+ param,
+ pInterface);
+ }
+}
+
+void cbXARecordItf(
+ XARecordItf caller,
+ void *pContext,
+ XAuint32 event)
+{
+ if (pContext) {
+ ((XARecordSessionImpl*)pContext)->cbRecordItf(
+ caller,
+ pContext,
+ event);
+ }
+}
+
+void cbXAAvailableAudioInputsChanged(
+ XAAudioIODeviceCapabilitiesItf caller,
+ void * pContext,
+ XAuint32 deviceID,
+ XAint32 numInputs,
+ XAboolean isNew)
+{
+ if (pContext) {
+ ((XARecordSessionImpl*)pContext)->cbAvailableAudioInputsChanged(
+ caller,
+ pContext,
+ deviceID,
+ numInputs,
+ isNew);
+ }
+}
diff --git a/src/plugins/symbian/openmaxal/mediarecorder/xarecordsessionimpl.h b/src/plugins/symbian/openmaxal/mediarecorder/xarecordsessionimpl.h
new file mode 100644
index 000000000..81e4ac763
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/mediarecorder/xarecordsessionimpl.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XARECORDSESSIONIMPL_H
+#define XARECORDSESSIONIMPL_H
+
+#include <OpenMAXAL.h>
+#include <badesca.h>
+
+
+class XARecordObserver;
+class XARecordSessionImpl
+{
+public:
+ XARecordSessionImpl(XARecordObserver &parent);
+ ~XARecordSessionImpl();
+ TInt32 postConstruct();
+
+ /* For QMediaRecorderControl begin */
+ TInt32 setURI(const TDesC &aURI);
+ TInt32 record();
+ TInt32 pause();
+ TInt32 stop();
+ TInt32 duration(TInt64 &aDur);
+ /* For QMediaRecorderControl end */
+
+ void cbMediaRecorder(XAObjectItf caller,
+ const void *pContext,
+ XAuint32 event,
+ XAresult result,
+ XAuint32 param,
+ void *pInterface);
+ void cbRecordItf(XARecordItf caller,
+ void *pContext,
+ XAuint32 event);
+
+ /* For QAudioEndpointSelector begin */
+ void getAudioInputDeviceNames(RArray<TPtrC> &aArray);
+ TInt32 defaultAudioInputDevice(TPtrC &endPoint);
+ TInt32 activeAudioInputDevice(TPtrC &endPoint);
+ TBool setAudioInputDevice(const TDesC &aDevice);
+ void cbAvailableAudioInputsChanged(XAAudioIODeviceCapabilitiesItf caller,
+ void *pContext,
+ XAuint32 deviceID,
+ XAint32 numInputs,
+ XAboolean isNew);
+ /* For QAudioEndpointSelector end */
+
+ /* For QAudioEncoderControl begin */
+ const RArray<TPtrC>& getAudioEncoderNames();
+ TInt32 getSampleRates(const TDesC &aEncoder,
+ RArray<TInt32> &aSampleRates,
+ TBool &aIsContinuous);
+ TInt32 getBitrates(const TDesC &aEncoder,
+ RArray<TUint32> &aBitrates,
+ TBool& aContinuous);
+ /* For QAudioEncoderControl end */
+
+ /* For QMediaContainerControl begin */
+ const RArray<TPtrC>& getContainerNames();
+ const RArray<TPtrC>& getContainerDescs();
+ /* For QMediaContainerControl end */
+
+ void resetEncoderAttributes();
+ void setContainerType(const TDesC &aURI);
+ TBool setCodec(const TDesC &aURI);
+ TUint32 getBitRate();
+ void setBitRate(TUint32 aBitRate);
+ TUint32 getChannels();
+ void setChannels(TUint32 aChannels);
+ void setOptimalChannelCount();
+ TUint32 getSampleRate();
+ void setSampleRate(TUint32 aSampleRate);
+ void setOptimalSampleRate();
+ TInt32 setCBRMode();
+ TInt32 setVBRMode();
+ void setVeryLowQuality();
+ void setLowQuality();
+ void setNormalQuality();
+ void setHighQuality();
+ void setVeryHighQuality();
+
+private:
+ TInt32 createMediaRecorderObject();
+ TInt32 mapError(XAresult xa_err,
+ TBool debPrn);
+ TInt32 initContainersList();
+ TInt32 initAudioEncodersList();
+ TInt32 initAudioInputDevicesList();
+ TInt32 setEncoderSettingsToMediaRecorder();
+ TInt32 getBitratesByAudioCodecID(XAuint32 encoderId,
+ RArray<TUint32> &aBitrates,
+ XAboolean& aContinuous);
+ TInt32 getSampleRatesByAudioCodecID(XAuint32 encoderId,
+ RArray<TInt32> &aSampleRates);
+
+
+private:
+ XARecordObserver &m_Parent;
+ XAObjectItf m_EOEngine;
+ XAObjectItf m_MORecorder;
+ XARecordItf m_RecordItf;
+ XAAudioEncoderItf m_AudioEncItf;
+ /* Audio Source */
+ XADataSource m_DataSource;
+ XADataLocator_IODevice m_LocatorMic;
+ XADataFormat_MIME m_Mime;
+ XADataLocator_URI m_Uri;
+ /*Audio Sink*/
+ XADataSink m_DataSink;
+ HBufC8 *m_WAVMime;
+
+ /* Set by client*/
+ HBufC8 *m_URIName;
+ XAuint32 m_AudioEncoderId;
+ XAuint32 m_InputDeviceId;
+ XAuint32 m_ContainerType;
+ XAuint32 m_BitRate;
+ XAuint32 m_RateControl;
+ XAuint32 m_ProfileSetting;
+ XAuint32 m_ChannelsOut;
+ XAuint32 m_SampleRate;
+
+ /* For QAudioEndpointSelector begin */
+ XAAudioIODeviceCapabilitiesItf m_AudioIODevCapsItf;
+ RArray<TUint32> m_InputDeviceIDs;
+ CDesC16ArrayFlat *m_AudioInputDeviceNames;
+ RArray<TUint32> m_DefaultInputDeviceIDs;
+ CDesC16ArrayFlat *m_DefaultAudioInputDeviceNames;
+ /* For QAudioEndpointSelector end */
+
+ /* For QAudioEncoderControl begin */
+ XAAudioEncoderCapabilitiesItf m_AudioEncCapsItf;
+ RArray<XAuint32> m_EncoderIds;
+ RArray<TPtrC> m_EncoderNames;
+ RArray<TPtrC> m_ContainerNames;
+ RArray<TPtrC> m_ContainerDescs;
+ /* For QAudioEncoderControl begin */
+};
+
+#endif /* XARECORDSESSIONIMPL_H */
diff --git a/src/plugins/symbian/openmaxal/openmaxal.pro b/src/plugins/symbian/openmaxal/openmaxal.pro
new file mode 100644
index 000000000..0565536a4
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/openmaxal.pro
@@ -0,0 +1,58 @@
+TEMPLATE = lib
+
+CONFIG += plugin
+TARGET = $$qtLibraryTarget(qtmultimediakit_openmaxalengine)
+PLUGIN_TYPE = mediaservice
+include (../../../../common.pri)
+qtAddLibrary(QtMultimediaKit)
+
+#includes here so that all defines are added here also
+include(mediaplayer/mediaplayer.pri)
+include(mediarecorder/mediarecorder.pri)
+include(radiotuner/radiotuner.pri)
+
+DEPENDPATH += .
+
+HEADERS += qxamediaserviceproviderplugin.h \
+ qxacommon.h \
+ xacommon.h
+
+SOURCES += qxamediaserviceproviderplugin.cpp
+
+# Input parameters for the generated bld.inf file
+# -----------------------------------------------
+SYMBIAN_PLATFORMS = DEFAULT
+
+# Input parameters for the generated mmp file
+# -------------------------------------------
+load(data_caging_paths)
+TARGET.UID3 = 0x10207CA1
+TARGET.CAPABILITY = ALL -TCB
+TARGET.EPOCALLOWDLLDATA = 1
+MMP_RULES += EXPORTUNFROZEN
+
+# Macros controlling debug traces
+#DEFINES += PROFILE_TIME
+#DEFINES += PROFILE_RAM_USAGE
+#DEFINES += PROFILE_HEAP_USAGE
+#DEFINES += PLUGIN_QT_TRACE_ENABLED
+#DEFINES += PLUGIN_QT_SIGNAL_EMIT_TRACE_ENABLED
+#DEFINES += PLUGIN_SYMBIAN_TRACE_ENABLED
+
+INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE
+INCLUDEPATH += /epoc32/include/platform/mw/khronos
+
+
+# Input parameters for qmake to make the dll a qt plugin
+pluginDep.sources = $${TARGET}.dll
+pluginDep.path = $${QT_PLUGINS_BASE_DIR}/$${PLUGIN_TYPE}
+DEPLOYMENT += pluginDep
+
+LIBS += \
+ -lQtMultimediaKit \
+ -lopenmaxal
+
+# check for PROFILE_RAM_USAGE
+contains(DEFINES, PROFILE_RAM_USAGE) {
+ LIBS += -lhal
+}
diff --git a/src/plugins/symbian/openmaxal/qxacommon.h b/src/plugins/symbian/openmaxal/qxacommon.h
new file mode 100644
index 000000000..f19a75d1c
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/qxacommon.h
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXACOMMON_H
+#define QXACOMMON_H
+
+#if defined(PLUGIN_QT_TRACE_ENABLED) \
+ || defined(PLUGIN_QT_SIGNAL_EMIT_TRACE_ENABLED) \
+ || defined(PROFILE_TIME) \
+ || defined(PROFILE_RAM_USAGE) \
+ || defined(PROFILE_HEAP_USAGE)
+# include <QDebug>
+#endif /* PLUGIN_QT_TRACE_ENABLED */
+
+#ifdef PROFILE_RAM_USAGE
+# include <hal.h>
+#endif
+
+
+#ifdef PLUGIN_QT_TRACE_ENABLED
+# define QT_TRACE_FUNCTION_ENTRY qDebug() << __PRETTY_FUNCTION__ << ">"
+# define QT_TRACE_FUNCTION_EXIT qDebug() << __PRETTY_FUNCTION__ << "<"
+# define QT_TRACE_FUNCTION_ENTRY_EXIT qDebug() << __PRETTY_FUNCTION__ << "><"
+# define QT_TRACE1(v1) qDebug() << v1
+# define QT_TRACE2(v1, v2) qDebug() << v1 << v2
+#else
+# define QT_TRACE_FUNCTION_ENTRY
+# define QT_TRACE_FUNCTION_EXIT
+# define QT_TRACE_FUNCTION_ENTRY_EXIT
+# define QT_TRACE1(v1)
+# define QT_TRACE2(v1, v2)
+#endif /*PLUGIN_QT_TRACE_ENABLED*/
+
+#ifdef PLUGIN_QT_SIGNAL_EMIT_TRACE_ENABLED
+# define SIGNAL_EMIT_TRACE1(v1) qDebug() << __PRETTY_FUNCTION__ << v1
+#else
+# define SIGNAL_EMIT_TRACE1(v1)
+#endif /*PLUGIN_QT_SIGNAL_EMIT_TRACE_ENABLED*/
+
+#ifdef PROFILE_TIME_ELAPSED
+# define TAG_TIME_PROFILING_BEGIN \
+ TTime beginProfilingTime; \
+ beginProfilingTime.HomeTime()
+
+# define TAG_TIME_PROFILING_END \
+ TTime endProfilingTime; \
+ endProfilingTime.HomeTime(); \
+ TTimeIntervalMicroSeconds diffInMicroSecs = endProfilingTime.MicroSecondsFrom(beginProfilingTime)
+
+# define QT_PRINT_TO_CONSOLE_TIME_DIFF \
+ qDebug() << "VPROFILEDAT: " << __PRETTY_FUNCTION__ << ": Time taken " << diffInMicroSecs.Int64() << " microseconds"
+#else /* Empty macros */
+# define TAG_TIME_PROFILING_BEGIN
+# define TAG_TIME_PROFILING_END
+# define QT_PRINT_TO_CONSOLE_TIME_DIFF
+#endif /*PROFILE_TIME_ELAPSED*/
+
+#ifdef PROFILE_RAM_USAGE
+# define TAG_RAM_PROFILING_BEGIN \
+ TInt beginProfilingRAM; \
+ TInt err1 = HAL::Get(HALData::EMemoryRAMFree, beginProfilingRAM)
+
+# define TAG_RAM_PROFILING_END \
+ TInt endProfilingRAM; \
+ TInt err2 = HAL::Get(HALData::EMemoryRAMFree, endProfilingRAM)
+
+# define QT_PRINT_TO_CONSOLE_RAM_DIFF \
+ if ((err1 == KErrNone) && (err2 == KErrNone)) \
+ { \
+ TInt diffRAM = (beginProfilingRAM - endProfilingRAM); \
+ if ( diffRAM > 0 ) \
+ { \
+ qDebug() << "VPROFILEDAT: " << __PRETTY_FUNCTION__ << ": " << diffRAM << " bytes of RAM used"; \
+ } \
+ else \
+ { \
+ qDebug() << "VPROFILEDAT: " << __PRETTY_FUNCTION__ << ": " << -(diffRAM) << " bytes of RAM freed"; \
+ } \
+ } \
+ else \
+ { \
+ qDebug() << "VPROFILEDAT: " << __PRETTY_FUNCTION__ << "Error1[" << err1 << "] Error2[" << err2; \
+ }
+
+#else /* Empty macros */
+# define TAG_RAM_PROFILING_BEGIN
+# define TAG_RAM_PROFILING_END
+# define QT_PRINT_TO_CONSOLE_RAM_DIFF
+#endif /*PROFILE_RAM_USAGE*/
+
+#ifdef PROFILE_HEAP_USAGE
+# define TAG_DEFAULT_HEAP_PROFILING_BEGIN \
+ TInt beginProfilingHEAPBiggestBlock; \
+ TInt beginProfilingHEAP = User::Available(beginProfilingHEAPBiggestBlock) \
+
+# define TAG_DEFAULT_HEAP_PROFILING_END \
+ TInt endProfilingHEAPBiggestBlock; \
+ TInt endProfilingHEAP = User::Available(endProfilingHEAPBiggestBlock) \
+
+# define QT_PRINT_TO_CONSOLE_HEAP_DIFF \
+ TInt diffHEAP = beginProfilingHEAP - endProfilingHEAP; \
+ if ( diffHEAP > 0 ) \
+ { \
+ qDebug() << "VPROFILEDAT: " << __PRETTY_FUNCTION__ << ": " << diffHEAP << " bytes in default HEAP used"; \
+ } \
+ else \
+ { \
+ qDebug() << "VPROFILEDAT: " << __PRETTY_FUNCTION__ << ": " << -(diffHEAP) << " bytes in default HEAP freed"; \
+ }
+#else /* Empty macros */
+# define TAG_DEFAULT_HEAP_PROFILING_BEGIN
+# define TAG_DEFAULT_HEAP_PROFILING_END
+# define QT_PRINT_TO_CONSOLE_HEAP_DIFF
+#endif /*PROFILE_HEAP_USAGE*/
+
+/* This macro checks p pointer for null. If it is, returns value 's' from
+ * function immediately.
+ */
+#define RET_s_IF_p_IS_NULL(p, s) \
+ if (p == NULL) { \
+ return s; \
+ }
+
+/* This macro checks p pointer for null. If it is, returns from function
+ * immediately.
+ */
+#define RET_IF_p_IS_NULL(p) \
+ if (p == NULL) { \
+ return; \
+ }
+
+/* This macro checks p pointer for null. If it is, emits an error signal
+ * error(QMediaPlayer::ResourceError, tr("Resource Error"));
+ * and returns value 's' from function immediately.
+ */
+#define RET_s_IF_p_IS_NULL_EMIT_PLAYER_RESOURCE_ERROR(p, s) \
+ if (p == NULL) { \
+ emit error(QMediaPlayer::ResourceError, tr("Resource Error")); \
+ SIGNAL_EMIT_TRACE1("emit error(QMediaPlayer::ResourceError, tr(\"Resource Error\"))"); \
+ return s; \
+ }
+
+/* This macro checks p pointer for null. If it is, emits an error signal
+ * error(QMediaPlayer::ResourceError, tr("Resource Error"));
+ * and returns from function immediately.
+ */
+#define RET_IF_p_IS_NULL_EMIT_PLAYER_RESOURCE_ERROR(p) \
+ if (p == NULL) { \
+ emit error(QMediaPlayer::ResourceError, tr("Resource Error")); \
+ SIGNAL_EMIT_TRACE1("emit error(QMediaPlayer::ResourceError, tr(\"Resource Error\"))"); \
+ return; \
+ }
+
+/* This macro checks p pointer for null. If it is, emits an error signal
+ * error(QMediaPlayer::ResourceError, tr("Resource Error"));
+ * and returns from function immediately.
+ */
+#define RET_IF_ERROR(p) \
+ if (p != KErrNone) { \
+ emit error(QMediaPlayer::ResourceError, tr("Resource Error")); \
+ SIGNAL_EMIT_TRACE1("emit error(QMediaPlayer::ResourceError, tr(\"Resource Error\"))"); \
+ return; \
+ }
+
+#endif /* QXACOMMON_H */
diff --git a/src/plugins/symbian/openmaxal/qxamediaserviceproviderplugin.cpp b/src/plugins/symbian/openmaxal/qxamediaserviceproviderplugin.cpp
new file mode 100644
index 000000000..bfbb4333a
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/qxamediaserviceproviderplugin.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QString>
+#include "qxamediaserviceproviderplugin.h"
+#include "qxaplaymediaservice.h"
+#include "qxarecordmediaservice.h"
+#include "qxaradiomediaservice.h"
+#include "qxacommon.h"
+
+QStringList QXAMediaServiceProviderPlugin::keys() const
+{
+ return QStringList()
+ << QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)
+ << QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE)
+ << QLatin1String(Q_MEDIASERVICE_RADIO);
+}
+
+QMediaService* QXAMediaServiceProviderPlugin::create(QString const& key)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ QMediaService* service = NULL;
+ if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER) ) {
+ service = new QXAPlayMediaService;
+ QT_TRACE1("Created QXAPlayMediaService");
+ }
+ else if (key == QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE)) {
+ service = new QXARecodMediaService;
+ QT_TRACE1("Created QXARecodMediaService");
+ }
+ else if (key == QLatin1String(Q_MEDIASERVICE_RADIO) ) {
+ service = new QXARadioMediaService;
+ QT_TRACE1("Created QXARadioMediaService");
+ }
+ else {
+ QT_TRACE2("unsupported key:", key);
+ }
+ QT_TRACE_FUNCTION_EXIT;
+ return service;
+}
+
+void QXAMediaServiceProviderPlugin::release(QMediaService *service)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ delete service;
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+Q_EXPORT_PLUGIN2(qtmultimediakit_openmaxalengine, QXAMediaServiceProviderPlugin);
diff --git a/src/plugins/symbian/openmaxal/qxamediaserviceproviderplugin.h b/src/plugins/symbian/openmaxal/qxamediaserviceproviderplugin.h
new file mode 100644
index 000000000..6d3530349
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/qxamediaserviceproviderplugin.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXAMEDIASERVICEPROVIDERPLUGIN_H
+#define QXAMEDIASERVICEPROVIDERPLUGIN_H
+
+#include <QtCore/qobject.h>
+#include <qmediaserviceprovider.h>
+#include <qmediaserviceproviderplugin.h>
+
+QT_USE_NAMESPACE
+
+class QXAMediaServiceProviderPlugin : public QMediaServiceProviderPlugin
+{
+ Q_OBJECT
+public:
+ QStringList keys() const;
+ QMediaService* create(QString const& key);
+ void release(QMediaService *service);
+};
+
+#endif /* QXAMEDIASERVICEPROVIDERPLUGIN_H */
diff --git a/src/plugins/symbian/openmaxal/radiotuner/qxaradiocontrol.cpp b/src/plugins/symbian/openmaxal/radiotuner/qxaradiocontrol.cpp
new file mode 100644
index 000000000..9666b0410
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/radiotuner/qxaradiocontrol.cpp
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qxaradiocontrol.h"
+#include "qxaradiosession.h"
+#include "xaradiosessionimpl.h"
+
+QXARadioControl::QXARadioControl(QXARadioSession *session, QObject *parent)
+:QRadioTunerControl(parent), m_session(session)
+{
+
+ connect(m_session, SIGNAL(stateChanged(QRadioTuner::State)), this, SIGNAL(stateChanged(QRadioTuner::State)));
+
+ connect(m_session, SIGNAL(bandChanged(QRadioTuner::Band)), this, SIGNAL(bandChanged(QRadioTuner::Band)));
+
+ connect(m_session, SIGNAL(frequencyChanged(int)), this, SIGNAL(frequencyChanged(int)));
+
+ connect(m_session, SIGNAL(stereoStatusChanged(bool)), this, SIGNAL(stereoStatusChanged(bool)));
+
+ connect(m_session, SIGNAL(searchingChanged(bool)), this, SIGNAL(searchingChanged(bool)));
+
+ connect(m_session, SIGNAL(signalStrengthChanged(int)), this, SIGNAL(signalStrengthChanged(int)));
+
+ connect(m_session, SIGNAL(volumeChanged(int)), this, SIGNAL(volumeChanged(int)));
+
+ connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool)));
+
+// connect(m_session, SIGNAL(error(int,QString)), this,SIGNAL(error(int,QString)));
+}
+
+QXARadioControl::~QXARadioControl()
+{
+
+}
+
+QtMultimediaKit::AvailabilityError QXARadioControl::availabilityError() const
+{
+ return m_session->availabilityError();
+}
+
+bool QXARadioControl::isAvailable() const
+{
+ return m_session->isAvailable();
+}
+
+QRadioTuner::State QXARadioControl::state() const
+{
+ return m_session->state();
+}
+
+QRadioTuner::Band QXARadioControl::band() const
+{
+ return m_session->band();
+}
+
+void QXARadioControl::setBand(QRadioTuner::Band band)
+{
+ m_session->setBand(band);
+}
+
+bool QXARadioControl::isBandSupported(QRadioTuner::Band band) const
+{
+ return m_session->isBandSupported(band);
+}
+
+int QXARadioControl::frequency() const
+{
+ return m_session->frequency();
+}
+
+int QXARadioControl::frequencyStep(QRadioTuner::Band band) const
+{
+ return m_session->frequencyStep(band);
+}
+
+QPair<int,int> QXARadioControl::frequencyRange(QRadioTuner::Band band) const
+{
+ return m_session->frequencyRange(band);
+}
+
+void QXARadioControl::setFrequency(int freq)
+{
+ m_session->setFrequency(freq);
+}
+
+bool QXARadioControl::isStereo() const
+{
+ return m_session->isStereo();
+}
+
+QRadioTuner::StereoMode QXARadioControl::stereoMode() const
+{
+ return m_session->stereoMode();
+}
+
+void QXARadioControl::setStereoMode(QRadioTuner::StereoMode stereoMode)
+{
+ m_session->setStereoMode(stereoMode);
+}
+
+int QXARadioControl::signalStrength() const
+{
+ return m_session->signalStrength();
+}
+
+int QXARadioControl::volume() const
+{
+ return m_session->volume();
+}
+
+void QXARadioControl::setVolume(int volume)
+{
+ m_session->setVolume(volume);
+}
+
+bool QXARadioControl::isMuted() const
+{
+ return m_session->isMuted();
+}
+
+void QXARadioControl::setMuted(bool muted)
+{
+ m_session->setMuted(muted);
+}
+
+bool QXARadioControl::isSearching() const
+{
+ return m_session->isSearching();
+}
+
+void QXARadioControl::searchForward()
+{
+ m_session->searchForward();
+}
+
+void QXARadioControl::searchBackward()
+{
+ m_session->searchBackward();
+}
+
+void QXARadioControl::cancelSearch()
+{
+ m_session->cancelSearch();
+}
+
+void QXARadioControl::start()
+{
+ m_session->start();
+}
+
+void QXARadioControl::stop()
+{
+ m_session->stop();
+}
+
+QRadioTuner::Error QXARadioControl::error() const
+{
+ return m_session->error();
+}
+
+QString QXARadioControl::errorString() const
+{
+ return m_session->errorString();
+}
diff --git a/src/plugins/symbian/openmaxal/radiotuner/qxaradiocontrol.h b/src/plugins/symbian/openmaxal/radiotuner/qxaradiocontrol.h
new file mode 100644
index 000000000..47d4f827d
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/radiotuner/qxaradiocontrol.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXARADIOCONTROL_H
+#define QXARADIOCONTROL_H
+
+#include <QObject>
+#include <QRadioTunerControl>
+
+QT_USE_NAMESPACE
+
+class QXARadioSession;
+
+class QXARadioControl : public QRadioTunerControl
+{
+ Q_OBJECT
+
+public:
+ QXARadioControl(QXARadioSession *session, QObject *parent = 0);
+ virtual ~QXARadioControl();
+ QRadioTuner::State state() const;
+
+ QRadioTuner::Band band() const;
+ void setBand(QRadioTuner::Band band);
+ bool isBandSupported(QRadioTuner::Band band) const;
+ int frequency() const;
+ int frequencyStep(QRadioTuner::Band band) const;
+ QPair<int,int> frequencyRange(QRadioTuner::Band band) const;
+ void setFrequency(int freq);
+ bool isStereo() const;
+ QRadioTuner::StereoMode stereoMode() const;
+ void setStereoMode(QRadioTuner::StereoMode stereoMode);
+ int signalStrength() const;
+ int volume() const;
+ void setVolume(int volume);
+ bool isMuted() const;
+ void setMuted(bool muted);
+ bool isSearching() const;
+ void searchForward();
+ void searchBackward();
+ void cancelSearch();
+ bool isValid() const;
+ bool isAvailable() const;
+ QtMultimediaKit::AvailabilityError availabilityError() const;
+ void start();
+ void stop();
+ QRadioTuner::Error error() const;
+ QString errorString() const;
+
+private:
+ QXARadioSession *m_session;
+
+protected:
+ QXARadioControl(QObject* parent = 0);
+};
+
+#endif /* QXARADIOCONTROL_H */
diff --git a/src/plugins/symbian/openmaxal/radiotuner/qxaradiomediaservice.cpp b/src/plugins/symbian/openmaxal/radiotuner/qxaradiomediaservice.cpp
new file mode 100644
index 000000000..f399ef8c5
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/radiotuner/qxaradiomediaservice.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QString>
+
+#include "qxaradiomediaservice.h"
+#include "qxaradiosession.h"
+#include "qxaradiocontrol.h"
+#include <qradiotunercontrol.h>
+
+QXARadioMediaService::QXARadioMediaService(QObject *parent)
+ : QMediaService(parent)
+{
+ m_session = new QXARadioSession(this);
+ m_control = new QXARadioControl(m_session, this);
+}
+
+QXARadioMediaService::~QXARadioMediaService()
+{
+}
+
+QMediaControl* QXARadioMediaService::requestControl(const char *name)
+{
+
+ if (qstrcmp(name, QRadioTunerControl_iid) == 0) {
+ return m_control;
+ }
+ return 0;
+}
+
+void QXARadioMediaService::releaseControl(QMediaControl *control)
+{
+ Q_UNUSED(control)
+}
diff --git a/src/plugins/symbian/openmaxal/radiotuner/qxaradiomediaservice.h b/src/plugins/symbian/openmaxal/radiotuner/qxaradiomediaservice.h
new file mode 100644
index 000000000..7ac014f8f
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/radiotuner/qxaradiomediaservice.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXARADIOMEDIASERVICE_H
+#define QXARADIOMEDIASERVICE_H
+
+#include <QtCore/qobject.h>
+#include <qmediaservice.h>
+
+QT_USE_NAMESPACE
+
+class QXARadioSession;
+class QXARadioControl;
+
+class QXARadioMediaService : public QMediaService
+{
+ Q_OBJECT
+public:
+ QXARadioMediaService(QObject *parent = 0);
+ ~QXARadioMediaService();
+ QMediaControl *requestControl(const char *name);
+ void releaseControl( QMediaControl *control);
+private:
+ QXARadioSession *m_session;
+ QXARadioControl *m_control;
+};
+
+#endif /*QXARADIOMEDIASERVICE_H*/
diff --git a/src/plugins/symbian/openmaxal/radiotuner/qxaradiosession.cpp b/src/plugins/symbian/openmaxal/radiotuner/qxaradiosession.cpp
new file mode 100644
index 000000000..6822813c4
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/radiotuner/qxaradiosession.cpp
@@ -0,0 +1,323 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qradiotuner.h>
+#include "qxaradiosession.h"
+#include "xaradiosessionimpl.h"
+#include "qxacommon.h"
+
+QXARadioSession::QXARadioSession(QObject *parent)
+:QObject(parent)
+{
+ QT_TRACE_FUNCTION_ENTRY;
+ m_impl = new XARadioSessionImpl(*this);
+ if (!m_impl) {
+ QT_TRACE1("RadioSession::RadioSession(): ERROR creating RadioSessionImpl...");
+ return;
+ }
+ if (m_impl->PostConstruct() != QRadioTuner::NoError) {
+ QT_TRACE1("RadioSession::RadioSession(): ERROR from RadioSessionImpl::PostContstruct...");
+ delete m_impl;
+ m_impl = NULL;
+ }
+ QT_TRACE_FUNCTION_EXIT;
+}
+
+QXARadioSession::~QXARadioSession()
+{
+ delete m_impl;
+}
+
+QRadioTuner::State QXARadioSession::state() const
+{
+ QRadioTuner::State state = QRadioTuner::StoppedState;
+ if (m_impl)
+ state = m_impl->State();
+ return state;
+ }
+QtMultimediaKit::AvailabilityError QXARadioSession::availabilityError() const
+{
+ QtMultimediaKit::AvailabilityError error = QtMultimediaKit::NoError;
+ if (m_impl)
+ error = m_impl->AvailabilityError();
+ return error;
+}
+
+QRadioTuner::Band QXARadioSession::band() const
+{
+ QRadioTuner::Band band = QRadioTuner::FM;
+ if (m_impl)
+ band = m_impl->Band();
+ return band;
+}
+
+void QXARadioSession::setBand(QRadioTuner::Band band)
+{
+ if (m_impl)
+ m_impl->SetBand(band);
+}
+
+bool QXARadioSession::isBandSupported(QRadioTuner::Band band) const
+{
+ if (m_impl)
+ return m_impl->IsBandSupported(band);
+ return false;
+}
+
+bool QXARadioSession::isAvailable() const
+{
+ if (m_impl)
+ return m_impl->IsAvailable();
+ return false;
+}
+
+int QXARadioSession::frequency() const
+{
+ TInt frequency = 0;
+ if (m_impl)
+ frequency = m_impl->GetFrequency();
+ return (int)frequency;
+}
+
+int QXARadioSession::frequencyStep(QRadioTuner::Band band) const
+{
+ TInt freqStep = 0;
+ if (m_impl)
+ freqStep = m_impl->FrequencyStep(band);
+ return (int)freqStep;
+}
+
+QPair<int, int> QXARadioSession::frequencyRange(QRadioTuner::Band /*band*/) const
+{
+ QPair<int, int> freqRange;
+ freqRange.first = 0;
+ freqRange.second =0;
+
+ if (m_impl) {
+ TInt freqRangeType = m_impl->GetFrequencyRange();
+ m_impl->GetFrequencyRangeProperties(freqRangeType, freqRange.first, freqRange.second);
+ }
+
+ return freqRange;
+}
+
+void QXARadioSession::setFrequency(int frequency)
+{
+ if (m_impl)
+ m_impl->SetFrequency(frequency);
+}
+
+bool QXARadioSession::isStereo() const
+{
+ bool isStereo = false;
+ if (m_impl)
+ isStereo = m_impl->IsStereo();
+ return isStereo;
+}
+
+QRadioTuner::StereoMode QXARadioSession::stereoMode() const
+{
+ QRadioTuner::StereoMode mode(QRadioTuner::Auto);
+ if (m_impl)
+ mode = m_impl->StereoMode();
+ return mode;
+}
+
+void QXARadioSession::setStereoMode(QRadioTuner::StereoMode mode)
+{
+ if (m_impl)
+ m_impl->SetStereoMode(mode);
+}
+
+int QXARadioSession::signalStrength() const
+{
+ TInt signalStrength = 0;
+ if (m_impl)
+ signalStrength = m_impl->GetSignalStrength();
+ return (int)signalStrength;
+}
+
+int QXARadioSession::volume() const
+{
+ TInt volume = 0;
+ if (m_impl)
+ volume = m_impl->GetVolume();
+ return volume;
+}
+
+int QXARadioSession::setVolume(int volume)
+{
+ TInt newVolume = 0;
+ if (m_impl) {
+ m_impl->SetVolume(volume);
+ newVolume = m_impl->GetVolume();
+ }
+ return newVolume;
+}
+
+bool QXARadioSession::isMuted() const
+{
+ bool isMuted = false;
+ if (m_impl)
+ isMuted = m_impl->IsMuted();
+ return isMuted;
+}
+
+void QXARadioSession::setMuted(bool muted)
+{
+ if (m_impl)
+ m_impl->SetMuted(muted);
+}
+
+bool QXARadioSession::isSearching() const
+{
+ bool isSearching = false;
+ if (m_impl)
+ isSearching = m_impl->IsSearching();
+ return isSearching;
+}
+
+void QXARadioSession::searchForward()
+{
+ if (m_impl)
+ m_impl->Seek(true);
+}
+
+void QXARadioSession::searchBackward()
+{
+ if (m_impl)
+ m_impl->Seek(false);
+}
+
+void QXARadioSession::cancelSearch()
+{
+ if (m_impl)
+ m_impl->StopSeeking();
+}
+
+void QXARadioSession::start()
+{
+ if (m_impl)
+ m_impl->Start();
+}
+
+void QXARadioSession::stop()
+{
+ if (m_impl)
+ m_impl->Stop();
+}
+
+QRadioTuner::Error QXARadioSession::error() const
+{
+ QRadioTuner::Error err(QRadioTuner::NoError);
+ if (m_impl)
+ err = m_impl->Error();
+ return err;
+}
+
+QString QXARadioSession::errorString() const
+{
+ QString str = NULL;
+ switch (iError) {
+ case QRadioTuner::ResourceError:
+ str = "Resource Error";
+ break;
+ case QRadioTuner::OpenError:
+ str = "Open Error";
+ break;
+ case QRadioTuner::OutOfRangeError:
+ str = "Out of Range Error";
+ break;
+ default:
+ break;
+ }
+
+ return str;
+}
+
+// Callbacks, which will emit signals to client:
+void QXARadioSession::CBStateChanged(QRadioTuner::State state)
+{
+ emit stateChanged(state);
+}
+
+void QXARadioSession::CBBandChanged(QRadioTuner::Band band)
+{
+ emit bandChanged(band);
+}
+
+void QXARadioSession::CBFrequencyChanged(TInt newFrequency)
+{
+ emit frequencyChanged(newFrequency);
+}
+
+void QXARadioSession::CBStereoStatusChanged(bool isStereo)
+{
+ emit stereoStatusChanged(isStereo);
+}
+
+void QXARadioSession::CBSignalStrengthChanged(int signalStrength)
+{
+ emit signalStrengthChanged(signalStrength);
+}
+
+void QXARadioSession::CBVolumeChanged(int volume)
+{
+ emit volumeChanged(volume);
+}
+
+void QXARadioSession::CBMutedChanged(bool isMuted)
+{
+ emit mutedChanged(isMuted);
+}
+
+void QXARadioSession::CBSearchingChanged(bool isSearching)
+{
+ emit searchingChanged(isSearching);
+}
+
+void QXARadioSession::CBError(QRadioTuner::Error err)
+{
+ iError = err;
+ emit error((int)err, errorString());
+}
+
+
diff --git a/src/plugins/symbian/openmaxal/radiotuner/qxaradiosession.h b/src/plugins/symbian/openmaxal/radiotuner/qxaradiosession.h
new file mode 100644
index 000000000..72f6a7a01
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/radiotuner/qxaradiosession.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QXARADIOSESSION_H
+#define QXARADIOSESSION_H
+
+#include <QObject>
+#include <QUrl>
+#include <qradiotuner.h>
+#include "xaradiosessionimplobserver.h"
+
+QT_USE_NAMESPACE
+
+class XARadioSessionImpl;
+
+class QXARadioSession : public QObject, public XARadioSessionImplObserver
+{
+Q_OBJECT
+
+public:
+ QXARadioSession(QObject *parent);
+ virtual ~QXARadioSession();
+
+ QRadioTuner::State state() const;
+ QRadioTuner::Band band() const;
+ void setBand(QRadioTuner::Band band);
+ bool isBandSupported(QRadioTuner::Band band) const;
+ int frequency() const;
+ int frequencyStep(QRadioTuner::Band b) const;
+ QPair<int,int> frequencyRange(QRadioTuner::Band b) const;
+ void setFrequency(int frequency);
+ bool isStereo() const;
+ QRadioTuner::StereoMode stereoMode() const;
+ void setStereoMode(QRadioTuner::StereoMode mode);
+ int signalStrength() const;
+ int volume() const;
+ int setVolume(int volume);
+ bool isMuted() const;
+ void setMuted(bool muted);
+ bool isSearching() const;
+ void searchForward();
+ void searchBackward();
+ void cancelSearch();
+ void start();
+ void stop();
+ bool isAvailable() const;
+ QtMultimediaKit::AvailabilityError availabilityError() const;
+ QRadioTuner::Error error() const;
+ QString errorString() const;
+
+ /* Callbacks from XARadioSessionImplObserver begin */
+ void CBBandChanged(QRadioTuner::Band band);
+ void CBStateChanged(QRadioTuner::State state);
+ void CBFrequencyChanged(TInt newFrequency);
+ void CBStereoStatusChanged(bool isStereo);
+ void CBSignalStrengthChanged(int signalStrength);
+ void CBVolumeChanged(int volume);
+ void CBMutedChanged(bool isMuted);
+ void CBSearchingChanged(bool isSearching);
+ void CBError(QRadioTuner::Error err);
+ /* Callbacks from XARadioSessionImplObserver end */
+
+signals:
+ void stateChanged(QRadioTuner::State state);
+ void bandChanged(QRadioTuner::Band band);
+ void frequencyChanged(int frequency);
+ void stereoStatusChanged(bool stereo);
+ void searchingChanged(bool stereo);
+ void signalStrengthChanged(int signalStrength);
+ void volumeChanged(int volume);
+ void mutedChanged(bool muted);
+ void error(int err, QString str);
+
+private:
+ /* Own */
+ QRadioTuner::Error iError;
+ XARadioSessionImpl* m_impl;
+};
+
+#endif /*QXARADIOSESSION_H*/
diff --git a/src/plugins/symbian/openmaxal/radiotuner/radiotuner.pri b/src/plugins/symbian/openmaxal/radiotuner/radiotuner.pri
new file mode 100644
index 000000000..bf83d05fc
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/radiotuner/radiotuner.pri
@@ -0,0 +1,18 @@
+INCLUDEPATH += $$PWD
+
+# Input
+HEADERS += \
+ $$PWD/qxaradiomediaservice.h \
+ $$PWD/qxaradiosession.h \
+ $$PWD/qxaradiocontrol.h \
+ $$PWD/xaradiosessionimpl.h \
+ $$PWD/xaradiosessionimplobserver.h
+
+SOURCES += \
+ $$PWD/qxaradiomediaservice.cpp \
+ $$PWD/qxaradiosession.cpp \
+ $$PWD/qxaradiocontrol.cpp \
+ $$PWD/xaradiosessionimpl.cpp
+
+LIBS += \
+ -lbafl
diff --git a/src/plugins/symbian/openmaxal/radiotuner/xaradiosessionimpl.cpp b/src/plugins/symbian/openmaxal/radiotuner/xaradiosessionimpl.cpp
new file mode 100644
index 000000000..94bebc373
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/radiotuner/xaradiosessionimpl.cpp
@@ -0,0 +1,715 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "xaradiosessionimpl.h"
+#include "xaradiosessionimplobserver.h"
+#include <xaradioitfext.h>
+#include "xacommon.h"
+
+#define MAX_NUMBER_INTERFACES 20
+#define FM_STEP 100000; // Hz (.1 MHz)
+
+/*
+ * function declarations.
+ * */
+void EngineObjectCallback(XAObjectItf caller, const void */*pContext*/,
+ XAuint32 event, XAresult result, XAuint32 /*param*/,
+ void */*pInterface*/);
+
+void RadioCallback(XARadioItf caller, void* pContext, XAuint32 event, XAuint32 eventIntData, XAboolean eventBooleanData);
+void NokiaVolumeExtItfCallback(XANokiaVolumeExtItf caller, void* pContext, XAuint32 event, XAboolean eventBooleanData);
+void NokiaLinearVolumeItfCallback(XANokiaLinearVolumeItf caller, void* pContext, XAuint32 event, XAboolean eventBooleanData);
+void PlayItfCallbackForRadio(XAPlayItf caller, void* pContext, XAuint32 event);
+
+XARadioSessionImpl::XARadioSessionImpl(XARadioSessionImplObserver& parent)
+:iParent(parent),
+iRadio(NULL),
+iEngine(NULL),
+iPlayer(NULL),
+iSearching(EFalse),
+iRadioAvailable(EFalse),
+iState(QRadioTuner::StoppedState)
+{
+ iAvailabilityError = QtMultimediaKit::NoError;
+}
+
+XARadioSessionImpl::~XARadioSessionImpl()
+{
+ if (iRadio) {
+ TRACE_LOG((_L("XARadioSessionImpl::~XARadioSessionImpl(): Deleting Radio Device...")));
+ (*iRadio)->Destroy(iRadio);
+ iRadio = NULL;
+ TRACE_LOG((_L("XARadioSessionImpl::~XARadioSessionImpl(): Deleted Radio Device")));
+ }
+ if (iPlayer) {
+ TRACE_LOG((_L("XARadioSessionImpl::~XARadioSessionImpl(): Deleting player...")));
+ (*iPlayer)->Destroy(iPlayer);
+ iPlayer = NULL;
+ TRACE_LOG((_L("XARadioSessionImpl::~XARadioSessionImpl(): Deleted iPlayer")));
+ }
+ if ( iEngine ) {
+ TRACE_LOG((_L("XARadioSessionImpl::~XARadioSessionImpl(): Deleting engine...")));
+ (*iEngine)->Destroy(iEngine);
+ iEngine = NULL;
+ TRACE_LOG((_L("XARadioSessionImpl::~XARadioSessionImpl(): Deleted engine")));
+ }
+}
+
+QRadioTuner::Error XARadioSessionImpl::PostConstruct()
+{
+ XAresult res = CreateEngine();
+ if (res != KErrNone)
+ return QRadioTuner::ResourceError;
+ else
+ return QRadioTuner::NoError;
+}
+
+TInt XARadioSessionImpl::CreateEngine()
+{
+ TRACE_FUNCTION_ENTRY;
+ XAboolean required[MAX_NUMBER_INTERFACES];
+ XAInterfaceID iidArray[MAX_NUMBER_INTERFACES];
+ XAuint32 noOfInterfaces = 0;
+ int i;
+ XAresult res;
+
+ XAEngineOption EngineOption[] =
+ {
+ {
+ (XAuint32) XA_ENGINEOPTION_THREADSAFE,
+ (XAuint32) XA_BOOLEAN_TRUE
+ }
+ };
+
+ /* Create XA engine */
+ if (!iEngine) {
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Creating Engine...")));
+ res = xaCreateEngine(&iEngine, 1, EngineOption, 0, NULL, NULL);
+ RET_ERR_IF_ERR(CheckErr(res));
+ res = (*iEngine)->RegisterCallback(iEngine, EngineObjectCallback, NULL);
+ RET_ERR_IF_ERR(CheckErr(res));
+
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Realizing...")));
+ res = (*iEngine)->Realize(iEngine, XA_BOOLEAN_FALSE);
+ RET_ERR_IF_ERR(CheckErr(res));
+
+ // Create Engine Interface:
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Creating Engine Interface")));
+ RET_ERR_IF_ERR(CheckErr((*iEngine)->GetInterface(iEngine, XA_IID_ENGINE, (void*)&iEngineItf)));
+
+ // Create Radio Device and interface(s):
+ if (!iRadio) {
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Creating Radio Device")));
+ res = (*iEngineItf)->CreateRadioDevice(iEngineItf,&iRadio, 0, NULL, NULL);
+ RET_ERR_IF_ERR(CheckErr(res));
+
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Realize Radio Device")));
+ res = (*iRadio)->Realize(iRadio, XA_BOOLEAN_FALSE);
+ RET_ERR_IF_ERR(CheckErr(res));
+
+ // Get Radio interface:
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Get Radio Interface")));
+ res = (*iRadio)->GetInterface(iRadio, XA_IID_RADIO, (void*)&iRadioItf);
+ RET_ERR_IF_ERR(CheckErr(res));
+ iRadioAvailable = ETrue;
+ // Register Radio Callback:
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Create Radio Callback:")));
+ res = (*iRadioItf)->RegisterRadioCallback(iRadioItf, RadioCallback, (void*)this);
+ RET_ERR_IF_ERR(CheckErr(res));
+ }
+ XADataSource audioSource;
+ XADataLocator_IODevice locatorIODevice;
+ XADataSink audioSink;
+ XADataLocator_OutputMix locator_outputmix;
+
+ /* Init arrays required[] and iidArray[] */
+ for (i = 0; i < MAX_NUMBER_INTERFACES; i++) {
+ required[i] = XA_BOOLEAN_FALSE;
+ iidArray[i] = XA_IID_NULL;
+ }
+
+ iidArray[0] = XA_IID_NOKIAVOLUMEEXT;
+ iidArray[1] = XA_IID_NOKIALINEARVOLUME;
+ noOfInterfaces = 2;
+
+ locatorIODevice.locatorType = XA_DATALOCATOR_IODEVICE;
+ locatorIODevice.deviceType = XA_IODEVICE_RADIO;
+ locatorIODevice.deviceID = 0; /* ignored */
+ locatorIODevice.device = iRadio;
+ audioSource.pLocator = (void*) &locatorIODevice;
+ audioSource.pFormat = NULL;
+
+ /* Setup the data sink structure */
+ locator_outputmix.locatorType = XA_DEFAULTDEVICEID_AUDIOOUTPUT;
+ locator_outputmix.outputMix = NULL;
+ audioSink.pLocator = (void*) &locator_outputmix;
+ audioSink.pFormat = NULL;
+
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Create Media Player:")));
+ res = (*iEngineItf)->CreateMediaPlayer(iEngineItf, &iPlayer, &audioSource, NULL, &audioSink, NULL, NULL, NULL, noOfInterfaces, iidArray, required);
+ RET_ERR_IF_ERR(CheckErr(res));
+
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Realize Media Player:")));
+ res = (*iPlayer)->Realize(iPlayer, XA_BOOLEAN_FALSE);
+ RET_ERR_IF_ERR(CheckErr(res));
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Get Play Interface from player:")));
+ res = (*iPlayer)->GetInterface(iPlayer, XA_IID_PLAY, (void*) &iPlayItf);
+ RET_ERR_IF_ERR(CheckErr(res));
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Create PlayItf Callback:")));
+ res = (*iPlayItf)->RegisterCallback(iPlayItf, PlayItfCallbackForRadio, (void*)this);
+ RET_ERR_IF_ERR(CheckErr(res));
+
+ // Get Volume Interfaces specific for Nokia impl:
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Get NokiaVolumeExt Interface")));
+ res = (*iPlayer)->GetInterface(iPlayer, XA_IID_NOKIAVOLUMEEXT, (void*)&iNokiaVolumeExtItf);
+ RET_ERR_IF_ERR(CheckErr(res));
+
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Get NokiaLinearVolume Interface")));
+ res = (*iPlayer)->GetInterface(iPlayer, XA_IID_NOKIALINEARVOLUME, (void*)&iNokiaLinearVolumeItf);
+ RET_ERR_IF_ERR(CheckErr(res));
+
+ // Register Volume Callbacks:
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Create NokiaVolumeExtItf Callback:")));
+ res = (*iNokiaVolumeExtItf)->RegisterVolumeCallback(iNokiaVolumeExtItf, NokiaVolumeExtItfCallback, (void*)this);
+ RET_ERR_IF_ERR(CheckErr(res));
+ res = (*iNokiaVolumeExtItf)->SetCallbackEventsMask(iNokiaVolumeExtItf,(XA_NOKIAVOLUMEEXT_EVENT_MUTE_CHANGED));
+ RET_ERR_IF_ERR(CheckErr(res));
+ TRACE_LOG((_L("XARadioSessionImpl::CreateEngine: Create NokiaLinearVolumeItf Callback:")));
+ res = (*iNokiaLinearVolumeItf)->RegisterVolumeCallback(iNokiaLinearVolumeItf, NokiaLinearVolumeItfCallback, (void*)this);
+ RET_ERR_IF_ERR(CheckErr(res));
+ res = (*iNokiaLinearVolumeItf)->SetCallbackEventsMask(iNokiaLinearVolumeItf,(XA_NOKIALINEARVOLUME_EVENT_VOLUME_CHANGED));
+ RET_ERR_IF_ERR(CheckErr(res));
+ }
+
+ TRACE_FUNCTION_EXIT;
+ return EFalse;
+}
+
+QRadioTuner::State XARadioSessionImpl::State() const
+{
+ TRACE_FUNCTION_ENTRY_EXIT;
+ return iState;
+}
+
+QtMultimediaKit::AvailabilityError XARadioSessionImpl::AvailabilityError() const
+{
+ TRACE_FUNCTION_ENTRY_EXIT;
+ return iAvailabilityError;
+}
+
+ bool XARadioSessionImpl::IsAvailable() const
+{
+ TRACE_FUNCTION_ENTRY_EXIT;
+ return iRadioAvailable;
+}
+
+QRadioTuner::Band XARadioSessionImpl::Band() const
+{
+ TRACE_FUNCTION_ENTRY_EXIT;
+ return iBand;
+}
+
+void XARadioSessionImpl::SetBand(QRadioTuner::Band band)
+{
+ if (band != QRadioTuner::FM)
+ iParent.CBError(QRadioTuner::OpenError);
+ else
+ iBand = band;
+}
+
+bool XARadioSessionImpl::IsBandSupported(QRadioTuner::Band band) const
+{
+ if (band == QRadioTuner::FM)
+ return ETrue;
+ else
+ return EFalse;
+}
+
+// Returns the number of Hertz to increment the frequency by when stepping through frequencies within a given band.
+TInt XARadioSessionImpl::FrequencyStep(QRadioTuner::Band /*band*/) const
+{
+ TInt freqStep = FM_STEP;
+ return (int)freqStep;
+}
+
+bool XARadioSessionImpl::IsStereo() //const
+{
+ bool isStereo = EFalse;
+ QRadioTuner::StereoMode mode = StereoMode();
+ if (mode == QRadioTuner::ForceStereo || mode == QRadioTuner::Auto)
+ isStereo = ETrue;
+ return isStereo;
+}
+
+bool XARadioSessionImpl::IsMuted() const
+{
+ TRACE_FUNCTION_ENTRY;
+ XAboolean isMuted = EFalse;
+ (*iNokiaVolumeExtItf)->GetMute(iNokiaVolumeExtItf, &isMuted );
+ TRACE_LOG((_L("XARadioSessionImpl::IsMuted: isMuted = %d"), isMuted));
+
+ TRACE_FUNCTION_EXIT;
+ return isMuted;
+}
+
+bool XARadioSessionImpl::IsSearching() const
+{
+ //iSearching is set when seek (QT:searchForward-backward)
+ // iSearching is cleared when SearchingStatusChanged is called or StopSeeking is called
+ return iSearching;
+}
+
+TInt XARadioSessionImpl::GetFrequency()
+{
+ TRACE_FUNCTION_ENTRY;
+
+ XAuint32 freq = 0;
+ XAresult res = (*iRadioItf)->GetFrequency(iRadioItf, &freq );
+ RET_ERR_IF_ERR(CheckErr(res));
+ TRACE_LOG((_L("XARadioSessionImpl::GetFrequency: Frequency = %d"), freq));
+
+ TRACE_FUNCTION_EXIT;
+ return (int)freq;
+}
+
+TInt XARadioSessionImpl::GetFrequencyRange()
+{
+ TRACE_FUNCTION_ENTRY;
+ XAuint8 range = 0;
+
+ XAresult res = (*iRadioItf)->GetFreqRange(iRadioItf, &range);
+ RET_ERR_IF_ERR(CheckErr(res));
+ TRACE_LOG((_L("XARadioSessionImpl::GetFrequencyRange: Frequency Range = %d"), range));
+
+ TRACE_FUNCTION_EXIT;
+ return (int)range;
+}
+
+TInt XARadioSessionImpl::GetFrequencyRangeProperties(TInt range, TInt &minFreq, TInt &maxFreq)
+{
+ TRACE_FUNCTION_ENTRY;
+ XAuint32 freqInterval = 0;
+ XAresult res = (*iRadioItf)->GetFreqRangeProperties(iRadioItf, (XAuint8)range, (XAuint32*)&minFreq,(XAuint32*)&maxFreq, (XAuint32*)&freqInterval);
+ RET_ERR_IF_ERR(CheckErr(res));
+ TRACE_LOG((_L("XARadioSessionImpl::GetFrequencyRangeProperties: minFreq = %d, maxFreq = %d"), minFreq, maxFreq));
+
+ TRACE_FUNCTION_EXIT;
+ return res;
+}
+
+TInt XARadioSessionImpl::SetFrequency(TInt aFreq)
+{
+ TRACE_FUNCTION_ENTRY;
+
+ TRACE_LOG((_L("XARadioSessionImpl::SetFrequency: Setting Frequency to: %d"), aFreq));
+ XAresult res = (*iRadioItf)->SetFrequency(iRadioItf, aFreq );
+ RET_ERR_IF_ERR(CheckErr(res));
+
+ TRACE_FUNCTION_EXIT;
+ return res;
+}
+
+QRadioTuner::StereoMode XARadioSessionImpl::StereoMode()
+{
+ TRACE_FUNCTION_ENTRY;
+ QRadioTuner::StereoMode qtStereoMode;
+ XAuint32 symStereoMode;
+ (*iRadioItf)->GetStereoMode(iRadioItf, &symStereoMode);
+
+ if (symStereoMode == XA_STEREOMODE_MONO)
+ qtStereoMode = QRadioTuner::ForceMono;
+ else if (symStereoMode == XA_STEREOMODE_STEREO)
+ qtStereoMode = QRadioTuner::ForceStereo;
+ else
+ qtStereoMode = QRadioTuner::Auto;
+
+ TRACE_FUNCTION_EXIT;
+ return qtStereoMode;
+}
+
+TInt XARadioSessionImpl::SetStereoMode(QRadioTuner::StereoMode qtStereoMode)
+{
+ TRACE_FUNCTION_ENTRY;
+ XAuint32 symStereoMode;
+
+ if (qtStereoMode == QRadioTuner::ForceMono)
+ symStereoMode = XA_STEREOMODE_MONO;
+ else if (qtStereoMode == QRadioTuner::ForceStereo)
+ symStereoMode = XA_STEREOMODE_STEREO;
+ else
+ symStereoMode = XA_STEREOMODE_AUTO;
+
+ XAresult res = (*iRadioItf)->SetStereoMode(iRadioItf, (symStereoMode));
+ TRACE_FUNCTION_EXIT;
+ return res;
+}
+
+TInt XARadioSessionImpl::GetSignalStrength()
+{
+ TRACE_FUNCTION_ENTRY;
+ XAuint32 signalStrength = 0;
+
+ (*iRadioItf)->GetSignalStrength(iRadioItf, &signalStrength );
+ TRACE_LOG((_L("XARadioSessionImpl::GetSignalStrength: Signal Strength = %d"), signalStrength));
+ TRACE_FUNCTION_EXIT;
+ return (int)signalStrength;
+}
+
+TInt XARadioSessionImpl::GetVolume()
+{
+ TRACE_FUNCTION_ENTRY;
+ XAuint32 vol;
+ if (iPlayer && iNokiaLinearVolumeItf) {
+ (*iNokiaLinearVolumeItf)->GetVolumeLevel(iNokiaLinearVolumeItf, &vol );
+ TRACE_LOG((_L("XARadioSessionImpl::GetVolume: Volume = %d"), vol));
+ }
+ TRACE_FUNCTION_EXIT;
+ return (TInt)vol;
+}
+
+TInt XARadioSessionImpl::SetVolume(TInt aVolume)
+{
+ TRACE_FUNCTION_ENTRY;
+ XAuint32 newVolume = 0;
+ TRACE_LOG((_L("XARadioSessionImpl::SetVolume: Setting volume to: %d"), aVolume));
+ if (iPlayer && iNokiaLinearVolumeItf) {
+ newVolume = aVolume;
+ XAresult res = (*iNokiaLinearVolumeItf)->SetVolumeLevel(iNokiaLinearVolumeItf, &newVolume);
+ }
+ TRACE_FUNCTION_EXIT;
+ return (TInt)newVolume;
+}
+
+TInt XARadioSessionImpl::SetMuted(TBool aMuted)
+{
+ TRACE_FUNCTION_ENTRY;
+ XAresult res = (*iNokiaVolumeExtItf)->SetMute(iNokiaVolumeExtItf, aMuted);
+ TRACE_FUNCTION_EXIT;
+ return res;
+}
+
+TInt XARadioSessionImpl::Seek(TBool aDirection)
+{
+ TRACE_FUNCTION_ENTRY;
+ iSearching = true;
+ XAresult res = (*iRadioItf)->Seek(iRadioItf, aDirection );
+ TRACE_FUNCTION_EXIT;
+ return res;
+}
+
+TInt XARadioSessionImpl::StopSeeking()
+{
+ TRACE_FUNCTION_ENTRY;
+ XAresult res = (*iRadioItf)->StopSeeking(iRadioItf);
+ iSearching = EFalse;
+ TRACE_FUNCTION_EXIT;
+ return res;
+}
+
+void XARadioSessionImpl::Start()
+{
+ TRACE_FUNCTION_ENTRY;
+ if (iPlayItf) {
+ XAresult res = (*iPlayItf)->SetPlayState(iPlayItf, XA_PLAYSTATE_PLAYING);
+ // add error handling if res != 0 (call errorCB)
+ }
+ TRACE_FUNCTION_EXIT;
+}
+
+void XARadioSessionImpl::Stop()
+{
+ TRACE_FUNCTION_ENTRY;
+ if (iPlayItf) {
+ XAresult res = (*iPlayItf)->SetPlayState(iPlayItf, XA_PLAYSTATE_STOPPED);
+ // add error handling if res != 0 (call errorCB)
+ }
+ TRACE_FUNCTION_EXIT;
+}
+
+QRadioTuner::Error XARadioSessionImpl::Error()
+{
+ TRACE_FUNCTION_ENTRY_EXIT;
+ return QRadioTuner::NoError;
+}
+
+//TInt XARadioSessionImpl::ErrorString();
+// {
+// TRACE_FUNCTION_ENTRY;
+
+// TRACE_FUNCTION_EXIT;
+// }
+
+void XARadioSessionImpl::StateChanged(QRadioTuner::State state)
+{
+ TRACE_FUNCTION_ENTRY;
+ iState = state;
+ iParent.CBStateChanged(state);
+ TRACE_FUNCTION_EXIT;
+}
+
+void XARadioSessionImpl::FrequencyChanged(XAuint32 freq)
+{
+ TRACE_FUNCTION_ENTRY;
+ iParent.CBFrequencyChanged(freq);
+ TRACE_FUNCTION_EXIT;
+}
+
+void XARadioSessionImpl::SearchingChanged(TBool isSearching)
+{
+ TRACE_FUNCTION_ENTRY;
+ iSearching = EFalse;
+ iParent.CBSearchingChanged(isSearching);
+ TRACE_FUNCTION_EXIT;
+}
+
+void XARadioSessionImpl::StereoStatusChanged(TBool stereoStatus)
+{
+ TRACE_FUNCTION_ENTRY;
+ iParent.CBStereoStatusChanged(stereoStatus);
+ TRACE_FUNCTION_EXIT;
+}
+
+void XARadioSessionImpl::SignalStrengthChanged(TBool stereoStatus)
+{
+ TRACE_FUNCTION_ENTRY;
+ iParent.CBSignalStrengthChanged(stereoStatus);
+ TRACE_FUNCTION_EXIT;
+}
+
+void XARadioSessionImpl::VolumeChanged()
+{
+ TRACE_FUNCTION_ENTRY;
+ int vol = 0;
+ iParent.CBVolumeChanged(vol);
+ TRACE_FUNCTION_EXIT;
+}
+
+void XARadioSessionImpl::MutedChanged(TBool mute)
+{
+ TRACE_FUNCTION_ENTRY;
+ iParent.CBMutedChanged(mute);
+ TRACE_FUNCTION_EXIT;
+}
+
+void EngineObjectCallback(XAObjectItf /*caller*/,
+ const void */*pContext*/,
+#ifdef PLUGIN_SYMBIAN_TRACE_ENABLED
+ XAuint32 event,
+#else
+ XAuint32 /*event*/,
+#endif /*PLUGIN_SYMBIAN_TRACE_ENABLED*/
+ XAresult /*result*/,
+ XAuint32 /*param*/,
+ void */*pInterface*/)
+{
+#ifdef PLUGIN_SYMBIAN_TRACE_ENABLED
+ TRACE_LOG((_L("Engine object event: 0x%x\n"), (int)event));
+#endif /*PLUGIN_SYMBIAN_TRACE_ENABLED*/
+}
+
+void RadioCallback(XARadioItf /*caller*/,
+ void* pContext,
+ XAuint32 event,
+ XAuint32 eventIntData,
+ XAboolean eventBooleanData)
+{
+ XAuint32 freq;
+ XAboolean stereoStatus(XA_BOOLEAN_FALSE);
+
+ switch (event) {
+ case XA_RADIO_EVENT_ANTENNA_STATUS_CHANGED:
+ TRACE_LOG((_L("RadioCallback: XA_RADIO_EVENT_ANTENNA_STATUS_CHANGED")));
+ // Qt API has no callback defined for this event.
+ break;
+ case XA_RADIO_EVENT_FREQUENCY_CHANGED:
+ freq = eventIntData;
+ TRACE_LOG((_L("RadioCallback: XA_RADIO_EVENT_FREQUENCY_CHANGED to: %d"), freq));
+ if (pContext)
+ ((XARadioSessionImpl*)pContext)->FrequencyChanged(freq);
+ break;
+ case XA_RADIO_EVENT_FREQUENCY_RANGE_CHANGED:
+ TRACE_LOG((_L("RadioCallback: XA_RADIO_EVENT_FREQUENCY_RANGE_CHANGED")));
+ // Qt API has no callback defined for this event.
+ break;
+ case XA_RADIO_EVENT_PRESET_CHANGED:
+ TRACE_LOG((_L("RadioCallback: XA_RADIO_EVENT_PRESET_CHANGED")));
+ // Qt API has no callback defined for this event.
+ break;
+ case XA_RADIO_EVENT_SEEK_COMPLETED:
+ TRACE_LOG((_L("RadioCallback: XA_RADIO_EVENT_SEEK_COMPLETED")));
+ if (pContext)
+ ((XARadioSessionImpl*)pContext)->SearchingChanged(false);
+ break;
+ case XA_RADIO_EVENT_STEREO_STATUS_CHANGED:
+ stereoStatus = eventBooleanData;
+ TRACE_LOG((_L("RadioCallback: XA_RADIO_EVENT_STEREO_STATUS_CHANGED: %d"), stereoStatus));
+ if (pContext)
+ ((XARadioSessionImpl*)pContext)->StereoStatusChanged(stereoStatus);
+ break;
+ case XA_RADIO_EVENT_SIGNAL_STRENGTH_CHANGED:
+ TRACE_LOG((_L("RadioCallback: XA_RADIO_EVENT_SIGNAL_STRENGTH_CHANGED")));
+ if (pContext)
+ ((XARadioSessionImpl*)pContext)->SignalStrengthChanged(stereoStatus);
+ break;
+ default:
+ TRACE_LOG((_L("RadioCallback: default")));
+ break;
+ }
+}
+
+void NokiaVolumeExtItfCallback(XANokiaVolumeExtItf /*caller*/,
+ void* pContext,
+ XAuint32 event,
+ XAboolean eventBooleanData)
+{
+ XAboolean mute;
+ switch (event) {
+ case XA_NOKIAVOLUMEEXT_EVENT_MUTE_CHANGED:
+ mute = eventBooleanData;
+ TRACE_LOG((_L("NokiaVolumeExtItfCallback: XA_NOKIAVOLUMEEXT_EVENT_MUTE_CHANGED to: %d"), mute));
+ if (pContext)
+ ((XARadioSessionImpl*)pContext)->MutedChanged(mute);
+ break;
+ default:
+ TRACE_LOG((_L("NokiaVolumeExtItfCallback: default")));
+ break;
+ }
+}
+
+void NokiaLinearVolumeItfCallback(XANokiaLinearVolumeItf /*caller*/,
+ void* pContext,
+ XAuint32 event,
+ XAboolean /*eventBooleanData*/)
+{
+ switch (event) {
+ case XA_NOKIALINEARVOLUME_EVENT_VOLUME_CHANGED:
+ if (pContext)
+ ((XARadioSessionImpl*)pContext)->VolumeChanged();
+ break;
+ default:
+ TRACE_LOG((_L("NokiaLinearVolumeItfCallback: default")));
+ break;
+ }
+}
+
+void PlayItfCallbackForRadio(XAPlayItf /*caller*/,
+ void* pContext,
+ XAuint32 event)
+{
+ switch (event) {
+ case XA_PLAYEVENT_HEADMOVING:
+ if (pContext)
+ ((XARadioSessionImpl*)pContext)->StateChanged(QRadioTuner::ActiveState);
+ break;
+ case XA_PLAYEVENT_HEADSTALLED:
+ if (pContext)
+ ((XARadioSessionImpl*)pContext)->StateChanged(QRadioTuner::StoppedState);
+ break;
+ default:
+ TRACE_LOG((_L("NokiaLinearVolumeItfCallback: default")));
+ break;
+ }
+}
+
+TInt XARadioSessionImpl::CheckErr(XAresult res)
+{
+ TInt status(KErrGeneral);
+ switch(res) {
+ case XA_RESULT_SUCCESS:
+ //TRACE_LOG((_L("XA_RESULT_SUCCESS")));
+ status = KErrNone;
+ break;
+ case XA_RESULT_PRECONDITIONS_VIOLATED:
+ TRACE_LOG((_L("XA_RESULT_PRECONDITIONS_VIOLATED")));
+ break;
+ case XA_RESULT_PARAMETER_INVALID:
+ TRACE_LOG((_L("XA_RESULT_PARAMETER_INVALID")));
+ break;
+ case XA_RESULT_MEMORY_FAILURE:
+ TRACE_LOG((_L("XA_RESULT_MEMORY_FAILURE")));
+ iAvailabilityError = QtMultimediaKit::ResourceError;
+ break;
+ case XA_RESULT_RESOURCE_ERROR:
+ TRACE_LOG((_L("XA_RESULT_RESOURCE_ERROR")));
+ iAvailabilityError = QtMultimediaKit::ResourceError;
+ break;
+ case XA_RESULT_RESOURCE_LOST:
+ TRACE_LOG((_L("XA_RESULT_RESOURCE_LOST")));
+ iAvailabilityError = QtMultimediaKit::ResourceError;
+ break;
+ case XA_RESULT_IO_ERROR:
+ TRACE_LOG((_L("XA_RESULT_IO_ERROR")));
+ break;
+ case XA_RESULT_BUFFER_INSUFFICIENT:
+ TRACE_LOG((_L("XA_RESULT_BUFFER_INSUFFICIENT")));
+ break;
+ case XA_RESULT_CONTENT_CORRUPTED:
+ TRACE_LOG((_L("XA_RESULT_CONTENT_CORRUPTED")));
+ break;
+ case XA_RESULT_CONTENT_UNSUPPORTED:
+ TRACE_LOG((_L("XA_RESULT_CONTENT_UNSUPPORTED")));
+ break;
+ case XA_RESULT_CONTENT_NOT_FOUND:
+ TRACE_LOG((_L("XA_RESULT_CONTENT_NOT_FOUND")));
+ break;
+ case XA_RESULT_PERMISSION_DENIED:
+ TRACE_LOG((_L("XA_RESULT_PERMISSION_DENIED")));
+ break;
+ case XA_RESULT_FEATURE_UNSUPPORTED:
+ TRACE_LOG((_L("XA_RESULT_FEATURE_UNSUPPORTED")));
+ break;
+ case XA_RESULT_INTERNAL_ERROR:
+ TRACE_LOG((_L("XA_RESULT_INTERNAL_ERROR")));
+ break;
+ case XA_RESULT_UNKNOWN_ERROR:
+ TRACE_LOG((_L("XA_RESULT_UNKNOWN_ERROR")));
+ break;
+ case XA_RESULT_OPERATION_ABORTED:
+ TRACE_LOG((_L("XA_RESULT_OPERATION_ABORTED")));
+ break;
+ case XA_RESULT_CONTROL_LOST:
+ TRACE_LOG((_L("XA_RESULT_CONTROL_LOST")));
+ break;
+ default:
+ TRACE_LOG((_L("Unknown Error!!!")));
+ }
+ return status;
+}
diff --git a/src/plugins/symbian/openmaxal/radiotuner/xaradiosessionimpl.h b/src/plugins/symbian/openmaxal/radiotuner/xaradiosessionimpl.h
new file mode 100644
index 000000000..ee5f53a2f
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/radiotuner/xaradiosessionimpl.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XARADIOSESSIONIMPL_H
+#define XARADIOSESSIONIMPL_H
+
+#include <OpenMAXAL.h>
+#include <xanokialinearvolumeitf.h>
+#include <xanokiavolumeextitf.h>
+#include <qradiotuner.h>
+#include <qtmedianamespace.h>
+
+QT_USE_NAMESPACE
+
+class XARadioSessionImplObserver;
+
+class XARadioSessionImpl
+{
+public:
+ XARadioSessionImpl(XARadioSessionImplObserver& parent);
+ ~XARadioSessionImpl();
+ QRadioTuner::Error PostConstruct();
+ QRadioTuner::Band Band() const;
+ QRadioTuner::State State() const;
+ QtMultimediaKit::AvailabilityError AvailabilityError() const;
+ bool IsAvailable() const;
+ void SetBand(QRadioTuner::Band band);
+ bool IsBandSupported(QRadioTuner::Band band) const;
+ TInt FrequencyStep(QRadioTuner::Band band) const;
+ bool IsStereo(); //const;
+ bool IsMuted() const;
+ bool IsSearching() const;
+ TInt GetFrequency();
+ TInt GetFrequencyRange();
+ TInt GetFrequencyRangeProperties(TInt range, TInt &minFreq, TInt &maxFreq);
+ TInt SetFrequency(TInt aFreq);
+ QRadioTuner::StereoMode StereoMode();
+ TInt SetStereoMode(QRadioTuner::StereoMode stereoMode);
+ TInt GetSignalStrength();
+ TInt GetVolume();
+ TInt SetVolume(TInt aVolume);
+ TInt SetMuted(TBool aMuted);
+ TInt Seek(TBool aDirection);
+ TInt StopSeeking();
+ void Start();
+ void Stop();
+ QRadioTuner::Error Error();
+//TInt ErrorString();
+ void StateChanged(QRadioTuner::State state);
+ void FrequencyChanged(XAuint32 freq);
+ void SearchingChanged(TBool isSearching);
+ void StereoStatusChanged(TBool stereoStatus);
+ void SignalStrengthChanged(TBool stereoStatus);
+ void VolumeChanged();
+ void MutedChanged(TBool mute);
+
+private:
+ TInt CreateEngine();
+ TInt CheckErr(XAresult res);
+
+
+private:
+ XARadioSessionImplObserver& iParent;
+ XAObjectItf iRadio;
+ XAObjectItf iEngine;
+ XAObjectItf iPlayer;
+ XAEngineItf iEngineItf;
+ XARecordItf iRecordItf;
+ XAPlayItf iPlayItf;
+ XARadioItf iRadioItf;
+ XARDSItf iRdsItf;
+ XANokiaVolumeExtItf iNokiaVolumeExtItf; // used for mute functionality
+ XANokiaLinearVolumeItf iNokiaLinearVolumeItf; // used for volume functionality
+
+ /* Audio Source */
+ XADataSource iDataSource;
+
+ /*Audio Sink*/
+ XADataSink iAudioSink;
+ XADataLocator_OutputMix iLocator_outputmix;
+
+ TBool iAutoFlag;
+ TBool iSearching;
+ TBool iRadioAvailable;
+ QtMultimediaKit::AvailabilityError iAvailabilityError;
+ QRadioTuner::Band iBand;
+ QRadioTuner::State iState;
+};
+
+#endif /* XARADIOSESSIONIMPL_H */
diff --git a/src/plugins/symbian/openmaxal/radiotuner/xaradiosessionimplobserver.h b/src/plugins/symbian/openmaxal/radiotuner/xaradiosessionimplobserver.h
new file mode 100644
index 000000000..73c734fd3
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/radiotuner/xaradiosessionimplobserver.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XARADIOSESSIONIMPLOBSERVER_H
+#define XARADIOSESSIONIMPLOBSERVER_H
+
+#include <e32base.h>
+#include <qradiotuner.h>
+
+QT_USE_NAMESPACE
+
+class XARadioSessionImplObserver
+{
+public:
+ virtual void CBStateChanged(QRadioTuner::State state) = 0;
+ virtual void CBBandChanged(QRadioTuner::Band band) = 0;
+ virtual void CBFrequencyChanged(TInt newFrequency) = 0;
+ virtual void CBStereoStatusChanged(bool isStereo) = 0;
+ virtual void CBSignalStrengthChanged(int signalStrength) = 0;
+ virtual void CBVolumeChanged(int volume) = 0;
+ virtual void CBMutedChanged(bool isMuted) = 0;
+ virtual void CBSearchingChanged(bool isSearching) = 0;
+ virtual void CBError(QRadioTuner::Error err) = 0;
+};
+
+#endif /*XARADIOSESSIONIMPLOBSERVER_H*/
diff --git a/src/plugins/symbian/openmaxal/xacommon.h b/src/plugins/symbian/openmaxal/xacommon.h
new file mode 100644
index 000000000..9aecbc8f5
--- /dev/null
+++ b/src/plugins/symbian/openmaxal/xacommon.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef XACOMMON_H
+#define XACOMMON_H
+
+#ifdef PLUGIN_SYMBIAN_TRACE_ENABLED
+# include <e32debug.h>
+#endif /* PLUGIN_SYMBIAN_TRACE_ENABLED */
+
+#ifdef PLUGIN_SYMBIAN_TRACE_ENABLED
+# define TRACE_FUNCTION_ENTRY RDebug::Printf( "%s >", __PRETTY_FUNCTION__)
+# define TRACE_FUNCTION_EXIT RDebug::Printf( "%s <", __PRETTY_FUNCTION__)
+# define TRACE_FUNCTION_ENTRY_EXIT RDebug::Printf( "%s ><", __PRETTY_FUNCTION__)
+# define TRACE_LOG(s) RDebug::Print s
+#else
+# define TRACE_FUNCTION_ENTRY
+# define TRACE_FUNCTION_EXIT
+# define TRACE_FUNCTION_ENTRY_EXIT
+# define TRACE_LOG
+#endif /* PLUGIN_SYMBIAN_TRACE_ENABLED */
+
+#define RET_IF_FALSE(e) \
+ if (e == false) \
+ { \
+ return; \
+ }
+
+#define RET_BOOL_IF_FALSE(e) \
+ if (e == false) \
+ { \
+ return e; \
+ }
+
+#define RET_ERR_IF_ERR(e) \
+ if (e != 0) \
+ { \
+ return e; \
+ }
+
+#endif /* XACOMMON_H */
diff --git a/src/plugins/symbian/symbian.pro b/src/plugins/symbian/symbian.pro
new file mode 100644
index 000000000..7fc2c8690
--- /dev/null
+++ b/src/plugins/symbian/symbian.pro
@@ -0,0 +1,23 @@
+######################################################################
+#
+# Mobility API project - Symbian backends
+#
+######################################################################
+
+TEMPLATE = subdirs
+
+include (../../../config.pri)
+
+# The openmax-al backend is currently not supported
+# we include mmf only if we are not building openmaxal based backend
+#contains(openmaxal_symbian_enabled, no) {
+# message("Enabling mmf mediarecording, playback and radio backend")
+# symbian:SUBDIRS += mmf
+#
+#else {
+# message("Enabling OpenMAX AL audio record, playback and radio backend")
+# symbian:SUBDIRS += openmaxal
+#
+
+symbian:SUBDIRS += ecam mmf
+
diff --git a/src/plugins/symbian/videooutput/s60videodisplay.cpp b/src/plugins/symbian/videooutput/s60videodisplay.cpp
new file mode 100644
index 000000000..35e234e98
--- /dev/null
+++ b/src/plugins/symbian/videooutput/s60videodisplay.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "s60videodisplay.h"
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
+#include <coecntrl.h>
+#include <w32std.h>
+
+S60VideoDisplay::S60VideoDisplay(QObject *parent)
+: QObject(parent)
+, m_fullScreen(false)
+, m_visible(true)
+, m_aspectRatioMode(Qt::KeepAspectRatio)
+, m_paintingEnabled(false)
+, m_rotation(0.0f)
+{
+ connect(this, SIGNAL(displayRectChanged(QRect, QRect)),
+ this, SLOT(updateContentRect()));
+ connect(this, SIGNAL(nativeSizeChanged(QSize)),
+ this, SLOT(updateContentRect()));
+}
+
+S60VideoDisplay::~S60VideoDisplay()
+{
+
+}
+
+RWindow *S60VideoDisplay::windowHandle() const
+{
+ return winId() ? static_cast<RWindow *>(winId()->DrawableWindow()) : 0;
+}
+
+QRect S60VideoDisplay::clipRect() const
+{
+ QRect displayableRect;
+#ifdef VIDEOOUTPUT_GRAPHICS_SURFACES
+ if (RWindow *window = windowHandle())
+ displayableRect = QRect(0, 0, window->Size().iWidth, window->Size().iHeight);
+#else
+ displayableRect = QApplication::desktop()->screenGeometry();
+#endif
+ return extentRect().intersected(displayableRect);
+}
+
+QRect S60VideoDisplay::contentRect() const
+{
+ return m_contentRect;
+}
+
+void S60VideoDisplay::setFullScreen(bool enabled)
+{
+ if (m_fullScreen != enabled) {
+ m_fullScreen = enabled;
+ emit fullScreenChanged(m_fullScreen);
+ }
+}
+
+bool S60VideoDisplay::isFullScreen() const
+{
+ return m_fullScreen;
+}
+
+void S60VideoDisplay::setVisible(bool enabled)
+{
+ if (m_visible != enabled) {
+ m_visible = enabled;
+ emit visibilityChanged(m_visible);
+ }
+}
+
+bool S60VideoDisplay::isVisible() const
+{
+ return m_visible;
+}
+
+void S60VideoDisplay::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ if (m_aspectRatioMode != mode) {
+ m_aspectRatioMode = mode;
+ emit aspectRatioModeChanged(m_aspectRatioMode);
+ }
+}
+
+Qt::AspectRatioMode S60VideoDisplay::aspectRatioMode() const
+{
+ return m_aspectRatioMode;
+}
+
+void S60VideoDisplay::setNativeSize(const QSize &size)
+{
+ if (m_nativeSize != size) {
+ m_nativeSize = size;
+ emit nativeSizeChanged(m_nativeSize);
+ }
+}
+
+const QSize& S60VideoDisplay::nativeSize() const
+{
+ return m_nativeSize;
+}
+
+void S60VideoDisplay::setPaintingEnabled(bool enabled)
+{
+ if (m_paintingEnabled != enabled) {
+ m_paintingEnabled = enabled;
+ emit paintingEnabledChanged(m_paintingEnabled);
+ }
+}
+
+bool S60VideoDisplay::isPaintingEnabled() const
+{
+ return m_paintingEnabled;
+}
+
+void S60VideoDisplay::setRotation(qreal value)
+{
+ if (value != m_rotation) {
+ m_rotation = value;
+ emit rotationChanged(m_rotation);
+ }
+}
+
+qreal S60VideoDisplay::rotation() const
+{
+ return m_rotation;
+}
+
+void S60VideoDisplay::updateContentRect()
+{
+ if (isPaintingEnabled()) {
+ const int dx = qMax(0, extentRect().width() - nativeSize().width());
+ const int dy = qMax(0, extentRect().height() - nativeSize().height());
+ QRect contentRect(QPoint(dx/2, dy/2), nativeSize());
+ if (m_contentRect != contentRect) {
+ m_contentRect = contentRect;
+ emit contentRectChanged(m_contentRect);
+ }
+ }
+}
+
diff --git a/src/plugins/symbian/videooutput/s60videodisplay.h b/src/plugins/symbian/videooutput/s60videodisplay.h
new file mode 100644
index 000000000..e16e7bb71
--- /dev/null
+++ b/src/plugins/symbian/videooutput/s60videodisplay.h
@@ -0,0 +1,188 @@
+/**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEODISPLAY_H
+#define S60VIDEODISPLAY_H
+
+#include <QtCore/QMetaType>
+#include <QtCore/QObject>
+#include <QtCore/QRect>
+#include <QtCore/QSize>
+#include <QtGui/qwindowdefs.h>
+
+class CFbsBitmap;
+class RWindow;
+
+QT_USE_NAMESPACE
+
+/*
+ * This class defines a common API used by Symbian camera and mediaplayer
+ * backends to render to on-screen video outputs, i.e. implementations of
+ * QVideoWidgetControl and QVideoWindowControl.
+ */
+class S60VideoDisplay : public QObject
+{
+ Q_OBJECT
+public:
+ S60VideoDisplay(QObject *parent);
+ virtual ~S60VideoDisplay();
+
+ /*
+ * Returns native Symbian handle of the window to be used for rendering
+ */
+ RWindow *windowHandle() const;
+
+ /*
+ * Returns Qt WId (CCoeControl* on Symbian)
+ */
+ virtual WId winId() const = 0;
+
+ /*
+ * Returns video display rectangle
+ *
+ * This is the rectangle which includes both the video content itself, plus
+ * any border bars which added around the video. The aspect ratio of this
+ * rectangle therefore may differ from that of the nativeSize().
+ *
+ * If running on a platform supporting video rendering to graphics
+ * surfaces (i.e. if VIDEOOUTPUT_GRAPHICS_SURFACES is defined), the return
+ * value is the relative to the origin of the video window. Otherwise, the
+ * return value is an absolute screen rectangle.
+ *
+ * Note that this rectangle can extend beyond the bounds of the screen or of
+ * the video window.
+ *
+ * When using QVideoWindowControl, the size of the extentRect matches the
+ * displayRect; if running on a platform which supports only DSA rendering,
+ * the origin differs as described above.
+ *
+ * See also clipRect, contentRect
+ */
+ virtual QRect extentRect() const = 0;
+
+ /*
+ * Returns video clipping rectangle
+ *
+ * This rectangle is the intersection of displayRect() with either the window
+ * rectangle (on platforms supporting video rendering to graphics surfaces),
+ * or the screen rectangle (on platforms supporting only DSA video rendering).
+ *
+ * If running on a platform supporting video rendering to graphics
+ * surfaces (i.e. if VIDEOOUTPUT_GRAPHICS_SURFACES is defined), the return
+ * value is the relative to the origin of the video window. Otherwise, the
+ * return value is an absolute screen rectangle.
+ *
+ * See also extentRect, contentRect
+ */
+ QRect clipRect() const;
+
+ /*
+ * Returns video content rectangle
+ *
+ * This is the rectangle in which the video content is rendered, i.e. its
+ * size is that of extentRect() minus border bars. The aspect ratio of this
+ * rectangle is therefore equal to that of the nativeSize().
+ *
+ * This rectangle is always relative to the window in which video is rendered.
+ *
+ * See also extentRect, clipRect
+ */
+ QRect contentRect() const;
+
+ void setFullScreen(bool enabled);
+ bool isFullScreen() const;
+
+ void setVisible(bool visible);
+ bool isVisible() const;
+
+ void setAspectRatioMode(Qt::AspectRatioMode mode);
+ Qt::AspectRatioMode aspectRatioMode() const;
+
+ const QSize& nativeSize() const;
+
+ void setPaintingEnabled(bool enabled);
+ bool isPaintingEnabled() const;
+
+ void setRotation(qreal value);
+ qreal rotation() const;
+
+public slots:
+ void setNativeSize(const QSize &size);
+
+ /*
+ * Provide new video frame
+ *
+ * If setPaintingEnabled(true) has been called, the frame is rendered to
+ * the display.
+ *
+ * If a QWidget is available to the control (i.e. the control is a
+ * QVideoWidgetControl), the frame is rendered via QPainter. Otherwise, the
+ * frame is blitted to the window using native Symbian drawing APIs.
+ */
+ virtual void setFrame(const CFbsBitmap &bitmap) = 0;
+
+signals:
+ void windowHandleChanged(RWindow *);
+ void displayRectChanged(QRect extentRect, QRect clipRect);
+ void fullScreenChanged(bool);
+ void visibilityChanged(bool);
+ void aspectRatioModeChanged(Qt::AspectRatioMode);
+ void nativeSizeChanged(QSize);
+ void contentRectChanged(QRect);
+ void paintingEnabledChanged(bool);
+ void rotationChanged(qreal);
+ void beginVideoWindowNativePaint();
+ void endVideoWindowNativePaint();
+
+private slots:
+ void updateContentRect();
+
+private:
+ QRect m_contentRect;
+ bool m_fullScreen;
+ bool m_visible;
+ Qt::AspectRatioMode m_aspectRatioMode;
+ QSize m_nativeSize;
+ bool m_paintingEnabled;
+ qreal m_rotation;
+};
+
+#endif // S60VIDEODISPLAY_H
+
diff --git a/src/plugins/symbian/videooutput/s60videooutpututils.cpp b/src/plugins/symbian/videooutput/s60videooutpututils.cpp
new file mode 100644
index 000000000..feac346d1
--- /dev/null
+++ b/src/plugins/symbian/videooutput/s60videooutpututils.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "s60videooutpututils.h"
+
+#ifdef PRIVATE_QTGUI_HEADERS_AVAILABLE
+#if QT_VERSION >= 0x040601 && !defined(__WINSCW__)
+#include <QtGui/private/qt_s60_p.h>
+#include <QtGui/private/qwidget_p.h>
+#define USE_PRIVATE_QTGUI_APIS
+#endif // QT_VERSION >= 0x040601 && !defined(__WINSCW__)
+#endif // PRIVATE_QTGUI_HEADERS_AVAILABLE
+
+namespace S60VideoOutputUtils
+{
+
+void setIgnoreFocusChanged(QWidget *widget)
+{
+#ifdef USE_PRIVATE_QTGUI_APIS
+ // Warning: if this flag is not set, the application may crash due to
+ // CGraphicsContext being called from within the context of
+ // QGraphicsVideoItem::paint(), when the video widget is shown.
+ static_cast<QSymbianControl *>(widget->winId())->setIgnoreFocusChanged(true);
+#else
+ Q_UNUSED(widget)
+#endif
+}
+
+void setNativePaintMode(QWidget *widget, NativePaintMode mode)
+{
+#ifdef USE_PRIVATE_QTGUI_APIS
+ QWidgetPrivate *widgetPrivate = qt_widget_private(widget->window());
+ widgetPrivate->createExtra();
+ QWExtra::NativePaintMode widgetMode = QWExtra::Default;
+ switch (mode) {
+ case Default:
+ break;
+ case ZeroFill:
+ widgetMode = QWExtra::ZeroFill;
+ break;
+ case BlitWriteAlpha:
+#if QT_VERSION >= 0x040704
+ widgetMode = QWExtra::BlitWriteAlpha;
+#endif
+ break;
+ case Disable:
+ widgetMode = QWExtra::Disable;
+ break;
+ }
+ widgetPrivate->extraData()->nativePaintMode = widgetMode;
+#else
+ Q_UNUSED(widget)
+ Q_UNUSED(mode)
+#endif
+}
+
+void setNativePaintMode(WId wid, NativePaintMode mode)
+{
+#ifdef USE_PRIVATE_QTGUI_APIS
+ QWidget *window = static_cast<QSymbianControl *>(wid)->widget()->window();
+ setNativePaintMode(window, mode);
+#else
+ Q_UNUSED(wid)
+ Q_UNUSED(mode)
+#endif
+}
+
+void setReceiveNativePaintEvents(QWidget *widget, bool enabled)
+{
+#ifdef USE_PRIVATE_QTGUI_APIS
+ QWidgetPrivate *widgetPrivate = qt_widget_private(widget);
+ widgetPrivate->createExtra();
+ widgetPrivate->extraData()->receiveNativePaintEvents = enabled;
+#else
+ Q_UNUSED(widget)
+ Q_UNUSED(enabled)
+#endif
+}
+
+} // namespace S60VideoOutputUtils
+
diff --git a/src/plugins/symbian/videooutput/s60videooutpututils.h b/src/plugins/symbian/videooutput/s60videooutpututils.h
new file mode 100644
index 000000000..6d83062c3
--- /dev/null
+++ b/src/plugins/symbian/videooutput/s60videooutpututils.h
@@ -0,0 +1,71 @@
+/**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEOOUTPUTUTILS_H
+#define S60VIDEOOUTPUTUTILS_H
+
+#include <QtCore/qglobal.h>
+#include <QtGui/qwindowdefs.h>
+
+QT_FORWARD_DECLARE_CLASS(QWidget)
+
+/*
+ * Helper functions used by video output.
+ */
+namespace S60VideoOutputUtils
+{
+
+enum NativePaintMode
+{
+ Default,
+ ZeroFill,
+ BlitWriteAlpha,
+ Disable
+};
+
+void setIgnoreFocusChanged(QWidget *widget);
+void setNativePaintMode(QWidget *widget, NativePaintMode mode);
+void setNativePaintMode(WId wid, NativePaintMode mode);
+void setReceiveNativePaintEvents(QWidget *widget, bool enabled);
+
+} // namespace S60VideoOutputUtils
+
+#endif // S60VIDEOOUTPUTUTILS_H
+
diff --git a/src/plugins/symbian/videooutput/s60videowidget.cpp b/src/plugins/symbian/videooutput/s60videowidget.cpp
new file mode 100644
index 000000000..44c0919ba
--- /dev/null
+++ b/src/plugins/symbian/videooutput/s60videowidget.cpp
@@ -0,0 +1,237 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "s60videowidget.h"
+#include "s60videooutpututils.h"
+
+#include <QtCore/QVariant>
+#include <QtCore/QEvent>
+#include <QtGui/QApplication>
+#include <QtGui/QPainter>
+
+#include <coemain.h> // CCoeEnv
+#include <coecntrl.h> // CCoeControl
+#include <w32std.h>
+
+using namespace S60VideoOutputUtils;
+
+const int NullOrdinalPosition = -1;
+
+S60VideoWidget::S60VideoWidget(QWidget *parent)
+: QWidget(parent)
+, m_pixmap(NULL)
+, m_paintingEnabled(false)
+, m_topWinId(0)
+, m_ordinalPosition(NullOrdinalPosition)
+{
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ setPalette(QPalette(Qt::black));
+ setAutoFillBackground(false);
+ if (!parent)
+ setProperty("_q_DummyWindowSurface", true);
+ S60VideoOutputUtils::setIgnoreFocusChanged(this);
+}
+
+S60VideoWidget::~S60VideoWidget()
+{
+
+}
+
+bool S60VideoWidget::event(QEvent *event)
+{
+ if (event->type() == QEvent::WinIdChange)
+ updateOrdinalPosition();
+ return QWidget::event(event);
+}
+
+void S60VideoWidget::paintEvent(QPaintEvent *event)
+{
+ if (m_paintingEnabled && m_pixmap) {
+ QPainter painter(this);
+ if (m_pixmap->size() != m_contentRect.size())
+ qWarning("pixmap size does not match expected value");
+ painter.drawPixmap(m_contentRect.topLeft(), *m_pixmap);
+ }
+}
+
+void S60VideoWidget::setVisible(bool visible)
+{
+ queueReactivateWindow();
+ QWidget::setVisible(visible);
+}
+
+
+WId S60VideoWidget::videoWinId() const
+{
+ WId wid = 0;
+ if (internalWinId())
+ wid = internalWinId();
+ else if (parentWidget() && effectiveWinId())
+ wid = effectiveWinId();
+ return wid;
+}
+
+void S60VideoWidget::setPixmap(const QPixmap *pixmap)
+{
+ m_pixmap = pixmap;
+ update();
+}
+
+void S60VideoWidget::setContentRect(const QRect &rect)
+{
+ if (m_contentRect != rect) {
+ m_contentRect = rect;
+ update();
+ }
+}
+
+void S60VideoWidget::setWindowBackgroundColor()
+{
+ if (WId wid = internalWinId())
+ static_cast<RWindow *>(wid->DrawableWindow())->SetBackgroundColor(TRgb(0, 0, 0, 255));
+}
+
+WId S60VideoWidget::topWinId() const
+{
+ return m_topWinId;
+}
+
+void S60VideoWidget::setTopWinId(WId id)
+{
+ m_topWinId = id;
+ updateOrdinalPosition();
+#ifdef VIDEOOUTPUT_GRAPHICS_SURFACES
+ // This function may be called from a paint event, so defer any window
+ // manipulation until painting is complete.
+ QMetaObject::invokeMethod(this, "setWindowsNonFading", Qt::QueuedConnection);
+#endif
+}
+
+void S60VideoWidget::setOrdinalPosition(int ordinalPosition)
+{
+ m_ordinalPosition = ordinalPosition;
+ updateOrdinalPosition();
+}
+
+int S60VideoWidget::ordinalPosition() const
+{
+ return m_ordinalPosition;
+}
+
+void S60VideoWidget::updateOrdinalPosition()
+{
+ if ((m_ordinalPosition != NullOrdinalPosition) && m_topWinId) {
+ if (WId wid = videoWinId()) {
+ int topOrdinalPosition = m_topWinId->DrawableWindow()->OrdinalPosition();
+ queueReactivateWindow();
+ wid->DrawableWindow()->SetOrdinalPosition(m_ordinalPosition + topOrdinalPosition);
+ }
+ }
+}
+
+void S60VideoWidget::queueReactivateWindow()
+{
+ if (!parent()) {
+ if (QWidget *activeWindow = QApplication::activeWindow())
+ QMetaObject::invokeMethod(this, "reactivateWindow", Qt::QueuedConnection,
+ Q_ARG(QWidget *, activeWindow));
+ }
+}
+
+void S60VideoWidget::reactivateWindow(QWidget *widget)
+{
+ widget->activateWindow();
+}
+
+void S60VideoWidget::setWindowsNonFading()
+{
+ winId()->DrawableWindow()->SetNonFading(ETrue);
+ if (m_topWinId)
+ m_topWinId->DrawableWindow()->SetNonFading(ETrue);
+}
+
+void S60VideoWidget::beginNativePaintEvent(const QRect &rect)
+{
+ Q_UNUSED(rect)
+ emit beginVideoWidgetNativePaint();
+}
+
+void S60VideoWidget::endNativePaintEvent(const QRect &rect)
+{
+ Q_UNUSED(rect)
+ CCoeEnv::Static()->WsSession().Flush();
+ emit endVideoWidgetNativePaint();
+}
+
+void S60VideoWidget::setPaintingEnabled(bool enabled)
+{
+ if (enabled) {
+#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES
+ setAttribute(Qt::WA_OpaquePaintEvent, false);
+ setAttribute(Qt::WA_NoSystemBackground, false);
+ S60VideoOutputUtils::setReceiveNativePaintEvents(this, false);
+ S60VideoOutputUtils::setNativePaintMode(this, Default);
+#else
+ S60VideoOutputUtils::setNativePaintMode(this, Default);
+#endif // !VIDEOOUTPUT_GRAPHICS_SURFACES
+ } else {
+#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES
+ setAttribute(Qt::WA_OpaquePaintEvent, true);
+ setAttribute(Qt::WA_NoSystemBackground, true);
+ S60VideoOutputUtils::setReceiveNativePaintEvents(this, true);
+ S60VideoOutputUtils::setNativePaintMode(this, ZeroFill);
+#else
+ S60VideoOutputUtils::setNativePaintMode(this, Disable);
+#endif // !VIDEOOUTPUT_GRAPHICS_SURFACES
+ winId(); // Create native window handle
+ }
+ m_paintingEnabled = enabled;
+ setWindowBackgroundColor();
+}
+
+void S60VideoWidget::setFullScreen(bool enabled)
+{
+ if (enabled)
+ showFullScreen();
+ else
+ showMaximized();
+}
+
diff --git a/src/plugins/symbian/videooutput/s60videowidget.h b/src/plugins/symbian/videooutput/s60videowidget.h
new file mode 100644
index 000000000..30e7a3bd0
--- /dev/null
+++ b/src/plugins/symbian/videooutput/s60videowidget.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEOWIDGET_H
+#define S60VIDEOWIDGET_H
+
+#include <QtGui/QWidget>
+
+QT_USE_NAMESPACE
+
+class S60VideoWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ S60VideoWidget(QWidget *parent = 0);
+ ~S60VideoWidget();
+
+ // QWidget
+ bool event(QEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void setVisible(bool visible);
+
+ WId videoWinId() const;
+ void setPixmap(const QPixmap *pixmap);
+ void setWindowBackgroundColor();
+ void setTopWinId(WId id);
+ WId topWinId() const;
+ void setOrdinalPosition(int ordinalPosition);
+ int ordinalPosition() const;
+
+public slots:
+ void beginNativePaintEvent(const QRect &rect);
+ void endNativePaintEvent(const QRect &rect);
+ void setPaintingEnabled(bool enabled);
+ void setFullScreen(bool enabled);
+ void setContentRect(const QRect &rect);
+
+signals:
+ void beginVideoWidgetNativePaint();
+ void endVideoWidgetNativePaint();
+
+private:
+ void updateOrdinalPosition();
+ void queueReactivateWindow();
+
+private slots:
+ void reactivateWindow(QWidget *window);
+ void setWindowsNonFading();
+
+private:
+ const QPixmap *m_pixmap;
+ QRect m_contentRect;
+ bool m_paintingEnabled;
+ WId m_topWinId;
+ int m_ordinalPosition;
+};
+
+#endif // S60VIDEOWIDGET_H
+
diff --git a/src/plugins/symbian/videooutput/s60videowidgetcontrol.cpp b/src/plugins/symbian/videooutput/s60videowidgetcontrol.cpp
new file mode 100644
index 000000000..46cb2963e
--- /dev/null
+++ b/src/plugins/symbian/videooutput/s60videowidgetcontrol.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "s60videowidgetcontrol.h"
+#include "s60videowidgetdisplay.h"
+
+S60VideoWidgetControl::S60VideoWidgetControl(QObject *parent)
+: QVideoWidgetControl(parent)
+, m_display(new S60VideoWidgetDisplay(this))
+{
+ connect(m_display, SIGNAL(nativeSizeChanged(QSize)),
+ this, SIGNAL(nativeSizeChanged()));
+}
+
+S60VideoWidgetControl::~S60VideoWidgetControl()
+{
+
+}
+
+QWidget *S60VideoWidgetControl::videoWidget()
+{
+ return m_display->widget();
+}
+
+Qt::AspectRatioMode S60VideoWidgetControl::aspectRatioMode() const
+{
+ return m_display->aspectRatioMode();
+}
+
+void S60VideoWidgetControl::setAspectRatioMode(Qt::AspectRatioMode ratio)
+{
+ m_display->setAspectRatioMode(ratio);
+}
+
+bool S60VideoWidgetControl::isFullScreen() const
+{
+ return m_display->isFullScreen();
+}
+
+void S60VideoWidgetControl::setFullScreen(bool fullScreen)
+{
+ m_display->setFullScreen(fullScreen);
+}
+
+int S60VideoWidgetControl::brightness() const
+{
+ return 0;
+}
+
+void S60VideoWidgetControl::setBrightness(int brightness)
+{
+ Q_UNUSED(brightness);
+}
+
+int S60VideoWidgetControl::contrast() const
+{
+ return 0;
+}
+
+void S60VideoWidgetControl::setContrast(int contrast)
+{
+ Q_UNUSED(contrast);
+}
+
+int S60VideoWidgetControl::hue() const
+{
+ return 0;
+}
+
+void S60VideoWidgetControl::setHue(int hue)
+{
+ Q_UNUSED(hue);
+}
+
+int S60VideoWidgetControl::saturation() const
+{
+ return 0;
+}
+
+void S60VideoWidgetControl::setSaturation(int saturation)
+{
+ Q_UNUSED(saturation);
+}
+
+S60VideoWidgetDisplay *S60VideoWidgetControl::display() const
+{
+ return m_display;
+}
+
+void S60VideoWidgetControl::setTopWinId(WId id)
+{
+ m_display->setTopWinId(id);
+}
+
+WId S60VideoWidgetControl::topWinId() const
+{
+ return m_display->topWinId();
+}
+
+int S60VideoWidgetControl::ordinalPosition() const
+{
+ return m_display->ordinalPosition();
+}
+
+void S60VideoWidgetControl::setOrdinalPosition(int ordinalPosition)
+{
+ m_display->setOrdinalPosition(ordinalPosition);
+}
+
+const QRect &S60VideoWidgetControl::extentRect() const
+{
+ return m_display->explicitExtentRect();
+}
+
+void S60VideoWidgetControl::setExtentRect(const QRect &rect)
+{
+ m_display->setExplicitExtentRect(rect);
+}
+
+QSize S60VideoWidgetControl::nativeSize() const
+{
+ return m_display->nativeSize();
+}
+
+qreal S60VideoWidgetControl::rotation() const
+{
+ return m_display->rotation();
+}
+
+void S60VideoWidgetControl::setRotation(qreal value)
+{
+ m_display->setRotation(value);
+}
diff --git a/src/plugins/symbian/videooutput/s60videowidgetcontrol.h b/src/plugins/symbian/videooutput/s60videowidgetcontrol.h
new file mode 100644
index 000000000..eb103b6b8
--- /dev/null
+++ b/src/plugins/symbian/videooutput/s60videowidgetcontrol.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEOWIDGETCONTROL_H
+#define S60VIDEOWIDGETCONTROL_H
+
+#include <qvideowidgetcontrol.h>
+
+QT_USE_NAMESPACE
+
+class S60VideoWidgetDisplay;
+
+class S60VideoWidgetControl : public QVideoWidgetControl
+{
+ Q_OBJECT
+
+ /**
+ * WId of the topmost window in the application, used to calculate the
+ * absolute ordinal position of the video widget.
+ * This is used by the "window" implementation of QGraphicsVideoItem.
+ */
+ Q_PROPERTY(WId topWinId READ topWinId WRITE setTopWinId)
+
+ /**
+ * Ordinal position of the video widget, relative to the topmost window
+ * in the application. If both the topWinId property and the ordinalPosition
+ * property are set, the absolute ordinal position of the video widget is
+ * the sum of the topWinId ordinal position and the value of the
+ * ordinalPosition property.
+ * This is used by the "window" implementation of QGraphicsVideoItem.
+ */
+ Q_PROPERTY(int ordinalPosition READ ordinalPosition WRITE setOrdinalPosition)
+
+ /**
+ * Extent of the video, relative to this video widget.
+ * This is used by the "window" implementation of QGraphicsVideoItem.
+ */
+ Q_PROPERTY(QRect extentRect READ extentRect WRITE setExtentRect)
+
+ /**
+ * Native size of video.
+ * This is used by the "window" implementation of QGraphicsVideoItem.
+ */
+ Q_PROPERTY(QSize nativeSize READ nativeSize)
+
+ /**
+ * Rotation to be applied to video.
+ * Angle is measured in degrees, with positive values counter-clockwise.
+ * Zero is at 12 o'clock.
+ */
+ Q_PROPERTY(qreal rotation READ rotation WRITE setRotation)
+
+public:
+ S60VideoWidgetControl(QObject *parent);
+ ~S60VideoWidgetControl();
+
+public:
+ // QVideoWidgetControl
+ QWidget *videoWidget();
+ Qt::AspectRatioMode aspectRatioMode() const;
+ void setAspectRatioMode(Qt::AspectRatioMode ratio);
+ bool isFullScreen() const;
+ void setFullScreen(bool fullScreen);
+ int brightness() const;
+ void setBrightness(int brightness);
+ int contrast() const;
+ void setContrast(int contrast);
+ int hue() const;
+ void setHue(int hue);
+ int saturation() const;
+ void setSaturation(int saturation);
+
+ S60VideoWidgetDisplay *display() const;
+
+ WId topWinId() const;
+ void setTopWinId(WId id);
+ int ordinalPosition() const;
+ void setOrdinalPosition(int ordinalPosition);
+ const QRect &extentRect() const;
+ void setExtentRect(const QRect &rect);
+ QSize nativeSize() const;
+ qreal rotation() const;
+ void setRotation(qreal value);
+
+signals:
+ void nativeSizeChanged();
+
+private:
+ S60VideoWidgetDisplay *m_display;
+};
+
+#endif // S60VIDEOWIDGETCONTROL_H
+
diff --git a/src/plugins/symbian/videooutput/s60videowidgetdisplay.cpp b/src/plugins/symbian/videooutput/s60videowidgetdisplay.cpp
new file mode 100644
index 000000000..de7440dbf
--- /dev/null
+++ b/src/plugins/symbian/videooutput/s60videowidgetdisplay.cpp
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "s60videowidget.h"
+#include "s60videowidgetdisplay.h"
+#include <QtCore/QEvent>
+#include <QtCore/QVariant>
+#include <fbs.h>
+#include <w32std.h>
+
+S60VideoWidgetDisplay::S60VideoWidgetDisplay(QObject *parent)
+: S60VideoDisplay(parent)
+, m_widget(new S60VideoWidget)
+{
+ connect(this, SIGNAL(paintingEnabledChanged(bool)), m_widget, SLOT(setPaintingEnabled(bool)));
+ connect(this, SIGNAL(fullScreenChanged(bool)), m_widget, SLOT(setFullScreen(bool)));
+ connect(this, SIGNAL(contentRectChanged(const QRect&)), m_widget, SLOT(setContentRect(const QRect &)));
+#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES
+ connect(m_widget, SIGNAL(beginVideoWidgetNativePaint()), this, SIGNAL(beginVideoWindowNativePaint()));
+ connect(m_widget, SIGNAL(endVideoWidgetNativePaint()), this, SIGNAL(endVideoWindowNativePaint()));
+#endif
+ m_widget->installEventFilter(this);
+ m_widget->setPaintingEnabled(false);
+}
+
+S60VideoWidgetDisplay::~S60VideoWidgetDisplay()
+{
+ // Notify observers that window is about to be destroyed
+ QScopedPointer<QWidget> widget(m_widget);
+ m_widget = 0;
+ emit windowHandleChanged(windowHandle());
+ // Widget will be deleted by QScopedPointer
+}
+
+bool S60VideoWidgetDisplay::eventFilter(QObject *object, QEvent *e)
+{
+ if (object == m_widget) {
+ switch (e->type()) {
+ case QEvent::ParentChange:
+ if (QWidget *parent = m_widget->parentWidget())
+ parent->setProperty("_q_DummyWindowSurface", true);
+ break;
+ case QEvent::WinIdChange:
+ m_widget->setWindowBackgroundColor();
+ emit windowHandleChanged(windowHandle());
+ break;
+ case QEvent::Resize:
+ emit displayRectChanged(extentRect(), clipRect());
+ break;
+#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES
+ case QEvent::Move:
+ // TODO: this is insufficient - we also need to respond to changes in
+ // the position of ancestor widgets
+ emit displayRectChanged(extentRect(), clipRect());
+ break;
+#endif
+ case QEvent::Show:
+ emit windowHandleChanged(windowHandle());
+ emit visibilityChanged(true);
+ break;
+ case QEvent::Hide:
+ emit visibilityChanged(false);
+ break;
+ default:
+ // Do nothing
+ break;
+ }
+ }
+ return false;
+}
+
+WId S60VideoWidgetDisplay::winId() const
+{
+ return m_widget ? m_widget->videoWinId() : 0;
+}
+
+QRect S60VideoWidgetDisplay::extentRect() const
+{
+ QRect rect;
+ if (const RWindow *window = windowHandle()) {
+ const TSize size = window ? window->Size() : TSize();
+ if (m_explicitExtentRect.isValid())
+ rect = m_explicitExtentRect;
+ else
+ rect = QRect(0, 0, size.iWidth, size.iHeight);
+#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES
+ const TPoint pos = window ? window->AbsPosition() : TPoint();
+ rect.moveTopLeft(QPoint(pos.iX, pos.iY));
+#endif
+ }
+ return rect;
+}
+
+void S60VideoWidgetDisplay::setFrame(const CFbsBitmap &bitmap)
+{
+ m_pixmap = QPixmap::fromSymbianCFbsBitmap(const_cast<CFbsBitmap*>(&bitmap));
+ m_widget->setPixmap(&m_pixmap);
+}
+
+QWidget *S60VideoWidgetDisplay::widget() const
+{
+ return m_widget;
+}
+
+void S60VideoWidgetDisplay::setTopWinId(WId id)
+{
+ m_widget->setTopWinId(id);
+}
+
+WId S60VideoWidgetDisplay::topWinId() const
+{
+ return m_widget->topWinId();
+}
+
+void S60VideoWidgetDisplay::setOrdinalPosition(int ordinalPosition)
+{
+ m_widget->setOrdinalPosition(ordinalPosition);
+}
+
+int S60VideoWidgetDisplay::ordinalPosition() const
+{
+ return m_widget->ordinalPosition();
+}
+
+const QRect &S60VideoWidgetDisplay::explicitExtentRect() const
+{
+ return m_explicitExtentRect;
+}
+
+void S60VideoWidgetDisplay::setExplicitExtentRect(const QRect &rect)
+{
+ if (rect != m_explicitExtentRect) {
+ m_explicitExtentRect = rect;
+ emit displayRectChanged(extentRect(), clipRect());
+ }
+}
diff --git a/src/plugins/symbian/videooutput/s60videowidgetdisplay.h b/src/plugins/symbian/videooutput/s60videowidgetdisplay.h
new file mode 100644
index 000000000..d3d92d953
--- /dev/null
+++ b/src/plugins/symbian/videooutput/s60videowidgetdisplay.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEOWIDGETDISPLAY_H
+#define S60VIDEOWIDGETDISPLAY_H
+
+#include "s60videodisplay.h"
+#include <QtGui/qwindowdefs.h>
+#include <QtGui/QPixmap>
+
+class CFbsBitmap;
+class S60VideoWidget;
+class QWidget;
+
+QT_USE_NAMESPACE
+
+class S60VideoWidgetDisplay : public S60VideoDisplay
+{
+ Q_OBJECT
+public:
+ S60VideoWidgetDisplay(QObject *parent);
+ ~S60VideoWidgetDisplay();
+
+ // QObject
+ bool eventFilter(QObject *object, QEvent *e);
+
+ // S60VideoDisplay
+ WId winId() const;
+ QRect extentRect() const;
+ void setFrame(const CFbsBitmap &bitmap);
+
+ QWidget *widget() const;
+ WId topWinId() const;
+ void setTopWinId(WId id);
+ void setOrdinalPosition(int ordinalPosition);
+ int ordinalPosition() const;
+ const QRect &explicitExtentRect() const;
+ void setExplicitExtentRect(const QRect &rect);
+
+private:
+ S60VideoWidget *m_widget;
+ QPixmap m_pixmap;
+ QRect m_explicitExtentRect;
+};
+
+#endif // S60VIDEOWIDGETDISPLAY_H
+
diff --git a/src/plugins/symbian/videooutput/s60videowindowcontrol.cpp b/src/plugins/symbian/videooutput/s60videowindowcontrol.cpp
new file mode 100644
index 000000000..db33a5f32
--- /dev/null
+++ b/src/plugins/symbian/videooutput/s60videowindowcontrol.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "s60videowindowcontrol.h"
+#include "s60videowindowdisplay.h"
+
+S60VideoWindowControl::S60VideoWindowControl(QObject *parent)
+: QVideoWindowControl(parent)
+, m_display(new S60VideoWindowDisplay(this))
+{
+ connect(m_display, SIGNAL(nativeSizeChanged(QSize)),
+ this, SIGNAL(nativeSizeChanged()));
+ connect(m_display, SIGNAL(fullScreenChanged(bool)),
+ this, SIGNAL(fullScreenChanged(bool)));
+}
+
+S60VideoWindowControl::~S60VideoWindowControl()
+{
+
+}
+
+WId S60VideoWindowControl::winId() const
+{
+ return m_display->winId();
+}
+
+void S60VideoWindowControl::setWinId(WId id)
+{
+ m_display->setWinId(id);
+}
+
+QRect S60VideoWindowControl::displayRect() const
+{
+ return m_display->displayRect();
+}
+
+void S60VideoWindowControl::setDisplayRect(const QRect &rect)
+{
+ m_display->setDisplayRect(rect);
+}
+
+Qt::AspectRatioMode S60VideoWindowControl::aspectRatioMode() const
+{
+ return m_display->aspectRatioMode();
+}
+
+void S60VideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode ratio)
+{
+ m_display->setAspectRatioMode(ratio);
+}
+
+QSize S60VideoWindowControl::customAspectRatio() const
+{
+ return QSize();
+}
+
+void S60VideoWindowControl::setCustomAspectRatio(const QSize &customRatio)
+{
+ Q_UNUSED(customRatio);
+}
+
+void S60VideoWindowControl::repaint()
+{
+ m_display->repaint();
+}
+
+int S60VideoWindowControl::brightness() const
+{
+ return 0;
+}
+
+void S60VideoWindowControl::setBrightness(int brightness)
+{
+ Q_UNUSED(brightness)
+}
+
+int S60VideoWindowControl::contrast() const
+{
+ return 0;
+}
+
+void S60VideoWindowControl::setContrast(int contrast)
+{
+ Q_UNUSED(contrast)
+}
+
+int S60VideoWindowControl::hue() const
+{
+ return 0;
+}
+
+void S60VideoWindowControl::setHue(int hue)
+{
+ Q_UNUSED(hue)
+}
+
+int S60VideoWindowControl::saturation() const
+{
+ return 0;
+}
+
+void S60VideoWindowControl::setSaturation(int saturation)
+{
+ Q_UNUSED(saturation)
+}
+
+bool S60VideoWindowControl::isFullScreen() const
+{
+ return m_display->isFullScreen();
+}
+
+void S60VideoWindowControl::setFullScreen(bool fullScreen)
+{
+ m_display->setFullScreen(fullScreen);
+}
+
+QSize S60VideoWindowControl::nativeSize() const
+{
+ return m_display->nativeSize();
+}
+
+void S60VideoWindowControl::refreshDisplay()
+{
+ m_display->refreshDisplay();
+}
+
+S60VideoWindowDisplay *S60VideoWindowControl::display() const
+{
+ return m_display;
+}
+
+qreal S60VideoWindowControl::rotation() const
+{
+ return m_display->rotation();
+}
+
+void S60VideoWindowControl::setRotation(qreal value)
+{
+ m_display->setRotation(value);
+}
diff --git a/src/plugins/symbian/videooutput/s60videowindowcontrol.h b/src/plugins/symbian/videooutput/s60videowindowcontrol.h
new file mode 100644
index 000000000..a62d29a13
--- /dev/null
+++ b/src/plugins/symbian/videooutput/s60videowindowcontrol.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEOWINDOWCONTROL_H
+#define S60VIDEOWINDOWCONTROL_H
+
+#include <qvideowindowcontrol.h>
+
+class S60VideoWindowDisplay;
+
+QT_USE_NAMESPACE
+
+class S60VideoWindowControl : public QVideoWindowControl
+{
+ Q_OBJECT
+
+ /**
+ * Rotation to be applied to video.
+ * Angle is measured in degrees, with positive values counter-clockwise.
+ * Zero is at 12 o'clock.
+ */
+ Q_PROPERTY(qreal rotation READ rotation WRITE setRotation)
+
+public:
+ S60VideoWindowControl(QObject *parent);
+ ~S60VideoWindowControl();
+
+public:
+ // QVideoWindowControl
+ WId winId() const;
+ void setWinId(WId id);
+ QRect displayRect() const;
+ void setDisplayRect(const QRect &rect);
+ bool isFullScreen() const;
+ void setFullScreen(bool fullScreen);
+ void repaint();
+ QSize nativeSize() const;
+ Qt::AspectRatioMode aspectRatioMode() const;
+ void setAspectRatioMode(Qt::AspectRatioMode mode);
+ QSize customAspectRatio() const;
+ void setCustomAspectRatio(const QSize &customRatio);
+ int brightness() const;
+ void setBrightness(int brightness);
+ int contrast() const;
+ void setContrast(int contrast);
+ int hue() const;
+ void setHue(int hue);
+ int saturation() const;
+ void setSaturation(int saturation);
+
+ S60VideoWindowDisplay *display() const;
+
+ qreal rotation() const;
+ void setRotation(qreal value);
+
+public slots:
+ void refreshDisplay();
+
+private:
+ S60VideoWindowDisplay *m_display;
+};
+
+#endif // S60VIDEOWINDOWCONTROL_H
+
diff --git a/src/plugins/symbian/videooutput/s60videowindowdisplay.cpp b/src/plugins/symbian/videooutput/s60videowindowdisplay.cpp
new file mode 100644
index 000000000..a8bdb8b4a
--- /dev/null
+++ b/src/plugins/symbian/videooutput/s60videowindowdisplay.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "s60videowindowdisplay.h"
+#include "s60videooutpututils.h"
+#include <QtCore/QVariant>
+#include <coecntrl.h>
+#include <w32std.h>
+
+using namespace S60VideoOutputUtils;
+
+S60VideoWindowDisplay::S60VideoWindowDisplay(QObject *parent)
+: S60VideoDisplay(parent)
+, m_winId(0)
+, m_bitmap(0)
+{
+ parent->setProperty("colorKey", Qt::transparent);
+}
+
+S60VideoWindowDisplay::~S60VideoWindowDisplay()
+{
+
+}
+
+WId S60VideoWindowDisplay::winId() const
+{
+ return m_winId;
+}
+
+QRect S60VideoWindowDisplay::extentRect() const
+{
+ QRect rect = displayRect();
+#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES
+ if (RWindow *window = windowHandle()) {
+ const TPoint windowPos = window->AbsPosition();
+ rect.translate(windowPos.iX, windowPos.iY);
+ }
+#endif // VIDEOOUTPUT_GRAPHICS_SURFACES
+ return rect;
+}
+
+void S60VideoWindowDisplay::setFrame(const CFbsBitmap &bitmap)
+{
+ m_bitmap = const_cast<CFbsBitmap*>(&bitmap);
+ if (m_winId) {
+ // Blit the bitmap into the native window owned by m_winId
+ CWindowGc &gc = m_winId->SystemGc();
+ RWindow *window = windowHandle();
+ gc.Activate(*window);
+ const QPoint offsetQ = displayRect().topLeft() + contentRect().topLeft();
+ const TPoint offsetT(offsetQ.x(), offsetQ.y());
+ const TRect winRect(offsetT, m_bitmap->SizeInPixels());
+ window->BeginRedraw(winRect);
+ gc.BitBlt(offsetT, m_bitmap);
+ window->EndRedraw();
+ gc.Deactivate();
+ }
+}
+
+void S60VideoWindowDisplay::setWinId(WId id)
+{
+ if (m_winId != id) {
+ m_winId = id;
+ if (m_winId) {
+ static_cast<RWindow *>(m_winId->DrawableWindow())->SetBackgroundColor(TRgb(0, 0, 0, 0));
+#ifndef VIDEOOUTPUT_GRAPHICS_SURFACES
+ if (QSysInfo::s60Version() >= QSysInfo::SV_S60_5_0)
+ S60VideoOutputUtils::setNativePaintMode(m_winId, BlitWriteAlpha);
+#endif // !VIDEOOUTPUT_GRAPHICS_SURFACES
+ }
+ emit windowHandleChanged(windowHandle());
+ }
+}
+
+void S60VideoWindowDisplay::setDisplayRect(const QRect &rect)
+{
+ if (m_displayRect != rect) {
+ // If QGraphicsVideoItem moves out of screen, display rect is invalidated
+ if (rect == QRect(QPoint(-1,-1), QSize(1,1)))
+ emit visibilityChanged(false);
+ else
+ emit visibilityChanged(true);
+ m_displayRect = rect;
+ emit displayRectChanged(extentRect(), clipRect());
+ }
+}
+
+QRect S60VideoWindowDisplay::displayRect() const
+{
+ return m_displayRect;
+}
+
+void S60VideoWindowDisplay::repaint()
+{
+ // TODO
+}
+
+void S60VideoWindowDisplay::refreshDisplay()
+{
+ emit displayRectChanged(extentRect(), clipRect());
+}
+
diff --git a/src/plugins/symbian/videooutput/s60videowindowdisplay.h b/src/plugins/symbian/videooutput/s60videowindowdisplay.h
new file mode 100644
index 000000000..8e749dcf3
--- /dev/null
+++ b/src/plugins/symbian/videooutput/s60videowindowdisplay.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef S60VIDEOWINDOWDISPLAY_H
+#define S60VIDEOWINDOWDISPLAY_H
+
+#include "s60videodisplay.h"
+
+QT_USE_NAMESPACE
+
+class S60VideoWindowDisplay : public S60VideoDisplay
+{
+public:
+ S60VideoWindowDisplay(QObject *parent);
+ ~S60VideoWindowDisplay();
+
+ // S60VideoDisplay
+ WId winId() const;
+ QRect extentRect() const;
+ void setFrame(const CFbsBitmap &bitmap);
+
+ void setWinId(WId id);
+ void setDisplayRect(const QRect &rect);
+ QRect displayRect() const;
+ void repaint();
+ void refreshDisplay();
+
+private:
+ WId m_winId;
+ QRect m_displayRect;
+ CFbsBitmap *m_bitmap;
+};
+
+#endif // S60VIDEOWINDOWDISPLAY_H
+
diff --git a/src/plugins/symbian/videooutput/videooutput.pri b/src/plugins/symbian/videooutput/videooutput.pri
new file mode 100644
index 000000000..13aa7a0fc
--- /dev/null
+++ b/src/plugins/symbian/videooutput/videooutput.pri
@@ -0,0 +1,37 @@
+INCLUDEPATH += $$PWD
+
+message("VideoOutput: using common implementation")
+
+contains(surfaces_s60_enabled, yes) {
+ message("VideoOutput: graphics surface rendering supported")
+ DEFINES += VIDEOOUTPUT_GRAPHICS_SURFACES
+} else {
+ message("VideoOutput: no graphics surface rendering support - DSA only")
+}
+
+exists($$[QT_INSTALL_HEADERS]/QtGui/private/qwidget_p.h) {
+ DEFINES += PRIVATE_QTGUI_HEADERS_AVAILABLE
+ message("VideoOutput: private QtGui headers are available")
+} else {
+ message("VideoOutput: private QtGui headers not available - video and viewfinder may not be rendered correctly")
+}
+
+HEADERS += $$PWD/s60videodisplay.h \
+ $$PWD/s60videooutpututils.h \
+ $$PWD/s60videowidget.h \
+ $$PWD/s60videowidgetcontrol.h \
+ $$PWD/s60videowidgetdisplay.h \
+ $$PWD/s60videowindowcontrol.h \
+ $$PWD/s60videowindowdisplay.h
+
+SOURCES += $$PWD/s60videodisplay.cpp \
+ $$PWD/s60videooutpututils.cpp \
+ $$PWD/s60videowidget.cpp \
+ $$PWD/s60videowidgetcontrol.cpp \
+ $$PWD/s60videowidgetdisplay.cpp \
+ $$PWD/s60videowindowcontrol.cpp \
+ $$PWD/s60videowindowdisplay.cpp
+
+LIBS *= -lcone
+LIBS *= -lws32
+