这是设计者写的原始设计文档,
多读几遍,结合代码来看。
http://cgit.freedesktop.org/gstreamer/gstreamer/tree/docs/design/
可见,pipeline的主要布局是elements, Bins 和pads.把上述几个对象继承关系牢记脑海中。PADs是连接器。pipeline的各对象之间的通信通过缓存buffers、事件event、查询query、消息message机制实现, 调度通过时钟clock和队列queue实现。
个人阅读顺序:
初步对gstreamer的设计有个大致的了解。
GstElement 一般是从GstElementFactory中create, 为什么不直接用g_object_new()?
(工厂名,就是插件名, 所以需要加载插件,然后创建对应的Element)
GstPad也是从GstObject派生,和GstElement是并行的派生关系,
但是GstPad一般隶属于GstElement.
GstPad是GstElement的property, 在GstElement内部:用几个GList来保存GstPad.
sink的设计要被source element复杂一些,都是实际使用的抽象。
现实中,sink就是比source复杂些。
根据user case分析内部的运行情况。
GstPad和GstPadTemplate是什么关系?
GstPadTemplate就是一个工厂吗?
push/poll模式
chain函数的作用?
caps其实是描述媒体类型(media type)的,用GstStructure保存;
caps似附属于gstPads/GstPadTemplate上的。
GstCaps是数据类型。
caps的negotiation: 规格的协商。
pipeline的各对象之间的通信通过缓存buffers、事件event、查询query、消息message机制实现, 调度通过时钟clock和队列queue实现。
buffering的目的:缓冲数据,使得播放更平顺。
buffer包含由(内存指针,内存大小,时间戳,引用计数等信息)。简单的使用方式是:创建buffer,分配内存,放入数据,传输到后续element,后续element读数据,处理后减去引用计数。更复杂的情况是element就地修改buffer中的内容,而不是分配一个新的buffer。element还写到硬件内存(video-capture src等),bufer还可以是只读的。
Events are objects passed around in parallel to the buffer dataflow to notify elements of various events.
Events are received on pads using the event function. Some events should be interleaved with the data stream so they require taking the STREAM_LOCK, others don't.
Different types of events exist to implement various functionalities.
GST_EVENT_FLUSH_START: data is to be discarded
GST_EVENT_FLUSH_STOP: data is allowed again
GST_EVENT_EOS: no more data is to be expected on a pad. GST_EVENT_NEWSEGMENT: A new group of buffers with common start time GST_EVENT_TAG: Stream metadata.
GST_EVENT_BUFFERSIZE: Buffer size requirements
GST_EVENT_QOS: A notification of the quality of service of the stream GST_EVENT_SEEK: A seek should be performed to a new position in the stream GST_EVENT_NAVIGATION: A navigation event.
GST_EVENT_LATENCY: Configure the latency in a pipeline
* GST_EVENT_DRAIN: Play all data downstream before returning.
* not yet implemented, under investigation, might be needed to do still frames in DVD.
Event控制包,可以发送给上/下游element。发送给下游的event统治后续element流状态,是断绝,涮新,流结尾等信息。发送给上游event用在应用交互和event-event交互,用来请求改变流状态,例如seek等。对于应用来说,只有上流event比较重要。下流event仅仅维持一个完整的数据流概念。
typedef enum { GST_EVENT_UNKNOWN = GST_EVENT_MAKE_TYPE (0, 0), /* bidirectional events */ GST_EVENT_FLUSH_START = GST_EVENT_MAKE_TYPE (1, FLAG(BOTH)), GST_EVENT_FLUSH_STOP = GST_EVENT_MAKE_TYPE (2, FLAG(BOTH) | FLAG(SERIALIZED)), /* downstream serialized events */ GST_EVENT_EOS = GST_EVENT_MAKE_TYPE (5, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_NEWSEGMENT = GST_EVENT_MAKE_TYPE (6, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_TAG = GST_EVENT_MAKE_TYPE (7, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_BUFFERSIZE = GST_EVENT_MAKE_TYPE (8, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_SINK_MESSAGE = GST_EVENT_MAKE_TYPE (9, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), /* upstream events */ GST_EVENT_QOS = GST_EVENT_MAKE_TYPE (15, FLAG(UPSTREAM)), GST_EVENT_SEEK = GST_EVENT_MAKE_TYPE (16, FLAG(UPSTREAM)), GST_EVENT_NAVIGATION = GST_EVENT_MAKE_TYPE (17, FLAG(UPSTREAM)), GST_EVENT_LATENCY = GST_EVENT_MAKE_TYPE (18, FLAG(UPSTREAM)), GST_EVENT_STEP = GST_EVENT_MAKE_TYPE (19, FLAG(UPSTREAM)), /* custom events start here */ GST_EVENT_CUSTOM_UPSTREAM = GST_EVENT_MAKE_TYPE (32, FLAG(UPSTREAM)), GST_EVENT_CUSTOM_DOWNSTREAM = GST_EVENT_MAKE_TYPE (32, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_CUSTOM_DOWNSTREAM_OOB = GST_EVENT_MAKE_TYPE (32, FLAG(DOWNSTREAM)), GST_EVENT_CUSTOM_BOTH = GST_EVENT_MAKE_TYPE (32, FLAG(BOTH) | FLAG(SERIALIZED)), GST_EVENT_CUSTOM_BOTH_OOB = GST_EVENT_MAKE_TYPE (32, FLAG(BOTH)) } GstEventType;
static GstEventQuarks event_quarks[] = { {GST_EVENT_UNKNOWN, "unknown", 0}, {GST_EVENT_FLUSH_START, "flush-start", 0}, {GST_EVENT_FLUSH_STOP, "flush-stop", 0}, {GST_EVENT_EOS, "eos", 0}, {GST_EVENT_NEWSEGMENT, "newsegment", 0}, {GST_EVENT_TAG, "tag", 0}, {GST_EVENT_BUFFERSIZE, "buffersize", 0}, {GST_EVENT_SINK_MESSAGE, "sink-message", 0}, {GST_EVENT_QOS, "qos", 0}, {GST_EVENT_SEEK, "seek", 0}, {GST_EVENT_NAVIGATION, "navigation", 0}, {GST_EVENT_LATENCY, "latency", 0}, {GST_EVENT_STEP, "step", 0}, {GST_EVENT_CUSTOM_UPSTREAM, "custom-upstream", 0}, {GST_EVENT_CUSTOM_DOWNSTREAM, "custom-downstream", 0}, {GST_EVENT_CUSTOM_DOWNSTREAM_OOB, "custom-downstream-oob", 0}, {GST_EVENT_CUSTOM_BOTH, "custom-both", 0}, {GST_EVENT_CUSTOM_BOTH_OOB, "custom-both-oob", 0}, {0, NULL, 0} };
从pipeline线程向应用程序发送发送消息,目的是对应用屏蔽线程的概念。缺省情况下,每个pipeline包含一个bus,所以应用不需要创建bus,仅仅需要在bus上设定一个对象信号处理类似的消息处理。当主循环开始运行后,bus周期性的检查新消息,如果有消息,那么调用注册的回调函数。如果使用glib,那么glib有对应的处理机制,否则使用信号机制。
流过pipeline的数据由buffers和events组成。buffers中是确切的pipeline数据,events中是控制信息,比如seek信息,end-of-stream指示等。src-element通常创建一个新的buffer,通过pad传递到链中的下一个element。