From: Tim-Philipp Müller Date: Sat, 23 Mar 2019 12:24:04 +0000 (+0000) Subject: tests: icles: add video conversion benchmark X-Git-Tag: 1.19.3~511^2~1163 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ba183af4792bc7dd6acda705dcabebcbce16b700;p=platform%2Fupstream%2Fgstreamer.git tests: icles: add video conversion benchmark Split out the benchmarking code from the unit test and make it a bit more useful. --- diff --git a/tests/icles/.gitignore b/tests/icles/.gitignore index 51f9fe2..5eb9d9a 100644 --- a/tests/icles/.gitignore +++ b/tests/icles/.gitignore @@ -1,6 +1,7 @@ audio-trickplay benchmark-appsink benchmark-appsrc +benchmark-video-conversion input-selector-test output-selector-test playbin-text diff --git a/tests/icles/Makefile.am b/tests/icles/Makefile.am index a51da87..74b575c 100644 --- a/tests/icles/Makefile.am +++ b/tests/icles/Makefile.am @@ -17,6 +17,13 @@ benchmark_appsrc_LDADD = \ $(top_builddir)/gst-libs/gst/app/libgstapp-$(GST_API_VERSION).la \ $(GST_LIBS) +benchmark_video_conversion_SOURCES = benchmark-video-conversion.c +benchmark_video_conversion_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \ + $(GST_BASE_CFLAGS) $(GST_CFLAGS) +benchmark_video_conversion_LDADD = \ + $(top_builddir)/gst-libs/gst/video/libgstvideo-$(GST_API_VERSION).la \ + $(GST_LIBS) $(LIBM) + if USE_X X_TESTS = stress-videooverlay @@ -119,4 +126,4 @@ test_reverseplay_LDADD = $(GST_LIBS) $(LIBM) noinst_PROGRAMS = $(X_TESTS) $(PANGO_TESTS) \ audio-trickplay playbin-text position-formats stress-playbin \ test-scale test-box test-effect-switch test-overlay-blending test-reverseplay \ - test-resample benchmark-appsink benchmark-appsrc + test-resample benchmark-appsink benchmark-appsrc benchmark-video-conversion diff --git a/tests/icles/benchmark-video-conversion.c b/tests/icles/benchmark-video-conversion.c new file mode 100644 index 0000000..f81377e --- /dev/null +++ b/tests/icles/benchmark-video-conversion.c @@ -0,0 +1,154 @@ +/* GStreamer video format conversion benchmark + * Copyright (C) 2014 Wim Taymans + * Copyright (C) 2019 Tim-Philipp Müller + + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#define DEFAULT_WIDTH 1920 +#define DEFAULT_HEIGHT 1080 + +#define DEFAULT_DURATION 2.0 + +static gint +get_num_formats (void) +{ + gint num_formats = 100; + + while (gst_video_format_to_string (num_formats) == NULL) + --num_formats; + GST_INFO ("number of known video formats: %d", num_formats); + return num_formats + 1; +} + +static void +do_benchmark_conversions (guint width, guint height, const gchar * in_format, + const gchar * out_format, gdouble max_duration) +{ + const gchar *infmt_str, *outfmt_str; + GstVideoFormat infmt, outfmt; + GTimer *timer; + gint num_formats; + + timer = g_timer_new (); + + num_formats = get_num_formats (); + + for (infmt = GST_VIDEO_FORMAT_I420; infmt < num_formats; infmt++) { + GstVideoInfo ininfo; + GstVideoFrame inframe; + GstBuffer *inbuffer; + + infmt_str = gst_video_format_to_string (infmt); + if (in_format != NULL && !g_str_equal (in_format, infmt_str)) + continue; + + gst_video_info_set_format (&ininfo, infmt, width, height); + inbuffer = gst_buffer_new_and_alloc (ininfo.size); + gst_buffer_memset (inbuffer, 0, 0, -1); + gst_video_frame_map (&inframe, &ininfo, inbuffer, GST_MAP_READ); + + for (outfmt = GST_VIDEO_FORMAT_I420; outfmt < num_formats; outfmt++) { + GstVideoInfo outinfo; + GstVideoFrame outframe; + GstBuffer *outbuffer; + GstVideoConverter *convert; + gdouble elapsed, convert_sec; + gint count; + + outfmt_str = gst_video_format_to_string (outfmt); + if (out_format != NULL && !g_str_equal (out_format, outfmt_str)) + continue; + + /* Or maybe we should allocate more buffers to minimise cache effects? */ + gst_video_info_set_format (&outinfo, outfmt, width, height); + outbuffer = gst_buffer_new_and_alloc (outinfo.size); + gst_video_frame_map (&outframe, &outinfo, outbuffer, GST_MAP_WRITE); + + convert = gst_video_converter_new (&ininfo, &outinfo, NULL); + /* warmup */ + gst_video_converter_frame (convert, &inframe, &outframe); + + count = 0; + g_timer_start (timer); + while (TRUE) { + gst_video_converter_frame (convert, &inframe, &outframe); + + count++; + elapsed = g_timer_elapsed (timer, NULL); + if (elapsed >= max_duration) + break; + } + + convert_sec = count / elapsed; + + gst_println ("%8.1f conversions/sec %s -> %s @ %ux%u, %d/%.5f", + convert_sec, infmt_str, outfmt_str, width, height, count, elapsed); + + gst_video_converter_free (convert); + + gst_video_frame_unmap (&outframe); + gst_buffer_unref (outbuffer); + } + gst_video_frame_unmap (&inframe); + gst_buffer_unref (inbuffer); + } + + g_timer_destroy (timer); +} + +int +main (int argc, char **argv) +{ + GError *err = NULL; + gint width = DEFAULT_WIDTH; + gint height = DEFAULT_HEIGHT; + gdouble max_dur = DEFAULT_DURATION; + gchar *from_fmt = NULL; + gchar *to_fmt = NULL; + GOptionContext *ctx; + GOptionEntry options[] = { + {"width", 'w', 0, G_OPTION_ARG_INT, &width, "Width", NULL}, + {"height", 'h', 0, G_OPTION_ARG_INT, &height, "Height", NULL}, + {"from-format", 'f', 0, G_OPTION_ARG_STRING, &from_fmt, "From Format", + NULL}, + {"to-format", 't', 0, G_OPTION_ARG_STRING, &to_fmt, "To Format", NULL}, + {"duration", 'd', 0, G_OPTION_ARG_DOUBLE, &max_dur, + "Benchmark duration for each run (in seconds)", NULL}, + {NULL} + }; + + ctx = g_option_context_new (""); + g_option_context_add_main_entries (ctx, options, NULL); + g_option_context_add_group (ctx, gst_init_get_option_group ()); + if (!g_option_context_parse (ctx, &argc, &argv, &err)) { + g_print ("Error initializing: %s\n", GST_STR_NULL (err->message)); + g_option_context_free (ctx); + g_clear_error (&err); + return 1; + } + g_option_context_free (ctx); + + do_benchmark_conversions (width, height, from_fmt, to_fmt, max_dur); + return 0; +} diff --git a/tests/icles/meson.build b/tests/icles/meson.build index d753761..5b9d519 100644 --- a/tests/icles/meson.build +++ b/tests/icles/meson.build @@ -1,6 +1,7 @@ base_icles = [ [ 'benchmark-appsink.c', false, [gst_base_dep, app_dep], true ], [ 'benchmark-appsrc.c', false, [gst_base_dep, app_dep], true ], + [ 'benchmark-video-conversion.c', false, [gst_base_dep, video_dep], true ], [ 'audio-trickplay.c', false, [gst_controller_dep] ], [ 'playbin-text.c' ], [ 'stress-playbin.c' ],