void AVDemuxThread::nextFrame() { // clock type will be wrong if no lock because slot frameDeliveredNextFrame() is in video thread QMutexLocker locker(&next_frame_mutex); Q_UNUSED(locker); pause(true); // must pause AVDemuxThread (set user_paused true) AVThread* av[] = {video_thread, audio_thread}; bool connected = false; for (size_t i = 0; i < sizeof(av)/sizeof(av[0]); ++i) { AVThread *t = av[i]; if (!t) continue; // set clock first if (clock_type < 0) clock_type = (int)t->clock()->isClockAuto() + 2*(int)t->clock()->clockType(); t->clock()->setClockType(AVClock::VideoClock); t->scheduleFrameDrop(false); t->pause(false); t->packetQueue()->blockFull(false); if (!connected) { connect(t, SIGNAL(frameDelivered()), this, SLOT(frameDeliveredNextFrame()), Qt::DirectConnection); connected = true; } } emit requestClockPause(false); nb_next_frame.ref(); pauseInternal(false); }
void AVDemuxThread::frameDeliveredNextFrame() { AVThread *thread = video_thread ? video_thread : audio_thread; Q_ASSERT(thread); if (nb_next_frame.deref()) { #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) || QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) Q_ASSERT_X((int)nb_next_frame > 0, "frameDeliveredNextFrame", "internal error. frameDeliveredNextFrame must be > 0"); #else Q_ASSERT_X((int)nb_next_frame.load() > 0, "frameDeliveredNextFrame", "internal error. frameDeliveredNextFrame must be > 0"); #endif return; } QMutexLocker locker(&next_frame_mutex); Q_UNUSED(locker); disconnect(thread, SIGNAL(frameDelivered()), this, SLOT(frameDeliveredNextFrame())); if (user_paused) { pause(true); // restore pause state emit requestClockPause(true); // need direct connection // pause both video and audio thread if (video_thread) video_thread->pause(true); if (audio_thread) audio_thread->pause(true); } if (clock_type >= 0) { thread->clock()->setClockAuto(clock_type & 1); thread->clock()->setClockType(AVClock::ClockType(clock_type/2)); clock_type = -1; } }
void AVDemuxThread::frameDeliveredNextFrame() { AVThread *thread = video_thread ? video_thread : audio_thread; Q_ASSERT(thread); QMutexLocker locker(&next_frame_mutex); Q_UNUSED(locker); disconnect(thread, SIGNAL(frameDelivered()), this, SLOT(frameDeliveredNextFrame())); if (user_paused) { pause(true); // restore pause state emit requestClockPause(true); // need direct connection // pause both video and audio thread if (video_thread) video_thread->pause(true); if (audio_thread) audio_thread->pause(true); } if (clock_type >= 0) { thread->clock()->setClockAuto(clock_type & 1); thread->clock()->setClockType(AVClock::ClockType(clock_type/2)); clock_type = -1; } }