callback - rtspclientsink 的 Gstreamer 管道信号
问题描述
我使用 gstreamer 已经有一段时间了——它的效果给我留下了深刻的印象。但最近出现了一项检查 RTSP 请求和响应内容的要求。我在想我可以使用 rtspclientsink 的句柄请求回调功能 - 如果我错了,请纠正我。但我根本无法让回调工作。这是我一直在玩的代码示例。有任何想法吗?
static void handle_request_callback (GstElement rtsp_client_sink,
gpointer request,
gpointer response,
gpointer udata)
{
printf("here\n\r");
}
int main (int argc, char *argv[])
{
GMainLoop *loop;
GstElement *pipeline, *videosrc, *sink, *videofilter, *videoencoder, *encoderfilter, *h264parse;
GstCaps *filtercaps;
GstPad *pad;
/* init GStreamer */
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/* build */
pipeline = gst_pipeline_new ("my-pipeline");
videosrc = gst_element_factory_make ("v4l2src", "videosrc");
if (videosrc == NULL)
g_error ("Could not create 'v4l2src' element");
videofilter = gst_element_factory_make ("capsfilter", "videofilter");
g_assert (videofilter != NULL); /* should always exist */
encoderfilter = gst_element_factory_make ("capsfilter", "encoderfilter");
g_assert (encoderfilter != NULL); /* should always exist */
h264parse = gst_element_factory_make ("h264parse", "parser");
if (h264parse == NULL)
g_error ("Could not create 'h264parse' element");
videoencoder = gst_element_factory_make ("omxh264enc", "videoencoder");
if (videoencoder == NULL)
g_error ("Could not create 'omxh264enc' element");
sink = gst_element_factory_make ("rtspclientsink", "sink");
if (sink == NULL)
g_error ("Could not create 'rtspclientsink' element");
g_object_set(G_OBJECT(sink), "protocols", 0x00000004, NULL);
g_object_set(G_OBJECT(sink), "latency", "100", NULL);
g_object_set(G_OBJECT(sink), "location", "rtspt://192.169.1.2:1935/video", NULL);
g_object_set(G_OBJECT(sink), "name", "rtspsink", NULL);
//g_object_set(G_OBJECT(sink), "debug", true, NULL);
gst_bin_add_many (GST_BIN (pipeline), videosrc, videofilter, videoencoder, h264parse, sink, NULL);
gst_element_link_many (videosrc, videofilter, videoencoder, h264parse, sink, NULL);
filtercaps = gst_caps_new_simple ("video/x-raw",
"width", G_TYPE_INT, 1280,
"height", G_TYPE_INT, 720,
"framerate", GST_TYPE_FRACTION, 30, 1,
NULL);
g_object_set (G_OBJECT (videofilter), "caps", filtercaps, NULL);
gst_caps_unref (filtercaps);
filtercaps = gst_caps_new_simple ("video/x-h264",
"width", G_TYPE_INT, 1280,
"height", G_TYPE_INT, 720,
"framerate", GST_TYPE_FRACTION, 30, 1,
"profile", G_TYPE_STRING, "high",
NULL);
g_object_set (G_OBJECT (encoderfilter), "caps", filtercaps, NULL);
gst_caps_unref (filtercaps);
gulong ret = g_signal_connect(sink, "handle-request", G_CALLBACK(handle_request_callback), sink);
printf("%d\r\n", ret);
/* run */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* wait until it's up and running or failed */
if (gst_element_get_state (pipeline, NULL, NULL, -1) == GST_STATE_CHANGE_FAILURE) {
g_error ("Failed to go into PLAYING state");
}
g_print ("Running ...\n");
g_main_loop_run (loop);
/* exit */
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return 0;
}
这是 rtspclientsink 信息:
$ gst-inspect-1.0 rtspclientsink
Factory Details:
Rank none (0)
Long-name RTSP RECORD client
Klass Sink/Network
Description Send data over the network via RTSP RECORD(RFC 2326)
Author Jan Schmidt <jan@centricular.com>
Plugin Details:
Name rtspclientsink
Description RTSP client sink element
Filename /usr/lib/arm-linux-gnueabihf/gstreamer-1.0/libgstrtspclientsink.so
Version 1.14.4
License LGPL
Source module gst-rtsp-server
Source release date 2018-10-02
Binary package GStreamer RTSP Server Library source release
Origin URL Unknown package origin
解决方案
我通过查看 gstrtspclientsink.c 文件(https://github.com/GStreamer/gst-rtsp-server/blob/master/tests/check/gst/rtspclientsink.c)找到了答案。用于句柄请求的信号发射函数是从旨在用作 rtsp 服务器的代码的一部分调用的,而 rtspclientsink 是一个 RTSP 客户端,它以发送 ANNOUNCE + sdp(而不是 DESCRIBE)开始。
基本上 rtspclientsink "handle-request" 信号仅适用于来自服务器的请求。在 RTSP ANNOUNCE 的上下文中,初始请求是在生成媒体内容的设备上生成的,该信号永远不会被触发。
无论如何 - 可以将用于“handle-request”之类的信号的 g_signal_emit() 添加到 RTSP 命令的前后处理逻辑中,以允许操纵 RTSP 请求并监视 RTSP 响应。
推荐阅读
- firebase - Flutter Firestore 在地图列表上使用 FieldValue.arrayRemove 并仅按 id 删除
- java - 所有 Java 输出流都有缓冲区吗?
- apache-beam - 运行 SDFBoundedSourceReader 时 Apache Beam 没有 watermark_estimator_provider
- opencart - Cupon opencart eeror
- salesforce - 显示包含产品和产品系列详细信息的机会
- visual-studio - 如何将 csv 文件作为 movesense 模拟器的输入
- sql - 在多列和单行中获取选择结果
- tree - 方案相等树过程
- android - 在后台模式下使用应用程序更改应用程序权限(从常规设置)时出现问题
- php - 如何计算用户在php中上传的图像、pdf、ppt或doc文件大小