【GStreamer开发】GStreamer基础教程15——继承Clutter
目标
Clutter是一个开源的库,用来创建快速、可移植和动态的GUI。GStreamer可以通过cluttersink这个element把clutter集成进来,允许视频像纹理一样使用。本教程会展示:
如何把GStreamer pipeline的视频输出在clutter里面作为纹理来处理
介绍
连接GStreamer和clutter的流程实际上非常简单。我们必须使用cluttersink这个element(或者autocluttersink)并把它作为视频的sink。通过texture这个属性,这个element接受一个被GStreamer刷新的clutter的纹理。
一个3D的媒体播放器
- <span style="font-size:14px;">#include <clutter-gst/clutter-gst.h>
- /* Setup the video texture once its size is known */
- void size_change (ClutterActor *texture, gint width, gint height, gpointer user_data) {
- ClutterActor *stage;
- gfloat new_x, new_y, new_width, new_height;
- gfloat stage_width, stage_height;
- ClutterAnimation *animation = NULL;
- stage = clutter_actor_get_stage (texture);
- if (stage == NULL)
- return;
- clutter_actor_get_size (stage, &stage_width, &stage_height);
- /* Center video on window and calculate new size preserving aspect ratio */
- new_height = (height * stage_width) / width;
- if (new_height <= stage_height) {
- new_width = stage_width;
- ;
- ;
- } else {
- new_width = (width * stage_height) / height;
- new_height = stage_height;
- ;
- ;
- }
- clutter_actor_set_position (texture, new_x, new_y);
- clutter_actor_set_size (texture, new_width, new_height);
- .0, stage_width / 2, 0, 0);
- /* Animate it */
- 0000, "rotation-angle-y", 360.0, NULL);
- clutter_animation_set_loop (animation, TRUE);
- }
- int main(int argc, charchar *argv[]) {
- GstElement *pipeline, *sink;
- ClutterTimeline *timeline;
- ClutterActor *stage, *texture;
- /* clutter-gst takes care of initializing Clutter and GStreamer */
- if (clutter_gst_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) {
- g_error ("Failed to initialize clutter\n");
- ;
- }
- stage = clutter_stage_get_default ();
- /* Make a timeline */
- 000);
- g_object_set(timeline, "loop", TRUE, NULL);
- /* Create new texture and disable slicing so the video is properly mapped onto it */
- texture = CLUTTER_ACTOR (g_object_new (CLUTTER_TYPE_TEXTURE, "disable-slicing", TRUE, NULL));
- g_signal_connect (texture, "size-change", G_CALLBACK (size_change), NULL);
- /* Build the GStreamer pipeline */
- pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480p.webm", NULL);
- /* Instantiate the Clutter sink */
- sink = gst_element_factory_make ("autocluttersink", NULL);
- if (sink == NULL) {
- /* Revert to the older cluttersink, in case autocluttersink was not found */
- sink = gst_element_factory_make ("cluttersink", NULL);
- }
- if (sink == NULL) {
- g_printerr ("Unable to find a Clutter sink.\n");
- ;
- }
- /* Link GStreamer with Clutter by passing the Clutter texture to the Clutter sink*/
- g_object_set (sink, "texture", texture, NULL);
- /* Add the Clutter sink to the pipeline */
- g_object_set (pipeline, "video-sink", sink, NULL);
- /* Start playing */
- gst_element_set_state (pipeline, GST_STATE_PLAYING);
- /* start the timeline */
- clutter_timeline_start (timeline);
- /* Add texture to the stage, and show it */
- clutter_group_add (CLUTTER_GROUP (stage), texture);
- clutter_actor_show_all (stage);
- clutter_main();
- /* Free resources */
- gst_element_set_state (pipeline, GST_STATE_NULL);
- gst_object_unref (pipeline);
- ;
- }
- </span>
工作流程
这篇教程的目的不是教你如何使用clutter,而是如何把它集成到GStreamer里来。这个工作通过clutter-gst库来完成,所以它的头文件必须包含进来。
- <span style="font-size:14px;">#include <clutter-gst/clutter-gst.h></span>
这个库的第一件事是初始化GStreamer和Clutter,所以你调用clutter-gst-init()方法而不是自己来初始化。
- /* clutter-gst takes care of initializing Clutter and GStreamer */
- if (clutter_gst_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) {
- g_error ("Failed to initialize clutter\n");
- ;
- }
GStreamer视频是作为Clutter的纹理来播放,所以我们需要创建一个纹理。请记住关闭纹理的切片:
- /* Create new texture and disable slicing so the video is properly mapped onto it */
- texture = CLUTTER_ACTOR (g_object_new (CLUTTER_TYPE_TEXTURE, "disable-slicing", TRUE, NULL));
- g_signal_connect (texture, "size-change", G_CALLBACK (size_change), NULL);
我们注册size-change信号,这样我们一旦知道视频的尺寸之后就可以做最后的设置。
- /* Instantiate the Clutter sink */
- sink = gst_element_factory_make ("autocluttersink", NULL);
- if (sink == NULL) {
- /* Revert to the older cluttersink, in case autocluttersink was not found */
- sink = gst_element_factory_make ("cluttersink", NULL);
- }
- if (sink == NULL) {
- g_printerr ("Unable to find a Clutter sink.\n");
- ;
- }
正确创建的Clutter sink element是autocluttersink,这个element工作起来或多或少的像autovideosink。然而,autocluttersink在2012.7后发布的SDK里面才有,如果找不到这个element,那么创建cluttersink来代替。
- /* Link GStreamer with Clutter by passing the Clutter texture to the Clutter sink*/
- g_object_set (sink, "texture", texture, NULL);
这个纹理是GStreamer唯一需要了解的关于Clutter的内容。
- /* Add the Clutter sink to the pipeline */
- g_object_set (pipeline, "video-sink", sink, NULL);
最后,告诉playbin2使用我们创建的sink而不是默认的。
然后GStreamer的pipeline和Clutter的timeline就开始工作了。一旦pipeline获得了视频的尺寸,我们在收到一个通知后更新Clutter的纹理,调用size_change的回调。这个方法会把纹理设置正确地尺寸,把它输出到窗口的中心然后开始做动画旋转(仅供演示使用),当然,这个和GStreamer就没有任何关系了。
【GStreamer开发】GStreamer基础教程15——继承Clutter的更多相关文章
- Android程序开发0基础教程(一)
程序猿学英语就上视觉英语网 Android程序开发0基础教程(一) 平台简单介绍 令人激动的Google手机操作系统平台-Android在2007年11月13日正式公布了,这是一个开放源码的操 ...
- [SQL基础教程] 1-5 表的删除和更新
[SQL基础教程] 1-5 表的删除和更新 表的删除 语法 DROP TABLE <表名>; 法则 1-12 删除的表无法恢复 表定义的更新 语法 ALTER TABLE<表名> ...
- Java基础教程(18)--继承
一.继承的概念 继承是面向对象中一个非常重要的概念,使用继承可以从逻辑和层次上更好地组织代码,大大提高代码的复用性.在Java中,继承可以使得子类具有父类的属性和方法或者重新定义.追加属性和方法. ...
- JPA 菜鸟教程 15 继承-一个表-SINGLE_TABLE
原地址:http://blog.csdn.net/JE_GE/article/details/53678422 继承映射策略 一个类继承结构一个表的策略,最终只生成一个表,这是继承映射的默认策略. 举 ...
- python开发面向对象基础:组合&继承
一,组合 组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合 人类装备了武器类就是组合 1.圆环,将圆类实例后传给圆环类 #!/usr/bin/env python #_*_ ...
- iOS开发零基础教程之生成git所需的SSH keys
在我们github看到了一个不错的第三方库时,可能我们想把他git clone到本地,我们需要复制他的SSH URL,如下图: 复制完地址之后,我们需要打开终端,然后输入命令: git clone + ...
- Java基础教程(15)--枚举类型
枚举类型定义了一个枚举值的列表,每个值是一个标识符.例如,下面的语句声明了一个枚举类型,用来表示星期的可能情况: public enum Day { SUNDAY, MONDAY, TUESDAY ...
- Ruby 基础教程1-5
1.条件语句 if unless case unless和if相反,条件不成立则执行 2.条件 除了 false和nil 其他都是true 3.unless 语法 ...
- Chrome扩展开发基础教程(附HelloWorld)
1 概述 Chrome扩展开发的基础教程,代码基于原生JS+H5,教程内容基于谷歌扩展开发官方文档. 2 环境 Chrome 88.0.4324.96 Chromium 87.0.4280.141 B ...
随机推荐
- CSS3 新增选择器:伪类选择器和属性选择器
一.结构(位置)伪类选择器( : ) 1.:first-child 2.:last-child 3.:nth-child(n)或者:nth-child(2n)或者:nth-child(2n+1) &l ...
- PHP 高手博客网站集合
风雪之隅-Laruence的博客 韩天峰(Rango)的博客 我的志愿是做一个校长 张宴的博客 - Web系统架构与底层研发 沈逸的个人站点 博学无忧 - 信海龙的博客
- luogu 2592 区间dp
\(f_{i, j, a, b}\) 表示当前一共有 \(i\) 人排队, \(j\) 名男生,男生数目 - 女生数目为 \(a\), 女生数目 - 男生数目为 \(b\),\(a, b >= ...
- Luogu P3391 【模板】文艺平衡树 Splay 平衡树
https://www.luogu.org/problemnew/show/P3391 以前写过题解的入门题重写练板子.wdnmd真就 ' == ' 写成 ' = ' 了编译器不报错呗. #inclu ...
- Codevs 1070 普通递归关系(矩阵乘法)
1070 普通递归关系 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 考虑以下定义在非负整数n上的递归关系 f(n) = f0 ...
- P3388 【模板】割点(割顶)&& 桥
题目背景 割点 题目描述 给出一个n个点,m条边的无向图,求图的割点. 输入输出格式 输入格式: 第一行输入n,m 下面m行每行输入x,y表示x到y有一条边 输出格式: 第一行输出割点个数 第二行按照 ...
- ArcGIS分支版本化( Branch Versioning )技术介绍
概述 分支版本化技术是有别于传统的SDE版本化技术,它用于支持WebGIS模式下的多用户长事务编辑. 优势功能 使用分支版本化技术将获得以下功能 1. 支持长事务的编辑. 2. 支持Undo和Redo ...
- XMind 8 pro for Mac(思维导图软件)附序列号和破解教程【亲测可用!!】
年后了,又到一年面试时,最近在用思维导图整理知识点,原本使用的是在线思维导图 ProcessOn,奈何免费版的个人文件数量只能有9 张,远远不能满足我的需要,所以还是使用一个本地版的吧,but依然不想 ...
- Redis哨兵日志说明
一.说明
- EasyTrader踩坑之旅总结
easytrader是用python写的可以调用主要券商完成自动化炒股的一个软件 ,但我用的是同花顺,在研究过程中,发现同花顺暂时调不通.后来搜索发现thstrade的源码作者说是easytrad ...