Skip to content

Commit

Permalink
support continue playback on timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
wang-bin committed Apr 20, 2015
1 parent 674d696 commit e70686a
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 5 deletions.
5 changes: 5 additions & 0 deletions qml/QmlAV/QmlAVPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class QmlAVPlayer : public QObject, public QQmlParserStatus
// not supported by QtMultimedia
Q_PROPERTY(bool fastSeek READ isFastSeek WRITE setFastSeek NOTIFY fastSeekChanged)
Q_PROPERTY(int timeout READ timeout WRITE setTimeout NOTIFY timeoutChanged)
Q_PROPERTY(bool abortOnTimeout READ abortOnTimeout WRITE setAbortOnTimeout NOTIFY abortOnTimeoutChanged)
Q_PROPERTY(ChannelLayout channelLayout READ channelLayout WRITE setChannelLayout NOTIFY channelLayoutChanged)
Q_PROPERTY(QStringList videoCodecs READ videoCodecs)
Q_PROPERTY(QStringList videoCodecPriority READ videoCodecPriority WRITE setVideoCodecPriority NOTIFY videoCodecPriorityChanged)
Expand Down Expand Up @@ -167,6 +168,8 @@ class QmlAVPlayer : public QObject, public QQmlParserStatus

void setTimeout(int value); // ms
int timeout() const;
void setAbortOnTimeout(bool value);
bool abortOnTimeout() const;
public Q_SLOTS:
void play();
void pause();
Expand Down Expand Up @@ -201,6 +204,7 @@ public Q_SLOTS:
void videoCodecOptionsChanged();
void channelLayoutChanged();
void timeoutChanged();
void abortOnTimeoutChanged();

void errorChanged();
void error(Error error, const QString &errorString);
Expand Down Expand Up @@ -239,6 +243,7 @@ private Q_SLOTS:
QStringList mVideoCodecs;
ChannelLayout mChannelLayout;
int m_timeout;
bool m_abort_timeout;

QScopedPointer<MediaMetaData> m_metaData;
QVariantMap vcodec_opt;
Expand Down
18 changes: 17 additions & 1 deletion qml/QmlAVPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,21 @@ int QmlAVPlayer::timeout() const
return m_timeout;
}

void QmlAVPlayer::setAbortOnTimeout(bool value)
{
if (m_abort_timeout == value)
return;
m_abort_timeout = value;
emit abortOnTimeoutChanged();
if (mpPlayer)
mpPlayer->setInterruptOnTimeout(value);
}

bool QmlAVPlayer::abortOnTimeout() const
{
return m_abort_timeout;
}

