示例#1
0
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);
}
示例#2
0
void AVDemuxThread::seekInternal(qint64 pos, SeekType type)
{
    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);
    demuxer->setSeekType(type);
    demuxer->seek(pos);
    if (ademuxer) {
        ademuxer->setSeekType(type);
        ademuxer->seek(pos);
    }

    AVThread *watch_thread = 0;
    // TODO: why queue may not empty?
    int sync_id = 0;
    for (size_t i = 0; i < sizeof(av)/sizeof(av[0]); ++i) {
        AVThread *t = av[i];
        if (!t)
            continue;
        if (!sync_id)
            sync_id = t->clock()->syncStart(!!audio_thread + !!video_thread);
        Q_ASSERT(sync_id != 0);
        qDebug("demuxer sync id: %d/%d", sync_id, t->clock()->syncId());
        t->packetQueue()->clear();
        t->requestSeek();
        // TODO: the first frame (key frame) will not be decoded correctly if flush() is called.
        //PacketBuffer *pb = t->packetQueue();
        //qDebug("%s put seek packet. %d/%d-%.3f, progress: %.3f", t->metaObject()->className(), pb->buffered(), pb->bufferValue(), pb->bufferMax(), pb->bufferProgress());
        t->packetQueue()->setBlocking(false); // aqueue bufferValue can be small (1), we can not put and take
        Packet pkt;
        pkt.pts = qreal(pos)/1000.0;
        pkt.position = sync_id;
        t->packetQueue()->put(pkt);
        t->packetQueue()->setBlocking(true); // blockEmpty was false when eof is read.
        if (isPaused()) { //TODO: deal with pause in AVThread?
            t->pause(false);
            watch_thread = t;
        }
    }
    if (watch_thread) {
        pauseInternal(false);
        Q_EMIT requestClockPause(false); // need direct connection
        // direct connection is fine here
        connect(watch_thread, SIGNAL(seekFinished(qint64)), this, SLOT(seekOnPauseFinished()), Qt::DirectConnection);
    }
}