GStreamer框架

1、GStreamer是什么?

众所周知,Microsoft's Windows和Apple's MacOS对多媒体设备、多媒体创作、播放和实时处理等方面都有很好的支持,而Linux对多媒体应用一直略显不足,所以为了解决Linux上对多媒体方面的支持,才引进GStreamer。

GStreamer是一个通用的跨平台的流媒体应用程序框架,基于GObject,以C语言写成。 GStreamer并不受限于音频和视频处理,它能够处理任意类型的数据流,因此任意一种流媒体应用都可以支持,如:MeidaPlayer、A/V Editor、VOIP、RTSP、A/V Coder等等。 GStreamer框架是基于插件(plugin)和管道(pipeline)的体系结构,框架中所有功能模块都是可插拔的组件,可随意安装到任意管道上,因此造就了大量的GStreamer的共享库。

2、 pipeline是什么?

这是个典型的MeidaPlayer的模型。

source —— 数据来源,可能是file、http、rtp等。

demux —— 负责把容器里的音视频数据剥离出来,然后分别送给audio/video decoder。

decoder —— 解码,然后把解完后的数据(pcm/yuv)送给audio/video output输出。

output —— 负责将decoder过来的数据呈现出来。

如果把数据想象成流水的话,每个模块功能虽然不同,但基本都是接收上个模块过来的数据,然后加工,把加工后的数据送到下一个模块,这些模块通过某种方式连接起来,就形成了一个流水线(pipeline),这个流水线就是一个MediaPlayer。 GStreamer 把每个模块都看做是一个元件(element),然后构建连接和操作这些element的方法,用户可以通过自己的需求把不同的elements排列组合,形成不同的pipeline。

3. element是什么?

element是一个对多媒体流进行处理的object,也是一个具体的功能模块,是pipeline的最小组成部分。

element分类:source(只提供数据源),sink(如播放设备),transform,demuxer,muxer element的输入为sink pad,输出为source pad,通过pad把element连接起来构成pipeline 图中downstream为顺流方向,upstream为逆流方向

4. pad是什么?

element的衬垫(pad)对应输入和输出接口,对于输入衬垫为sink pad,对于输出衬垫为source pad element之间都是通过pad来链接的,顺序流向不能错,也基于pad类型进行分类

pad有处理特殊数据的能力,一个pad能够限制数据流类型(GstCaps)的通过。 链接成功的条件是:只有在两个衬垫(pads)允许通过的数据类型一致的时候才被建立,通过caps negotiation方法。 衬垫有三种类型的时效性: 永久型(always)、随机型(sometimes)、请求型(on request)。 永久型的衬垫一直会存在,随机型的衬垫只在某种特定的条件下才存在(会随机消失的衬垫也属于随机型), 请求型的衬垫只在应用程序明确发出请求时才出现。

5. 四种状态

element有四种可能的状态,分别是NULL,READY,PAUSED,PLAYING。

GST_STATE_NULL 默认状态,该状态将会回收所有被元件占用的资源。

GST_STATE_READY 准备状态,该状态会得到所需的全局资源,但数据流并未处理。

GST_STATE_PAUSED 暂停状态,元件已经对流开始处理,一旦状态变为 PLAYING,可以重放数据流, 与PLAYING 状态的区别是:时钟是禁止运行的,主要对数据进行preroll。

GST_STATE_PLAYING 与 PAUSED 状态一模一样,但可以运行时钟,对数据进行处理。

通过函数gst_element_set_state()可以改变一个元件的状态,但状态变换不能跳变,比如不能从READY状态 直接变换到PLAYING状态,必须经过中间的PAUSE状态。

6. element流程

element create   

  gstreamer加载时,扫描/usr/lib/gstreamer-1.0目录下的库,识别其中的feature,并记录相关信息。当使用时,检查gstreamer core是否支持该功能,如果有,则加载相应库,获取信息,创建相应的element实例。

element link

  element创建后,会添加到pipeline,在link时会通过gst_pad_query_caps(pad, NULL)查询pad template caps。因为此时尚未打开设备、初始化等,所以不知道element真正支持的caps,但只要查询的caps有交集即可link成功。

NULL->READY

  该状态下,会初始化设备,根据相应的class调用start()或open()等函数初始化相应的硬件设备,初始化class的结构参数等。

READY->PAUSED

  进一步申请资源,确定相应的参数设置,同时会激活pad。然后数据预滚(preroll),当数据到达时,检查数据时间戳是否在segment内,进行数据同步,最后就是commit,进入PAUSED。