QStringList QmlAVPlayer::videoCodecPriority() const
{
return mVideoCodecs;
Expand Down Expand Up @@ -407,6 +422,7 @@ void QmlAVPlayer::setPlaybackState(PlaybackState playbackState)
mpPlayer->pause(false);
} else {
mpPlayer->setInterruptTimeout(m_timeout);
mpPlayer->setInterruptOnTimeout(m_abort_timeout);
mpPlayer->setRepeat(mLoopCount - 1);
if (!vcodec_opt.isEmpty()) {
QVariantHash vcopt;
Expand Down Expand Up @@ -550,7 +566,7 @@ void QmlAVPlayer::_q_started()
// applyChannelLayout() first because it may reopen audio device
applyVolume(); //sender is AVPlayer

mpPlayer->setMute(isMuted());
mpPlayer->audio()->setMute(isMuted());
mpPlayer->setSpeed(playbackRate());
// TODO: in load()?
m_metaData->setValuesFromStatistics(mpPlayer->statistics());
Expand Down
1 change: 1 addition & 0 deletions qml/Video.qml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Item {
property alias fastSeek: player.fastSeek
property alias opengl: videoOut.opengl
property alias timeout: player.timeout
property alias abortOnTimeout: player.abortOnTimeout
property alias subtitle: subtitle
property alias subtitleText: text_sub // not for ass.
/*** Properties of VideoOutput ***/
Expand Down
1 change: 1 addition & 0 deletions qml/plugins.qmltypes
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ Module {
Property { name: "errorString"; type: "string"; isReadonly: true }
Property { name: "fastSeek"; type: "bool" }
Property { name: "timeout"; type: "int" }
Property { name: "abortOnTimeout"; type: "bool" }
Property { name: "channelLayout"; type: "ChannelLayout" }
Property { name: "videoCodecs"; type: "QStringList"; isReadonly: true }
Property { name: "videoCodecPriority"; type: "QStringList" }
Expand Down
42 changes: 39 additions & 3 deletions src/AVDemuxer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ class AVDemuxer::InterruptHandler : public AVIOInterruptCB
InterruptHandler(AVDemuxer* demuxer, int timeout = 30000)
: mStatus(0)
, mTimeout(timeout)
, mTimeoutAbort(true)
, mEmitError(true)
//, mLastTime(0)
, mAction(Open)
, mpDemuxer(demuxer)
Expand All @@ -95,6 +97,7 @@ class AVDemuxer::InterruptHandler : public AVIOInterruptCB
#endif
}
void begin(Action act) {
mEmitError = true;
mAction = act;
mTimer.start();
}
Expand All @@ -114,6 +117,16 @@ class AVDemuxer::InterruptHandler : public AVIOInterruptCB
}
qint64 getTimeout() const { return mTimeout; }
void setTimeout(qint64 timeout) { mTimeout = timeout; }
bool setInterruptOnTimeout(bool value) {
if (mTimeoutAbort == value)
return false;
mTimeoutAbort = value;
if (mTimeoutAbort) {
mEmitError = true;
}
return true;
}
bool isInterruptOnTimeout() const {return mTimeoutAbort;}
int getStatus() const { return mStatus; }
void setStatus(int status) { mStatus = status; }
/*
Expand Down Expand Up @@ -153,7 +166,7 @@ class AVDemuxer::InterruptHandler : public AVIOInterruptCB
if (handler->mTimeout < 0)
return 0;
if (!handler->mTimer.isValid()) {
qDebug("timer is not valid, start it");
//qDebug("timer is not valid, start it");
handler->mTimer.start();
//handler->mLastTime = handler->mTimer.elapsed();
return 0;
Expand All @@ -175,11 +188,22 @@ class AVDemuxer::InterruptHandler : public AVIOInterruptCB
} else if (handler->mAction == Read) {
handler->mStatus = int(AVError::ReadTimedout);
}
return 1;
if (handler->mTimeoutAbort)
return 1;
// emit demuxer error, handleerror
if (handler->mEmitError) {
handler->mEmitError = false;
AVError::ErrorCode ec = AVError::ErrorCode(handler->mStatus);
QString es;
handler->mpDemuxer->handleError(AVERROR_EXIT, &ec, es);
}
return 0;
}
private:
int mStatus;
qint64 mTimeout;
bool mTimeoutAbort;
bool mEmitError;
//qint64 mLastTime;
Action mAction;
AVDemuxer *mpDemuxer;
Expand Down Expand Up @@ -975,6 +999,16 @@ void AVDemuxer::setInterruptTimeout(qint64 timeout)
d->interrupt_hanlder->setTimeout(timeout);
}

bool AVDemuxer::isInterruptOnTimeout() const
{
return d->interrupt_hanlder->isInterruptOnTimeout();
}

void AVDemuxer::setInterruptOnTimeout(bool value)
{
d->interrupt_hanlder->setInterruptOnTimeout(value);
}

int AVDemuxer::getInterruptStatus() const
{
return d->interrupt_hanlder->getStatus();
Expand Down Expand Up @@ -1125,11 +1159,13 @@ void AVDemuxer::handleError(int averr, AVError::ErrorCode *errorCode, QString &m
QString err_msg(msg);
if (interrupted) { // interrupted by callback, so can not determine whether the media is valid
// insufficient buffering or other interruptions
setMediaStatus(StalledMedia);
if (getInterruptStatus() < 0) {
setMediaStatus(StalledMedia);
emit userInterrupted();
err_msg += " [" + tr("interrupted by user") + "]";
} else {
if (isInterruptOnTimeout())
setMediaStatus(StalledMedia);
// averr is eof for open timeout
err_msg += " [" + tr("timeout") + "]";
}
Expand Down
13 changes: 13 additions & 0 deletions src/AVPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,19 @@ qint64 AVPlayer::interruptTimeout() const
return d->interrupt_timeout;
}

void AVPlayer::setInterruptOnTimeout(bool value)
{
if (isInterruptOnTimeout() == value)
return;
d->demuxer.setInterruptOnTimeout(value);
emit interruptOnTimeoutChanged();
}

bool AVPlayer::isInterruptOnTimeout() const
{
return d->demuxer.isInterruptOnTimeout();
}

void AVPlayer::setFrameRate(qreal value)
{
d->force_fps = value;
Expand Down
3 changes: 3 additions & 0 deletions src/QtAV/AVDemuxer.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ class Q_AV_EXPORT AVDemuxer : public QObject
* @param timeout in ms
*/
void setInterruptTimeout(qint64 timeout);
bool isInterruptOnTimeout() const;
void setInterruptOnTimeout(bool value);
/**
* @brief getInterruptStatus return the interrupt status.
* \return -1: interrupted by user
Expand Down Expand Up @@ -187,6 +189,7 @@ class Q_AV_EXPORT AVDemuxer : public QObject
class Private;
QScopedPointer<Private> d;
class InterruptHandler;
friend class InterruptHandler;
};

} //namespace QtAV
Expand Down
12 changes: 11 additions & 1 deletion src/QtAV/AVPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class Q_AV_EXPORT AVPlayer : public QObject
Q_PROPERTY(qint64 repeat READ repeat WRITE setRepeat NOTIFY repeatChanged)
Q_PROPERTY(int currentRepeat READ currentRepeat NOTIFY currentRepeatChanged)
Q_PROPERTY(qint64 interruptTimeout READ interruptTimeout WRITE setInterruptTimeout NOTIFY interruptTimeoutChanged)
Q_PROPERTY(bool interruptOnTimeout READ isInterruptOnTimeout WRITE setInterruptOnTimeout NOTIFY interruptOnTimeoutChanged)
Q_PROPERTY(int notifyInterval READ notifyInterval WRITE setNotifyInterval NOTIFY notifyIntervalChanged)
Q_PROPERTY(int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged)
Q_PROPERTY(int contrast READ contrast WRITE setContrast NOTIFY contrastChanged)
Expand Down Expand Up @@ -219,11 +220,19 @@ class Q_AV_EXPORT AVPlayer : public QObject

/*!
* \brief setInterruptTimeout
* Abort current operation(open, read) if it spends too much time.
* Emit error(usually network error) if open/read spends too much time.
* If isInterruptOnTimeout() is true, abort current operation and stop playback
* \param ms milliseconds. <0: never interrupt.
*/
/// TODO: rename to timeout
void setInterruptTimeout(qint64 ms);
qint64 interruptTimeout() const;
/*!
* \brief setInterruptOnTimeout
* \param value
*/
void setInterruptOnTimeout(bool value);
bool isInterruptOnTimeout() const;
/*!
* \brief setFrameRate
* Force the (video) frame rate to a given value.
Expand Down Expand Up @@ -401,6 +410,7 @@ public slots:
void seekableChanged();
void positionChanged(qint64 position);
void interruptTimeoutChanged();
void interruptOnTimeoutChanged();
void notifyIntervalChanged();
void brightnessChanged(int val);
void contrastChanged(int val);
Expand Down

0 comments on commit e70686a

Please sign in to comment.