mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 15:27:07 +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 "validate.h"
|
||||
#include <gst/controller/controller.h>
|
||||
#include <gst/app/app.h>
|
||||
#include <gst/validate/gst-validate-override.h>
|
||||
#include <gst/validate/gst-validate-override-registry.h>
|
||||
#include <gst/validate/gst-validate-pipeline-monitor.h>
|
||||
|
@ -7043,7 +7044,8 @@ subscenario_done_cb (GstBus * bus, GstMessage * message, gpointer data)
|
|||
}
|
||||
|
||||
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;
|
||||
GError *error = NULL;
|
||||
|
@ -7116,6 +7118,102 @@ done:
|
|||
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:
|
||||
|
@ -8193,6 +8291,26 @@ register_action_types (void)
|
|||
"queues a eos event in an appsrc.",
|
||||
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,
|
||||
((GstValidateActionParameter [])
|
||||
{
|
||||
|
|
|
@ -56,7 +56,7 @@ gst_validate_enums = gnome.mkenums('gstvalidateenumtypes',
|
|||
install_header : true,
|
||||
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]
|
||||
gstvalidate = library('gstvalidate-@0@'.format(apiversion),
|
||||
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