PAUSED->PLAYING

  在这个过程,设置clock时钟运行,接收到数据时,检查时间有效性,进行数据同步、处理,push到下游,发送QOS事件到上游,完成一个循环。

7. bin是什么?

箱柜(bin)是由多个element构成的容器,同时bin本身也是一种element,所以能够像操作普通element一样操作一个bin,改变bin的状态可以改变bin内部所有elements的状态。

bin可以发送总线消息给它的子集elements ,包括:错误消息(error messages),标签消息(tag messages),EOS消息(EOS messages)。

管道(pipeline)是一个特殊的bin,当设定管道暂停或播放状态的时候,数据流将开始流动,并且媒体数据处理也开始处理。一旦开始,pipeline将在一个单独的线程中运行,直到被停止或者数据流播放完毕。

data flow:数据流在pads之间传送,封装在Buffer里,Buffer包含指向数据的指针和一些metadata。

event flow:事件流与数据量不同,既有downstream方向,也有upstream,可以捕捉事件信号,进行回调处理

pipeline构建过程

gst_pipeline_new()函数:创建一个pipeline

gst_bin_add()函数:向pipeline中添加elements

gst_bin_remove()函数:从pipeline中移除element

gst_element_link()函数:链接pipeline中的elements

8. 缓冲区

缓冲区是指管道里的数据流,通常一个源元件会创建一个新的缓冲区,同时元件还将会把缓冲区的数据传递给下一个元件。使用GStreamer创建管道,不需要自己来处理缓冲区,元件将会自动处理这些缓冲区。

一个缓冲区主要组成:

指向某块内存的指针

内存的大小

缓冲区的时间戳

一个引用计数,指出了缓冲区所使用的元件数。没有元件可引用的时候,这个引用将用于销毁缓冲区

9. message/event/signal

Bus message —— 用于gstreamer和app之间交互的,比如当一个文件播放结束的时候,gstreamer会发一个EOS的message到GstBus上,如果app有去侦听(函数gst_bus_add_watch),那么在处理消息的callback函数中就可以收到这个消息。

event —— 用于gstreamer内部element之间(或pad之间)传递事件的,比如source element数据已经结束,会发出一个EOS event,顺着pipeline依次向downstream方向传递,elements得到通知,做一些cleanup工作,当所有sink element都收到并处理之后,gstreamer内部产生一条GSTMessage,并post至GstBus,如果APP有监听,就能知道当前播放已经结束。

signal —— 属于GObject体系,用于app和GObject之间交互的一种机制。在gstreamer中,element本身也是gobject,所以通过signal,就可以将app和element联系起来。 当element发生了一些事情相让app知道时,就可以用signal的方式来通知app,比如动态创建了一个Pad。

10. 初步总结

需要包含头文件gst/gst.h来访问库函数。

使用gst_init初始化GStreamer库和一些必要的参数。

使用gst_element_factory_make创建元件,参数为工厂对象名和新元件名,在bin中可查询该元件。

使用gst_object_unref释放元件,元件引用记数减1,任一元件创建时,引用记数为1,当引用记数为0时,元件会被销毁。

使用gst_bin_new或gst_pipeline_new创建箱柜。

使用gst_bin_add/remove添加/移除元件,元件所属箱柜,销毁箱柜,则箱柜中的元件同样被销毁,元件移除则自动销毁。

使用gst_element_link链接元件

每个管道默认包含一个总线,应用程序不需要再创建总线,只需在总线上设置一个消息处理器,总线会轮询消息处理器是否有新的消息,当采集到消息后,总线将呼叫相应的回调函数来处理。使用gst_bus_add_watch或gst_bus_add_signal_watch侦听回调,或使用gst_bus_peek/poll主动轮询消息。

11. 编译说明

比如之前的helloworld程序

编译: gcc -Wall helloworld.c -o helloworld $(pkg-config --cflags --libs gstreamer-0.10)

编译时借助了pkg-config命令,用于获得某一个库/模块的所有编译相关的信息。

pkg-config --cflags --libs gstreamer-0.10 会把gstreamer-0.10编译所依赖的库路径和头文件路径全部找出来,不用再依次写出,这条命令参数相当于: -pthread -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/gstreamer-0.10 -I/usr/include/libxml2 -pthread -L/usr/lib/i386-linux-gnu -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lxml2 -lgthread-2.0 -lrt -lglib-2.0)

