From Rafa Gaitan, "Current ffmpeg plugin didn't support pause and seek, I have added this

functionality and I also modified osgmovie example to support "seek"."

Note from Robert Osfield, changes osgmovie to use '>' for the seek as '+' was already used in a separate submission that had been merged.
This commit is contained in:
Robert Osfield
2009-11-20 14:31:11 +00:00
parent 733431004a
commit 3ef770a9ff
5 changed files with 102 additions and 3 deletions

View File

@@ -166,12 +166,18 @@ bool FFmpegDecoder::readNextPacket()
case NORMAL:
return readNextPacketNormal();
case PAUSE:
return false;
case END_OF_STREAM:
return readNextPacketEndOfStream();
case REWINDING:
return readNextPacketRewinding();
case SEEKING:
return readNextPacketSeeking();
default:
assert(false);
return false;
@@ -189,8 +195,32 @@ void FFmpegDecoder::rewind()
rewindButDontFlushQueues();
}
void FFmpegDecoder::seek(double time)
{
m_pending_packet.clear();
flushAudioQueue();
flushVideoQueue();
seekButDontFlushQueues(time);
}
void FFmpegDecoder::pause()
{
m_pending_packet.clear();
flushAudioQueue();
flushVideoQueue();
m_state = PAUSE;
}
void FFmpegDecoder::resume()
{
m_pending_packet.clear();
flushAudioQueue();
flushVideoQueue();
m_state = NORMAL;
}
void FFmpegDecoder::findAudioStream()
{
@@ -346,6 +376,29 @@ void FFmpegDecoder::rewindButDontFlushQueues()
m_state = REWINDING;
}
bool FFmpegDecoder::readNextPacketSeeking()
{
const FFmpegPacket packet(FFmpegPacket::PACKET_FLUSH);
if (m_audio_queue.timedPush(packet, 10) && m_video_queue.timedPush(packet, 10))
m_state = NORMAL;
return false;
}
void FFmpegDecoder::seekButDontFlushQueues(double time)
{
const AVRational AvTimeBaseQ = { 1, AV_TIME_BASE }; // = AV_TIME_BASE_Q
const int64_t pos = int64_t(m_clocks.getStartTime()+time * double(AV_TIME_BASE));
const int64_t seek_target = av_rescale_q(pos, AvTimeBaseQ, m_video_stream->time_base);
if (av_seek_frame(m_format_context.get(), m_video_index, seek_target, 0/*AVSEEK_FLAG_BYTE |*/ /*AVSEEK_FLAG_BACKWARD*/) < 0)
throw std::runtime_error("av_seek_frame failed()");
m_state = SEEKING;
}
} // namespace osgFFmpeg