Skip to content

Commit

Permalink
Report audio pts if video is AV_DISPOSITION_ATTACHED_PIC
Browse files Browse the repository at this point in the history
  • Loading branch information
valbok committed Jan 24, 2024
1 parent d15af34 commit 48090d1
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 12 deletions.
5 changes: 3 additions & 2 deletions src/QtAVPlayer/qavaudiooutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class QAVAudioOutputPrivate : public QIODevice
bool isSequential() const override { return true; }
bool atEnd() const override { return false; }

void init(const QAudioFormat &fmt, int bsize)
void tryInit(const QAudioFormat &fmt, int bsize, qreal v)
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
auto audioDevice = QAudioDeviceInfo::defaultOutputDevice();
Expand Down Expand Up @@ -184,6 +184,7 @@ class QAVAudioOutputPrivate : public QIODevice

if (bsize > 0)
audioOutput->setBufferSize(bsize);
audioOutput->setVolume(v);
audioOutput->start(this);
}
}
Expand All @@ -201,7 +202,7 @@ class QAVAudioOutputPrivate : public QIODevice
auto bsize = bufferSize;
locker.unlock();
if (fmt.isValid())
init(fmt, bsize);
tryInit(fmt, bsize, v);
if (audioOutput)
audioOutput->setVolume(v);
QCoreApplication::processEvents();
Expand Down
19 changes: 19 additions & 0 deletions src/QtAVPlayer/qavdemuxer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,25 @@ void QAVDemuxer::onFrameSent(const QAVStreamFrame &frame)
d->progress[index].onFrameSent(frame.pts());
}

bool QAVDemuxer::isStreamMaster(const QAVStream &stream) const
{
auto s = stream.stream();
switch (s->codecpar->codec_type) {
case AVMEDIA_TYPE_VIDEO:
return s->disposition != AV_DISPOSITION_ATTACHED_PIC;
case AVMEDIA_TYPE_AUDIO:
// Check if there are any video streams available
for (const auto &vs: currentVideoStreams()) {
if (vs.stream()->disposition != AV_DISPOSITION_ATTACHED_PIC)
return false;
}
return true;
default:
Q_ASSERT(false);
return false;
}
}

QAVStream::Progress QAVDemuxer::progress(const QAVStream &s) const
{
Q_D(const QAVDemuxer);
Expand Down
2 changes: 2 additions & 0 deletions src/QtAVPlayer/qavdemuxer_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ class QAVDemuxer
void onFrameSent(const QAVStreamFrame &frame);
QAVStream::Progress progress(const QAVStream &s) const;

bool isStreamMaster(const QAVStream &stream) const;

static QStringList supportedFormats();
static QStringList supportedVideoCodecs();
static QStringList supportedProtocols();
Expand Down
22 changes: 14 additions & 8 deletions src/QtAVPlayer/qavplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ class QAVPlayerPrivate
const std::vector<std::unique_ptr<QAVFilter>> &filters,
QList<QAVFrame> &filteredFrames);

