目录
1. 要点记录
- 研究Gstreamer RSTP的内在机制
- 为硬件编解码做准备
- 进一步开发嵌入式视频推流
- 为智能硬件传感器铺垫
- 为Xilinx VCU调用做准备
2. GStreamer简介
GStreamer是一个非常强大的开源多媒体框架,用于构建各种媒体处理组件,如音频和视频播放、录制、编辑和转码等。RTSP(Real Time Streaming Protocol)是一种网络控制协议,设计用于娱乐和通信系统来控制流媒体服务器。学习GStreamer处理RTSP流有以下几个意义:
理解流媒体技术:通过学习GStreamer与RTSP的交互,理解流媒体的工作原理,包括如何在网络上发送和接收实时音视频数据。流媒体技术广泛应用于在线视频播放、监控系统、远程教育等。
多媒体应用开发:GStreamer提供了一套丰富的API和插件,可以相对容易地开发出复杂的多媒体应用,视频会议、直播推流等。学习如何在GStreamer中处理RTSP流可以构建这类应用。
性能优化:通过深入学习和实践,掌握如何优化RTSP流的处理,比如降低延迟、提高视频质量和稳定性。
跨平台能力:GStreamer支持多种操作系统,包括Linux、Windows和macOS等。学习GStreamer处理RTSP流,可以让你具备跨平台开发多媒体应用的能力,增加你的项目适用范围和受众。
解决实际问题:在很多实际应用场景中,如安防监控、远程医疗和在线教育等,都需要处理RTSP流。掌握这一技能可以让你在这些领域内更加游刃有余,解决实际问题。
3. 主要步骤
1. 通过git下载gstreamer源码和示例
>> git clone https://gitlab.freedesktop.org/gstreamer/gstreamer
2. RTSP简单示例存于此目录
<gstreamer>/subprojects/gst-rtsp-server/examples/test-launch.c
3. 编译命令
>> gcc example.c -o example `pkg-config --cflags --libs gstreamer-1.0 gstreamer-rtsp-server-1.0`
4. 运行
>> ./example "( videotestsrc ! x264enc ! rtph264pay name=pay0 pt=96 )"
4. RTSP源码
RTSP示例
#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
#define DEFAULT_RTSP_PORT "8554"
#define DEFAULT_MOUNT "/test"
#define DEFAULT_DISABLE_RTCP FALSE
static char *port = (char *) DEFAULT_RTSP_PORT;
static char *mount = (char *) DEFAULT_MOUNT;
static gboolean disable_rtcp = DEFAULT_DISABLE_RTCP;
static GOptionEntry entries[] = {
{"port" ,'p' , 0, G_OPTION_ARG_STRING, &port , "Port to listen on (default: " DEFAULT_RTSP_PORT ")" , "PORT" },
{"mount" ,'m' , 0, G_OPTION_ARG_STRING, &mount , "Mountpoint (default: " DEFAULT_MOUNT ")" , "MOUNT" },
{"disable-rtcp" ,'\0', 0, G_OPTION_ARG_NONE , &disable_rtcp, "Whether RTCP should be disabled (default false)" , NULL },
{NULL}
};
int main (int argc, char *argv[])
{
GMainLoop *loop;
GstRTSPServer *server;
GstRTSPMountPoints *mounts;
GstRTSPMediaFactory *factory;
GOptionContext *optctx;
GError *error = NULL;
optctx = g_option_context_new ("<launch line> - Test RTSP Server, Launch\n\n"
"Example: \"( videotestsrc ! x264enc ! rtph264pay name=pay0 pt=96 )\"");
g_option_context_add_main_entries (optctx, entries, NULL);
g_option_context_add_group (optctx, gst_init_get_option_group ());
if (!g_option_context_parse (optctx, &argc, &argv, &error)) {
g_printerr ("Error parsing options: %s\n", error->message);
g_option_context_free (optctx);
g_clear_error (&error);
return -1;
}
g_option_context_free (optctx);
loop = g_main_loop_new (NULL, FALSE);
/* create a server instance */
server = gst_rtsp_server_new ();
g_object_set (server, "service", port, NULL);
/* get the mount points for this server, every server has a default object
* that be used to map uri mount points to media factories */
mounts = gst_rtsp_server_get_mount_points (server);
/* make a media factory for a test stream. The default media factory can use
* gst-launch syntax to create pipelines.
* any launch line works as long as it contains elements named pay%d. Each
* element with pay%d names will be a stream */
factory = gst_rtsp_media_factory_new ();
gst_rtsp_media_factory_set_launch (factory, argv[1]);
gst_rtsp_media_factory_set_shared (factory, TRUE);
gst_rtsp_media_factory_set_enable_rtcp (factory, !disable_rtcp);
/* attach the test factory to the mount url */
gst_rtsp_mount_points_add_factory (mounts, mount, factory);
/* don't need the ref to the mapper anymore */
g_object_unref (mounts);
/* attach the server to the default maincontext */
gst_rtsp_server_attach (server, NULL);
/* start serving */
g_print ("stream ready at rtsp://127.0.0.1:%s%s\n", port, mount);
g_main_loop_run (loop);
return 0;
}
5. RTSP关键代码解释
- 创建GMainLoop对象后,需要将事件源添加到GMainContext中,以便循环能够检测和分发事件。
- 在RTSP示例代码中,事件源是由gst_rtsp_server_new ();创建的GstRTSPServer对象,它封装了一个RTSP服务器的功能。
- 将GstRTSPServer对象添加到GMainContext中的方法是调用gst_rtsp_server_attach (server, NULL);,这样就可以让服务器监听和处理来自客户端的RTSP请求。
- GLib内部实现了几种类型的事件源,分别是文件描述符(文件、管道和socket)、超时、idle事件、自定义事件。
- 调用g_main_loop_unref减少GMainLoop对象的引用计数,如果引用计数为0,释放GMainLoop对象。
这个循环事件的用途如下:
- 等待事件:事件循环会在没有事件处理时阻塞程序的执行。这意味着程序会等待直到有事件发生,比如网络连接、用户输入、定时器超时等。
- 处理GStreamer事件:在GStreamer应用程序中,GMainLoop用于处理各种GStreamer事件,包括消息传递、状态变化、异步操作完成等。
- 保持程序运行:在多媒体应用中,经常需要程序保持运行状态,等待和处理流媒体相关的事件。如果没有事件循环,程序可能会执行完所有初始化代码后立即退出。
- 集成其他库:GMainLoop可以与其他Glib/GObject库集成,允许同时处理来自GStreamer和其他库的事件。