一、总述
本章以RK3568,OV13850为例。这是gst-launch-1.0的语法:
# 实时预览
gst-launch-1.0 v4l2src device=/dev/video0 !video/x-raw, format=NV12, width=640, height=480, framerate=30/1 ! autovideosink
# 采集H.264
gst-launch-1.0 v4l2src device=/dev/video0 num-buffers=100 !video/x-raw,format=NV12, width=640,height=480 ! tee name=t ! queue !mpph264enc !queue !h264parse !qtmux !filesink location=13850_h264.mp4 t. ! queue !autovideosink
# 播放视频
gst-launch-1.0 filesrc location=13850_h264.mp4 !qtdemux !queue !h264parse !mppvideodec !autovideosink
二、代码
#include <gstreamer-1.0/gst/gst.h>
int glibDemo(int argc, char** argv)
{
GstElement *pipeline;
GstBus *bus;
GstMessage *msg;
/* Initialize GStreamer */
gst_init (&argc, &argv);
/* Build the pipeline */
pipeline = gst_parse_launch(
"filesrc location=13850_h264.mp4 !qtdemux !queue !h264parse !mppvideodec !autovideosink",
NULL
);
/* Start playing */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* Wait until error or EOS */
bus = gst_element_get_bus (pipeline);
msg = gst_bus_timed_pop_filtered (
bus, GST_CLOCK_TIME_NONE,
GST_MESSAGE_ERROR | GST_MESSAGE_EOS
);
/* See next tutorial for proper error message handling/parsing */
if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
g_error ("An error occurred! Re-run with the GST_DEBUG=*:WARN environment "
"variable set for more details.");
}
/* Free resources */
gst_message_unref (msg);
gst_object_unref (bus);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return 0;
}
三、解释
下面我们回顾上述的代码,并理解发生了什么:
3.1 初始化
GstElement *pipeline;
GstBus *bus;
这永远是写GStreamer的第一条命令。除其他事项外,gst_init()
有如下作用:
- 初始化所有内部结构。
- 确保所有插件可用。
- 执行任何可能适用于GStreamer的命令行选项。
/* Initialize GStreamer */
gst_init (&argc, &argv);
/* Build the pipeline */
3.2 管线
GStreamer是一个旨在处理多媒体流的框架。 媒体从“source”元素(生产者)向下传播到“sink”元素(消费者),通过一系列执行各种任务的中间元素。所有互连元素的集合称为“pipeline”。
在GStreamer中,通常手动地组装各个元素来构建管道,但是,当管道足够简单并且不需要任何高级功能时,就可以采用快捷方式:gst_parse_launch()。这种方式将直接使用与gst-launch-1.0语法相同的方式来构建管道。
/* Build the pipeline */
pipeline = gst_parse_launch(
"filesrc location=13850_h264.mp4 !qtdemux !queue !h264parse !mppvideodec !autovideosink",
NULL
);
上述代码和下面的命令是等效的:
gst-launch-1.0 filesrc location=13850_h264.mp4 !qtdemux !queue !h264parse !mppvideodec !autovideosink
3.3 播放
在上面我们已经构建了一个管道,通过命令行我们可以知道,我们为管线添加了一个本地的视频文件。但此时,除非我们手动的去播放它,否则管线本身并不会播放视频。
/* Start playing */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
此时gst_element_set_state()
将设置管线(实例中我们唯一的元素)状态设置为“PLAYING”,此时视频才被播放。这条命令将会一直等到流结束(EOS)或者遇到错误。
3.4 清理
在应用程序结束之前,我们需要手动的进行一些清理工作:
/* Wait until error or EOS */
bus = gst_element_get_bus (pipeline);
msg = gst_bus_timed_pop_filtered (
bus, GST_CLOCK_TIME_NONE,
GST_MESSAGE_ERROR | GST_MESSAGE_EOS
);
/* See next tutorial for proper error message handling/parsing */
if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
g_error ("An error occurred! Re-run with the GST_DEBUG=*:WARN environment "
"variable set for more details.");
}
/* Free resources */
gst_message_unref (msg);
gst_object_unref (bus);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
gst_bus_timed_pop_filtered()
返回一条消息,该消息使用gst_message_unref
释放。gst_element_get_bus()
返回的总线则由gst_object_unref()
释放。- 最后这是取消管线的引用,并释放它。
四、总结
下面我们回顾一下文章的内容。
- 使用
gst_init()
初始化GStreamer。 - 使用
gst_parse_launch()
快速构建管线。 - 使用
gst_element_set_state()
设置管线的状态以播放视频。 - 清理与释放。