




已阅读5页,还剩14页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1: 本文介绍如何使用GStreamer 编写一个简单的MP3播放器2: 理解Gstreamer架构3: Gstreamer的同步机制4: streamer下采用ffmpeg复用成单节目TS流时的码率控制5: gstreamer应用程序的调试GStreamer学习笔记(一) 本文介绍如何使用GStreamer 编写一个简单的MP3播放器。1,需要使用mad解码插件,因此需要先安装gstreamer0.10-plugins-ugly2,编写mp3播放器下面来看看如何利用GStreamer框架提供的组件,来实现一个简单的MP3播放器。数据源元件负责从磁盘上读取数据,过滤器元件负责对数据进行解码,而接受器元件则负责将解码后的数据写入声卡。如果想要在程序中应用GStreamer提供的各种功能,首先必须在主函数中调用gst_init()来完成相应的初始化工作,以便将用户从命令行输入的参数传递给GStreamer函数库。一个典型的GStreamer应用程序的初始化如下所示:#includeintmain(intargc,char*argv)gst_init(&argc,&argv);/*/接下去需要创建三个元件并连接成管道,由于所有GStreamer元件都具有相同的基类GstElement,因此能够采用如下方式进行定义:GstElement*pipeline,*filesrc,*decoder,*audiosink;管道在GStreamer框架中是用来容纳和管理元件的,下面的代码将创建一条名为pipeline的新管道:/*创建用来容纳元件的新管道*/pipeline=gst_pipeline_new(pipeline);数据源元件负责从磁盘文件中读取数据,它具有名为location的属性,用来指明文件在磁盘上的位置。使用标准的GObject属性机制可以为元件设置相应的属性:/*创建数据源元件*/filesrc=gst_element_factory_make(filesrc,disk_source);g_object_set(G_OBJECT(filesrc),location,argv1,NULL);过滤器元件负责完成对MP3格式的数据进行解码,最简单的办法是安装mad这一插件,借助它来完成相应的解码工作:/*创建过滤器元件*/decoder=gst_element_factory_make(mad,decoder);接收器元件负责将解码后的数据利用声卡播放出来:/*创建接收器元件*/audiosink=gst_element_factory_make(audiosink,play_audio)已经创建好的三个元件需要全部添加到管道中,并按顺序连接起来: /*添加元件到管道中*/gst_bin_add_many(GST_BIN(pipeline),filesrc,decoder,audiosink,NULL);/*通过衬垫连接元件*/gst_element_link_many(filesrc,decoder,audiosink,NULL);所有准备工作都做好之后,就可以通过将管道的状态切换到PLAYING状态,来启动整个管道的数据处理流程:/*启动管道*/gst_element_set_state(pipeline,GST_STATE_PLAYING);这里加入一个消息处理函数bus_call来监视产生的消息/*终止管道*/gst_element_set_state(pipeline,GST_STATE_NULL);/*释放资源*/gst_object_unref(GST_OBJECT(pipeline);3,完整的源代码如下所示:#include#include/定义消息处理函数,staticgbooleanbus_call(GstBus*bus,GstMessage*msg,gpointerdata)GMainLoop*loop=(GMainLoop*)data;/这个是主循环的指针,在接受EOS消息时退出循环switch(GST_MESSAGE_TYPE(msg)caseGST_MESSAGE_EOS:g_print(Endofstreamn);g_main_loop_quit(loop);break;caseGST_MESSAGE_ERROR:gchar*debug;GError*error;gst_message_parse_error(msg,&error,&debug);g_free(debug);g_printerr(ERROR:%sn,error-message);g_error_free(error);g_main_loop_quit(loop);break;default:break;returnTRUE;intmain(intargc,char*argv)GMainLoop*loop;GstElement*pipeline,*source,*decoder,*sink;/定义组件GstBus*bus;gst_init(&argc,&argv);loop=g_main_loop_new(NULL,FALSE);/创建主循环,在执行g_main_loop_run后正式开始循环if(argc!=2)g_printerr(Usage:%sn,argv0);return-1;/创建管道和组件pipeline=gst_pipeline_new(audio-player);source=gst_element_factory_make(filesrc,file-source);decoder=gst_element_factory_make(mad,mad-decoder);sink=gst_element_factory_make(autoaudiosink,audio-output);if(!pipeline|!source|!decoder|!sink)g_printerr(Oneelementcouldnotbecreated.Exiting.n);return-1;/设置source的location参数。即文件地址.g_object_set(G_OBJECT(source),location,argv1,NULL);/得到管道的消息总线bus=gst_pipeline_get_bus(GST_PIPELINE(pipeline);/添加消息监视器gst_bus_add_watch(bus,bus_call,loop);gst_object_unref(bus);/把组件添加到管道中.管道是一个特殊的组件,可以更好的让数据流动gst_bin_add_many(GST_BIN(pipeline),source,decoder,sink,NULL);/依次连接组件gst_element_link_many(source,decoder,sink,NULL);/开始播放gst_element_set_state(pipeline,GST_STATE_PLAYING);g_print(Runningn);/开始循环g_main_loop_run(loop);g_print(Returned,stoppingplaybackn);gst_element_set_state(pipeline,GST_STATE_NULL);gst_object_unref(GST_OBJECT(pipeline);return0;理解Gstreamer架构 (2011-03-14 18:03:15)转载标签:gstreamer分类:gstreamer本文给出了Gstreamer的总体设计。通过阅读本文可以了解Gstreamer的内部工作原理。本文编译自gstreamer源码中的文档,原文在源码中的位置是/gstreamer/docs/design/part-overview.txt。概述Gstreamer是一个libraries和plugins的集合,用于帮助实现各种类型的多媒体应用程序,比如播放器,转码工具,多媒体服务器等。利用Gstreamer编写多媒体应用程序,就是利用elements构建一个pipeline。element是一个对多媒体流进行处理的object,比如如下的处理: 读取文件。 不同格式的编解码。 从硬件采集设备上采集数据。 在硬件设备上播放多媒体。 多个流的复用。elements的输入叫做sink pads,输出叫做source pads。应用程序通过pad把element连接起来构成pipeline,如下图所示,其中顺着流的方向为downstream,相反方向是upstream。应用程序会收到来自pipeline的消息和通知,比如EOS等。总体设计Gstreamer的设计目标如下: 快速处理大规模数据。 对多线程处理的完全支持。 能处理各种格式的流媒体。 不同数据流的同步。 处理多种设备的能力。基于Gstreamer的应用程序能够具备的处理能力依赖于系统中安装的不同种类功能的elements的数量。Gstreamer核心不具备处理具体的media的功能,但是element处理media时需要具备的特性很多是由Gstreamer的核心提供的。elementselement是pipeline的最小组成部分。element提供了多个pads,或者为sink,或者为source。一个element有四种可能的状态,分别是NULL,READY,PAUSED,PLAYING。NULL和READY状态下,element不对数据做任何处理,PLAYING状态对数据进行处理,PAUSE状态介于两者之间,对数据进行preroll。应用程序通过函数调用控制pipeline在不同状态之间进行转换。element的状态变换不能跳过中间状态,比如不能从READY状态直接变换到PLAYING状态,必须经过中间的PAUSE状态。element的状态转换成PAUSE会激活element的pad。首先是source pad被激活,然后是sink pad。pad被激活后会调用activate函数,有一些pad会启动一个Task。PAUSE状态下,pipeline会进行数据的preroll,目的是为后续的PLAYING状态准备好数据,使得PLAYING启动的速度更快。一些element需接收到足够的数据才能完成向PAUSE状态的转变,sink pad只有在接收到第一个数据才能实现向PAUSE的状态转变。通常情况下,element的状态转变需要协调一致。可对element进行如下分类: source,只提供数据源。 sink,比如播放设备。 transform demuxer muxerBinbin是由多个element构成的特殊的element,用图来说明:Pipelinepipeline是具备如下特性的特殊的bin: 选择并管理一个全局的时钟。 基于选定的时钟管理running_time。running_time用于同步,指的是pipeline在PLAYING状态下花费的时间。 管理pipeline的延迟。 通过GstBus提供element与应用程序间的通讯方式。 管理elements的全局状态,比如EOS,Error等。Dataflow and buffersGstreamer支持两种类型的数据流,分别是push模式和pull模式。在push模式下,upstream的element通过调用downstream的sink pads的函数实现数据的传送。在pull模式下,downstream的element通过调用upstream的source pads的函数实现对数据的请求。push模式是常用的模式,pull模式一般用于demuxer或者低延迟的音频应用等。在pads之间传送的数据封装在Buffer里,Buffer中有一个指向实际数据的指针以及一些metadata。metadata的内容包括: timestamp offset duration media type 其它在push模式下,element通过调用gst_pad_push()函数把buffer传送给对应的pad。在pull模式下,element通过调用gst_pad_pull_range()函数把pull过来。element在push buffer之前需要确认对应的element具备处理buffer中的数据类型的能力。在传说红之前首先查询对应的element能够处理的格式的种类,并从中选择合适的格式,通过gst_buffer_set_caps()函数对buffer进行设置,然后才传送数据。收到一个buffer后,element要首先对buffer进行检查以确认是否能够处理。可以调用gst_buffer_new()函数创建一个新的buffer,也可以调用gst_pad_alloc_buffer()函数申请一个可用的buffer。采用第二种方法接收数据的buffer可以设定接收其它类型的数据,这是通过对buffer的caps进行设定来实现的。选择媒体类型并对buffer进行设定的处理过程叫做caps negotianation。CapsCaps,也就是媒体类型,采用key/value对的列表来描述。key是一个字符串类型,value的类型可能是int/float/string类型的single/list/range。Data flow and events除了数据流,还有events流。与数据流不同,events的传送方向既有downstream的,也有upstream的。events用于传递EOS,flushing,seeking等消息。有的events必须和data flow一起进行serialized。serialized的events比如TAG,非serialized的events比如FLUSH。Pipeline constructiongst_pipeline_create()函数用于创建一个pipeline,gst_bin_add()函数用于向pipeline中添加element,gst_bin_remove()函数用于从pipeline中移除element。gst_element_get_pad()函数用于检索pipeline中的element。gst_pad_link()函数用于把pads连接在一起。有的element会在数据流开始传送的时候创建新的pads,通过调用函数g_signal_connect()函数,能在新的pads被创建的时候接收到消息。由于处理的数据互相不兼容,有的elements是不能被连接到一起的。gst_pad_get_caps()函数查询element能够处理的数据类型。Pipeline clockPipeline的一个重要功能是为pipeline中的所有elements选择一个全局时钟。时钟的作用是提供一个每秒为GST_SECOND的单调递增的时钟,单位是纳秒。element利用这个时钟时间来播放数据。在pipeline被设为PLAYING之前,pipeline查询每一个element是否能提供clock,并按照如下次序来选择clock: 应用程序选择了一个clock。 如果source element提供了clock。 其它任何提供了clock的element。 选择一个默认的系统clock。也有特殊的情况,比如存在音频sink提供了clock,那么就选择其提供的clock。Pipeline states完成了pads的链接和signals的链接,就可以设定pipeline为PAUSED状态启动数据流的处理。当bin(这里指的是pipeline)进行状态转换的时候要转换所有的children的状态,转换的次序是从sink element开始到source element结束,这样做的目的是为了确保upstream element提供数据的时候,downstream element已经准备好。Pipeline statusPipeline会通过bus向应用程序通报发生的events。bus是由pipeline提供的一个object,可以通过gst_pipeline_get_bus()函数取得。bus分布到加入pipeline的每一个element。element利用bus来发布messages。有各种不同类型的messages,比如ERRORS,WARNINGS,EOS,STATE_CHANGED等。pipeline以特殊的方式处理接收到的EOS message,只有当所有的sink element发送了EOS message的时候,pipeline才会把EOS发送给应用程序。也可以通过gst_element_query()函数获取pipeline status,比如获取当前的位置或者播放的时间。Pipeline EOS当source filter遇上了流结束,会沿着downstream的方向向下一个element发送一个EOS的event,这个event依次传送给每一个element,接收到EOS event的element不再接收数据。启动了线程的element发送了EOS event后就不再发送数据。EOS event最终会到达sink element。sink element会发送一个EOS消息,通告流结束。pipeline在接收到EOS消息以后,把消息发送给应用程序。只有在PLAYING状态下会把EOS的消息传送给应用程序。发送了EOS以后,pipeline保持PLAYING状态,等待应用程序把pipeline的状态置为PAUSE或者READY。应用程序也可以进行seek操作。Gstreamer的同步机制(2011-03-16 19:07:21)转载标签:gstreamer同步分类:gstreamer本文编译自gstreamer源代码中的文档,原文的路径是gstreamer/docs/design/part-synchronisation.txt。本文描述了Gstreamer的同步机制,Gstreamer中实现同步的组件如下: GstClock,是全局的,用于pipeline中的所有elements。 GstBuffer的timestamps。 buffers之前的NEW_SEGMENT event。GstClockGstClock是精确到纳秒的表示当前时间的一个计数。其值用absolute_time表示。这个计数的源的选择如下: 系统时间,精度是微妙。 音频设备。 基于网络的数据包,比如RTP数据包。 其它。在Gstreamer中任何element都可以提供GstClock,pipeline从所有可用的GstClock中选定一个并用于pipeline中所有的elements。时间计数单调递增,可以不是从0开始计数。Running time选定了clock之后pipeline会维护一个基于选定时钟的running_time。running_time指的是pipeline处于PLAYING状态下的时间总和,计算方法如下: 如果pipeline处于NULL或者READY状态则running_time处于undefined。 PAUSE状态下,running_time的值保持不变,如果处于刚开始启动时的PAUSE状态,running_time的值为0。 flushing seek之后,running_time被置为0。这需要向所有被flush的elemnt指定一个新的base_time。上述的计算方法在pipeline的状态从PLAYING状态设定为PAUSE状态时记录running_time,当从PAUSE状态转变为PLAYING状态后基于absolute_time恢复running_time。针对PAUSE后继续计数的clock,比如system clock,以及PAUSE后不再计数的clock,比如audioclock都是适用的。running_time的计算方法如下:C.running_time = absolute_time - base_timeTimestampsGstBuffer的timestamps以及NEW_SEGMENT event定义了 buffer timestamps 到 running_time的变换B: GstBuffer B.timestamp = buffer timestamp (GST_BUFFER_TIMESTAMP)NS:NEWSEGMENT event preceeding the buffers. NS.start: start field in the NEWSEGMENT event NS.stop: stop field in the NEWSEGMENT event NS.rate: rate field of NEWSEGMENT event NS.abs_rate: absolute value of rate field of NEWSEGMENT event NS.time: time field in the NEWSEGMENT event NS.accum: total accumulated time of all previous NEWSEGMENT events. This field is kept in the GstSegment structure.符合同步要求的buffers其B.timestamp需在NS.start和NS.stop之间,B.timestamp不在这个范围内的buffers需要丢掉或者进行修正。对于running_time存在如下变换:if (NS.rate 0.0)B.running_time = (B.timestamp - NS.start) / NS.abs_rate + NS.accumelseB.running_time = (NS.stop - B.timestamp) / NS.abs_rate + NS.accumB.running_time由NEWSEGMENT event以及该segment的buffers得到。可显示的第一个buffer的running_time的值为0。对于 NS.rate 1.0,timestamps的值缩小从而使得播放速度加快。For negative rates, timestamps are received stop NS.stop to NS.start so that the first buffer received will be transformed into B.running_time of 0 (B.timestamp = NS.stop and NS.accum = 0).Synchronisation对于running_time的计算方法如下: 采用clock以及element的base_time:C.running_time = absolute_time - base_time 采用buffer timestamp和其前面的NEWSEGMENT event,假定为正向播放:B.running_time = (B.timestamp - NS.start) / NS.abs_rate + NS.accum这里的前缀C.和B.代表不同的计算方法。同步播放的目的就是确保running_time为B.running_time的buffer在C.running_time的时刻播放。这需要满足如下条件:B.running_time = C.running_time也就是:B.running_time = absolute_time - base_time或者absolute_time = B.running_time + base_time具有B.running_time的buffer应当被播放时的absolute_time记为B.sync_time,那么:B.sync_time = B.running_time + base_time这意味着等到clock到了B.sync_time的时候才播放buffer,对于多个流中具有相同的running_time的buffer应该同时播放。dumuxer必须确保向输出pads发出的NEWSEGMENT能为buffers生成一样的running_time,从而使之保持同步。通常向pads发出同样的NEWSEGMENT来确保同步的buffer具有一样的timestamp。Stream timestream time,也称作在流中的位置,是一个在0和媒体文件长度(时间)之间的值。具有如下用途: report the POSITION query in the pipeline the position used in seek events/queries the position used to synchronize controller values通过buffer和其前面的NEWSEGMENT event来计算stream time:stream_time = (B.timestamp - NS.start) * NS.abs_applied_rate + NS.time对于播放速度为负的情况,B.timestamp将从NS.stop 到 NS.start,使得stream time反向。在PLAYING 状态,也可以采用pipeline clock 计算当前的stream_time。 Give the two formulas above to match the clock times with buffer timestamps allows us to rewrite the above formula for stream_time (and for positive rates).C.running_time = absolute_time - base_timeB.running_time = (B.timestamp - NS.start) / NS.abs_rate + NS.accum=(B.timestamp - NS.start) / NS.abs_rate + NS.accum = absolute_time - base_time;=(B.timestamp - NS.start) / NS.abs_rate = absolute_time - base_time - NS.accum;=(B.timestamp - NS.start) = (absolute_time - base_time - NS.accum) * NS.abs_ratefilling (B.timestamp - NS.start) in the above formule for stream time=stream_time = (absolute_time - base_time - NS.accum) * NS.abs_rate * NS.abs_applied_rate + NS.time最后的计算公式通常是sink用于report当前的position的准确和有效的方式。Note that the stream time is never used for synchronisation against the clock.streamer下采用ffmpeg复用成单节目TS流时的码率控制(2011-04-14 15:47:26)转载标签:gstreamercbrit分类:gstreamer复用成单节目TS流时的码率控制mux
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 农业合作社合同制定及信息交流措施
- 餐饮行业供应合同管理措施
- 公共停车场运营管理合同样本
- 蓄水池合同3篇
- 合资公司劳动合同3篇
- 防盗、防火门制作安装合同2篇
- 乡镇自来水厂承包合同4篇
- XX年十月底翻译版权许可合同3篇
- 有关电脑维护合同(六)6篇
- 公交站亭广告位经营权入股合同6篇
- 2025年监理工程师考试《建设工程监理基本理论与相关法规》真题及答案
- 小学道德与法制教学中“责任担当”核心素养的培养
- 水利安全风险防控“六项机制”与安全生产培训
- 机械专业面试真题及答案
- TCPQSXF006-2023消防水带产品维护更换及售后服务
- 酒店客房送餐服务流程与规范
- DB61-T+1418-2021 河湖和水利工程管理范围及保护范围划界技术规范
- 2025年江苏省昆山市五校联考中考三模道德与法治试题(原卷版+解析版)
- 露营基地管理制度清单
- 2025年上海市黄浦区高三语文二模试卷及答案
- 老年脑卒中患者居家护理
评论
0/150
提交评论