mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 23:36:38 +00:00
validate: scenario: Add an action type to forward stream from an appsink to an appsrc
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5803>
This commit is contained in:
parent
fd4cd3d85f
commit
aad06b091e
5 changed files with 190 additions and 2 deletions
|
@ -59,6 +59,7 @@
|
||||||
#include "gst-validate-internal.h"
|
#include "gst-validate-internal.h"
|
||||||
#include "validate.h"
|
#include "validate.h"
|
||||||
#include <gst/controller/controller.h>
|
#include <gst/controller/controller.h>
|
||||||
|
#include <gst/app/app.h>
|
||||||
#include <gst/validate/gst-validate-override.h>
|
#include <gst/validate/gst-validate-override.h>
|
||||||
#include <gst/validate/gst-validate-override-registry.h>
|
#include <gst/validate/gst-validate-override-registry.h>
|
||||||
#include <gst/validate/gst-validate-pipeline-monitor.h>
|
#include <gst/validate/gst-validate-pipeline-monitor.h>
|
||||||
|
@ -7043,7 +7044,8 @@ subscenario_done_cb (GstBus * bus, GstMessage * message, gpointer data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstValidateExecuteActionReturn
|
static GstValidateExecuteActionReturn
|
||||||
_create_sub_pipeline (GstValidateScenario * scenario, GstValidateAction * action)
|
_create_sub_pipeline (GstValidateScenario * scenario,
|
||||||
|
GstValidateAction * action)
|
||||||
{
|
{
|
||||||
const gchar *pipeline_desc = NULL, *scenario_name = NULL, *name = NULL;
|
const gchar *pipeline_desc = NULL, *scenario_name = NULL, *name = NULL;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
@ -7116,6 +7118,102 @@ done:
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
forward_appsink_to_appsrc_new_sample (GstAppSink * appsink, gpointer user_data)
|
||||||
|
{
|
||||||
|
GstAppSrc *appsrc = GST_APP_SRC (user_data);
|
||||||
|
|
||||||
|
GstSample *sample = gst_app_sink_pull_sample (appsink);
|
||||||
|
if (!sample) {
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
GstFlowReturn ret = gst_app_src_push_sample (appsrc, sample);
|
||||||
|
gst_sample_unref (sample);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
forward_appsink_to_appsrc_eos (GstAppSink * appsink, gpointer user_data)
|
||||||
|
{
|
||||||
|
GstAppSrc *appsrc = GST_APP_SRC (user_data);
|
||||||
|
|
||||||
|
gst_app_src_end_of_stream (GST_APP_SRC (appsrc));
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstValidateExecuteActionReturn
|
||||||
|
_execute_forward_appsink_to_appsrc (GstValidateScenario * scenario,
|
||||||
|
GstValidateAction * action)
|
||||||
|
{
|
||||||
|
GstElement *sink = NULL, *src = NULL;
|
||||||
|
GstElement *sink_pipeline = NULL, *src_pipeline = NULL;
|
||||||
|
gchar **src_pipeline_element = NULL, **sink_pipeline_element = NULL;
|
||||||
|
GstValidateExecuteActionReturn res = GST_VALIDATE_EXECUTE_ACTION_OK;
|
||||||
|
|
||||||
|
const gchar *sink_name = gst_structure_get_string (action->structure, "sink");
|
||||||
|
const gchar *src_name = gst_structure_get_string (action->structure, "src");
|
||||||
|
|
||||||
|
sink_pipeline_element = g_strsplit (sink_name, "/", 2);
|
||||||
|
if (sink_pipeline_element[1]) {
|
||||||
|
sink_pipeline =
|
||||||
|
gst_validate_scenario_get_sub_pipeline (scenario,
|
||||||
|
sink_pipeline_element[0]);
|
||||||
|
|
||||||
|
REPORT_UNLESS (sink_pipeline, done, "Could not find subpipeline `%s`",
|
||||||
|
sink_pipeline_element[0]);
|
||||||
|
} else {
|
||||||
|
sink_pipeline = gst_validate_scenario_get_pipeline (scenario);
|
||||||
|
}
|
||||||
|
|
||||||
|
src_pipeline_element = g_strsplit (src_name, "/", 2);
|
||||||
|
if (src_pipeline_element[1]) {
|
||||||
|
src_pipeline =
|
||||||
|
gst_validate_scenario_get_sub_pipeline (scenario,
|
||||||
|
src_pipeline_element[0]);
|
||||||
|
|
||||||
|
REPORT_UNLESS (sink_pipeline, done, "Could not find subpipeline `%s`",
|
||||||
|
src_pipeline_element[0]);
|
||||||
|
} else {
|
||||||
|
src_pipeline = gst_validate_scenario_get_pipeline (scenario);
|
||||||
|
}
|
||||||
|
|
||||||
|
REPORT_UNLESS (((sink =
|
||||||
|
gst_bin_get_by_name (GST_BIN (sink_pipeline),
|
||||||
|
sink_pipeline_element[1] ? sink_pipeline_element[1] :
|
||||||
|
sink_name))
|
||||||
|
&& GST_IS_APP_SINK (sink)), done,
|
||||||
|
"Could not find appsink '%s' (%" GST_PTR_FORMAT ") in %" GST_PTR_FORMAT,
|
||||||
|
sink_name, sink, sink_pipeline);
|
||||||
|
REPORT_UNLESS (((src =
|
||||||
|
gst_bin_get_by_name (GST_BIN (src_pipeline),
|
||||||
|
src_pipeline_element[1] ? src_pipeline_element[1] : src_name))
|
||||||
|
&& GST_IS_APP_SRC (src)), done,
|
||||||
|
"Could not find appsrc '%s' (%" GST_PTR_FORMAT ") in %" GST_PTR_FORMAT,
|
||||||
|
src_name, src, src_pipeline);
|
||||||
|
|
||||||
|
GstAppSinkCallbacks callbacks = {
|
||||||
|
.eos = forward_appsink_to_appsrc_eos,
|
||||||
|
.new_preroll = NULL,
|
||||||
|
.new_sample = forward_appsink_to_appsrc_new_sample
|
||||||
|
};
|
||||||
|
|
||||||
|
gst_app_sink_set_callbacks (GST_APP_SINK (sink), &callbacks,
|
||||||
|
gst_object_ref (src), gst_object_unref);
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (src_pipeline_element)
|
||||||
|
g_strfreev (src_pipeline_element);
|
||||||
|
if (sink_pipeline_element)
|
||||||
|
g_strfreev (sink_pipeline_element);
|
||||||
|
gst_clear_object (&src_pipeline);
|
||||||
|
gst_clear_object (&sink_pipeline);
|
||||||
|
gst_clear_object (&src);
|
||||||
|
gst_clear_object (&sink);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_validate_action_get_scenario:
|
* gst_validate_action_get_scenario:
|
||||||
|
@ -8193,6 +8291,26 @@ register_action_types (void)
|
||||||
"queues a eos event in an appsrc.",
|
"queues a eos event in an appsrc.",
|
||||||
GST_VALIDATE_ACTION_TYPE_NONE);
|
GST_VALIDATE_ACTION_TYPE_NONE);
|
||||||
|
|
||||||
|
REGISTER_ACTION_TYPE ("appsink-forward-to-appsrc", _execute_forward_appsink_to_appsrc,
|
||||||
|
((GstValidateActionParameter [])
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.name = "sink",
|
||||||
|
.description = "the name of the appsink to forward samples/events from",
|
||||||
|
.mandatory = TRUE,
|
||||||
|
.types = "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "src",
|
||||||
|
.description = "the name of the appsrc to forward samples/events to",
|
||||||
|
.mandatory = TRUE,
|
||||||
|
.types = "string"
|
||||||
|
},
|
||||||
|
{NULL}
|
||||||
|
}),
|
||||||
|
"queues a eos event in an appsrc.",
|
||||||
|
GST_VALIDATE_ACTION_TYPE_NONE);
|
||||||
|
|
||||||
REGISTER_ACTION_TYPE ("flush", _execute_flush,
|
REGISTER_ACTION_TYPE ("flush", _execute_flush,
|
||||||
((GstValidateActionParameter [])
|
((GstValidateActionParameter [])
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,7 +56,7 @@ gst_validate_enums = gnome.mkenums('gstvalidateenumtypes',
|
||||||
install_header : true,
|
install_header : true,
|
||||||
install_dir : join_paths(get_option('includedir'), 'gstreamer-1.0/gst/validate'))
|
install_dir : join_paths(get_option('includedir'), 'gstreamer-1.0/gst/validate'))
|
||||||
|
|
||||||
validate_deps = [gst_check_dep, gst_dep, gst_controller_dep, gstbase_dep,
|
validate_deps = [gst_check_dep, gst_dep, gst_controller_dep, gstbase_dep, gstapp_dep,
|
||||||
gio_dep, gmodule_dep, gst_pbutils_dep, mathlib, json_dep]
|
gio_dep, gmodule_dep, gst_pbutils_dep, mathlib, json_dep]
|
||||||
gstvalidate = library('gstvalidate-@0@'.format(apiversion),
|
gstvalidate = library('gstvalidate-@0@'.format(apiversion),
|
||||||
sources: gstvalidate_sources + gst_validate_enums + runner_file,
|
sources: gstvalidate_sources + gst_validate_enums + runner_file,
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
set-globals,
|
||||||
|
appsrc_props="handle-segment-change=true \
|
||||||
|
automatic-eos=false \
|
||||||
|
min-latency=0 \
|
||||||
|
max-latency=-1 \
|
||||||
|
format=time \
|
||||||
|
is-live=true \
|
||||||
|
max-buffers=0 \
|
||||||
|
max-bytes=0 \
|
||||||
|
max-time=5000000000 \
|
||||||
|
leaky-type=downstream"
|
||||||
|
|
||||||
|
meta,
|
||||||
|
args = {
|
||||||
|
"appsrc name=src $(appsrc_props) ! videoconvert ! $(videosink) name=sink",
|
||||||
|
},
|
||||||
|
configs = {
|
||||||
|
"$(validateflow), pad=source-sink:sink, buffers-checksum=as-id, ignored-event-types={ tag, stream-start }",
|
||||||
|
"$(validateflow), pad=selector-sink:sink, buffers-checksum=as-id, ignored-event-types={ tag, stream-start }",
|
||||||
|
},
|
||||||
|
handles-states=true,
|
||||||
|
ignore-eos=true
|
||||||
|
|
||||||
|
# Source pipeline
|
||||||
|
create-sub-pipeline,
|
||||||
|
name=source,
|
||||||
|
desc="videotestsrc num-buffers=5 name=src ! video/x-raw,framerate=30/1,format=I420,width=320,height=240 ! timeoverlay ! appsink name=source-sink sync=true max-buffers=10 drop=true",
|
||||||
|
scenario={
|
||||||
|
[meta],
|
||||||
|
}
|
||||||
|
|
||||||
|
# "selector" pipeline
|
||||||
|
create-sub-pipeline,
|
||||||
|
name=selector,
|
||||||
|
desc="appsrc name=selector-src1 $(appsrc_props) ! input-selector ! appsink name=selector-sink sync=true max-buffers=10 drop=true",
|
||||||
|
scenario={
|
||||||
|
[meta],
|
||||||
|
}
|
||||||
|
|
||||||
|
appsink-forward-to-appsrc,
|
||||||
|
sink=source/source-sink,
|
||||||
|
src=selector/selector-src1
|
||||||
|
|
||||||
|
appsink-forward-to-appsrc,
|
||||||
|
sink=selector/selector-sink,
|
||||||
|
src=src
|
||||||
|
|
||||||
|
play
|
||||||
|
|
||||||
|
wait, subpipeline-done=source
|
||||||
|
wait, subpipeline-done=selector
|
||||||
|
|
||||||
|
stop
|
|
@ -0,0 +1,8 @@
|
||||||
|
event caps: video/x-raw, format=(string)I420, framerate=(fraction)30/1, height=(int)240, interlace-mode=(string)progressive, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, width=(int)320;
|
||||||
|
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
|
||||||
|
buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:00.033333333, flags=discont
|
||||||
|
buffer: content-id=1, pts=0:00:00.033333333, dur=0:00:00.033333333
|
||||||
|
buffer: content-id=2, pts=0:00:00.066666666, dur=0:00:00.033333334
|
||||||
|
buffer: content-id=3, pts=0:00:00.100000000, dur=0:00:00.033333333
|
||||||
|
buffer: content-id=4, pts=0:00:00.133333333, dur=0:00:00.033333333
|
||||||
|
event eos: (no structure)
|
|
@ -0,0 +1,9 @@
|
||||||
|
event caps: video/x-raw(memory:SystemMemory, meta:GstVideoOverlayComposition), format=(string)I420, framerate=(fraction)30/1, height=(int)240, interlace-mode=(string)progressive, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, width=(int)320;
|
||||||
|
event caps: video/x-raw, format=(string)I420, framerate=(fraction)30/1, height=(int)240, interlace-mode=(string)progressive, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, width=(int)320;
|
||||||
|
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
|
||||||
|
buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:00.033333333, flags=discont
|
||||||
|
buffer: content-id=1, pts=0:00:00.033333333, dur=0:00:00.033333333
|
||||||
|
buffer: content-id=2, pts=0:00:00.066666666, dur=0:00:00.033333334
|
||||||
|
buffer: content-id=3, pts=0:00:00.100000000, dur=0:00:00.033333333
|
||||||
|
buffer: content-id=4, pts=0:00:00.133333333, dur=0:00:00.033333333
|
||||||
|
event eos: (no structure)
|
Loading…
Reference in a new issue