Skip to content

Commit

Permalink
Merge pull request #385 from valbok/frames-count
Browse files Browse the repository at this point in the history
Fix multiple mixed filters and frames count
  • Loading branch information
valbok authored Jul 19, 2023
2 parents 06224e8 + 0dfc080 commit e0991da
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 16 deletions.
14 changes: 8 additions & 6 deletions src/QtAVPlayer/qavaudiofilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,13 @@ int QAVAudioFilter::write(const QAVFrame &frame)
return 0;
}

void QAVAudioFilter::read(QAVFrame &frame)
int QAVAudioFilter::read(QAVFrame &frame)
{
Q_D(QAVAudioFilter);
if (d->outputs.isEmpty() || d->isEmpty) {
if (!d->outputs.isEmpty())
frame = d->sourceFrame;
d->sourceFrame = {};
d->isEmpty = true;
return;
return AVERROR(EAGAIN);
}

int ret = 0;
Expand All @@ -113,7 +111,7 @@ void QAVAudioFilter::read(QAVFrame &frame)
if (out.frame()->duration == AV_NOPTS_VALUE || out.frame()->duration == 0)
out.frame()->duration = d->sourceFrame.frame()->duration;
#endif
frame.setTimeBase(av_buffersink_get_time_base(filter.ctx()));
out.setTimeBase(av_buffersink_get_time_base(filter.ctx()));
out.setFilterName(
!filter.name().isEmpty()
? filter.name()
Expand All @@ -125,12 +123,16 @@ void QAVAudioFilter::read(QAVFrame &frame)
}
}

if (!d->outputFrames.isEmpty())
ret = AVERROR(EAGAIN);
if (!d->outputFrames.isEmpty()) {
frame = d->outputFrames.takeFirst();
ret = 0;
}
if (d->outputFrames.isEmpty()) {
d->sourceFrame = {};
d->isEmpty = true;
}
return ret;
}

void QAVAudioFilter::flush()
Expand Down
2 changes: 1 addition & 1 deletion src/QtAVPlayer/qavaudiofilter_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class Q_AVPLAYER_EXPORT QAVAudioFilter : public QAVFilter
QMutex &mutex);

int write(const QAVFrame &frame) override;
void read(QAVFrame &frame) override;
int read(QAVFrame &frame) override;
void flush() override;

protected:
Expand Down
2 changes: 1 addition & 1 deletion src/QtAVPlayer/qavfilter_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class Q_AVPLAYER_EXPORT QAVFilter
virtual ~QAVFilter();

virtual int write(const QAVFrame &frame) = 0;
virtual void read(QAVFrame &frame) = 0;
virtual int read(QAVFrame &frame) = 0;
// Checks if all frames have been read
bool isEmpty() const;
virtual void flush() = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/QtAVPlayer/qavfilters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ static int readFrames(
// Read all frames from all filters at once
for (size_t i = 0; i < filters.size(); ++i) {
do {
filters[i]->read(frame);
if (frame)
int ret = filters[i]->read(frame);
if (ret >= 0)
filteredFrames.append(frame);
} while (!filters[i]->isEmpty());
}
Expand Down
12 changes: 7 additions & 5 deletions src/QtAVPlayer/qavvideofilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,13 @@ int QAVVideoFilter::write(const QAVFrame &frame)
return 0;
}

void QAVVideoFilter::read(QAVFrame &frame)
int QAVVideoFilter::read(QAVFrame &frame)
{
Q_D(QAVVideoFilter);
if (d->outputs.isEmpty() || d->isEmpty) {
if (!d->outputs.isEmpty())
frame = d->sourceFrame;
d->sourceFrame = {};
d->isEmpty = true;
return;
return AVERROR(EAGAIN);
}

int ret = 0;
Expand Down Expand Up @@ -120,12 +118,16 @@ void QAVVideoFilter::read(QAVFrame &frame)
}
}

if (!d->outputFrames.isEmpty())
ret = AVERROR(EAGAIN);
if (!d->outputFrames.isEmpty()) {
frame = d->outputFrames.takeFirst();
ret = 0;
}
if (d->outputFrames.isEmpty()) {
d->sourceFrame = {};
d->isEmpty = true;
}
return ret;
}

void QAVVideoFilter::flush()
Expand Down
2 changes: 1 addition & 1 deletion src/QtAVPlayer/qavvideofilter_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class Q_AVPLAYER_EXPORT QAVVideoFilter : public QAVFilter
QMutex &mutex);

int write(const QAVFrame &frame) override;
void read(QAVFrame &frame) override;
int read(QAVFrame &frame) override;
void flush() override;

protected:
Expand Down
49 changes: 49 additions & 0 deletions tests/auto/integration/qavplayer/tst_qavplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ private slots:
void filterNameStep();
void audioVideoFilter();
void audioFilterVideoFrames();
void multipleFilters();
void inputFormat();
void inputVideoCodec();
void flushFilters();
Expand Down Expand Up @@ -2993,6 +2994,54 @@ void tst_QAVPlayer::audioFilterVideoFrames()
QVERIFY(audioFramesCount > 0);
}

void tst_QAVPlayer::multipleFilters()
{
qputenv("QT_AVPLAYER_NO_HWDEVICE", "1");
QAVPlayer p;
QFileInfo file(testData("test.mkv"));
p.setSource(file.absoluteFilePath());
QList<QString> filters = {
"signalstats=stat=tout+vrep+brng [stats]",
"aformat=sample_fmts=flt|fltp,astats=metadata=1:reset=1:length=0.4,aphasemeter=video=0,ebur128=metadata=1,aformat=sample_fmts=flt|fltp",
"scale=72:72,format=rgb24 [thumbnails]",
"scale=iw/4:ih/4,format=gray,convolution=0m='0 1 0 1 -4 1 0 1 0':0bias=128,split[a][b];[a]scale=iw:1[a1];[a1][b]scale2ref[a2][b];[b][a2]lut2=c0=((x-y)*(x-y))/2,scale=iw:1,transpose=2,tile=layout=512x1,setsar=1/1,format=rgb24 [panel_0]",
"scale,format=rgb24,crop=1:ih:iw/2:0,tile=layout=512x1,setsar=1/1 [panel_1]",
"scale,format=rgb24,transpose=2,crop=1:ih:iw/2:0,tile=layout=512x1,setsar=1/1 [panel_2]",
"aformat=channel_layouts=stereo:sample_fmts=flt|fltp,ahistogram=dmode=separate:rheight=0:s=360x1:r=32,transpose=2,tile=layout=512x1,format=rgb24 [panel_3]",
"aformat=channel_layouts=stereo:sample_fmts=flt|fltp,showwaves=mode=p2p:split_channels=1:size=512x360:scale=lin:draw=full:rate=32/512,format=rgb24 [panel_4]",
};

QMap<QString, int> framesCount;
QObject::connect(&p, &QAVPlayer::videoFrame, &p, [&](const QAVVideoFrame &f) {
++framesCount[f.filterName()];
}, Qt::DirectConnection);

QObject::connect(&p, &QAVPlayer::audioFrame, &p, [&](const QAVAudioFrame &f) {
++framesCount[f.filterName()];
}, Qt::DirectConnection);

p.setSynced(false);
p.setFilters(filters);
p.play();
QTRY_COMPARE_WITH_TIMEOUT(p.mediaStatus(), QAVPlayer::EndOfMedia, 15000);
QVERIFY(framesCount.contains("stats"));
QCOMPARE(framesCount["stats"], 250);
QVERIFY(framesCount.contains("1:0"));
QCOMPARE(framesCount["1:0"], 101);
QVERIFY(framesCount.contains("thumbnails"));
QCOMPARE(framesCount["thumbnails"], 250);
QVERIFY(framesCount.contains("panel_0"));
QCOMPARE(framesCount["panel_0"], 1);
QVERIFY(framesCount.contains("panel_1"));
QCOMPARE(framesCount["panel_1"], 1);
QVERIFY(framesCount.contains("panel_2"));
QCOMPARE(framesCount["panel_2"], 1);
QVERIFY(framesCount.contains("panel_3"));
QCOMPARE(framesCount["panel_3"], 1);
QVERIFY(framesCount.contains("panel_4"));
QCOMPARE(framesCount["panel_4"], 1);
}

void tst_QAVPlayer::inputFormat()
{
QAVPlayer p;
Expand Down

0 comments on commit e0991da

Please sign in to comment.