[FFmpeg-devel] [PATCH 2/2] FATE: add tests for v360/ssim360 filters
Anton Khirnov
anton at khirnov.net
Mon Jan 23 13:54:18 EET 2023
---
Now using floats for comparison
---
libavfilter/Makefile | 3 +-
tests/Makefile | 4 +-
tests/fate-run.sh | 6 +
tests/fate/filter-video.mak | 19 +++
tests/ref/fate/filter-spherical-barrel | Bin 0 -> 160 bytes
tests/ref/fate/filter-spherical-c3x2 | Bin 0 -> 160 bytes
tools/Makefile | 1 +
tools/spherical_compare.c | 176 +++++++++++++++++++++++++
8 files changed, 207 insertions(+), 2 deletions(-)
create mode 100644 tests/ref/fate/filter-spherical-barrel
create mode 100644 tests/ref/fate/filter-spherical-c3x2
create mode 100644 tools/spherical_compare.c
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index d4e38bd4e8..2ae174a381 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -626,7 +626,8 @@ SKIPHEADERS-$(CONFIG_OPENCL) += opencl.h
SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_vpp.h
SKIPHEADERS-$(CONFIG_VULKAN) += vulkan.h vulkan_filter.h
-TOOLS = graph2dot
+TOOLS = graph2dot \
+ spherical_compare
TESTPROGS = drawutils filtfmts formats integral
TESTPROGS-$(CONFIG_DNN) += dnn-layer-avgpool dnn-layer-conv2d dnn-layer-dense \
dnn-layer-depth2space dnn-layer-mathbinary \
diff --git a/tests/Makefile b/tests/Makefile
index 1d50e1d175..078d8aa3ce 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -259,7 +259,8 @@ FATE_EXTERN-$(CONFIG_FFMPEG) += $(FATE_SAMPLES_AVCONV) $(FATE_SAMPLES_FFMPEG)
FATE_EXTERN-$(CONFIG_FFPROBE) += $(FATE_SAMPLES_FFPROBE)
FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_SAMPLES_FFMPEG_FFPROBE-yes)
FATE_EXTERN-$(call ALLYES, FFMPEG FFPROBE) += $(FATE_SAMPLES_FFMPEG_FFPROBE)
-FATE_EXTERN += $(FATE_EXTERN-yes) $(FATE_SAMPLES_FASTSTART)
+FATE_EXTERN += $(FATE_EXTERN-yes) $(FATE_SAMPLES_FASTSTART) \
+ $(FATE_SAMPLES_SPHERICAL_COMPARE)
FATE += $(FATE-yes)
@@ -273,6 +274,7 @@ $(FATE_FFPROBE) $(FATE_FFMPEG_FFPROBE) $(FATE_SAMPLES_FFPROBE) $(FATE_SAMPLES_FF
$(FATE_SAMPLES_FASTSTART): tools/qt-faststart$(EXESUF)
$(FATE_SAMPLES_DUMP_DATA) $(FATE_SAMPLES_DUMP_DATA-yes): tools/venc_data_dump$(EXESUF)
$(FATE_SAMPLES_SCALE_SLICE): tools/scale_slice_test$(EXESUF)
+$(FATE_SAMPLES_SPHERICAL_COMPARE): tools/spherical_compare$(EXESUF)
ifdef SAMPLES
FATE += $(FATE_EXTERN)
diff --git a/tests/fate-run.sh b/tests/fate-run.sh
index 61cc59acc0..41e6da5c5d 100755
--- a/tests/fate-run.sh
+++ b/tests/fate-run.sh
@@ -572,6 +572,12 @@ venc_data(){
run tools/venc_data_dump${EXECSUF} ${file} ${stream} ${frames} ${threads} ${thread_type}
}
+spherical_compare(){
+ file=$1
+ filterchain=$2
+ run tools/spherical_compare${EXECSUF} ${file} ${filterchain}
+}
+
null(){
:
}
diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak
index 63873a7a07..731d686cee 100644
--- a/tests/fate/filter-video.mak
+++ b/tests/fate/filter-video.mak
@@ -698,6 +698,25 @@ fate-filter-refcmp-blockdetect-yuv: CMD = cmp_metadata blockdetect yuv420p 0.015
FATE_FILTER_CMP_METADATA-$(CONFIG_BLURDETECT_FILTER) += fate-filter-refcmp-blurdetect-yuv
fate-filter-refcmp-blurdetect-yuv: CMD = cmp_metadata blurdetect yuv420p 0.015
+SPHERICAL_DEPS = MATROSKA_DEMUXER VP8_DECODER V360_FILTER SSIM360_FILTER
+SPHERICAL_SAMPLE = $(TARGET_SAMPLES)/spherical/Worlds_First_Live_360_Rocket_Launch-_Orbital_ATK_CRS-7_cut.mkv
+
+FATE_FILTER_SPHERICAL += fate-filter-spherical-c3x2
+fate-filter-spherical-c3x2: CMD = spherical_compare $(SPHERICAL_SAMPLE) \
+ "split[in][ref];[in]v360=input=e:output=c3x2[main];[main][ref]ssim360=main_projection=c3x2:ref_projection=e"
+
+FATE_FILTER_SPHERICAL += fate-filter-spherical-barrel
+fate-filter-spherical-barrel: CMD = spherical_compare $(SPHERICAL_SAMPLE) \
+ "split[in][ref];[in]v360=input=e:output=barrel[main];[main][ref]ssim360=main_projection=barrel:ref_projection=e"
+
+FATE_SAMPLES_SPHERICAL_COMPARE-$(call ALLYES, $(SPHERICAL_DEPS)) += $(FATE_FILTER_SPHERICAL)
+FATE_SAMPLES_SPHERICAL_COMPARE += $(FATE_SAMPLES_SPHERICAL_COMPARE-yes)
+
+$(FATE_SAMPLES_SPHERICAL_COMPARE): CMP = oneoff
+$(FATE_SAMPLES_SPHERICAL_COMPARE): CMP_UNIT = f32
+
+fate-filter-spherical: $(FATE_SAMPLES_SPHERICAL_COMPARE)
+
FATE_FILTER_CMP_METADATA-$(CONFIG_SITI_FILTER) += fate-filter-refcmp-siti-yuv
fate-filter-refcmp-siti-yuv: CMD = cmp_metadata siti yuv420p 0.015
diff --git a/tests/ref/fate/filter-spherical-barrel b/tests/ref/fate/filter-spherical-barrel
new file mode 100644
index 0000000000000000000000000000000000000000..11d36af7a1b26d4012a8ff5dd7973cb081a50af7
GIT binary patch
literal 160
zcmZ2dP;1Y?&;ZBstrs1apo!UXVTuLqxPYOq&=ylnzV$qYx^?cDVu!z;!%!E~f6fsA
Dpn5ON
literal 0
HcmV?d00001
diff --git a/tests/ref/fate/filter-spherical-c3x2 b/tests/ref/fate/filter-spherical-c3x2
new file mode 100644
index 0000000000000000000000000000000000000000..c59584abd5b89baf7a7bc15f6c4aef1f30f91a9a
GIT binary patch
literal 160
zcmbO=Gt!=cp#hAS6x7<s^iOe|g(T+ju*!ai+(buPu5h?IkXZkrehjhei~BIdY`J<d
U#HvMlFvK)tx-rDQX>>UP0KLjFFaQ7m
literal 0
HcmV?d00001
diff --git a/tools/Makefile b/tools/Makefile
index 4afa23342d..b8c88cd4d3 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -19,6 +19,7 @@ tools/target_io_dem_fuzzer.o: tools/target_dem_fuzzer.c
tools/venc_data_dump$(EXESUF): tools/decode_simple.o
tools/scale_slice_test$(EXESUF): tools/decode_simple.o
+tools/spherical_compare$(EXESUF): tools/decode_simple.o
tools/decode_simple.o: | tools
diff --git a/tools/spherical_compare.c b/tools/spherical_compare.c
new file mode 100644
index 0000000000..59b1283a18
--- /dev/null
+++ b/tools/spherical_compare.c
@@ -0,0 +1,176 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "decode_simple.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/common.h"
+#include "libavutil/dict.h"
+#include "libavutil/error.h"
+#include "libavutil/pixdesc.h"
+
+#include "libavformat/avformat.h"
+
+#include "libavcodec/avcodec.h"
+
+#include "libavfilter/avfilter.h"
+#include "libavfilter/buffersink.h"
+#include "libavfilter/buffersrc.h"
+
+typedef struct PrivData {
+ const char *filterchain;
+ AVFilterGraph *fg;
+ AVFilterContext *src;
+ AVFilterContext *sink;
+ AVFrame *frame;
+
+ uint64_t nb_frames;
+} PrivData;
+
+static int process_frame(DecodeContext *dc, AVFrame *frame)
+{
+ PrivData *pd = dc->opaque;
+ int ret;
+
+ if (!pd->fg) {
+ AVFilterInOut *inputs, *outputs;
+ char filterchain[1024];
+
+ if (!frame)
+ return 0;
+
+ snprintf(filterchain, sizeof(filterchain),
+ "buffer at src=width=%d:height=%d:pix_fmt=%s:time_base=%d/%d,"
+ "%s,buffersink at sink",
+ frame->width, frame->height,
+ av_get_pix_fmt_name(frame->format),
+ dc->stream->time_base.num, dc->stream->time_base.den,
+ pd->filterchain);
+
+ pd->fg = avfilter_graph_alloc();
+ if (!pd->fg)
+ return AVERROR(ENOMEM);
+
+ ret = avfilter_graph_parse2(pd->fg, filterchain, &inputs, &outputs);
+ if (ret < 0)
+ return ret;
+
+ av_assert0(!inputs && !outputs);
+
+ pd->src = avfilter_graph_get_filter(pd->fg, "buffer at src");
+ pd->sink = avfilter_graph_get_filter(pd->fg, "buffersink at sink");
+ av_assert0(pd->src && pd->sink);
+
+ ret = avfilter_graph_config(pd->fg, pd->fg);
+ if (ret < 0)
+ return ret;
+
+ pd->frame = av_frame_alloc();
+ if (!pd->frame)
+ return AVERROR(ENOMEM);
+ }
+
+ ret = av_buffersrc_write_frame(pd->src, frame);
+ if (ret < 0)
+ return ret;
+
+ while (ret >= 0) {
+ static const char *keys[] = {
+ "lavfi.ssim360.Y",
+ "lavfi.ssim360.U",
+ "lavfi.ssim360.V",
+ "lavfi.ssim360.All",
+ "lavfi.ssim360.dB",
+ };
+
+ av_frame_unref(pd->frame);
+ ret = av_buffersink_get_frame(pd->sink, pd->frame);
+ if ((frame && ret == AVERROR(EAGAIN)) ||
+ (!frame && ret == AVERROR_EOF))
+ return 0;
+ else if (ret < 0)
+ return ret;
+
+ fprintf(stderr, "frame %"PRIu64"\n", pd->nb_frames);
+
+ for (int i = 0; i < FF_ARRAY_ELEMS(keys); i++) {
+ const AVDictionaryEntry *t = av_dict_get(pd->frame->metadata, keys[i], NULL, 0);
+ float val;
+ size_t written;
+
+ if (!t) {
+ fprintf(stderr, "Metadata key '%s' not present in frame %"PRIu64"\n",
+ keys[i], pd->nb_frames);
+ return AVERROR(EINVAL);
+ }
+ fprintf(stderr, "%s=%s\n", t->key, t->value);
+
+ val = strtof(t->value, NULL);
+
+ written = fwrite(&val, sizeof(val), 1, stdout);
+ if (written != 1) {
+ fprintf(stderr, "Error writing to stdout\n");
+ return AVERROR(EIO);
+ }
+ }
+
+ pd->nb_frames++;
+ }
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ PrivData pd;
+ DecodeContext dc;
+
+ const char *filename, *fc;
+ int ret = 0;
+
+ if (argc <= 2) {
+ fprintf(stderr, "Usage: %s <input file> <filterchain>\n", argv[0]);
+ return 0;
+ }
+
+ filename = argv[1];
+ fc = argv[2];
+
+ memset(&pd, 0, sizeof(pd));
+ pd.filterchain = fc;
+
+ ret = ds_open(&dc, filename, 0);
+ if (ret < 0)
+ goto finish;
+
+ dc.process_frame = process_frame;
+ dc.opaque = &pd;
+
+ ret = ds_run(&dc);
+
+finish:
+ avfilter_graph_free(&pd.fg);
+ av_frame_free(&pd.frame);
+ ds_free(&dc);
+ return ret;
+}
--
2.35.1
More information about the ffmpeg-devel
mailing list