mirror of
https://github.com/aler9/gortsplib
synced 2025-10-07 16:10:59 +08:00
add server read tests with gstreamer
This commit is contained in:
@@ -277,8 +277,12 @@ func TestServerPublishReadTCP(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{"ffmpeg", "ffmpeg", false},
|
{"ffmpeg", "ffmpeg", false},
|
||||||
{"ffmpeg", "ffmpeg", true},
|
{"ffmpeg", "ffmpeg", true},
|
||||||
|
{"ffmpeg", "gstreamer", false},
|
||||||
|
{"ffmpeg", "gstreamer", true},
|
||||||
{"gstreamer", "ffmpeg", false},
|
{"gstreamer", "ffmpeg", false},
|
||||||
{"gstreamer", "ffmpeg", true},
|
{"gstreamer", "ffmpeg", true},
|
||||||
|
{"gstreamer", "gstreamer", false},
|
||||||
|
{"gstreamer", "gstreamer", true},
|
||||||
} {
|
} {
|
||||||
encryptedStr := func() string {
|
encryptedStr := func() string {
|
||||||
if ca.encrypted {
|
if ca.encrypted {
|
||||||
@@ -342,6 +346,15 @@ func TestServerPublishReadTCP(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer cnt2.close()
|
defer cnt2.close()
|
||||||
require.Equal(t, 0, cnt2.wait())
|
require.Equal(t, 0, cnt2.wait())
|
||||||
|
|
||||||
|
case "gstreamer":
|
||||||
|
cnt2, err := newContainer("gstreamer", "read", []string{
|
||||||
|
"rtspsrc location=" + proto + "://127.0.0.1:8554/teststream protocols=tcp tls-validation-flags=0 latency=0 " +
|
||||||
|
"! application/x-rtp,media=video ! decodebin ! exitafterframe ! fakesink",
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer cnt2.close()
|
||||||
|
require.Equal(t, 0, cnt2.wait())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
FROM amd64/alpine:3.12
|
FROM alpine:3.12
|
||||||
|
|
||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
ffmpeg
|
ffmpeg
|
||||||
|
@@ -1,12 +1,43 @@
|
|||||||
FROM amd64/ubuntu:20.04
|
######################################
|
||||||
|
FROM ubuntu:20.04 AS exitafterframe
|
||||||
|
|
||||||
|
RUN apt update && apt install -y --no-install-recommends \
|
||||||
|
pkg-config \
|
||||||
|
gcc \
|
||||||
|
libgstreamer-plugins-base1.0-dev \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY exitafterframe.c /s/
|
||||||
|
RUN cd /s \
|
||||||
|
&& gcc \
|
||||||
|
exitafterframe.c \
|
||||||
|
-o libexitafterframe.so \
|
||||||
|
-Ofast \
|
||||||
|
-s \
|
||||||
|
-Werror \
|
||||||
|
-Wall \
|
||||||
|
-Wextra \
|
||||||
|
-Wno-unused-parameter \
|
||||||
|
-fPIC \
|
||||||
|
-shared \
|
||||||
|
-Wl,--no-undefined \
|
||||||
|
$(pkg-config --cflags --libs gstreamer-1.0) \
|
||||||
|
&& mv libexitafterframe.so /usr/lib/x86_64-linux-gnu/gstreamer-1.0/ \
|
||||||
|
&& rm -rf /s
|
||||||
|
|
||||||
|
######################################
|
||||||
|
FROM ubuntu:20.04
|
||||||
|
|
||||||
RUN apt update && apt install -y --no-install-recommends \
|
RUN apt update && apt install -y --no-install-recommends \
|
||||||
gstreamer1.0-tools \
|
gstreamer1.0-tools \
|
||||||
gstreamer1.0-plugins-good \
|
gstreamer1.0-plugins-good \
|
||||||
gstreamer1.0-plugins-bad \
|
gstreamer1.0-plugins-bad \
|
||||||
gstreamer1.0-rtsp \
|
gstreamer1.0-rtsp \
|
||||||
|
gstreamer1.0-libav \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY --from=exitafterframe /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libexitafterframe.so /usr/lib/x86_64-linux-gnu/gstreamer-1.0/
|
||||||
|
|
||||||
COPY emptyvideo.ts /
|
COPY emptyvideo.ts /
|
||||||
|
|
||||||
COPY start.sh /
|
COPY start.sh /
|
||||||
|
95
testimages/gstreamer/exitafterframe.c
Normal file
95
testimages/gstreamer/exitafterframe.c
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
|
GType gst_exitafterframe_get_type ();
|
||||||
|
|
||||||
|
#define GST_TYPE_EXITAFTERFRAME (gst_exitafterframe_get_type())
|
||||||
|
#define GST_EXITAFTERFRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_EXITAFTERFRAME,GstExitAfterFrame))
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GstElement element;
|
||||||
|
GstPad *srcpad;
|
||||||
|
GstPad *sinkpad;
|
||||||
|
|
||||||
|
} GstExitAfterFrame;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GstElementClass parent_class;
|
||||||
|
|
||||||
|
} GstExitAfterFrameClass;
|
||||||
|
|
||||||
|
#define gst_exitafterframe_parent_class parent_class
|
||||||
|
G_DEFINE_TYPE (GstExitAfterFrame, gst_exitafterframe, GST_TYPE_ELEMENT);
|
||||||
|
|
||||||
|
static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE(
|
||||||
|
"sink",
|
||||||
|
GST_PAD_SINK,
|
||||||
|
GST_PAD_ALWAYS,
|
||||||
|
GST_STATIC_CAPS("video/x-raw")
|
||||||
|
);
|
||||||
|
|
||||||
|
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE(
|
||||||
|
"src",
|
||||||
|
GST_PAD_SRC,
|
||||||
|
GST_PAD_ALWAYS,
|
||||||
|
GST_STATIC_CAPS("video/x-raw")
|
||||||
|
);
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_exitafterframe_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
||||||
|
{
|
||||||
|
GstExitAfterFrame *filter = GST_EXITAFTERFRAME (parent);
|
||||||
|
exit(0);
|
||||||
|
return gst_pad_push (filter->srcpad, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_exitafterframe_class_init(GstExitAfterFrameClass* klass) {
|
||||||
|
GstElementClass* element_class = (GstElementClass*)klass;
|
||||||
|
|
||||||
|
gst_element_class_set_details_simple(
|
||||||
|
element_class,
|
||||||
|
"Plugin",
|
||||||
|
"FIXME:Generic",
|
||||||
|
"FIXME:Generic Template Element",
|
||||||
|
"AUTHOR_NAME AUTHOR_EMAIL"
|
||||||
|
);
|
||||||
|
|
||||||
|
gst_element_class_add_pad_template(element_class,
|
||||||
|
gst_static_pad_template_get(&src_factory));
|
||||||
|
gst_element_class_add_pad_template(element_class,
|
||||||
|
gst_static_pad_template_get(&sink_factory));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_exitafterframe_init (GstExitAfterFrame* filter)
|
||||||
|
{
|
||||||
|
GstElement* element = GST_ELEMENT(filter);
|
||||||
|
|
||||||
|
g_print("[lasermqtt] init()\n");
|
||||||
|
|
||||||
|
filter->sinkpad = gst_pad_new_from_static_template(&sink_factory, "sink");
|
||||||
|
gst_pad_set_chain_function(filter->sinkpad, gst_exitafterframe_chain);
|
||||||
|
GST_PAD_SET_PROXY_CAPS(filter->sinkpad);
|
||||||
|
gst_element_add_pad(element, filter->sinkpad);
|
||||||
|
|
||||||
|
filter->srcpad = gst_pad_new_from_static_template(&src_factory, "src");
|
||||||
|
GST_PAD_SET_PROXY_CAPS(filter->srcpad);
|
||||||
|
gst_element_add_pad(element, filter->srcpad);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
plugin_init (GstPlugin * plugin)
|
||||||
|
{
|
||||||
|
return gst_element_register (plugin, "exitafterframe", GST_RANK_NONE,
|
||||||
|
GST_TYPE_EXITAFTERFRAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PACKAGE "exitafterframe"
|
||||||
|
|
||||||
|
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, exitafterframe,
|
||||||
|
"exitafterframe", plugin_init, "1.0", "LGPL", "exitafterframe",
|
||||||
|
"http://example.com")
|
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
exec gst-launch-1.0 $@
|
exec gst-launch-1.0 $@ 2>&1
|
||||||
|
Reference in New Issue
Block a user