Commit cef6afcf authored by Adam Bakai's avatar Adam Bakai
Browse files

Clearing packetqueue and setting clock from avdemux thread.

If the packetqueue was cleared in the seek function then it can happen that
seek clears the packetqueue, then the other thread puts an other packet
with high timestamp and videothread takes it. In this case the videothread
waits a lot and video just freezes. This was fixed by putting the clear
into the SeekTask's run function. When I fixed this I realized that the
clock is sometimes wrong,too, so I put the clock updates into the SeekTask,
too. I am not sure if this is the perfect solution to make videothread's
waitAndCheck always work correctly, but it's definitely improved.
parent 34afa143
......@@ -211,37 +211,39 @@ void AVDemuxThread::stepBackward()
newSeekRequest(new stepBackwardTask(this, pre_pts));
}
void AVDemuxThread::seek(qint64 pos, SeekType type)
void AVDemuxThread::seek(qint64 external_pos, qint64 pos, SeekType type)
{
end = false;
// queue maybe blocked by put()
if (audio_thread) {
audio_thread->packetQueue()->clear();
}
if (video_thread) {
video_thread->packetQueue()->clear();
}
class SeekTask : public QRunnable {
public:
SeekTask(AVDemuxThread *dt, qint64 t, SeekType st)
SeekTask(AVDemuxThread *dt, qint64 external_pos, qint64 t, SeekType st)
: demux_thread(dt)
, type(st)
, position(t)
, external_pos(external_pos)
{}
void run() {
// queue maybe blocked by put()
if (demux_thread->audio_thread) {
demux_thread->audio_thread->packetQueue()->clear();
}
if (demux_thread->video_thread) {
demux_thread->video_thread->packetQueue()->clear();
}
if (demux_thread->video_thread)
demux_thread->video_thread->setDropFrameOnSeek(true);
demux_thread->seekInternal(position, type);
demux_thread->seekInternal(position, type, external_pos);
}
private:
AVDemuxThread *demux_thread;
SeekType type;
qint64 position;
qint64 external_pos;
};
newSeekRequest(new SeekTask(this, pos, type));
newSeekRequest(new SeekTask(this, external_pos, pos, type));
}
void AVDemuxThread::seekInternal(qint64 pos, SeekType type)
void AVDemuxThread::seekInternal(qint64 pos, SeekType type, qint64 external_pos)
{
AVThread* av[] = { audio_thread, video_thread};
qDebug("seek to %s %lld ms (%f%%)", QTime(0, 0, 0).addMSecs(pos).toString().toUtf8().constData(), pos, double(pos - demuxer->startTime())/double(demuxer->duration())*100.0);
......@@ -264,6 +266,9 @@ void AVDemuxThread::seekInternal(qint64 pos, SeekType type)
Q_ASSERT(sync_id != 0);
qDebug("demuxer sync id: %d/%d", sync_id, t->clock()->syncId());
t->packetQueue()->clear();
if (external_pos != std::numeric_limits < qint64 >::min() )
t->clock()->updateExternalClock(qMax(qint64(0), external_pos));
t->clock()->updateValue(double(pos)/1000.0);
t->requestSeek();
// TODO: the first frame (key frame) will not be decoded correctly if flush() is called.
//PacketBuffer *pb = t->packetQueue();
......
......@@ -46,7 +46,7 @@ public:
AVThread* videoThread();
void stepForward(); // show next video frame and pause
void stepBackward();
void seek(qint64 pos, SeekType type); //ms
void seek(qint64 external_pos, qint64 pos, SeekType type); //ms
//AVDemuxer* demuxer
bool isPaused() const;
bool isEnd() const;
......@@ -84,7 +84,7 @@ private:
void setAVThread(AVThread *&pOld, AVThread* pNew);
void newSeekRequest(QRunnable *r);
void processNextSeekTask();
void seekInternal(qint64 pos, SeekType type); //must call in AVDemuxThread
void seekInternal(qint64 pos, SeekType type, qint64 external_pos = std::numeric_limits < qint64 >::min()); //must call in AVDemuxThread
void pauseInternal(bool value);
bool paused;
......
......@@ -858,13 +858,11 @@ void AVPlayer::setPosition(qint64 position)
qint64 pos_pts = position;
if (pos_pts < 0)
pos_pts = 0;
masterClock()->updateExternalClock(pos_pts); //in msec. ignore usec part using t/1000
// position passed in is relative to the start pts in relative time mode
if (relativeTimeMode())
pos_pts += absoluteMediaStartPosition();
d->seeking = true;
masterClock()->updateValue(double(pos_pts)/1000.0); //what is duration == 0
d->read_thread->seek(pos_pts, seekType());
d->read_thread->seek(position,pos_pts, seekType());
Q_EMIT positionChanged(position); //emit relative position
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment