Skip to content

Commit

Permalink
Clearing packetqueue and setting clock from avdemux thread.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Adam Bakai committed Aug 8, 2018
1 parent 34afa14 commit cef6afc
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 17 deletions.
29 changes: 17 additions & 12 deletions src/AVDemuxThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions src/AVDemuxThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class AVDemuxThread : public QThread
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;
Expand Down Expand Up @@ -84,7 +84,7 @@ private slots:
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;
Expand Down
4 changes: 1 addition & 3 deletions src/AVPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down

0 comments on commit cef6afc

Please sign in to comment.