QtGStreamer  1.2.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
applicationsource.cpp
1 /*
2  Copyright (C) 2011 Collabora Ltd. <info@collabora.co.uk>
3  @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
4 
5  This library is free software; you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published
7  by the Free Software Foundation; either version 2.1 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "applicationsource.h"
19 #include "../elementfactory.h"
20 #include <gst/app/gstappsrc.h>
21 
22 namespace QGst {
23 namespace Utils {
24 
25 #ifndef DOXYGEN_RUN
26 
27 struct QTGSTREAMERUTILS_NO_EXPORT ApplicationSource::Priv
28 {
29 public:
30  ElementPtr m_appsrc;
31 
32  void lazyConstruct(ApplicationSource *self);
33  void setCallbacks(ApplicationSource *self);
34 
35  inline GstAppSrc *appSrc()
36  {
37  return reinterpret_cast<GstAppSrc*>(static_cast<GstElement*>(m_appsrc));
38  }
39 
40 private:
41  static void need_data(GstAppSrc *src, guint length, gpointer user_data);
42  static void enough_data(GstAppSrc *src, gpointer user_data);
43  static gboolean seek_data(GstAppSrc *src, guint64 offset, gpointer user_data);
44 
45  static void need_data_noop(GstAppSrc*, guint, gpointer) {}
46  static void enough_data_noop(GstAppSrc*, gpointer) {}
47  static gboolean seek_data_noop(GstAppSrc*, guint64, gpointer) { return FALSE; }
48 };
49 
50 void ApplicationSource::Priv::lazyConstruct(ApplicationSource *self)
51 {
52  if (!m_appsrc) {
53  m_appsrc = QGst::ElementFactory::make("appsrc");
54  if (!m_appsrc) {
55  qWarning() << "Failed to construct appsrc";
56  }
57  setCallbacks(self);
58  }
59 }
60 
61 void ApplicationSource::Priv::setCallbacks(ApplicationSource *self)
62 {
63  if (m_appsrc) {
64  if (self) {
65  static GstAppSrcCallbacks callbacks = { &need_data, &enough_data, &seek_data, NULL };
66  gst_app_src_set_callbacks(appSrc(), &callbacks, self, NULL);
67  } else {
68  static GstAppSrcCallbacks callbacks = { &need_data_noop, &enough_data_noop, &seek_data_noop, NULL };
69  gst_app_src_set_callbacks(appSrc(), &callbacks, NULL, NULL);
70  }
71  }
72 }
73 
74 void ApplicationSource::Priv::need_data(GstAppSrc *src, guint length, gpointer user_data)
75 {
76  Q_UNUSED(src);
77  static_cast<ApplicationSource*>(user_data)->needData(length);
78 }
79 
80 void ApplicationSource::Priv::enough_data(GstAppSrc *src, gpointer user_data)
81 {
82  Q_UNUSED(src);
83  static_cast<ApplicationSource*>(user_data)->enoughData();
84 }
85 
86 gboolean ApplicationSource::Priv::seek_data(GstAppSrc *src, guint64 offset, gpointer user_data)
87 {
88  Q_UNUSED(src);
89  return static_cast<ApplicationSource*>(user_data)->seekData(offset) ? TRUE : FALSE;
90 }
91 
92 #endif //DOXYGEN_RUN
93 
94 ApplicationSource::ApplicationSource()
95  : d(new Priv)
96 {
97 }
98 
99 ApplicationSource::~ApplicationSource()
100 {
101  d->setCallbacks(NULL); //remove the callbacks from the source
102  delete d;
103 }
104 
106 {
107  d->lazyConstruct(const_cast<ApplicationSource*>(this));
108  return d->m_appsrc;
109 }
110 
112 {
113  Q_ASSERT(QGlib::Type::fromInstance(appsrc).isA(GST_TYPE_APP_SRC));
114  d->setCallbacks(NULL); //remove the callbacks from the previous source
115  d->m_appsrc = appsrc;
116  d->setCallbacks(this);
117 }
118 
120 {
121  CapsPtr c;
122  if (d->appSrc()) {
123  c = CapsPtr::wrap(gst_app_src_get_caps(d->appSrc()), false);
124  }
125  return c;
126 }
127 
129 {
130  d->lazyConstruct(this);
131  if (d->appSrc()) {
132  gst_app_src_set_caps(d->appSrc(), caps);
133  }
134 }
135 
137 {
138  guint64 ret = -1;
139  if (d->appSrc()) {
140  gst_app_src_get_latency(d->appSrc(), &ret, NULL);
141  }
142  return ret;
143 }
144 
146 {
147  guint64 ret = -1;
148  if (d->appSrc()) {
149  gst_app_src_get_latency(d->appSrc(), NULL, &ret);
150  }
151  return ret;
152 }
153 
154 void ApplicationSource::setLatency(quint64 min, quint64 max)
155 {
156  d->lazyConstruct(this);
157  if (d->appSrc()) {
158  gst_app_src_set_latency(d->appSrc(), min, max);
159  }
160 }
161 
163 {
164  return d->appSrc() ? gst_app_src_get_size(d->appSrc()) : -1;
165 }
166 
167 void ApplicationSource::setSize(qint64 size)
168 {
169  d->lazyConstruct(this);
170  if (d->appSrc()) {
171  gst_app_src_set_size(d->appSrc(), size);
172  }
173 }
174 
175 AppStreamType ApplicationSource::streamType() const
176 {
177  return d->appSrc() ? static_cast<AppStreamType>(gst_app_src_get_stream_type(d->appSrc()))
178  : AppStreamTypeStream;
179 }
180 
181 void ApplicationSource::setStreamType(AppStreamType type)
182 {
183  d->lazyConstruct(this);
184  if (d->appSrc()) {
185  gst_app_src_set_stream_type(d->appSrc(), static_cast<GstAppStreamType>(type));
186  }
187 }
188 
190 {
191  return d->appSrc() ? gst_app_src_get_max_bytes(d->appSrc()) : 0;
192 }
193 
195 {
196  d->lazyConstruct(this);
197  if (d->appSrc()) {
198  gst_app_src_set_max_bytes(d->appSrc(), max);
199  }
200 }
201 
203 {
204  return d->m_appsrc ? d->m_appsrc->property("block").toBool() : false;
205 }
206 
208 {
209  d->lazyConstruct(this);
210  if (d->m_appsrc) {
211  d->m_appsrc->setProperty("block", enable);
212  }
213 }
214 
216 {
217  return d->m_appsrc ? d->m_appsrc->property("is-live").toBool() : false;
218 }
219 
220 void ApplicationSource::setLive(bool islive)
221 {
222  d->lazyConstruct(this);
223  if (d->m_appsrc) {
224  d->m_appsrc->setProperty("is-live", islive);
225  }
226 }
227 
229 {
230  return d->m_appsrc ? d->m_appsrc->property("min-percent").toUInt() : 0;
231 }
232 
234 {
235  d->lazyConstruct(this);
236  if (d->m_appsrc) {
237  d->m_appsrc->setProperty("min-percent", min);
238  }
239 }
240 
241 Format ApplicationSource::format() const
242 {
243  return d->m_appsrc ? d->m_appsrc->property("format").get<Format>() : FormatBytes;
244 }
245 
246 void ApplicationSource::setFormat(Format f)
247 {
248  d->lazyConstruct(this);
249  if (d->m_appsrc) {
250  d->m_appsrc->setProperty("format", f);
251  }
252 }
253 
254 FlowReturn ApplicationSource::pushBuffer(const BufferPtr & buffer)
255 {
256  if (d->appSrc()) {
257  return static_cast<FlowReturn>(gst_app_src_push_buffer(d->appSrc(), gst_buffer_ref(buffer)));
258  } else {
259  return FlowFlushing;
260  }
261 }
262 
264 {
265  if (d->appSrc()) {
266  return static_cast<FlowReturn>(gst_app_src_end_of_stream(d->appSrc()));
267  } else {
268  return FlowFlushing;
269  }
270 }
271 
273 {
274  Q_UNUSED(length);
275 }
276 
278 {
279 }
280 
281 bool ApplicationSource::seekData(quint64 offset)
282 {
283  Q_UNUSED(offset);
284  return false;
285 }
286 
287 } //namespace Utils
288 } //namespace QGst
static RefPointer< T > wrap(typename T::CType *nativePtr, bool increaseRef=true)
Definition: refpointer.h:326
void setElement(const ElementPtr &appsrc)
AppStreamType streamType() const
void setLatency(quint64 min, quint64 max)
void setStreamType(AppStreamType type)
virtual void needData(uint length)
void setCaps(const CapsPtr &caps)
FlowReturn pushBuffer(const BufferPtr &buffer)
virtual bool seekData(quint64 offset)