GStreamer流媒体知识介绍的更多相关文章

  1. [推荐]dubbo分布式服务框架知识介绍

    [推荐]dubbo分布式服务框架知识介绍 CentOS+Jdk+Jboss+dubbo+zookeeper集群配置教程    http://wenku.baidu.com/view/20e8f36bf ...

  2. [推荐]Zookeeper大型分布式系统的可靠协调系统知识介绍

    [推荐]Zookeeper大型分布式系统的可靠协调系统知识介绍 基于Zookeeper的锁开发手册 http://wenku.baidu.com/view/acbb8fc6102de2bd960588 ...

  3. [推荐]DDOS攻击与防范知识介绍

    [推荐]DDOS攻击与防范知识介绍 DDOS攻防体系建设v0.2(淘宝-林晓曦)     http://wenku.baidu.com/view/39549a11a8114431b90dd866.ht ...

  4. [推荐]WebService开发知识介绍

    [推荐]WebService开发知识介绍 WebService开发手册  http://wenku.baidu.com/view/df3992ce050876323112128a.html WebSe ...

  5. [转] - Linux网络编程 -- 网络知识介绍

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  6. [转]流媒体协议介绍(rtp/rtcp/rtsp/rtmp/mms/hls)

    [转]流媒体协议介绍(rtp/rtcp/rtsp/rtmp/mms/hls) http://blog.csdn.net/tttyd/article/details/12032357 RTP       ...

  7. (转)Linxu磁盘体系知识介绍及磁盘介绍

    Linxu磁盘体系知识介绍及磁盘介绍 系统管理 / 2017-01-14 / 0 条评论 / 浴春风 Linu磁盘设备基础知识指南磁盘速度快具备的条件: 1)主轴的转速5400/7200/10000/ ...

  8. linux字符设备驱动--基本知识介绍

    一.设备驱动的分类 1.字符设备 字符设备是指那些能一个字节一个字节读取数据的设备,如LED灯.键盘.鼠标等.字符设备一般需要在驱动层实现open().close().read().write().i ...

  9. PySpark SQL 相关知识介绍

    title: PySpark SQL 相关知识介绍 summary: 关键词:大数据 Hadoop Hive Pig Kafka Spark PySpark SQL 集群管理器 PostgreSQL ...

随机推荐

  1. python 基础学习笔记(1)

    声明:  本人是在校学生,自学python,也是刚刚开始学习,写博客纯属为了让自己整理知识点和关键内容,当然也希望可以通过我都博客来提醒一些零基础学习python的人们.若有什么不对,请大家及时指出, ...

  2. JAVA Stirng.format 使用理解

    JAVA Stirng.format 使用理解前言:项目中需要对一些字符串处理发现format方法的神奇之处一.api才是王道第一种二参使用①public static String format(S ...

  3. 侦听器watch 监听单个属性

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. springboot2.x纯注解整合dubbo

    springboot1.x和springboot2.x整合差距挺大的,基于最新的2.x进行整合,使用纯注解的方式 依赖选取 首先pom文件的依赖引入,maven仓库有Apache和alibaba两个 ...

  5. Acrobat pro Dc 2018破解版|Adobe Acrobat pro Dc 2018中文破解版下载(附序列号/免破解)

    Acrobat pro Dc 2018破解版是由Adobe公司开发的一款PDF编辑软件,它可以以PDF格式制作和保存用户的文档,以此方便浏览和打印,或使用更高级的功能,且PDF格式的文档可如实地保留原 ...

  6. CDQZ集训DAY2 日记

    依然很爆炸. T1上来有50分暴力分,打完后注意到了后50分的随机数据,开始想怎么去对付他.然后就开始思考随机数据意味着什么.想了想,想打一个扫描线或者分治.决策了一下还是打了一个扫描线+链表.然而只 ...

  7. Jmeter自定义Java请求开发

    一.本次实验目的 IDEA新建maven项目,使用java开发自定义jmeter的请求. 本次开发使用的代码,会百度云分享给大家. 二.本次实验环境 Idea 2017.02 Jmeter 5.1.1 ...

  8. BZOJ4152 The Captain(dijkstra+巧妙建图)

    BZOJ4152 The Captain 题面很简洁: 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. 很明显 ...

  9. JQuery学习笔记(3)——节点操作 节点查找

    插入节点 内部插入 所谓的内部插入,就是指在节点里面的插入,而外部插入,则是在节点外面插入. append() prepend() appendTo() prependTo() append和prep ...

  10. 个人永久性免费-Excel催化剂功能第73波-数据转换:单行多项目转多行单项目

    数据分析的前半部分数据处理.转换等工作是一个又脏又累的活,默默地干着,却又不出彩让人看到过程的艰辛和成果.如何让这个过程可以更加轻松一点,是Excel催化剂为大家所想的,今天带来一大刚需的数据转换功能 ...