GStreamer基础教程1 - Hello World

本篇教程会学到:

  • 如何使用gst_init()初始化GStreamer
  • 如何使用gst_parse_launch()从文本描述来快速构建一个pipeline
  • 如何使用playbin创建一个自动播放的pipeline
  • 如何使用gst_element_set_state()通知GStreamer开始播放
  • 如何使用gst_element_get_bus()和gst_bus_timed_pop_filtered()处理事件通知

学习一门编程语言,打印一个hello world是最好的实践。学习gstreamer也是,不过不是打印hello world,而是播放一个视频文件。

首先把如下代码拷贝到一个命名为basic-tutorial-1.c的文件中。

#include <gst/gst.h>

int
main(int argc, char *argv[])
{
    GstElement *pipeline;
    GstBus *bus;
    GstMessage *msg;
    
    /* Initialize GStreamer */
    gst_init(&argc, &argv);
    
    /* Build the pipeline */
    pipeline =
        gst_parse_launch
        ("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm",
        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);
    
    /* Free resources */
    if (msg != NULL)
        gst_message_unref(msg);
    gst_object_unref(bus);
    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref(pipeline);
    return 0;
}

执行编译(linux)

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

运行
效果是会弹出一个视频播放窗口,播放的是从网络上拉取一段带有音频的视频。


代码走读

/* Initialize GStreamer */ 
gst_init(&argc, &argv);

使用gstreamer必须先调用此函数,它做的事情包括:

  • 初始化所有内部数据结构
  • 检查所有可用的插件(plug-ins)
  • 执行所有的命令行选项

/* Build the pipeline */
pipeline =
    gst_parse_launch
    ("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm",
    NULL);

这行代码是本篇教程的核心,它包含了两个重要的点:gst_parse_launch()和playbin。


gst_parse_launch
GStreamer是一个用来处理多媒体流的框架。多媒体经过“source”元件(生产者),流到“sink”元件(消费者),中间经过一系列的用于处理各种任务的元件。这样将多个元件连接起来的集合就称为一个pipeline。注意,这里说的元件是一个专有名词,英文是element,后面还会提到。
在GStreamer中,通常是手动的组合各个独立的元件来构成一个pipeline。但是当pipeline足够简单的时候,你不需要一些高级特性的时候,你就可以使用gst_parse_launch()。
此函数采用管道的文本表示形式并将其转换为实际的管道,非常方便。 实际上,这个功能的使用非常方便,它有一个完全围绕它构建的工具,在看过后面的教程后你就会非常熟悉了(请参阅基础教程10:GStreamer工具以了解gst-launch-1.0和gst-launch-1.0语法)。


playbin
在本例中,我们用gst_parse_launch()构建了一个由称为playbin的单个元件组成的管道。
playbin是一个特殊的元件,它既是一个source元件,也是一个sink元件,并且也是一个完整的pipeline。在内部,他创建并连接了播放多媒体必需的所有元件,所以我们不用过多操心。
它没有像手工pipeline那样的控制粒度,但是仍然有足够的自定义部分以满足各种应用程序的需要,包括本教程。
在本例中,我们只向playbin传了一个参数,那就是我们想要播放的视频的URI,当然也可以尝试更改为其他的以http://或file://为前缀的URI。playbin都会透明地实例化相应的GStreamer source。
如果你写入的URI是错误的,或者文件不存在,或者缺少插件,则GStreamer提供了几种通知机制,但是在此例中我们唯一要做的就是错误时退出,不再做过多介绍。


/* Start playing */
gst_element_set_state(pipeline, GST_STATE_PLAYING);

这行代码里有一个重要的概念:状态。每一个GStreamer的元件都有一个关联的状态,你可以或多或少地将其视为常规DVD播放器中的“播放/暂停”按钮。 在将管道设置为“PLAYING”状态之前,播放不会开始。
这行代码用gst_element_set_state将pipeline的状态设置为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);

这段代码会一直等待,直到出现错误或到达流的结尾。gst_element_get_bus会获取pipeline的bus,gst_bus_timed_pop_filtered会阻塞到通过bus收到错误或者EOS(End-Of-Stream)。GStreamer的bus概念在第二篇教程还会解释。

这个示例就这些,GStreamer会做大部分的事情,直到遇到错误或者到达流的末尾,执行操作才会结束。当然,随时执行control+C都会立即中断程序。

清理
在退出程序之前,还有一些清理工作要做。

/* Free resources */
if (msg != NULL)
  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()释放的message对象。
gst_element_get_bus()的调用,会让bus增加一个引用,因此也必须用gst_object_unref()来释放。
将pipeline的状态设置为NULL,以确保它释放了所有之前申请的资源。
最后,释放pipeline以销毁它及其所有相关内容。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值