1 # Using appsink/appsrc in Qt
5 For those times when you need to stream data into or out of GStreamer
6 through your application, GStreamer includes two helpful elements:
8 - `appsink` - Allows applications to easily extract data from a
10 - `appsrc` - Allows applications to easily stream data into a
13 This tutorial will demonstrate how to use both of them by constructing a
14 pipeline to decode an audio file, stream it into an application's code,
15 then stream it back into your audio output device. All this, using
20 First, the files. These are also available in the
21 `examples/appsink-src` directory of the QGstreamer SDK.
26 project(qtgst-example-appsink-src)
27 find_package(QtGStreamer REQUIRED)
28 find_package(Qt4 REQUIRED)
29 include_directories(${QTGSTREAMER_INCLUDES} ${QT_QTCORE_INCLUDE_DIRS})
30 add_definitions(${QTGSTREAMER_DEFINITIONS})
31 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${QTGSTREAMER_FLAGS}")
32 add_executable(appsink-src main.cpp)
33 target_link_libraries(appsink-src ${QTGSTREAMER_UTILS_LIBRARIES} ${QT_QTCORE_LIBRARIES})
40 #include <QtCore/QCoreApplication>
41 #include <QGlib/Error>
42 #include <QGlib/Connect>
45 #include <QGst/Pipeline>
47 #include <QGst/Message>
48 #include <QGst/Utils/ApplicationSink>
49 #include <QGst/Utils/ApplicationSource>
51 class MySink : public QGst::Utils::ApplicationSink
54 MySink(QGst::Utils::ApplicationSource *src)
55 : QGst::Utils::ApplicationSink(), m_src(src) {}
61 virtual QGst::FlowReturn newBuffer()
63 m_src->pushBuffer(pullBuffer());
67 QGst::Utils::ApplicationSource *m_src;
70 class Player : public QCoreApplication
73 Player(int argc, char **argv);
76 void onBusMessage(const QGst::MessagePtr & message);
78 QGst::Utils::ApplicationSource m_src;
80 QGst::PipelinePtr pipeline1;
81 QGst::PipelinePtr pipeline2;
83 Player::Player(int argc, char **argv)
84 : QCoreApplication(argc, argv), m_sink(&m_src)
86 QGst::init(&argc, &argv);
88 std::cerr << "Usage: " << argv[0] << " <audio_file>" << std::endl;
91 const char *caps = "audio/x-raw-int,channels=1,rate=8000,"
92 "signed=(boolean)true,width=16,depth=16,endianness=1234";
94 QString pipe1Descr = QString("filesrc location=\"%1\" ! "
98 "appsink name=\"mysink\" caps=\"%2\"").arg(argv[1], caps);
99 pipeline1 = QGst::Parse::launch(pipe1Descr).dynamicCast<QGst::Pipeline>();
100 m_sink.setElement(pipeline1->getElementByName("mysink"));
101 QGlib::connect(pipeline1->bus(), "message::error", this, &Player::onBusMessage);
102 pipeline1->bus()->addSignalWatch();
104 QString pipe2Descr = QString("appsrc name=\"mysrc\" caps=\"%1\" ! autoaudiosink").arg(caps);
105 pipeline2 = QGst::Parse::launch(pipe2Descr).dynamicCast<QGst::Pipeline>();
106 m_src.setElement(pipeline2->getElementByName("mysrc"));
107 QGlib::connect(pipeline2->bus(), "message", this, &Player::onBusMessage);
108 pipeline2->bus()->addSignalWatch();
110 pipeline1->setState(QGst::StatePlaying);
111 pipeline2->setState(QGst::StatePlaying);
115 pipeline1->setState(QGst::StateNull);
116 pipeline2->setState(QGst::StateNull);
118 void Player::onBusMessage(const QGst::MessagePtr & message)
120 switch (message->type()) {
121 case QGst::MessageEos:
124 case QGst::MessageError:
125 qCritical() << message.staticCast<QGst::ErrorMessage>()->error();
132 int main(int argc, char **argv)
134 Player p(argc, argv);
141 As this is a very simple example, most of the action happens in the
142 `Player`'s constructor. First, GStreamer is initialized through
145 **GStreamer Initialization**
148 QGst::init(&argc, &argv);
151 Now we can construct the first half of the pipeline:
156 const char *caps = "audio/x-raw-int,channels=1,rate=8000,"
157 "signed=(boolean)true,width=16,depth=16,endianness=1234";
159 /* source pipeline */
160 QString pipe1Descr = QString("filesrc location=\"%1\" ! "
164 "appsink name=\"mysink\" caps=\"%2\"").arg(argv[1], caps);
165 pipeline1 = QGst::Parse::launch(pipe1Descr).dynamicCast<QGst::Pipeline>();
166 m_sink.setElement(pipeline1->getElementByName("mysink"));
167 QGlib::connect(pipeline1->bus(), "message::error", this, &Player::onBusMessage);
168 pipeline1->bus()->addSignalWatch();
171 `QGst::Parse::launch()` parses the text description of a pipeline and
172 returns a `QGst::PipelinePtr`. In this case, the pipeline is composed
175 - A `filesrc` element to read the file
176 - `decodebin2` to automatically examine the stream and pick the right
178 - `audioconvert` and `audioresample` to convert the output of the
179 `decodebin2` into the caps specified for the `appsink`
180 - An `appsink` element with specific caps
182 Next, we tell our `MySink` class (which is a subclass
183 of `QGst::Utils::ApplicationSink`) what `appsink` element to use.
185 The second half of the pipeline is created similarly:
191 QString pipe2Descr = QString("appsrc name=\"mysrc\" caps=\"%1\" ! autoaudiosink").arg(caps);
192 pipeline2 = QGst::Parse::launch(pipe2Descr).dynamicCast<QGst::Pipeline>();
193 m_src.setElement(pipeline2->getElementByName("mysrc"));
194 QGlib::connect(pipeline2->bus(), "message", this, &Player::onBusMessage);
195 pipeline2->bus()->addSignalWatch();
198 Finally, the pipeline is started:
200 **Starting the pipeline**
204 pipeline1->setState(QGst::StatePlaying);
205 pipeline2->setState(QGst::StatePlaying);
208 Once the pipelines are started, the first one begins pushing buffers
209 into the `appsink` element. Our `MySink` class implements the
210 `newBuffer()` method, which is called by QGStreamer when a new buffer is
211 ready for processing:
213 **MySink::newBuffer()**
216 virtual QGst::FlowReturn newBuffer()
218 m_src->pushBuffer(pullBuffer());
223 Our implementation takes the new buffer and pushes it into the
224 `appsrc` element, which got assigned in the `Player` constructor:
229 Player::Player(int argc, char **argv)
230 : QCoreApplication(argc, argv), m_sink(&m_src)
233 From there, buffers flow into the `autoaudiosink` element, which
234 automatically figures out a way to send it to your speakers.
238 You should now have an understanding of how to push and pull arbitrary
239 data into and out of a GStreamer pipeline.
241 It has been a pleasure having you here, and see you soon\!