Added QMediaRecorder::status property

QMediaRecorder::state property represents the user request and
changed synchronously during record(), pause() or stop() calls.

Recorder status is changed asynchronously
and represents the actual status of media recorder.

This also makes API more consistent with QMediaPlayer and QCamera.

Change-Id: I80b4aaa70bb88e555c492908da8c29d0fc5ed5ea
Reviewed-by: Ling Hu <ling.hu@nokia.com>
This commit is contained in:
Dmytro Poplavskiy
2012-05-01 13:10:33 +10:00
committed by Qt by Nokia
parent af932e8653
commit b7935a84d7
12 changed files with 324 additions and 37 deletions

View File

@@ -81,6 +81,8 @@ QDeclarativeCameraRecorder::QDeclarativeCameraRecorder(QCamera *camera, QObject
m_recorder = new QMediaRecorder(camera, this);
connect(m_recorder, SIGNAL(stateChanged(QMediaRecorder::State)),
SLOT(updateRecorderState(QMediaRecorder::State)));
connect(m_recorder, SIGNAL(statusChanged(QMediaRecorder::Status)),
SIGNAL(recorderStatusChanged()));
connect(m_recorder, SIGNAL(error(QMediaRecorder::Error)),
SLOT(updateRecorderError(QMediaRecorder::Error)));
connect(m_recorder, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool)));
@@ -383,6 +385,38 @@ QDeclarativeCameraRecorder::RecorderState QDeclarativeCameraRecorder::recorderSt
return RecorderState(state);
}
/*!
\qmlproperty enumeration QtMultimedia5::CameraRecorder::recorderStatus
The actual current status of media recording.
\table
\header \li Value \li Description
\row \li UnavailableStatus
\li Recording is not supported by the camera.
\row \li UnloadedStatus
\li The recorder is available but not loaded.
\row \li LoadingStatus
\li The recorder is initializing.
\row \li LoadedStatus
\li The recorder is initialized and ready to record media.
\row \li StartingStatus
\li Recording is requested but not active yet.
\row \li RecordingStatus
\li Recording is active.
\row \li PausedStatus
\li Recording is paused.
\row \li FinalizingStatus
\li Recording is stopped with media being finalized.
\endtable
*/
QDeclarativeCameraRecorder::RecorderStatus QDeclarativeCameraRecorder::recorderStatus() const
{
return RecorderStatus(m_recorder->status());
}
/*!
\qmlmethod QtMultimedia5::CameraRecorder::record()

View File

@@ -67,9 +67,11 @@ class QDeclarativeCameraRecorder : public QObject
{
Q_OBJECT
Q_ENUMS(RecorderState)
Q_ENUMS(RecorderStatus)
Q_ENUMS(EncodingMode)
Q_PROPERTY(RecorderState recorderState READ recorderState WRITE setRecorderState NOTIFY recorderStateChanged)
Q_PROPERTY(RecorderStatus recorderStatus READ recorderStatus NOTIFY recorderStatusChanged)
Q_PROPERTY(QString videoCodec READ videoCodec WRITE setVideoCodec NOTIFY videoCodecChanged)
Q_PROPERTY(QSize resolution READ captureResolution WRITE setCaptureResolution NOTIFY captureResolutionChanged)
@@ -98,6 +100,18 @@ public:
RecordingState = QMediaRecorder::RecordingState
};
enum RecorderStatus
{
UnavailableStatus = QMediaRecorder::UnavailableStatus,
UnloadedStatus = QMediaRecorder::UnloadedStatus,
LoadingStatus = QMediaRecorder::LoadingStatus,
LoadedStatus = QMediaRecorder::LoadedStatus,
StartingStatus = QMediaRecorder::StartingStatus,
RecordingStatus = QMediaRecorder::RecordingStatus,
PausedStatus = QMediaRecorder::PausedStatus,
FinalizingStatus = QMediaRecorder::FinalizingStatus
};
enum EncodingMode
{
ConstantQualityEncoding = QtMultimedia::ConstantQualityEncoding,
@@ -108,6 +122,7 @@ public:
~QDeclarativeCameraRecorder();
RecorderState recorderState() const;
RecorderStatus recorderStatus() const;
QSize captureResolution();
@@ -159,6 +174,7 @@ public Q_SLOTS:
Q_SIGNALS:
void recorderStateChanged(QDeclarativeCameraRecorder::RecorderState state);
void recorderStatusChanged();
void durationChanged(qint64 duration);
void mutedChanged(bool muted);
void outputLocationChanged(const QString &location);

View File

@@ -117,11 +117,17 @@ QMediaRecorderControl::~QMediaRecorderControl()
*/
/*!
\fn int QMediaRecorderControl::state() const
\fn QMediaRecorder::State QMediaRecorderControl::state() const
Return the current recording state.
*/
/*!
\fn QMediaRecorder::Status QMediaRecorderControl::status() const
Return the current recording status.
*/
/*!
\fn qint64 QMediaRecorderControl::duration() const
@@ -172,6 +178,13 @@ QMediaRecorderControl::~QMediaRecorderControl()
Signals that the \a state of a media recorder has changed.
*/
/*!
\fn void QMediaRecorderControl::statusChanged(QMediaRecorder::Status status)
Signals that the \a status of a media recorder has changed.
*/
/*!
\fn void QMediaRecorderControl::durationChanged(qint64 duration)

View File

@@ -67,6 +67,7 @@ public:
virtual bool setOutputLocation(const QUrl &location) = 0;
virtual QMediaRecorder::State state() const = 0;
virtual QMediaRecorder::Status status() const = 0;
virtual qint64 duration() const = 0;
@@ -76,6 +77,7 @@ public:
Q_SIGNALS:
void stateChanged(QMediaRecorder::State state);
void statusChanged(QMediaRecorder::Status status);
void durationChanged(qint64 position);
void mutedChanged(bool muted);
void actualLocationChanged(const QUrl &location);

View File

@@ -88,6 +88,7 @@ public:
MediaRecorderRegisterMetaTypes()
{
qRegisterMetaType<QMediaRecorder::State>("QMediaRecorder::State");
qRegisterMetaType<QMediaRecorder::State>("QMediaRecorder::Status");
qRegisterMetaType<QMediaRecorder::Error>("QMediaRecorder::Error");
}
} _registerRecorderMetaTypes;
@@ -278,6 +279,9 @@ bool QMediaRecorder::setMediaObject(QMediaObject *object)
disconnect(d->control, SIGNAL(stateChanged(QMediaRecorder::State)),
this, SLOT(_q_stateChanged(QMediaRecorder::State)));
disconnect(d->control, SIGNAL(statusChanged(QMediaRecorder::Status)),
this, SIGNAL(statusChanged(QMediaRecorder::Status)));
disconnect(d->control, SIGNAL(mutedChanged(bool)),
this, SIGNAL(mutedChanged(bool)));
@@ -378,6 +382,9 @@ bool QMediaRecorder::setMediaObject(QMediaObject *object)
connect(d->control, SIGNAL(stateChanged(QMediaRecorder::State)),
this, SLOT(_q_stateChanged(QMediaRecorder::State)));
connect(d->control, SIGNAL(statusChanged(QMediaRecorder::Status)),
this, SIGNAL(statusChanged(QMediaRecorder::Status)));
connect(d->control, SIGNAL(mutedChanged(bool)),
this, SIGNAL(mutedChanged(bool)));
@@ -482,6 +489,17 @@ QMediaRecorder::State QMediaRecorder::state() const
return d_func()->control ? QMediaRecorder::State(d_func()->control->state()) : StoppedState;
}
/*!
Returns the current media recorder status.
\sa QMediaRecorder::Status
*/
QMediaRecorder::Status QMediaRecorder::status() const
{
return d_func()->control ? QMediaRecorder::Status(d_func()->control->status()) : UnavailableStatus;
}
/*!
Returns the current error state.
@@ -801,9 +819,12 @@ void QMediaRecorder::setEncodingSettings(const QAudioEncoderSettings &audio,
/*!
Start recording.
This is an asynchronous call, with signal
stateChanged(QMediaRecorder::RecordingState) being emitted when recording
started, otherwise the error() signal is emitted.
While the recorder state is changed immediately to QMediaRecorder::RecordingState,
recording may start asynchronously, with statusChanged(QMediaRecorder::RecordingStatus)
signal emitted when recording starts.
If recording fails error() signal is emitted
with recorder state being reset back to QMediaRecorder::StoppedState.
*/
void QMediaRecorder::record()
@@ -825,6 +846,11 @@ void QMediaRecorder::record()
/*!
Pause recording.
The recorder state is changed to QMediaRecorder::PausedState.
Depending on platform recording pause may be not supported,
in this case the recorder state stays unchanged.
*/
void QMediaRecorder::pause()
@@ -836,6 +862,8 @@ void QMediaRecorder::pause()
/*!
Stop recording.
The recorder state is changed to QMediaRecorder::StoppedState.
*/
void QMediaRecorder::stop()
@@ -849,10 +877,31 @@ void QMediaRecorder::stop()
\enum QMediaRecorder::State
\value StoppedState The recorder is not active.
\value RecordingState The recorder is currently active and producing data.
\value RecordingState The recording is requested.
\value PausedState The recorder is paused.
*/
/*!
\enum QMediaRecorder::Status
\value UnavailableStatus
The recorder is not available or not supported by connected media object.
\value UnloadedStatus
The recorder is avilable but not loaded.
\value LoadingStatus
The recorder is initializing.
\value LoadedStatus
The recorder is initialized and ready to record media.
\value StartingStatus
Recording is requested but not active yet.
\value RecordingStatus
Recording is active.
\value PausedStatus
Recording is paused.
\value FinalizingStatus
Recording is stopped with media being finalized.
*/
/*!
\enum QMediaRecorder::Error
@@ -861,6 +910,23 @@ void QMediaRecorder::stop()
\value FormatError Current format is not supported.
*/
/*!
\property QMediaRecorder::state
\brief The current state of the media recorder.
The state property represents the user request and is changed synchronously
during record(), pause() or stop() calls.
Recorder state may also change asynchronously when recording fails.
*/
/*!
\property QMediaRecorder::status
\brief The current status of the media recorder.
The status is changed asynchronously and represents the actual status
of media recorder.
*/
/*!
\fn QMediaRecorder::stateChanged(State state)

View File

@@ -73,7 +73,10 @@ class Q_MULTIMEDIA_EXPORT QMediaRecorder : public QObject, public QMediaBindable
Q_OBJECT
Q_INTERFACES(QMediaBindableInterface)
Q_ENUMS(State)
Q_ENUMS(Status)
Q_ENUMS(Error)
Q_PROPERTY(QMediaRecorder::State state READ state NOTIFY stateChanged)
Q_PROPERTY(QMediaRecorder::Status status READ status NOTIFY statusChanged)
Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
Q_PROPERTY(QUrl outputLocation READ outputLocation WRITE setOutputLocation)
Q_PROPERTY(QUrl actualLocation READ actualLocation NOTIFY actualLocationChanged)
@@ -89,6 +92,17 @@ public:
PausedState
};
enum Status {
UnavailableStatus,
UnloadedStatus,
LoadingStatus,
LoadedStatus,
StartingStatus,
RecordingStatus,
PausedStatus,
FinalizingStatus
};
enum Error
{
NoError,
@@ -110,6 +124,7 @@ public:
QUrl actualLocation() const;
State state() const;
Status status() const;
Error error() const;
QString errorString() const;
@@ -163,6 +178,7 @@ public Q_SLOTS:
Q_SIGNALS:
void stateChanged(QMediaRecorder::State state);
void statusChanged(QMediaRecorder::Status status);
void durationChanged(qint64 duration);
void mutedChanged(bool muted);
void actualLocationChanged(const QUrl &location);
@@ -198,9 +214,11 @@ private:
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QMediaRecorder::State)
Q_DECLARE_METATYPE(QMediaRecorder::Status)
Q_DECLARE_METATYPE(QMediaRecorder::Error)
Q_MEDIA_ENUM_DEBUG(QMediaRecorder, State)
Q_MEDIA_ENUM_DEBUG(QMediaRecorder, Status)
Q_MEDIA_ENUM_DEBUG(QMediaRecorder, Error)
QT_END_HEADER

View File

@@ -46,11 +46,13 @@
AudioMediaRecorderControl::AudioMediaRecorderControl(QObject *parent)
:QMediaRecorderControl(parent)
, m_state(QMediaRecorder::StoppedState)
, m_prevStatus(QMediaRecorder::UnloadedStatus)
{
m_session = qobject_cast<AudioCaptureSession*>(parent);
connect(m_session,SIGNAL(positionChanged(qint64)),this,SIGNAL(durationChanged(qint64)));
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(stateChanged(QMediaRecorder::State)), this,SLOT(updateStatus()));
connect(m_session,SIGNAL(error(int,QString)),this,SLOT(handleSessionError(int,QString)));
}
AudioMediaRecorderControl::~AudioMediaRecorderControl()
@@ -72,6 +74,20 @@ QMediaRecorder::State AudioMediaRecorderControl::state() const
return (QMediaRecorder::State)m_session->state();
}
QMediaRecorder::Status AudioMediaRecorderControl::status() const
{
static QMediaRecorder::Status statusTable[3][3] = {
//Stopped recorder state:
{ QMediaRecorder::LoadedStatus, QMediaRecorder::FinalizingStatus, QMediaRecorder::FinalizingStatus },
//Recording recorder state:
{ QMediaRecorder::StartingStatus, QMediaRecorder::RecordingStatus, QMediaRecorder::PausedStatus },
//Paused recorder state:
{ QMediaRecorder::StartingStatus, QMediaRecorder::RecordingStatus, QMediaRecorder::PausedStatus }
};
return statusTable[m_state][m_session->state()];
}
qint64 AudioMediaRecorderControl::duration() const
{
return m_session->position();
@@ -79,17 +95,29 @@ qint64 AudioMediaRecorderControl::duration() const
void AudioMediaRecorderControl::record()
{
m_session->record();
if (m_state != QMediaRecorder::RecordingState) {
m_state = QMediaRecorder::RecordingState;
m_session->record();
updateStatus();
}
}
void AudioMediaRecorderControl::pause()
{
m_session->stop();
if (m_state != QMediaRecorder::PausedState) {
m_state = QMediaRecorder::PausedState;
m_session->pause();
updateStatus();
}
}
void AudioMediaRecorderControl::stop()
{
m_session->stop();
if (m_state != QMediaRecorder::StoppedState) {
m_state = QMediaRecorder::StoppedState;
m_session->pause();
updateStatus();
}
}
bool AudioMediaRecorderControl::isMuted() const
@@ -100,3 +128,18 @@ bool AudioMediaRecorderControl::isMuted() const
void AudioMediaRecorderControl::setMuted(bool)
{
}
void AudioMediaRecorderControl::updateStatus()
{
QMediaRecorder::Status newStatus = status();
if (m_prevStatus != newStatus) {
m_prevStatus = newStatus;
emit statusChanged(m_prevStatus);
}
}
void AudioMediaRecorderControl::handleSessionError(int code, const QString &description)
{
emit error(code, description);
stop();
}

View File

@@ -62,6 +62,7 @@ public:
bool setOutputLocation(const QUrl &sink);
QMediaRecorder::State state() const;
QMediaRecorder::Status status() const;
qint64 duration() const;
@@ -75,8 +76,14 @@ public slots:
void stop();
void setMuted(bool);
private slots:
void updateStatus();
void handleSessionError(int code, const QString &description);
private:
AudioCaptureSession* m_session;
QMediaRecorder::State m_state;
QMediaRecorder::Status m_prevStatus;
};
#endif

View File

@@ -46,10 +46,13 @@
#include <QtCore/QDebug>
QGstreamerRecorderControl::QGstreamerRecorderControl(QGstreamerCaptureSession *session)
:QMediaRecorderControl(session), m_session(session), m_state(QMediaRecorder::StoppedState)
:QMediaRecorderControl(session),
m_session(session),
m_state(QMediaRecorder::StoppedState),
m_status(QMediaRecorder::UnloadedStatus)
{
connect(m_session, SIGNAL(stateChanged(QGstreamerCaptureSession::State)), SLOT(updateState()));
connect(m_session, SIGNAL(error(int,QString)), SIGNAL(error(int,QString)));
connect(m_session, SIGNAL(stateChanged(QGstreamerCaptureSession::State)), SLOT(updateStatus()));
connect(m_session, SIGNAL(error(int,QString)), SLOT(handleSessionError(int,QString)));
connect(m_session, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64)));
connect(m_session, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool)));
m_hasPreviewState = m_session->captureMode() != QGstreamerCaptureSession::Audio;
@@ -74,27 +77,48 @@ bool QGstreamerRecorderControl::setOutputLocation(const QUrl &sink)
QMediaRecorder::State QGstreamerRecorderControl::state() const
{
switch ( m_session->state() ) {
case QGstreamerCaptureSession::RecordingState:
return QMediaRecorder::RecordingState;
case QGstreamerCaptureSession::PausedState:
return QMediaRecorder::PausedState;
case QGstreamerCaptureSession::PreviewState:
case QGstreamerCaptureSession::StoppedState:
return QMediaRecorder::StoppedState;
}
return QMediaRecorder::StoppedState;
return m_state;
}
void QGstreamerRecorderControl::updateState()
QMediaRecorder::Status QGstreamerRecorderControl::status() const
{
QMediaRecorder::State newState = state();
if (m_state != newState) {
m_state = newState;
emit stateChanged(m_state);
static QMediaRecorder::Status statusTable[3][3] = {
//Stopped recorder state:
{ QMediaRecorder::LoadedStatus, QMediaRecorder::FinalizingStatus, QMediaRecorder::FinalizingStatus },
//Recording recorder state:
{ QMediaRecorder::StartingStatus, QMediaRecorder::RecordingStatus, QMediaRecorder::PausedStatus },
//Paused recorder state:
{ QMediaRecorder::StartingStatus, QMediaRecorder::RecordingStatus, QMediaRecorder::PausedStatus }
};
QMediaRecorder::State sessionState = QMediaRecorder::StoppedState;
switch ( m_session->state() ) {
case QGstreamerCaptureSession::RecordingState:
sessionState = QMediaRecorder::RecordingState;
case QGstreamerCaptureSession::PausedState:
sessionState = QMediaRecorder::PausedState;
case QGstreamerCaptureSession::PreviewState:
case QGstreamerCaptureSession::StoppedState:
sessionState = QMediaRecorder::StoppedState;
}
return statusTable[m_state][sessionState];
}
void QGstreamerRecorderControl::updateStatus()
{
QMediaRecorder::Status newStatus = status();
if (m_status != newStatus) {
m_status = newStatus;
emit statusChanged(m_status);
}
}
void QGstreamerRecorderControl::handleSessionError(int code, const QString &description)
{
emit error(code, description);
stop();
}
qint64 QGstreamerRecorderControl::duration() const
@@ -104,6 +128,11 @@ qint64 QGstreamerRecorderControl::duration() const
void QGstreamerRecorderControl::record()
{
if (m_state == QMediaRecorder::RecordingState)
return;
m_state = QMediaRecorder::RecordingState;
if (m_outputLocation.isEmpty()) {
QString container = m_session->mediaContainerControl()->containerExtension();
if (container.isEmpty())
@@ -119,25 +148,44 @@ void QGstreamerRecorderControl::record()
emit error(QMediaRecorder::ResourceError, tr("Service has not been started"));
m_session->dumpGraph("after-record");
emit stateChanged(m_state);
updateStatus();
}
void QGstreamerRecorderControl::pause()
{
if (m_state == QMediaRecorder::PausedState)
return;
m_state = QMediaRecorder::PausedState;
m_session->dumpGraph("before-pause");
if (!m_hasPreviewState || m_session->state() != QGstreamerCaptureSession::StoppedState) {
m_session->setState(QGstreamerCaptureSession::PausedState);
} else
emit error(QMediaRecorder::ResourceError, tr("Service has not been started"));
emit stateChanged(m_state);
updateStatus();
}
void QGstreamerRecorderControl::stop()
{
if (m_state == QMediaRecorder::StoppedState)
return;
m_state = QMediaRecorder::StoppedState;
if (!m_hasPreviewState) {
m_session->setState(QGstreamerCaptureSession::StoppedState);
} else {
if (m_session->state() != QGstreamerCaptureSession::StoppedState)
m_session->setState(QGstreamerCaptureSession::PreviewState);
}
emit stateChanged(m_state);
updateStatus();
}
void QGstreamerRecorderControl::applySettings()

View File

@@ -62,6 +62,7 @@ public:
bool setOutputLocation(const QUrl &sink);
QMediaRecorder::State state() const;
QMediaRecorder::Status status() const;
qint64 duration() const;
@@ -76,7 +77,8 @@ public slots:
void setMuted(bool);
private slots:
void updateState();
void updateStatus();
void handleSessionError(int code, const QString &description);
private:
QDir defaultDir() const;
@@ -85,6 +87,7 @@ private:
QUrl m_outputLocation;
QGstreamerCaptureSession *m_session;
QMediaRecorder::State m_state;
QMediaRecorder::Status m_status;
bool m_hasPreviewState;
};