Files
fmviewer3/project/fm_viewer/fav/AVDemuxThread.h
2026-02-21 17:11:31 +09:00

130 lines
4.0 KiB
C++

/******************************************************************************
QtAV: Multimedia framework based on Qt and FFmpeg
Copyright (C) 2012-2017 Wang Bin <wbsecg1@gmail.com>
* This file is part of QtAV
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
#ifndef QAV_DEMUXTHREAD_H
#define QAV_DEMUXTHREAD_H
#include <QtCore/QMutex>
#include <QtCore/QSemaphore>
#include <QtCore/QThread>
#include <QtCore/QRunnable>
#include "PacketBuffer.h"
namespace FAV {
class AVDemuxer;
class AVThread;
class AVDemuxThread : public QThread
{
Q_OBJECT
public:
explicit AVDemuxThread(QObject *parent = 0);
explicit AVDemuxThread(AVDemuxer *dmx, QObject *parent = 0);
void setDemuxer(AVDemuxer *dmx);
void setAudioDemuxer(AVDemuxer *demuxer); //not thread safe
void setAudioThread(AVThread *thread);
AVThread* audioThread();
void setVideoThread(AVThread *thread);
AVThread* videoThread();
// void stepForward(); // show next video frame and pause
// void stepBackward();
void seek(qint64 pos, SeekType type); //ms
//AVDemuxer* demuxer
bool isPaused() const;
bool isEnd() const;
bool atEndOfMedia() const;
PacketBuffer* buffer();
void updateBufferState();
void stop(); //TODO: remove it?
void pause(bool p, bool wait = false);
int playerID;
#if (REAR_SYNC_FRONT)
double rear_delay;
#endif
bool seek_exist()
{
return seek_tasks.size() > 0;
}
MediaEndAction mediaEndAction() const;
void setMediaEndAction(MediaEndAction value);
bool waitForStarted(int msec = -1);
Q_SIGNALS:
void requestClockPause(bool value);
void mediaStatusChanged(FAV::MediaStatus);
void bufferProgressChanged(qreal);
#if (PLAY_SYNC_FIX2)
void seekFinished(qint64 timestamp,qint64 requested);
#else
void seekFinished(qint64 timestamp);
#endif
void stepFinished();
#if !(DO_NOT_USE_SUBTITLE)
void internalSubtitlePacketRead(int index, const FAV::Packet& packet);
#endif
private slots:
void seekOnPauseFinished();
//void frameDeliveredOnStepForward();
//void eofDecodedOnStepForward();
void onAVThreadQuit();
protected:
virtual void run();
/*
* If the pause state is true setted by pause(true), then block the thread and wait for pause state changed, i.e. pause(false)
* and return true. Otherwise, return false immediatly.
*/
bool tryPause(unsigned long timeout = 100);
private:
void setAVThread(AVThread *&pOld, AVThread* pNew);
void newSeekRequest(QRunnable *r);
void processNextSeekTask();
void seekInternal(qint64 pos, SeekType type); //must call in AVDemuxThread
void pauseInternal(bool value);
bool paused;
bool user_paused;
volatile bool end;
MediaEndAction end_action;
bool m_buffering;
PacketBuffer *m_buffer;
AVDemuxer *demuxer;
AVDemuxer *ademuxer;
AVThread *audio_thread, *video_thread;
int audio_stream, video_stream;
QMutex buffer_mutex;
QWaitCondition cond;
BlockingQueue<QRunnable*> seek_tasks;
QSemaphore sem;
QMutex next_frame_mutex;
int clock_type; // change happens in different threads(direct connection)
friend class SeekTask;
friend class stepBackwardTask;
};
} //namespace FAV
#endif // QAV_DEMUXTHREAD_H