加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

【GStreamer开发】GStreamer播放教程03——pipeline的快捷访问

发布时间:2020-12-14 01:51:14 所属栏目:百科 来源:网络整理
导读:目的 《GStreamer08——pipeline的快捷访问》展示了一个应用如何用appsrc和appsink这两个特殊的element在pipeline中手动输入/提取数据。playbin2也允许使用这两个element,但连接它们的方法有所不同。连接appsink到playbin2的方法在后面还会提到。这里我们主

目的

《GStreamer08——pipeline的快捷访问》展示了一个应用如何用appsrc和appsink这两个特殊的element在pipeline中手动输入/提取数据。playbin2也允许使用这两个element,但连接它们的方法有所不同。连接appsink到playbin2的方法在后面还会提到。这里我们主要讲述:

如何把appsrc连接到playbin2

如何配置appsrc


一个playbin2波形发生器

[objc]view plaincopy
  1. <spanstyle="font-size:14px;">#include<gst/gst.h>
  2. #include<string.h>
  3. #defineCHUNK_SIZE1024/*Amountofbyteswearesendingineachbuffer*/
  4. #defineSAMPLE_RATE44100/*Samplespersecondwearesending*/
  5. #defineAUDIO_CAPS"audio/x-raw-int,channels=1,rate=%d,signed=(boolean)true,width=16,depth=16,endianness=BYTE_ORDER"
  6. /*Structuretocontainallourinformation,sowecanpassittocallbacks*/
  7. typedefstruct_CustomData{
  8. GstElement*pipeline;
  9. GstElement*app_source;
  10. guint64num_samples;/*Numberofsamplesgeneratedsofar(fortimestampgeneration)*/
  11. gfloata,b,c,d;/*Forwaveformgeneration*/
  12. guintsourceid;/*TocontroltheGSource*/
  13. GMainLoop*main_loop;/*GLib'sMainLoop*/
  14. }CustomData;
  15. /*ThismethodiscalledbytheidleGSourceinthemainloop,tofeedCHUNK_SIZEbytesintoappsrc.
  16. *Theidehandlerisaddedtothemainloopwhenappsrcrequestsustostartsendingdata(need-datasignal)
  17. *andisremovedwhenappsrchasenoughdata(enough-datasignal).
  18. */
  19. staticgbooleanpush_data(CustomData*data){
  20. GstBuffer*buffer;
  21. GstFlowReturnret;
  22. inti;
  23. gint16*raw;
  24. gintnum_samples=CHUNK_SIZE/2;/*Becauseeachsampleis16bits*/
  25. gfloatfreq;
  26. /*Createanewemptybuffer*/
  27. buffer=gst_buffer_new_and_alloc(CHUNK_SIZE);
  28. /*Setitstimestampandduration*/
  29. GST_BUFFER_TIMESTAMP(buffer)=gst_util_uint64_scale(data->num_samples,GST_SECOND,SAMPLE_RATE);
  30. GST_BUFFER_DURATION(buffer)=gst_util_uint64_scale(CHUNK_SIZE,SAMPLE_RATE);
  31. /*Generatesomepsychodelicwaveforms*/
  32. raw=(gint16*)GST_BUFFER_DATA(buffer);
  33. data->c+=data->d;
  34. data->d-=data->c/1000;
  35. freq=1100+11000*data->d;
  36. for(i=0;i<num_samples;i++){
  37. data->a+=data->b;
  38. data->b-=data->a/freq;
  39. raw[i]=(gint16)(5500*data->a);
  40. }
  41. data->num_samples+=num_samples;
  42. /*Pushthebufferintotheappsrc*/
  43. g_signal_emit_by_name(data->app_source,"push-buffer",buffer,&ret);
  44. /*Freethebuffernowthatwearedonewithit*/
  45. gst_buffer_unref(buffer);
  46. if(ret!=GST_FLOW_OK){
  47. /*Wegotsomeerror,stopsendingdata*/
  48. returnFALSE;
  49. returnTRUE;
  50. }
  51. /*Thissignalcallbacktriggerswhenappsrcneedsdata.Here,weaddanidlehandler
  52. *tothemainlooptostartpushingdataintotheappsrc*/
  53. staticvoidstart_feed(GstElement*source,guintsize,CustomData*data){
  54. if(data->sourceid==0){
  55. g_print("Startfeedingn");
  56. data->sourceid=g_idle_add((GSourceFunc)push_data,data);
  57. /*Thiscallbacktriggerswhenappsrchasenoughdataandwecanstopsending.
  58. *Weremovetheidlehandlerfromthemainloop*/
  59. staticvoidstop_feed(GstElement*source,CustomData*data){
  60. if(data->sourceid!=0){
  61. g_print("Stopfeedingn");
  62. g_source_remove(data->sourceid);
  63. data->sourceid=0;
  64. /*Thisfunctioniscalledwhenanerrormessageispostedonthebus*/
  65. staticvoiderror_cb(GstBus*bus,GstMessage*msg,0)">GError*err;
  66. gchar*debug_info;
  67. /*Printerrordetailsonthescreen*/
  68. gst_message_parse_error(msg,&err,&debug_info);
  69. g_printerr("Errorreceivedfromelement%s:%sn",GST_OBJECT_NAME(msg->src),err->message);
  70. g_printerr("Debugginginformation:%sn",debug_info?debug_info:"none");
  71. g_clear_error(&err);
  72. g_free(debug_info);
  73. g_main_loop_quit(data->main_loop);
  74. /*Thisfunctioniscalledwhenplaybin2hascreatedtheappsrcelement,sowehave
  75. *achancetoconfigureit.*/
  76. staticvoidsource_setup(GstElement*pipeline,GstElement*source,0)">gchar*audio_caps_text;
  77. GstCaps*audio_caps;
  78. g_print("Sourcehasbeencreated.Configuring.n");
  79. data->app_source=source;
  80. /*Configureappsrc*/
  81. audio_caps_text=g_strdup_printf(AUDIO_CAPS,SAMPLE_RATE);
  82. audio_caps=gst_caps_from_string(audio_caps_text);
  83. g_object_set(source,"caps",audio_caps,NULL);
  84. g_signal_connect(source,"need-data",G_CALLBACK(start_feed),data);
  85. "enough-data",G_CALLBACK(stop_feed),data);
  86. gst_caps_unref(audio_caps);
  87. g_free(audio_caps_text);
  88. intmain(intargc,charchar*argv[]){
  89. CustomDatadata;
  90. GstBus*bus;
  91. /*Initializecumstomdatastructure*/
  92. memset(&data,0,sizeof(data));
  93. data.b=1;/*Forwaveformgeneration*/
  94. data.d=1;
  95. /*InitializeGStreamer*/
  96. gst_init(&argc,&argv);
  97. /*Createtheplaybin2element*/
  98. data.pipeline=gst_parse_launch("playbin2uri=appsrc://",0)">g_signal_connect(data.pipeline,"source-setup",G_CALLBACK(source_setup),&data);
  99. /*Instructthebustoemitsignalsforeachreceivedmessage,andconnecttotheinterestingsignals*/
  100. bus=gst_element_get_bus(data.pipeline);
  101. gst_bus_add_signal_watch(bus);
  102. g_signal_connect(G_OBJECT(bus),"message::error",(GCallback)error_cb,&data);
  103. gst_object_unref(bus);
  104. /*Startplayingthepipeline*/
  105. gst_element_set_state(data.pipeline,GST_STATE_PLAYING);
  106. /*CreateaGLibMainLoopandsetittorun*/
  107. data.main_loop=g_main_loop_new(NULL,FALSE);
  108. g_main_loop_run(data.main_loop);
  109. /*Freeresources*/
  110. gst_object_unref(data.pipeline);
  111. return0;
  112. </span>

把appsrc用作pipeline的source,仅仅把playbin2的UIR设置成appsrc://即可。

[objc]view plaincopy
<spanstyle="font-size:14px;">/*Createtheplaybin2element*/
  • NULL);</span>
  • playbin2创建一个内部的appsrc element并且发送source-setup信号来通知应用进行设置。

    [objc]view plaincopy
    <spanstyle="font-size:14px;">g_signal_connect(data.pipeline,&data);</span>

    特别地,设置appsrc的caps属性是很重要的,因为一旦这个信号的处理返回,playbin2就会根据返回值来初始化下一个element。

    [objc]view plaincopy
    <spanstyle="font-size:14px;">/*Thisfunctioniscalledwhenplaybin2hascreatedtheappsrcelement,sowehave
  • *achancetoconfigureit.*/
  • gchar*audio_caps_text;
  • GstCaps*audio_caps;
  • g_print("Sourcehasbeencreated.Configuring.n");
  • data->app_source=source;
  • /*Configureappsrc*/
  • audio_caps=gst_caps_from_string(audio_caps_text);
  • NULL);
  • gst_caps_unref(audio_caps);
  • g_free(audio_caps_text);
  • }</span>
  • appsrc的配置和《GStreamer08——pipeline的快捷访问》里面一样:caps设置成audio/x-raw-int,注册两个回调,这样element可以在需要/停止给它推送数据时通知应用。具体细节请参考《GStreamer08——pipeline的快捷访问》。

    在这个点之后,playbin2接管处理了剩下的pipeline,应用仅仅需要生成数据即可。

    至于使用appsink来从从playbin2里面提取数据,在后面的教程里面再讲述。

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读