GStreamer基础教程02——GStreamer概念

来源:互联网 发布:湖南广电网络董事长 编辑:程序博客网 时间:2024/04/28 23:15

原文:https://gstreamer.freedesktop.org/documentation/tutorials/basic/index.html

译文原文:http://blog.csdn.net/sakulafly/article/details/20862459

原码:git clone git://anongit.freedesktop.org/gstreamer/gst-docs


Need help?

If you need help to compile this code, refer to the Building the tutorials section for your platform: Linux, Mac OS X or Windows, or use this specific command on Linux:

gcc basic-tutorial-2.c -o basic-tutorial-2 `pkg-config --cflags --libs gstreamer-1.0`

If you need help to run this code, refer to the Running the tutorials section for your platform: Linux, Mac OS X or Windows.

This tutorial opens a window and displays a movie, with accompanying audio. The media is fetched from the Internet, so the window might take a few seconds to appear, depending on your connection speed. 10 seconds into the movie it skips to a new position

Required libraries: gstreamer-1.0


上一个教程演示了如何自动生成一个pipeline。这次我们打算用一个个element来手动搭建一个pipeline。我们这个教程会演示:

1. 什么是GStreamer的element以及如何建立一个element

2. 如何在element直接建立连接

3. 如何客制化element的行为

4. 如何监视总线上的错误并获得相关的信息


      手动建立Hello World

把下面的代码copy到basic-turtorial-2.c文件

#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,这些elements把数据从source经过filter传到sink。


      建立element

      因为上一篇教程以及介绍过了初始化这段内容,所以我们这次略过这一段。

  /* Create the elements */  source = gst_element_factory_make ("videotestsrc", "source");  sink = gst_element_factory_make ("autovideosink", "sink");

      新的element的建立可以使用gst_element_factory_make()。这个API的第一个参数是要创建的element的类型(后面第14讲会介绍一些常见的类型,第10讲会介绍如何获得可用的类型列表),第二个参数是我们想创建的element的名字,这个名字并非是必须的,但在调试中会非常有用,如果你传入的时NULL,那么GStreamer会自动创建一个名字。

      在本教程内我们创建了2个elements:videotestsrc和autovideosink.

      vieotestsrc是一个source element(生产数据),会创建一个video模式。这个element常用在调试中,很少用于实际的应用。

      autovideosink是一个sink element(消费数据),会在一个窗口显示收到的图像。在不同的操作系统中,会存在多个的video sink,autovideosink会自动选择一个最合适的,所以你不需要关心更多的细节,代码也会有更好的移植性。


      建立pipeline

  /* Create the empty pipeline */  pipeline = gst_pipeline_new ("test-pipeline");
      因为要统一处理时钟和一些信息,GStreamer中的所有elements都必须在使用之前包含到pipeline中。我们用gst_pipeline_new()来创建pipeline。

  /* 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;  }

      一个pipeline就是一个特定类型的可以包含其他element的bin,而且所以可以用在bin上的方法也都可以用在pipeline上。在这个例子中,我们调用了gst_bin_add_many()方法在pipeline中加入element。这个方法会接受一系列的element作为输入参数,最后由NULL来终止。增加单个element的方法是gst_bin_add()。

      这个时候,这些刚增加的elements还没有互相连接起来。我们用gst_element_link()方法来把element连接起来,这个方法的第一个参数是源,第二个参数是目标,这个顺序不能搞错,因为这确定了数据的流向。记住只有在同一个bin里面的element才能连接起来,所以一定要把element在连接之前加入到pipeline中。


      属性

  /* Modify the source's properties */  g_object_set (source, "pattern", 0, NULL);
      绝大部分的GStreamer elements有可以定制化的属性:只读的属性会显示element的内部状态,可写的属性会影响element的行为。我们用g_object_get()方法来获得属性,用g_object_set()方法来设置属性。

      g_object_set()方法接受一个用NULL结束的属性名称/属性值的组成的对,所以可以一次同时修改多项属性。

      上面的代码修改了videotestsrc的“pattern”属性,这个属性控制了视频的输出,大家可以试试不同的值看一下效果。

      关于一个element的名字和取值范围,使用gst-inspect工具可以查询到。


      错误检查

      在这一点上,本系列的教程内容都比较相似,和第一讲没什么不同,只是我们监测更多的错误罢了。

  /* 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()方法,但这次我们检查它的返回值。状态转换是一个很微妙的过程,在下一篇教程中我们会有更多的一些细节。

  /* 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_filted()会一直等到运行结束,然后返回一个GstMessage参数。我们让gst_bus_timed_pop_filtered()方法仅在收到错误或者播放结束的消息时才返回。所以我们需要检查是哪个消息并打印出来。

      GstMessage是一个非常通用的结构,它可以传递很多信息。幸好GStreamer提供了一系列的解析函数,在本教程里面,我们一旦知道message里面包含一个错误(通过使用GST_MESSAGE_TYPE宏),我们可以使用gst_message_parse_error()方法,这个方法会返回一个GLib的GError结构。


      GStreamer总线

      这里稍微介绍一下GStreamer总线。GStreamer总线本身也是一个对象,是创建来传递elements生成的GstMessage的对象。消息可以在总线上用gst_bus_timed_pop_filtered()方法抓出来,你的应用需要随时注意出错的信息和播放相关的其他问题。

      其他的代码是释放内存的,和上一篇教程是一样的。


Exercise

If you feel like practicing, try this exercise: Add a video filter element in between the source and the sink of this pipeline. Use vertigotv for a nice effect. You will need to create it, add it to the pipeline, and link it with the other elements.

Depending on your platform and available plugins, you might get a “negotiation” error, because the sink does not understand what the filter is producing (more about negotiation inBasic tutorial 6: Media formats and Pad Capabilities). In this case, try to add an element called videoconvert after the filter (this is, build a pipeline of 4 elements. More on videoconvert inBasic tutorial 14: Handy elements).


Conclusion

This tutorial showed:

  • How to create elements with gst_element_factory_make()
  • How to create an empty pipeline with gst_pipeline_new()
  • How to add elements to the pipeline with gst_bin_add_many()
  • How to link the elements with each other with gst_element_link()
This concludes the first of the two tutorials devoted to basic GStreamer concepts. The second one comes next.

Remember that attached to this page you should find the complete source code of the tutorial and any accessory files needed to build it.

It has been a pleasure having you here, and see you soon!

0 0