zoukankan      html  css  js  c++  java
  • 【GStreamer开发】GStreamer基础教程15——继承Clutter

    目标

          Clutter是一个开源的库,用来创建快速、可移植和动态的GUI。GStreamer可以通过cluttersink这个element把clutter集成进来,允许视频像纹理一样使用。本教程会展示:

          如何把GStreamer pipeline的视频输出在clutter里面作为纹理来处理


    介绍

          连接GStreamer和clutter的流程实际上非常简单。我们必须使用cluttersink这个element(或者autocluttersink)并把它作为视频的sink。通过texture这个属性,这个element接受一个被GStreamer刷新的clutter的纹理。


    一个3D的媒体播放器

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">#include <clutter-gst/clutter-gst.h>  
    2.     
    3. /* Setup the video texture once its size is known */  
    4. void size_change (ClutterActor *texture, gint width, gint height, gpointer user_data) {  
    5.   ClutterActor *stage;  
    6.   gfloat new_x, new_y, new_width, new_height;  
    7.   gfloat stage_width, stage_height;  
    8.   ClutterAnimation *animation = NULL;  
    9.     
    10.   stage = clutter_actor_get_stage (texture);  
    11.   if (stage == NULL)  
    12.     return;  
    13.     
    14.   clutter_actor_get_size (stage, &stage_width, &stage_height);  
    15.     
    16.   /* Center video on window and calculate new size preserving aspect ratio */  
    17.   new_height = (height * stage_width) / width;  
    18.   if (new_height <= stage_height) {  
    19.     new_width = stage_width;  
    20.       
    21.     new_x = 0;  
    22.     new_y = (stage_height - new_height) / 2;  
    23.   } else {  
    24.     new_width  = (width * stage_height) / height;  
    25.     new_height = stage_height;  
    26.       
    27.     new_x = (stage_width - new_width) / 2;  
    28.     new_y = 0;  
    29.   }  
    30.   clutter_actor_set_position (texture, new_x, new_y);  
    31.   clutter_actor_set_size (texture, new_width, new_height);  
    32.   clutter_actor_set_rotation (texture, CLUTTER_Y_AXIS, 0.0, stage_width / 200);  
    33.   /* Animate it */  
    34.   animation = clutter_actor_animate (texture, CLUTTER_LINEAR, 10000"rotation-angle-y"360.0NULL);  
    35.   clutter_animation_set_loop (animation, TRUE);  
    36. }  
    37.     
    38. int main(int argc, charchar *argv[]) {  
    39.   GstElement *pipeline, *sink;  
    40.   ClutterTimeline *timeline;  
    41.   ClutterActor *stage, *texture;  
    42.     
    43.   /* clutter-gst takes care of initializing Clutter and GStreamer */  
    44.   if (clutter_gst_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) {  
    45.     g_error ("Failed to initialize clutter ");  
    46.     return -1;  
    47.   }  
    48.     
    49.   stage = clutter_stage_get_default ();  
    50.     
    51.   /* Make a timeline */  
    52.   timeline = clutter_timeline_new (1000);  
    53.   g_object_set(timeline, "loop", TRUE, NULL);  
    54.     
    55.   /* Create new texture and disable slicing so the video is properly mapped onto it */  
    56.   texture = CLUTTER_ACTOR (g_object_new (CLUTTER_TYPE_TEXTURE, "disable-slicing", TRUE, NULL));  
    57.   g_signal_connect (texture, "size-change", G_CALLBACK (size_change), NULL);  
    58.     
    59.   /* Build the GStreamer pipeline */  
    60.   pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480p.webm"NULL);  
    61.     
    62.   /* Instantiate the Clutter sink */  
    63.   sink = gst_element_factory_make ("autocluttersink"NULL);  
    64.   if (sink == NULL) {  
    65.     /* Revert to the older cluttersink, in case autocluttersink was not found */  
    66.     sink = gst_element_factory_make ("cluttersink"NULL);  
    67.   }  
    68.   if (sink == NULL) {  
    69.     g_printerr ("Unable to find a Clutter sink. ");  
    70.     return -1;  
    71.   }  
    72.     
    73.   /* Link GStreamer with Clutter by passing the Clutter texture to the Clutter sink*/  
    74.   g_object_set (sink, "texture", texture, NULL);  
    75.     
    76.   /* Add the Clutter sink to the pipeline */  
    77.   g_object_set (pipeline, "video-sink", sink, NULL);  
    78.     
    79.   /* Start playing */  
    80.   gst_element_set_state (pipeline, GST_STATE_PLAYING);  
    81.     
    82.   /* start the timeline */  
    83.   clutter_timeline_start (timeline);  
    84.     
    85.   /* Add texture to the stage, and show it */  
    86.   clutter_group_add (CLUTTER_GROUP (stage), texture);  
    87.   clutter_actor_show_all (stage);  
    88.     
    89.   clutter_main();  
    90.     
    91.   /* Free resources */  
    92.   gst_element_set_state (pipeline, GST_STATE_NULL);  
    93.   gst_object_unref (pipeline);  
    94.   return 0;  
    95. }  
    96. </span>  


    工作流程

          这篇教程的目的不是教你如何使用clutter,而是如何把它集成到GStreamer里来。这个工作通过clutter-gst库来完成,所以它的头文件必须包含进来。

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:14px;">#include <clutter-gst/clutter-gst.h></span>  

          这个库的第一件事是初始化GStreamer和Clutter,所以你调用clutter-gst-init()方法而不是自己来初始化。

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. /* clutter-gst takes care of initializing Clutter and GStreamer */  
    2. if (clutter_gst_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) {  
    3.   g_error ("Failed to initialize clutter ");  
    4.   return -1;  
    5. }  

          GStreamer视频是作为Clutter的纹理来播放,所以我们需要创建一个纹理。请记住关闭纹理的切片:

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. /* Create new texture and disable slicing so the video is properly mapped onto it */  
    2. texture = CLUTTER_ACTOR (g_object_new (CLUTTER_TYPE_TEXTURE, "disable-slicing", TRUE, NULL));  
    3. g_signal_connect (texture, "size-change", G_CALLBACK (size_change), NULL);  

          我们注册size-change信号,这样我们一旦知道视频的尺寸之后就可以做最后的设置。

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. /* Instantiate the Clutter sink */  
    2. sink = gst_element_factory_make ("autocluttersink"NULL);  
    3. if (sink == NULL) {  
    4.   /* Revert to the older cluttersink, in case autocluttersink was not found */  
    5.   sink = gst_element_factory_make ("cluttersink"NULL);  
    6. }  
    7. if (sink == NULL) {  
    8.   g_printerr ("Unable to find a Clutter sink. ");  
    9.   return -1;  
    10. }  

          正确创建的Clutter sink element是autocluttersink,这个element工作起来或多或少的像autovideosink。然而,autocluttersink在2012.7后发布的SDK里面才有,如果找不到这个element,那么创建cluttersink来代替。

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. /* Link GStreamer with Clutter by passing the Clutter texture to the Clutter sink*/  
    2. g_object_set (sink, "texture", texture, NULL);  

          这个纹理是GStreamer唯一需要了解的关于Clutter的内容。

    [objc] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. /* Add the Clutter sink to the pipeline */  
    2. g_object_set (pipeline, "video-sink", sink, NULL);  

          最后,告诉playbin2使用我们创建的sink而不是默认的。

          然后GStreamer的pipeline和Clutter的timeline就开始工作了。一旦pipeline获得了视频的尺寸,我们在收到一个通知后更新Clutter的纹理,调用size_change的回调。这个方法会把纹理设置正确地尺寸,把它输出到窗口的中心然后开始做动画旋转(仅供演示使用),当然,这个和GStreamer就没有任何关系了。

  • 相关阅读:
    leetcode 268. Missing Number
    DBSCAN
    python二维数组初始化
    leetcode 661. Image Smoother
    leetcode 599. Minimum Index Sum of Two Lists
    Python中的sort() key含义
    leetcode 447. Number of Boomerangs
    leetcode 697. Degree of an Array
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(1月3日)
    北京Uber优步司机奖励政策(1月2日)
  • 原文地址:https://www.cnblogs.com/huty/p/8517303.html
Copyright © 2011-2022 走看看