summaryrefslogtreecommitdiffstats
path: root/src/plugins/symbian/ecam/s60videocapturesession.h
blob: cfa101f57af15e0c65cf59769f7f91387fa7d95e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
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