gstreamer 应用(一)——基本概念

Gstreamer基础概念

ELement
一个element实现一个功能(读取文件,解码,输出等),程序需要创建多个element,并按顺序将其串连起来,构成一个完整的pipeline。
Pad
Pad是一个element的输入/输出接口,分为src pad(生产数据)和sink pad(消费数据)两种。两个element必须通过pad才能连接起来。当element支持多种数据处理能力时,我们可以通过Cap来指定数据类型。

gst-launch-1.0 videotestsrc ! "video/x-raw,width=1280,height=720" ! autovideosink

在这里插入图片描述
Bin和Pipeline
Bin是一个容器,用于管理多个element,改变bin的状态时,bin会自动去修改所包含的element的状态,也会转发所收到的消息。如果没有bin,我们需要依次操作我们所使用的element。通过bin降低了应用的复杂度。
Pipeline继承自bin,为程序提供一个bus用于传输消息,并且对所有子element进行同步。当将pipeline的状态设置为PLAYING时,pipeline会在一个/多个新的线程中通过element处理数据。

在这里插入图片描述

gst-launch-1.0 filesrc location=sintel_trailer-480p.ogv ! oggdemux name=demux ! queue ! vorbisdec ! autoaudiosink demux. ! queue ! theoradec ! videoconvert ! autovideosink

pipeline由8个element组成,每个element实现各自的功能。
filesrc: 读取文件
oggdemux: 解析文件 提取audio video
queue: 缓存数据
vorbisdec: 解析audio
autoaudiosink: 自动选择音频设备输出
theoradec: 解析video
videoconvert: 转换video数据格式
autovideosink: 自动选择显示设备输出

//只有视频
 gst-launch-1.0 filesrc location=sintel_trailer-480p.ogv ! oggdemux name=demux ! queue ! theoradec ! videoconvert ! autovideosink
//只有音频
gst-launch-1.0 filesrc location=sintel_trailer-480p.ogv ! oggdemux name=demux ! queue ! vorbisdec ! autoaudiosink 

知识点

1.source element
只能生成数据,不能接收数据的element。如用于文件读取的filesrc等。
对于source element,我们通常用src pad表示element能产生数据,并将其放在element的右边。source element只有src pad,通过设备、文件、网络等方式读取数据后,通过src pad向pipeline发送数据,开始pipeline的处理流程。
2.sink element
只能接收数据,不能产生数据的element。例如播放声音的alsasink等。
对于sink element,我们通常用sink pad表示element能接收处理数据,并将其放在element的左边。sink element只有sink pad,从sink pad读取数据后,将数据发送到指定设备或位置,结束pipeline的处理流程。
3.filter-like element
既能接收数据,又能生成数据的element。例如分离器,解码器,音量控制器等。
对于filter-like element,既包含位于element左边的sink pad,又包含位于element右边的src pad。Element首先从sink pad读取数据,然后对数据进行处理,最后在src pad产生新的数据。
示例管道

源码分析

创建Element

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

对GStreamer初始化后,可以通过gst_element_factory_make创建element。第一个参数element的类型,第二个参数是这个实例中参数的名字。如果第二个参数为NULL,则GStreamer内部会为该element自动生成一个唯一的名字。

videotestsrc: 是一个source element,产生视频数据,用于调试(教程),在实际应用中基本不用。

autovideosink: 是一个sink element, 用于自动选择视频输出设备,创建视频显示窗口,并显示其收到的数据。

创建Pipeline

/* Create the empty pipeline */
pipeline = gst_pipeline_new ("test-pipeline");

我们通过 gst_pipeline_new创建pipeline,参数为管道的名字。
我们知道pipeline会提供播放所必须的时钟以及对消息的处理,所以我们需要把我们创建的element添加到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是继承自bin,所以所有bin的方法都可以应用于pipeline,需要注意的是,我们需要通过相应的宏(这里是GST_BIN)来将子类转换为父类,宏内部会对其做类型检查。在这里我们使用gst_bin_add_many将多个element加入到pipeline中,这个函数接受任意多个参数,最后以NULL表示参数列表的结束。如果一次只需要加入一个,可以使用gst_bin_add函数。

我们使用gst_element_link将这些element链接起来。需要注意的是,只有被加入到同一个bin的element才能够被连接在一起,所以我们需要在连接前,将所需要的element加入到pipeline/bin中。

设置属性

/* Modify the source's properties */
g_object_set (source, "pattern", 0, NULL);

大部分的element都有自己的属性。有的属性只能被读取,这种属性常用于查询element的状态。有的属性同时支持修改,这种属性常用于控制element的行为。
由于GstElement继承于GObject,同时GObject对象系统提供了 g_object_get()用于读取属性,g_object_set()用于修改属性,g_object_set()支持以NULL结束的属性-值的键值对,所以可以一次修改element的多个属性。

我们这里通过g_object_set()来修改videotestsrc的pattern属性。pattern属性可以控制测试图像的类型,可以尝试将0修改为1,查看输出结果有何不同。

我们可以通过gst-inspect-1.0 videotestsrc命令来查看pattern所支持的所有值。
在这里插入图片描述
在这里插入图片描述
错误检查

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

组件状态
一个组件被创建后,不会执行任何操作。所以需要改变组件的状态,使其能做某些事情。组件有四种状态:
GST_STATE_NULL:默认状态,会回收所有被该组件占用的资源。
GST_STATE_READY:准备状态,会得到所有所需的全局资源,这些资源将通过该组件的数据流所使用。如打开设备,分配缓存等,但这种状态下,数据流未开始被处理,数据流的位置信息应自动置0.如数据流打开过,应被关闭。其位置信息、特性信息被重置。
GST_STATE_PAUSED: 开始对流进行处理,但暂停了处理。时钟禁止运行。
GST_STATE_PLAYING: 除了运行时钟外,与PAUSED相同。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值