35 : m_context(
context), m_posWithOffset(posWithOffset), m_loops(loops)
37 qCDebug(qLcDemuxer) <<
"Create demuxer."
38 <<
"pos:" << posWithOffset.pos <<
"loop offset:" << posWithOffset.offset.pos
39 <<
"loop index:" << posWithOffset.offset.index <<
"loops:" << loops;
44 if (streamIndexes[
i] >= 0) {
46 qCDebug(qLcDemuxer) <<
"Activate demuxing stream" <<
i <<
", trackType:" << trackType;
47 m_streams[streamIndexes[
i]] = { trackType };
57 if (av_read_frame(m_context, packet.
avPacket()) < 0) {
61 if (loops >= 0 && m_posWithOffset.
offset.
index >= loops) {
62 qCDebug(qLcDemuxer) <<
"finish demuxing";
64 if (!std::exchange(m_buffered,
true))
70 m_posWithOffset.
pos = 0;
71 m_posWithOffset.
offset.
pos = m_maxPacketsEndPos;
72 m_maxPacketsEndPos = 0;
77 <<
"Offset:" << m_posWithOffset.
offset.
pos;
87 const auto streamIndex = avPacket.stream_index;
88 const auto stream = m_context->streams[streamIndex];
90 auto it = m_streams.find(streamIndex);
91 if (
it != m_streams.end()) {
92 auto &streamData =
it->second;
95 m_maxPacketsEndPos =
qMax(m_maxPacketsEndPos, endPos);
100 streamData.bufferedSize += avPacket.size;
101 streamData.maxSentPacketsPos =
qMax(streamData.maxSentPacketsPos, endPos);
102 updateStreamDataLimitFlag(streamData);
104 if (!m_buffered && streamData.isDataLimitReached) {
109 if (!m_firstPacketFound) {
110 m_firstPacketFound =
true;
129 auto &avPacket = *packet.
avPacket();
131 const auto streamIndex = avPacket.stream_index;
132 const auto stream = m_context->streams[streamIndex];
133 auto it = m_streams.find(streamIndex);
135 if (
it != m_streams.end()) {
136 auto &streamData =
it->second;
141 streamData.bufferedSize -= avPacket.size;
142 streamData.maxProcessedPacketPos =
148 updateStreamDataLimitFlag(streamData);
156 auto isDataLimitReached = [](
const auto &streamIndexToData) {
157 return streamIndexToData.second.isDataLimitReached;
167 && std::none_of(m_streams.begin(), m_streams.end(), isDataLimitReached);
170void Demuxer::ensureSeeked()
172 if (std::exchange(m_seeked,
true))
175 if ((m_context->ctx_flags & AVFMTCTX_UNSEEKABLE) == 0) {
176 const qint64 seekPos = m_posWithOffset.
pos * AV_TIME_BASE / 1000000;
177 auto err = av_seek_frame(m_context, -1, seekPos, AVSEEK_FLAG_BACKWARD);
180 qCWarning(qLcDemuxer) <<
"Failed to seek, pos" << seekPos;
184 if (seekPos != 0 || m_context->duration > 0)
211 qCDebug(qLcDemuxer) <<
"setLoops to demuxer" << loopsCount;
215void Demuxer::updateStreamDataLimitFlag(StreamData &streamData)
217 const auto packetsPosDiff = streamData.maxSentPacketsPos - streamData.maxProcessedPacketPos;
218 streamData.isDataLimitReached =
228#include "moc_qffmpegdemuxer_p.cpp"
T loadAcquire() const noexcept
void storeRelease(T newValue) noexcept
Demuxer(AVFormatContext *context, const PositionWithOffset &posWithOffset, const StreamIndexes &streamIndexes, int loops)
void setLoops(int loopsCount)
void doNextStep() override
void firstPacketFound(TimePoint tp, qint64 trackPos)
void requestProcessVideoPacket(Packet)
void(Demuxer::*)(Packet) RequestingSignal
void onPacketProcessed(Packet)
void requestProcessAudioPacket(Packet)
void requestProcessSubtitlePacket(Packet)
static RequestingSignal signalByTrackType(QPlatformMediaPlayer::TrackType trackType)
bool canDoNextStep() const override
virtual bool canDoNextStep() const
void setAtEnd(bool isAtEnd)
void scheduleNextStep(bool allowDoImmediatelly=true)
QSet< QString >::iterator it
QString err2str(int errnum)
static qint64 packetEndPos(const AVStream *stream, const Packet &packet)
std::unique_ptr< AVPacket, AVDeleter< decltype(&av_packet_free), &av_packet_free > > AVPacketUPtr
std::array< int, 3 > StreamIndexes
std::optional< qint64 > mul(qint64 a, AVRational b)
static qint64 streamTimeToUs(const AVStream *stream, qint64 time)
Combined button and popup list for selecting options.
DBusConnection const char DBusError * error
static QT_BEGIN_NAMESPACE constexpr qint64 MaxBufferedDurationUs
static constexpr qint64 MaxBufferedSize
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
constexpr const T & qMax(const T &a, const T &b)
AVPacket * avPacket() const
const LoopOffset & loopOffset() const