void doPlayStep(
bool master,
bool doPlayStep(
bool &master,
double refPts,
QAVQueueClock &clock,
QAVPacketQueue<QAVFrame> &queue,
Expand Down Expand Up @@ -279,7 +279,8 @@ void QAVPlayerPrivate::setVideoFrameRate(double v)
void QAVPlayerPrivate::setPts(double v)
{
QMutexLocker locker(&positionMutex);
currPts = v;
if (!isnan(v))
currPts = v;
}

double QAVPlayerPrivate::pts() const
Expand Down Expand Up @@ -688,8 +689,8 @@ bool QAVPlayerPrivate::skipFrame(
return result;
}

void QAVPlayerPrivate::doPlayStep(
bool master,
bool QAVPlayerPrivate::doPlayStep(
bool &master,
double refPts,
QAVQueueClock &clock,
QAVPacketQueue<QAVFrame> &queue,
Expand All @@ -704,6 +705,10 @@ void QAVPlayerPrivate::doPlayStep(
bool flushEvents = false;
int ret = 0;

// Determine if current thread is handling events and pts
if (decodedFrame)
master = demuxer.isStreamMaster(decodedFrame.stream());

// 2. Filter decoded frame
QList<QAVFrame> filteredFrames;
if (decodedFrame)
Expand All @@ -715,7 +720,7 @@ void QAVPlayerPrivate::doPlayStep(
filteredFrames.clear();
if (ret != AVERROR(ENOTSUP)) {
setError(QAVPlayer::FilterError, err_str(ret));
return;
return master;
}
applyFilters(true, decodedFrame);
} else {
Expand Down Expand Up @@ -750,12 +755,13 @@ void QAVPlayerPrivate::doPlayStep(

if (master)
step(flushEvents);
return master;
}

void QAVPlayerPrivate::doPlayVideo()
{
videoClock.setFrameRate(demuxer.videoFrameRate());
const bool master = true;
bool master = true;
bool sync = true;

while (!quit) {
Expand All @@ -777,7 +783,7 @@ void QAVPlayerPrivate::doPlayVideo()

void QAVPlayerPrivate::doPlayAudio()
{
const bool master = demuxer.currentVideoStreams().isEmpty();
bool master = false;
const double ref = -1;
bool sync = true;

Expand Down
22 changes: 20 additions & 2 deletions tests/auto/integration/qavplayer/tst_qavplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ private slots:
void stopAudio();
void seekAudio();
void speedAudio();
void audioPositionWithCover();
void playVideo();
void pauseVideo();
void seekVideo();
Expand Down Expand Up @@ -434,6 +435,23 @@ void tst_QAVPlayer::speedAudio()
QTRY_COMPARE(p.mediaStatus(), QAVPlayer::EndOfMedia);
}

void tst_QAVPlayer::audioPositionWithCover()
{
QAVPlayer p;
qint64 pos = 0;
QAVAudioFrame audioFrame;
QObject::connect(&p, &QAVPlayer::audioFrame, &p, [&](const QAVAudioFrame &f) { pos = p.position(); audioFrame = f; });

QFileInfo file(testData("test.mp3"));
p.setSource(file.absoluteFilePath());
QTRY_COMPARE(p.mediaStatus(), QAVPlayer::LoadedMedia);
p.play();
p.setSynced(false);
QTRY_COMPARE(p.mediaStatus(), QAVPlayer::EndOfMedia);
QVERIFY(audioFrame);
QVERIFY(pos > 0);
}

void tst_QAVPlayer::playVideo()
{
QAVPlayer p;
Expand Down Expand Up @@ -1886,9 +1904,9 @@ void tst_QAVPlayer::multiPlayers()
int framesCount2 = 0;
qint64 pos1 = 0;
qint64 pos2 = 0;
QObject::connect(&p1, &QAVPlayer::videoFrame, &p1, [&](const QAVVideoFrame &f) { ++framesCount1; pos1 = p1.position(); }, Qt::DirectConnection);
QObject::connect(&p1, &QAVPlayer::videoFrame, &p1, [&](const QAVVideoFrame &) { ++framesCount1; pos1 = p1.position(); }, Qt::DirectConnection);
QObject::connect(&p1, &QAVPlayer::audioFrame, &p1, [&](const QAVAudioFrame &f) { o1.play(f); }, Qt::DirectConnection);
QObject::connect(&p2, &QAVPlayer::videoFrame, &p2, [&](const QAVVideoFrame &f) { ++framesCount2; pos2 = p2.position(); }, Qt::DirectConnection);
QObject::connect(&p2, &QAVPlayer::videoFrame, &p2, [&](const QAVVideoFrame &) { ++framesCount2; pos2 = p2.position(); }, Qt::DirectConnection);
QObject::connect(&p2, &QAVPlayer::audioFrame, &p2, [&](const QAVAudioFrame &f) { o2.play(f); }, Qt::DirectConnection);
p1.play();
p2.play();
Expand Down
Binary file added tests/auto/integration/testdata/test.mp3
Binary file not shown.

0 comments on commit 48090d1

Please sign in to comment.