diff options
author | Benoit Bolsee <benoit.bolsee@online.be> | 2009-05-26 22:37:46 +0400 |
---|---|---|
committer | Benoit Bolsee <benoit.bolsee@online.be> | 2009-05-26 22:37:46 +0400 |
commit | 328d3128a5806be3bb4f11f852fde108ebba955a (patch) | |
tree | e8df9aab8ad957145e249bded78103f9a7502965 /source/gameengine/VideoTexture | |
parent | 25569b0f7df6c29033834c281f246523b42bf16c (diff) |
BGE VideoTexture: VideoFFmpeg was missing a rewind function: rename stop() to pause() and add stop() that will also reset the frame counter.
Diffstat (limited to 'source/gameengine/VideoTexture')
-rw-r--r-- | source/gameengine/VideoTexture/VideoBase.cpp | 5 | ||||
-rw-r--r-- | source/gameengine/VideoTexture/VideoBase.h | 13 | ||||
-rw-r--r-- | source/gameengine/VideoTexture/VideoFFmpeg.cpp | 64 | ||||
-rw-r--r-- | source/gameengine/VideoTexture/VideoFFmpeg.h | 5 |
4 files changed, 69 insertions, 18 deletions
diff --git a/source/gameengine/VideoTexture/VideoBase.cpp b/source/gameengine/VideoTexture/VideoBase.cpp index 3c703d75cda..ada672c5569 100644 --- a/source/gameengine/VideoTexture/VideoBase.cpp +++ b/source/gameengine/VideoTexture/VideoBase.cpp @@ -113,7 +113,10 @@ void Video_open (VideoBase * self, char * file, short captureID) PyObject * Video_play (PyImage * self) { if (getVideo(self)->play()) Py_RETURN_TRUE; else Py_RETURN_FALSE; } -// stop video +// pause video +PyObject * Video_pause (PyImage * self) +{ if (getVideo(self)->pause()) Py_RETURN_TRUE; else Py_RETURN_FALSE; } + PyObject * Video_stop (PyImage * self) { if (getVideo(self)->stop()) Py_RETURN_TRUE; else Py_RETURN_FALSE; } diff --git a/source/gameengine/VideoTexture/VideoBase.h b/source/gameengine/VideoTexture/VideoBase.h index 15ecb7a78f4..0c8668ee0bc 100644 --- a/source/gameengine/VideoTexture/VideoBase.h +++ b/source/gameengine/VideoTexture/VideoBase.h @@ -80,7 +80,17 @@ public: } return false; } - /// stop/pause video + /// pause video + virtual bool pause (void) + { + if (m_status == SourcePlaying) + { + m_status = SourceStopped; + return true; + } + return false; + } + /// stop video virtual bool stop (void) { if (m_status == SourcePlaying) @@ -170,6 +180,7 @@ template <class T> void Video_init (PyImage * self) // video functions void Video_open (VideoBase * self, char * file, short captureID); PyObject * Video_play (PyImage * self); +PyObject * Video_pause (PyImage * self); PyObject * Video_stop (PyImage * self); PyObject * Video_refresh (PyImage * self); PyObject * Video_getStatus (PyImage * self, void * closure); diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index d509f366910..7910113a225 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -669,12 +669,12 @@ bool VideoFFmpeg::play (void) } -// stop video -bool VideoFFmpeg::stop (void) +// pause video +bool VideoFFmpeg::pause (void) { try { - if (VideoBase::stop()) + if (VideoBase::pause()) { return true; } @@ -683,6 +683,20 @@ bool VideoFFmpeg::stop (void) return false; } +// stop video +bool VideoFFmpeg::stop (void) +{ + try + { + VideoBase::stop(); + // force restart when play + m_lastFrame = -1; + return true; + } + CATCH_EXCP; + return false; +} + // set video range void VideoFFmpeg::setRange (double start, double stop) @@ -721,6 +735,8 @@ void VideoFFmpeg::loadFrame (void) { // get actual time double startTime = PIL_check_seconds_timer(); + if (m_lastFrame == -1) + m_startTime = startTime; double actTime = startTime - m_startTime; // if video has ended if (m_isFile && actTime * m_frameRate >= m_range[1]) @@ -886,28 +902,47 @@ AVFrame *VideoFFmpeg::grabFrame(long position) if (position != m_curPosition + 1) { double timeBase = av_q2d(m_formatCtx->streams[m_videoStream]->time_base); - long long pos = (long long) - ((long long) (position - m_preseek) * AV_TIME_BASE / m_baseFrameRate); - long long startTs = m_formatCtx->streams[m_videoStream]->start_time; + int64_t pos = (int64_t)((position - m_preseek) / (m_baseFrameRate*timeBase)); + int64_t startTs = m_formatCtx->streams[m_videoStream]->start_time; + int seekres; if (pos < 0) pos = 0; if (startTs != AV_NOPTS_VALUE) - pos += (long long)(startTs * AV_TIME_BASE * timeBase); + pos += startTs; if (position <= m_curPosition || !m_eof) { - // no need to seek past the end of the file - if (av_seek_frame(m_formatCtx, -1, pos, AVSEEK_FLAG_BACKWARD) >= 0) +#if 0 + // Tried to make this work but couldn't: seeking on byte is ignored by the + // format plugin and it will generally continue to read from last timestamp. + // Too bad because frame seek is not always able to get the first frame + // of the file. + if (position <= m_preseek) + { + // we can safely go the begining of the file + if (av_seek_frame(m_formatCtx, m_videoStream, 0, AVSEEK_FLAG_BYTE) >= 0) + { + // binary seek does not reset the timestamp, must do it now + av_update_cur_dts(m_formatCtx, m_formatCtx->streams[m_videoStream], startTs); + m_curPosition = 0; + } + } + else +#endif { // current position is now lost, guess a value. - // It's not important because it will be set at this end of this function - m_curPosition = position - m_preseek - 1; + if (av_seek_frame(m_formatCtx, m_videoStream, pos, AVSEEK_FLAG_BACKWARD) >= 0) + { + // current position is now lost, guess a value. + // It's not important because it will be set at this end of this function + m_curPosition = position - m_preseek - 1; + } } } // this is the timestamp of the frame we're looking for - targetTs = (long long)(((double) position) / m_baseFrameRate / timeBase); + targetTs = (int64_t)(position / (m_baseFrameRate * timeBase)); if (startTs != AV_NOPTS_VALUE) targetTs += startTs; @@ -1097,8 +1132,9 @@ int VideoFFmpeg_setDeinterlace (PyImage * self, PyObject * value, void * closure // methods structure static PyMethodDef videoMethods[] = { // methods from VideoBase class - {"play", (PyCFunction)Video_play, METH_NOARGS, "Play video"}, - {"stop", (PyCFunction)Video_stop, METH_NOARGS, "Stop (pause) video"}, + {"play", (PyCFunction)Video_play, METH_NOARGS, "Play (restart) video"}, + {"pause", (PyCFunction)Video_pause, METH_NOARGS, "pause video"}, + {"stop", (PyCFunction)Video_stop, METH_NOARGS, "stop video (play will replay it from start)"}, {"refresh", (PyCFunction)Video_refresh, METH_NOARGS, "Refresh video - get its status"}, {NULL} }; diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h index 51f1067c466..fbd04e7e1fc 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.h +++ b/source/gameengine/VideoTexture/VideoFFmpeg.h @@ -83,9 +83,10 @@ public: /// play video virtual bool play (void); - /// stop/pause video + /// pause video + virtual bool pause (void); + /// stop video virtual bool stop (void); - /// set play range virtual void setRange (double start, double stop); /// set frame rate |