GStreamer+开发手册 -
它会自动选择解码器。对于每条需要解码的数据流,它会发射一个
\信号,让应用程序知道发现了一种新的需要被解码的流。对于未知的数据流(可能整条数据流都未知),它会发射一个\信号。应用 gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/* make sure we have input */ 程序负责把这个错误报告给用户。
#include
[.. my_bus_callback goes here ..]
GstElement *pipeline, *audio;
static void
void on_button_connect(gtkwidget *widget, gpointer data)。void on_delete_event(gtkwidget *widget, gdkevent *event, gpointer data)。static gboolean delete_event(gtkwidget *widget, gdkevent *event, gpointer data){。
if(str == null || str.equals("") || str.equals("*") || str.equals("{") ||str.equals("}") || str.equals("+") ||str.equals("-") || str.equals("/") 。 || str.equals(".") || str.equals(":") || str.equals("/**") || str.equals("//") || str.endswith("==") || str.equals("。else if(str[i]>=65&&str[i]<90||str[i]>=97&&str[i]<122) str[i]=str[i]+1。
/* only link once */
audiopad = gst_element_get_pad (audio, \ if (GST_PAD_IS_LINKED (audiopad)) {g_object_unref (audiopad);return; }
/* check media type */
caps = gst_pad_get_caps (pad);
str = gst_caps_get_structure (caps, 0);
if (!g_strrstr (gst_structure_get_name (str), \ gst_caps_unref (caps);
gst_object_unref (audiopad);return; }
gst_caps_unref (caps);
/* link'n'play */
gst_pad_link (pad, audiopad); } gint
main (gint argc,gchar *argv[]) {
GMainLoop *loop;
dec 70-40034-01 starligth bus lvd i/o module。(3)opencore中parser/dec/sink是并行处理的。drwxr-xr-x. 2 root root 4096 dec 4 2009 src。
/* init GStreamer */
if (argc != 2) {
g_print (\ return -1; }
/* setup */
pipeline = gst_pipeline_new (\
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); gst_bus_add_watch (bus, my_bus_callback, loop); gst_object_unref (bus);
src = gst_element_factory_make (\
g_object_set (G_OBJECT (src), \ dec = gst_element_factory_make (\
g_signal_connect(g_object(button),"clicked",g_callback(change_label_text), null)。g_signal_connect(but2,"clicked",g_callback(gtk_main_quit),null)。 g_signal_connect(g_object(test2_button), "clicked",g_callback(hide_test_window), null)。
/* create audio output */
audio = gst_bin_new (\
conv = gst_element_factory_make (\ audiopad = gst_element_get_pad (conv, \
sink = gst_element_factory_make (\ gst_bin_add_many (GST_BIN (audio), conv, sink, NULL); gst_element_link (conv, sink); gst_element_add_pad (audio,
gst_ghost_pad_new (\ gst_object_unref (audiopad);
gst_bin_add (GST_BIN (pipeline), audio);
/* run */
gst_element_set_state (pipeline, GST_STATE_PLAYING); g_main_loop_run (loop);
/* cleanup */
gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (GST_OBJECT (pipeline));
return 0; }
Decodebin同 playbin 类似,支持下列功能: 可以为解码输出衬垫输送无限多已包含的流。
以gstElement方式处理事件gstreamer中文开发手册,包括错误处理、标签处理、状态处理。 尽管 decodebin 是一个优秀的自动插件,但仍有一些事情是它处理的,decodebin 本身也并没打算处理这些事情:
41
处理已知的媒体类型(像 DVD,以及 audio-CD等)。
选择流(像在多语言的媒体文件流中选择一种音频声道)。 在解码的视频流中加载字幕。
简单地gstreamer中文开发手册,可以通过命令行来测试\:gst-launch-0.8 filesrc location=file.ogg ! decodebin ! audioconvert ! alsasink.
19.3. GstEditor
GstEditor使用一些窗口小部件来图形化显示一条管道。
第20章. XML在GStreamer 中的应用
GStreamer使用XML来存储和加载它的已有的管道信息 (definitions)。XML 同样被用来在GStreamer内部管理插件注册中心( plugin registry)。插件注册中心是一个包含了当前 GStreamer 所涵盖的所有插件定义的文件,GStreamer 能够根据这个文件快速访问到一个特定的插件。
我们将会介绍如何将一个管道的信息以XML文件形式存储,以及以后需要使用该管道的信息时如何再加载该XML文件。
20.1. 将GstElements 信息转换成 XML
我们创建一个简单的管道,然后使用gst_xml_write_file ()将其信息写到标准输出上。下面的代码构建了一个拥有2个线程的播放MP3的管道。然后将其XML信息写到标准输出和文件中。运行这个程序需要一个参数:磁盘上 MP3 文件的名字。
#include #include
gboolean playing; int
main (int argc, char *argv[]) {
GstElement *filesrc, *osssink, *queue, *queue2, *decode; GstElement *bin;
GstElement *thread, *thread2;
gst_init (&argc,&argv);
if (argc != 2) {
g_print (\ exit (-1); }
/* create a new thread to hold the elements */
thread consumer = new thread(new runnable() {//消费者 @override public void run() { testobj readobj = null。46 if((temp = pthread_create(&thread[1], null, thread2, null)) 。42 if((temp = pthread_create(&thread[0], null, thread1, null)) 。
thread thread2 = null。 pthread_create(&thread2, null, run, null)。pthread_create(&ppid2,&attr1,(void*)thread2,null)。
/* create a new bin to hold the elements */ bin = gst_bin_new (\ g_assert (bin != NULL);
/* create a disk reader */
filesrc = gst_element_factory_make (\ g_assert (filesrc != NULL);
42
g_object_set (G_OBJECT (filesrc), \
queue = gst_element_factory_make (\ queue2 = gst_element_factory_make (\
/* and an audio sink */
osssink = gst_element_factory_make (\ g_assert (osssink != NULL);
decode = gst_element_factory_make (\ g_assert (decode != NULL);
/* add objects to the main bin */
gst_bin_add_many (GST_BIN (bin), filesrc, queue, NULL);
thread consumer = new thread(new runnable() {//消费者@overridepublic void run() {testobj readobj = null。 thread consumer = new thread(new runnable() {//消费者 @override public void run() { try{ testobj readobj = null。concat,decode,dump,nvl,replace在调用了null参数时能够返回非null值。
gst_bin_add (GST_BIN (thread2), osssink);
gst_element_link_many (filesrc, queue, decode, queue2, osssink, NULL);
gst_bin_add_many (GST_BIN (bin), thread, thread2, NULL);
/* write the bin to stdout */
gst_xml_write_file (GST_ELEMENT (bin), stdout);
/* write the bin to a file */
gst_xml_write_file (GST_ELEMENT (bin), fopen (\est.gst\
exit (0); }
上面代码中最重要的一行是:
gst_xml_write_file (GST_ELEMENT (bin), stdout);
gst_xml_write_file () 函数会把给定的元件转换成 xmlDocPtr对象,xmlDocPtr对象会以一种XML格式存到文件中。如果想将信息存到磁盘上,在第二个参数处传递fopen(2)的结果。
完整的元件层次结构会随着连接的元件衬垫以及元件参数一起被存储,在今后的 GStreamer 版本将会允许你将信号信息也存到XML文件中。
20.2. 从XML文件加载一个GstElement对象
在XML文件被装载前,你必须创建一个 GstXML 对象。一个XML文件可以通过gst_xml_parse_file (xml, filename, rootelement)方法来装载,rootelement可以为NULL。下面的例子将装载上节创建的XML文件并运行管道。
43gst_xml_get_element (xml, \可以从XML文件中得到一个特定的元件。
gst_xml_get_topelements (xml)可以从XML文件中得到一个顶层元件列表。 除了装载文件以外,你还可以通过装载xmlDocPtr得到管道信息,然后在内存缓冲中分别使用gst_xml_parse_doc和 gst_xml_parse_memory方法。这两种方法都会返回一个 gboolean值来指示请求动作的成功或失败。
20.3. 新增自定义XML标签到核心XML数据中
你可以通过gst_xml_write给核心的XML文件添加自定义XML标签,这个功能可以使应用程序保存插件时存储更多的信息,例如编辑器 (editor)可以通过自定义XML标签存储元件在屏幕中的位置信息。
强烈建议使用命名空间(namespace)来存储和装载自定义XML标签,这将解决自定义XML标签与核心XML文件冲突的问题。
你可以使用下面的代码做这样一件事:当你给特定的GstElement 连接一个信号时,在存储该元件的过程中插入一个吊钩(hook)。
xmlNsPtr ns;
...
ns = xmlNewNs (NULL, \.net/gst-test/1.0/\ ...
thread = gst_element_factory_make (\ g_signal_connect (G_OBJECT (thread), \G_CALLBACK (object_saved), g_strdup (\ ...
当线程被保存时,方法 object_save 将会被调用。下面的例子将会插入一个 comment 标签:
static void
object_saved (GstObject *object, xmlNodePtr parent, gpointer data) {
xmlNodePtr child;
child = xmlNewChild (parent, ns, \ xmlNewChild (child, ns, \}
在上面加入添加自定义标签的例子中,你将会得到一个添加了自定义标签的 XML 文件。下面是一部分摘录:
...
threadthread
0.1.0
...
decoder thread...
为了重新得到自定义XML,你需要给 GstXML 对象添加一个信号来加载 XML 数据。只要GstXML被成功加载,你可以XML树来解析你的自定义XML文件。
我们可以使用下面的代码段来扩展我们先前提出的例子:
xml = gst_xml_new ();
g_signal_connect (G_OBJECT (xml), \G_CALLBACK (xml_loaded), xml);
ret = gst_xml_parse_file (xml, \est.gst\ g_assert (ret == TRUE);
不论什么时候一个新的对象被加载,xml_loaded函数都将被调用。函数如下所示:
static void
xml_loaded (GstXML *xml, GstObject *object, xmlNodePtr self, gpointer data) {
xmlNodePtr children = self->xmlChildrenNode;
while (children) {
if (!strcmp (children->name, \
xmlNodePtr nodes = children->xmlChildrenNode;
while (nodes) {
if (!strcmp (nodes->name, \
gchar *name = g_strdup (xmlNodeGetContent (nodes));g_print (\gst_object_get_name (object), name);}
nodes = nodes->next;}}
children = children->next; } }
如你所看到的那样,我们将得到一个处理 GstXML 对象的句柄(handle)。新加载的GstObject以及 xmlNodePtr都是用来创建该句柄。上面的例子中,我们在XML树中寻找特定的用来加载对象的标签,然后我们将提示信息打印到控制台上。
44
离衰退的日子不远了