summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/elements/test-roi.c200
1 files changed, 137 insertions, 63 deletions
diff --git a/tests/elements/test-roi.c b/tests/elements/test-roi.c
index 2818a10e..2ce614ef 100644
--- a/tests/elements/test-roi.c
+++ b/tests/elements/test-roi.c
@@ -20,55 +20,129 @@
*/
#include <stdio.h>
-#include <string.h>
#include <gst/gst.h>
+#include <gst/video/navigation.h>
+#include <gst/video/gstvideometa.h>
typedef struct _CustomData
{
GstElement *pipeline;
- GstPad *src_pad;
GMainLoop *loop;
+ gboolean roi_enabled;
} AppData;
static void
-send_roi_event (AppData * data)
+send_eos_event (AppData * data)
{
- gboolean res = FALSE;
- GstEvent *event;
- gint value[2] = { 4, 0 };
- static gint counter = 0;
-
- event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_OOB,
- gst_structure_new ("GstVaapiEncoderRegionOfInterest",
- "roi-x", G_TYPE_UINT, 0,
- "roi-y", G_TYPE_UINT, 0,
- "roi-width", G_TYPE_UINT, 320,
- "roi-height", G_TYPE_UINT, 240,
- "roi-value", G_TYPE_INT, value[counter++ % 2], NULL));
-
- /* Send the event */
- res = gst_pad_push_event (data->src_pad, event);
- g_print ("Sending event %p done: %d\n", event, res);
+ gst_element_send_event (data->pipeline, gst_event_new_eos ());
}
static void
-send_eos_event (AppData * data)
+dispatch_keystroke (AppData * app, const gchar * str)
{
- GstBus *bus;
- GstMessage *msg;
+ switch (g_ascii_tolower (str[0])) {
+ case 'r':
+ app->roi_enabled = !app->roi_enabled;
+ gst_println ("ROI %s", app->roi_enabled ? "enabled" : "disabled");
+ break;
+ case 'q':
+ send_eos_event (app);
+ break;
+ default:
+ break;
+ }
- bus = gst_element_get_bus (data->pipeline);
- gst_element_send_event (data->pipeline, gst_event_new_eos ());
- msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_EOS);
+ return;
+}
- gst_message_unref (msg);
- gst_object_unref (bus);
+static void
+cb_msg (GstBus * bus, GstMessage * msg, gpointer data)
+{
+ AppData *app = data;
+ GstNavigationMessageType mtype = gst_navigation_message_get_type (msg);
+ GstEvent *ev = NULL;
+ GstNavigationEventType type;
+ const gchar *key;
+
+ if (mtype != GST_NAVIGATION_MESSAGE_EVENT)
+ return;
+ if (!gst_navigation_message_parse_event (msg, &ev))
+ goto bail;
+
+ type = gst_navigation_event_get_type (ev);
+ if (type != GST_NAVIGATION_EVENT_KEY_PRESS)
+ goto bail;
+ if (!gst_navigation_event_parse_key_event (ev, &key))
+ goto bail;
+
+ dispatch_keystroke (app, key);
+
+bail:
+ if (ev)
+ gst_event_unref (ev);
+}
+
+static void
+cb_msg_eos (GstBus * bus, GstMessage * msg, gpointer data)
+{
+ AppData *app = data;
+ g_main_loop_quit (app->loop);
+}
+
+
+static void
+cb_msg_error (GstBus * bus, GstMessage * msg, gpointer data)
+{
+ AppData *app = data;
+ gchar *debug = NULL;
+ GError *err = NULL;
+
+ gst_message_parse_error (msg, &err, &debug);
+
+ g_print ("Error: %s\n", err->message);
+ g_error_free (err);
+
+ if (debug) {
+ g_print ("Debug details: %s\n", debug);
+ g_free (debug);
+ }
+
+ g_main_loop_quit (app->loop);
+}
+
+static GstPadProbeReturn
+cb_add_roi (GstPad * pad, GstPadProbeInfo * info, gpointer data)
+{
+ AppData *app = data;
+ GstVideoRegionOfInterestMeta *rmeta;
+ GstBuffer *buf = GST_PAD_PROBE_INFO_BUFFER (info);
+ GstStructure *s;
+
+ if (!app->roi_enabled)
+ return GST_PAD_PROBE_OK;
+
+ buf = gst_buffer_make_writable (buf);
+ if (!buf)
+ return GST_PAD_PROBE_OK;
+
+ rmeta =
+ gst_buffer_add_video_region_of_interest_meta (buf, "test", 0, 0, 320,
+ 240);
+ if (!rmeta)
+ return GST_PAD_PROBE_OK;
+
+ s = gst_structure_new ("roi/vaapi", "delta-qp", G_TYPE_INT, -10, NULL);
+ gst_video_region_of_interest_meta_add_param (rmeta, s);
+
+ GST_PAD_PROBE_INFO_DATA (info) = buf;
+ return GST_PAD_PROBE_OK;
}
/* Process keyboard input */
static gboolean
-handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data)
+handle_keyboard (GIOChannel * source, GIOCondition cond, gpointer data)
{
+ AppData *app = data;
gchar *str = NULL;
if (g_io_channel_read_line (source, &str, NULL, NULL,
@@ -76,20 +150,9 @@ handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data)
return TRUE;
}
- switch (g_ascii_tolower (str[0])) {
- case 'r':
- send_roi_event (data);
- break;
- case 'q':
- send_eos_event (data);
- g_main_loop_quit (data->loop);
- break;
- default:
- break;
- }
+ dispatch_keystroke (app, str);
g_free (str);
-
return TRUE;
}
@@ -97,7 +160,7 @@ handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data)
* This is an example pipeline to recognize difference between ROI and non-ROI.
* 1. Produce snow pattern with 320p
* 2. Encode and decode the raw data with 2 pipelines at same time.
- * 2.1. Inject a GstCustomEvent to the 2nd pipeline to enable ROI.
+ * 2.1. Insert GstVideoRegionOfInterestMeta to the 2nd pipeline buffers to enable ROI.
* 3. Mix both streams in videomixer.
* 5. Output the result in one window.
*
@@ -116,37 +179,41 @@ handle_keyboard (GIOChannel * source, GIOCondition cond, AppData * data)
'--->Q->|txtovrly|->|enc|->|dec|->|vpp|->|videobox|->'
^ '--------' '---' '---' '---' '--------'
|
- '-- Injection of GstCustomEvent "GstVaapiEncoderRegionOfInterest"
+ '-- Insert GstVideoRegionOfInterestMeta width roit/vaapi params on buffers
*/
int
main (int argc, char *argv[])
{
- AppData data;
+ AppData data = { 0, };
GstStateChangeReturn ret;
- GstElement *q;
- GIOChannel *io_stdin;
+ GstElement *el;
+ GstPad *pad;
GError *err = NULL;
+ GIOChannel *io_stdin;
+ GstBus *bus;
+
+ data.roi_enabled = TRUE;
/* Initialize GStreamer */
gst_init (&argc, &argv);
/* Print usage map */
- g_print ("USAGE: Choose one of the following options, then press enter:\n"
- " 'r' to send ROI event \n" " 'q' to quit\n");
+ g_print ("USAGE: 'r' to enable/disable ROI && 'q' to quit\n");
-#define ENCDEC "vaapih264enc rate-control=cbr bitrate=2000 ! vaapih264dec ! vaapipostproc width=640 "
-#define TEXT "textoverlay font-desc=\"Arial Bold 48\" text="
+#define SRC "videotestsrc pattern=snow ! " \
+ "video/x-raw, format=NV12, width=320, framerate=5/1"
+#define ENCDEC "vaapih265enc rate-control=cbr bitrate=2000 ! vaapih265dec ! " \
+ "vaapipostproc ! video/x-raw, width=640"
+#define TEXT "textoverlay font-desc=\"Arial Bold 48\" "
data.pipeline =
gst_parse_launch
("videomixer name=mix ! vaapipostproc ! vaapisink sync=false "
- "videotestsrc pattern=snow ! video/x-raw, width=320, framerate=5/1 "
- "! tee name=t "
- "t. ! queue ! " TEXT "\"non-ROI\" ! " ENCDEC
- "! videobox left=-640 ! mix. "
- "t. ! queue name=roi ! " TEXT "\"ROI\" ! " ENCDEC
- "! videobox ! mix.", &err);
+ SRC " ! tee name=t ! queue ! " TEXT " text=\"non-ROI\" ! " ENCDEC
+ " ! videobox left=-640 ! mix. "
+ " t. ! queue name=roi ! " TEXT " text=\"ROI\" ! " ENCDEC
+ " ! videobox ! mix.", &err);
if (err) {
g_printerr ("failed to parse pipeline: %s\n", err->message);
@@ -154,13 +221,23 @@ main (int argc, char *argv[])
return -1;
}
- q = gst_bin_get_by_name (GST_BIN (data.pipeline), "roi");
- data.src_pad = gst_element_get_static_pad (q, "src");
- gst_object_unref (q);
+ bus = gst_pipeline_get_bus (GST_PIPELINE (data.pipeline));
+ gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
+ gst_bus_enable_sync_message_emission (bus);
+ g_signal_connect (bus, "message::error", G_CALLBACK (cb_msg_error), &data);
+ g_signal_connect (bus, "message::eos", G_CALLBACK (cb_msg_eos), &data);
+ g_signal_connect (bus, "message::element", G_CALLBACK (cb_msg), &data);
+ gst_object_unref (bus);
+
+ el = gst_bin_get_by_name (GST_BIN (data.pipeline), "roi");
+ pad = gst_element_get_static_pad (el, "src");
+ gst_object_unref (el);
+ gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, cb_add_roi, &data, NULL);
+ gst_object_unref (pad);
/* Add a keyboard watch so we get notified of keystrokes */
io_stdin = g_io_channel_unix_new (fileno (stdin));
- g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc) handle_keyboard, &data);
+ g_io_add_watch (io_stdin, G_IO_IN, handle_keyboard, &data);
/* Start playing */
ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING);
@@ -176,12 +253,9 @@ main (int argc, char *argv[])
/* Free resources */
g_main_loop_unref (data.loop);
- g_io_channel_unref (io_stdin);
gst_element_set_state (data.pipeline, GST_STATE_NULL);
-
- if (data.src_pad)
- gst_object_unref (data.src_pad);
gst_object_unref (data.pipeline);
+ g_io_channel_unref (io_stdin);
return 0;
}