阁子

阁子

马上订阅 阁子 RSS 更新: https://dfine.tech/atom.xml

GStreamer笔记二: Dynamic Pipeline

2017年12月1日 15:52

主要也是关于建立Pipeline的,不过主要目的是建立动态的Pipeline,即在信息可用时随时创建Pipeline,而不是在应用程序开始时候定义单一Pipeline。

一些基本概念的重申

本次尝试: 将Pipeline在其未完全建立起来时设置为Playing状态。虽然这并没有什么问题,如果不做任何动作,当数据到达Pipeline末端时将会由Pipeline产生一个error并停止,所以尝试会采取进一步的操作。尝试打开一个多路复用(muxed)的文件,即视频和音频存在一个容器文件中。负责打开该容器的元素称之为分离器(demuxers)。容器格式例如: MKV(Matroska), QT/MOV(Quick Time), Ogg或高级系统格式如ASF, WMV, WMA等。

pad

如前所述,pad就是Gstreamer元素间互相通信的一个接口,也有人翻译为衬垫。数据通过sink pad流入,通过source pad流出。只包含source pad的称之为source元素,只包含sink pad的元素称为sink元素,两者兼有则称之为filter元素。如图所示:



分离器

如果一个容器嵌入多个流(例如一个视频和两个音频轨道),则分离器将分离它们并将其展示于不同的输出端口。通过这种方式,可以在流水线中创建不同的分支,处理不同类型的数据。
一个含有两个source pad和一个sink pad的分离器的例子如图所示:




使用分离器的一个Pipeline例子如下:




该例是一个基本的Ogg播放器的Gstreamer Pipeline。
处理分离器的主要复杂性在于,只有在接收到一些数据且有机会查看容器并看到其内部信息之后,才能产生信息。即分离器开始时,没有任何其他元素能连接的source pad,因此Pipeline必须终止它们。
解决方法是建立一个从source向下到分离器的一个Pipeline,并将其设置为运行(Play)。当分离器了解了关于容器中数据流的数目和种类的足够信息之后,其会开始创建source pads。此时即是完成Pipeline创建并将其添加到新的分离器pads上的最佳时机。
简单起见,所用例子仅连接到audio pad,忽略video pad。

动态建立示例

一个动态的HelloWorld示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <gst/gst.h>
/* Structure to contain all our information, so we can pass it to callbacks...

剩余内容已隐藏

查看完整文章以阅读更多