文章《GStreamer中AppSrc的简单使用》介绍了AppSrc的初步使用,但对于各种复杂的媒体格式,需要自动解析媒体内容,自动生成Pipeline,这需要借助Decodebin来完成。Decodebin是Playbin的后端组件,它支持对输入进来的数据类型进行自动探测并设置解码器。对于任意一路解码后的媒体流(audio或video),它都会emit一个”pad-added”信号,可以基于这个信号增加相应的sink组件。
针对AppSrc,上篇文章的代码可演化为(仅Audio):
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <gst/gst.h>
22 #include <gst/app/gstappsrc.h>
23
24 static FILE * fp;
25 static GstPad * audioPad;
26
27 void _needData( GstAppSrc * src, guint arg1, gpointer user_data )
28 {
29 GstBuffer * _buf;
30 GstFlowReturn _ret;
31 int _size;
32
33 _buf = gst_buffer_new_and_alloc( arg1 );
34
35 GST_BUFFER_OFFSET( _buf ) = ftell( fp );
36
37 _size = fread( GST_BUFFER_DATA( _buf ), 1, arg1, fp );
38
39 GST_BUFFER_SIZE( _buf ) = _size;
40
41 if( feof( fp ))
42 {
43 g_message( "rewind to head" );
44 fseek( fp, 0, SEEK_SET );
45 }
46
47 g_signal_emit_by_name( src, "push-buffer", _buf, &_ret );
48
49 gst_buffer_unref( _buf );
50 }
51
52 void _enoughData( GstElement * src, gpointer user_data )
53 {
54 g_message( "%s", __func__ );
55 }
57 /* 58 * === FUNCTION ====================================================================== 59 * Name: _decNewPad 60 * Description: 61 * ===================================================================================== 62 */
63 static void _decNewPad( GstElement * decodebin, GstPad * pad, gpointer user_data )
64 {
65 g_message( "%s", __func__ );
66 gst_pad_link( pad, audioPad );
67 } /* ----- end of static function _decNewPad ----- */
68
69 /* 70 * === FUNCTION ====================================================================== 71 * Name: main 72 * Description: 73 * ===================================================================================== 74 */
75 int main ( int argc, char *argv[] )
76 {
77 GstElement * _pipeline, * _src, * _codec, * _sink;
78
79 fp = fopen( argv[1], "r" );
80
81 g_assert( fp != NULL );
82
83 gst_init( &argc, &argv );
84
85 g_assert( _src = gst_element_factory_make( "appsrc", "source" ));
86
87 g_assert( _codec = gst_element_factory_make( "decodebin", "codec" ));
88 g_signal_connect( _codec, "pad-added", G_CALLBACK( _decNewPad ), NULL );
89
90 g_assert( _sink = gst_element_factory_make( "alsasink", "sink" ));
91 g_assert( audioPad = gst_element_get_static_pad( _sink, "sink" ));
92
93 _pipeline = gst_pipeline_new( "pipeline" );
94
95 gst_bin_add_many( GST_BIN( _pipeline ), _src, _codec, _sink, NULL );
96
97 gst_element_link_many( _src, _codec, NULL );
98
99 g_signal_connect ( _src, "need-data", G_CALLBACK( _needData ), NULL );
100 g_signal_connect ( _src, "enough-data", G_CALLBACK( _enoughData ), NULL );
101
102 gst_element_set_state( _pipeline, GST_STATE_PLAYING );
103
104 pause();
105
106 return 0;
107 } /* ---------- end of function main ---------- */