将下面代码copy到一个命名为basic-tutorial-1.c的文件中。html
#include <gst/gst.h> int main(int argc, char *argv[]) { GstElement *pipeline, *source, *sink; GstBus *bus; GstMessage *msg; GstStateChangeReturn ret; /* Initialize GStreamer */ gst_init (&argc, &argv); /* Create the elements */ source = gst_element_factory_make ("videotestsrc", "source"); sink = gst_element_factory_make ("autovideosink", "sink"); /* Create the empty pipeline */ pipeline = gst_pipeline_new ("test-pipeline"); if (!pipeline || !source || !sink) { g_printerr ("Not all elements could be created.\n"); return -1; } /* Build the pipeline */ gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL); if (gst_element_link (source, sink) != TRUE) { g_printerr ("Elements could not be linked.\n"); gst_object_unref (pipeline); return -1; } /* Modify the source's properties */ g_object_set (source, "pattern", 0, NULL); /* Start playing */ ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); if (ret == GST_STATE_CHANGE_FAILURE) { g_printerr ("Unable to set the pipeline to the playing state.\n"); gst_object_unref (pipeline); return -1; } /* 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); /* Parse message */ if (msg != NULL) { GError *err; gchar *debug_info; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_ERROR: gst_message_parse_error (msg, &err, &debug_info); g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message); g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none"); g_clear_error (&err); g_free (debug_info); break; case GST_MESSAGE_EOS: g_print ("End-Of-Stream reached.\n"); break; default: /* We should not reach here because we only asked for ERRORs and EOS */ g_printerr ("Unexpected message received.\n"); break; } gst_message_unref (msg); } /* Free resources */ gst_object_unref (bus); gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (pipeline); return 0; }
GStreamer的基本构造块为元素(elements),它向下游流动从source elements(数据的制做者)向sink elements(数据的消费者),穿过过滤器元件(filter elements)而处理数据。异步
/* Create the elements */ source = gst_element_factory_make ("videotestsrc", "source"); sink = gst_element_factory_make ("autovideosink", "sink");
能够看出在这段代码中,新元素能够用gst_element_factory_make()来建立。第一个参数是元素的建立类型(Basic tutorial 14: Handy elements:显示了一些常见的类型,以及 Basic tutorial 10: GStreamer tools:展现了如何获取全部可用类型的列表)。第二个参数是咱们想给这个特定实例的名称。命名你的元素是很是有用之后对它们进行检索,若是你没有保持一个指针(和更有意义的调试输出)。若是你传递NULL的名字,然而,,GStreamer将会为您提供一个惟一的名称。ide
在本教程中,咱们建立两个元素:一个 videotestsrc 和 autovideosink。函数
videotestsrc 是源元素(它产生的数据),它建立了一个测试视频模式。此元素对于调试目的(和教程)是有用的,而不是在实际应用中使用。工具
autovideosink是一个接收元素(它消耗的数据),它在一个窗口中显示接收到的图像。存在几个视频接收器,根据不一样的操做系统,具备能力的变化范围。 autovideosink自动选择并实例化最好的一个,因此你没必要担忧的细节,你的代码更是平台无关的。测试
/* Create the empty pipeline */ pipeline = gst_pipeline_new ("test-pipeline");
GStreamer中的全部元素都必须典型地包含在一个管道内才能使用它们,由于它须要一些时钟和短信功能护理。咱们建立gst_pipeline_new()等的管道。ui
/* Build the pipeline */ gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL); if (gst_element_link (source, sink) != TRUE) { g_printerr ("Elements could not be linked.\n"); gst_object_unref (pipeline); return -1; }
管道是一种特殊类型的bin,这是用来包含其余元素的元素。所以,适用于bin的全部方法也适用于管道。在咱们的例子中,咱们调用 gst_bin_add_many() 将元素添加到管道(mind the cast)。这个函数接受要添加元素的列表,用NULL结束。单个元素能够用 gst_bin_add() 进行添加。this
这些元素,可是,没有相互链接的呢。对于这一点,咱们须要使用 gst_element_link() 。它的第一个参数是source,而第二个是destination。顺序计数,由于连接必须遵循数据流(这是 from source elements to sink elements)成立。请记住,只有居住在同一个bin的元素能够彼此连接,因此记得将它们添加到统一管道在试图连接它们以前!spa
/* Modify the source's properties */ g_object_set (source, "pattern", 0, NULL);
大多数的GStreamer元素具备可定制的属性:能够修改来改变元素的行为(可写属性),或者询问,了解元素的内部状态(可读属性)。属性用 g_object_get() 读取和用 g_object_set()写入。操作系统
g_object_set()
accepts a NULL-terminated list of property-name, property-value pairs,这样多个属性能够一次改变(GStreamer的元素都是一种特殊的GObject,这是实体提供物业设施:这就是为何属性的处理方法有g_前缀。
以上代码的行更改 videotestsrc 中的“模式”属性,该属性控制测试视频的类型元素输出。尝试不一样的值!
全部属性的元素自曝的名称和可能的值可使用Basic tutorial 10: GStreamer tools中描述的GST-检验工具中找到。
在这一点上,咱们有整个管道建造和设置,以及本教程的其他部分是很是类似的前一个,但咱们将增长更多的错误检查:
/* Start playing */ ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); if (ret == GST_STATE_CHANGE_FAILURE) { g_printerr ("Unable to set the pipeline to the playing state.\n"); gst_object_unref (pipeline); return -1; }
咱们称 gst_element_set_state(),可是这一次咱们检查它的返回值的错误。改变状态是一个微妙的过程和一些更细节的Basic tutorial 3: Dynamic pipelines中给出。
/* 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); /* Parse message */ if (msg != NULL) { GError *err; gchar *debug_info; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_ERROR: gst_message_parse_error (msg, &err, &debug_info); g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message); g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none"); g_clear_error (&err); g_free (debug_info); break; case GST_MESSAGE_EOS: g_print ("End-Of-Stream reached.\n"); break; default: /* We should not reach here because we only asked for ERRORs and EOS */ g_printerr ("Unexpected message received.\n"); break; } gst_message_unref (msg); }
gst_bus_timed_pop_filtered() 执行结束并返回等待一个 GstMessage 这是咱们之前忽略。咱们要求gst_bus_timed_pop_filtered()返回遇到的任何错误状况或EOS,因此咱们须要检查哪个发生的事情,并在屏幕上打印一条消息(您的应用程序可能要进行更复杂的动做)。
GstMessage
是它几乎能够提供任何种类的信息很是灵活的结构。幸运的是,GStreamer中提供了一系列分析功能,为各种消息的。
在这种状况下,一旦咱们知道了消息中包含一个错误(使用 GST_MESSAGE_TYPE() 宏),咱们可使用 gst_message_parse_error()
,它返回一个GLib的 GError
错误信息结构和一个字符串用于调试。检查代码,看看它们是如何使用和释放。
在这一点上是值得正式的介绍一下GStreamer总线。它负责把元素所生成的 GstMessage
s提供给应用程序,为了与应用程序的线程保持联系。最后一点很重要,由于媒体的实际流工做是在另外一个线程而不是应用程序。
消息能够从总线实时地经过 gst_bus_timed_pop_filtered()和它的兄弟姐妹,或异步,使用信号(在接下来的教程中所示)。您的应用程序应该始终注意错误和其余回放产生的相关问题。
代码的其他部分是在清理序列,这是相同 Basic tutorial 1: Hello world!。
若是你以为本身练,试试这个练习:添加source和the sink of this pipeline之间的视频过滤器元件。使用 vertigotv 会有一个不错的效果。您将须要建立它,将它添加到管道,并与其余元素联系起来。
根据您的平台,可用插件时,你可能会获得一个“谈判(negotiation)”的错误,由于接收器不明白的过滤器生产(更多关于谈判的 Basic tutorial 6: Media formats and Pad Capabilities:媒体格式和垫功能)。在这种状况下,添加过滤器后,尝试添加一个被称为 ffmpegcolorspace
的元素(这是,创建4个元素的管道,更多关于 ffmpegcolorspace
请参看Basic tutorial 14: Handy elements:方便的元素)。
本教程显示:
如何用 gst_element_factory_make()
创建元素
如何用 gst_pipeline_new() 创建一个空的管道
如何用 gst_bin_add_many() 将元素添加管道
如何用 gst_element_link()
将元素彼此连接
这样就完成了最近两个教程致力于GStreamer的基本概念。
记住,此页你应该找到本教程的完整源代码,并创建它所需的任何附件文件。
很高兴你能受用这个教程,之后的教程再见!