00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "applicationsource.h"
00019 #include "../elementfactory.h"
00020 #include <gst/app/gstappsrc.h>
00021
00022 namespace QGst {
00023 namespace Utils {
00024
00025 #ifndef DOXYGEN_RUN
00026
00027 struct QTGSTREAMERUTILS_NO_EXPORT ApplicationSource::Priv
00028 {
00029 public:
00030 ElementPtr m_appsrc;
00031
00032 void lazyConstruct(ApplicationSource *self);
00033 void setCallbacks(ApplicationSource *self);
00034
00035 inline GstAppSrc *appSrc()
00036 {
00037 return reinterpret_cast<GstAppSrc*>(static_cast<GstElement*>(m_appsrc));
00038 }
00039
00040 private:
00041 static void need_data(GstAppSrc *src, guint length, gpointer user_data);
00042 static void enough_data(GstAppSrc *src, gpointer user_data);
00043 static gboolean seek_data(GstAppSrc *src, guint64 offset, gpointer user_data);
00044
00045 static void need_data_noop(GstAppSrc*, guint, gpointer) {}
00046 static void enough_data_noop(GstAppSrc*, gpointer) {}
00047 static gboolean seek_data_noop(GstAppSrc*, guint64, gpointer) { return FALSE; }
00048 };
00049
00050 void ApplicationSource::Priv::lazyConstruct(ApplicationSource *self)
00051 {
00052 if (!m_appsrc) {
00053 m_appsrc = QGst::ElementFactory::make("appsrc");
00054 if (!m_appsrc) {
00055 qWarning() << "Failed to construct appsrc";
00056 }
00057 setCallbacks(self);
00058 }
00059 }
00060
00061 void ApplicationSource::Priv::setCallbacks(ApplicationSource *self)
00062 {
00063 if (m_appsrc) {
00064 if (self) {
00065 static GstAppSrcCallbacks callbacks = { &need_data, &enough_data, &seek_data };
00066 gst_app_src_set_callbacks(appSrc(), &callbacks, self, NULL);
00067 } else {
00068 static GstAppSrcCallbacks callbacks = { &need_data_noop, &enough_data_noop, &seek_data_noop };
00069 gst_app_src_set_callbacks(appSrc(), &callbacks, NULL, NULL);
00070 }
00071 }
00072 }
00073
00074 void ApplicationSource::Priv::need_data(GstAppSrc *src, guint length, gpointer user_data)
00075 {
00076 Q_UNUSED(src);
00077 static_cast<ApplicationSource*>(user_data)->needData(length);
00078 }
00079
00080 void ApplicationSource::Priv::enough_data(GstAppSrc *src, gpointer user_data)
00081 {
00082 Q_UNUSED(src);
00083 static_cast<ApplicationSource*>(user_data)->enoughData();
00084 }
00085
00086 gboolean ApplicationSource::Priv::seek_data(GstAppSrc *src, guint64 offset, gpointer user_data)
00087 {
00088 Q_UNUSED(src);
00089 return static_cast<ApplicationSource*>(user_data)->seekData(offset) ? TRUE : FALSE;
00090 }
00091
00092 #endif //DOXYGEN_RUN
00093
00094 ApplicationSource::ApplicationSource()
00095 : d(new Priv)
00096 {
00097 }
00098
00099 ApplicationSource::~ApplicationSource()
00100 {
00101 d->setCallbacks(NULL);
00102 delete d;
00103 }
00104
00105 ElementPtr ApplicationSource::element() const
00106 {
00107 d->lazyConstruct(const_cast<ApplicationSource*>(this));
00108 return d->m_appsrc;
00109 }
00110
00111 void ApplicationSource::setElement(const ElementPtr & appsrc)
00112 {
00113 Q_ASSERT(QGlib::Type::fromInstance(appsrc).isA(GST_TYPE_APP_SRC));
00114 d->setCallbacks(NULL);
00115 d->m_appsrc = appsrc;
00116 d->setCallbacks(this);
00117 }
00118
00119 CapsPtr ApplicationSource::caps() const
00120 {
00121 CapsPtr c;
00122 if (d->appSrc()) {
00123 c = CapsPtr::wrap(gst_app_src_get_caps(d->appSrc()), false);
00124 }
00125 return c;
00126 }
00127
00128 void ApplicationSource::setCaps(const CapsPtr & caps)
00129 {
00130 d->lazyConstruct(this);
00131 if (d->appSrc()) {
00132 gst_app_src_set_caps(d->appSrc(), caps);
00133 }
00134 }
00135
00136 quint64 ApplicationSource::minLatency() const
00137 {
00138 guint64 ret = -1;
00139 if (d->appSrc()) {
00140 gst_app_src_get_latency(d->appSrc(), &ret, NULL);
00141 }
00142 return ret;
00143 }
00144
00145 quint64 ApplicationSource::maxLatency() const
00146 {
00147 guint64 ret = -1;
00148 if (d->appSrc()) {
00149 gst_app_src_get_latency(d->appSrc(), NULL, &ret);
00150 }
00151 return ret;
00152 }
00153
00154 void ApplicationSource::setLatency(quint64 min, quint64 max)
00155 {
00156 d->lazyConstruct(this);
00157 if (d->appSrc()) {
00158 gst_app_src_set_latency(d->appSrc(), min, max);
00159 }
00160 }
00161
00162 qint64 ApplicationSource::size() const
00163 {
00164 return d->appSrc() ? gst_app_src_get_size(d->appSrc()) : -1;
00165 }
00166
00167 void ApplicationSource::setSize(qint64 size)
00168 {
00169 d->lazyConstruct(this);
00170 if (d->appSrc()) {
00171 gst_app_src_set_size(d->appSrc(), size);
00172 }
00173 }
00174
00175 AppStreamType ApplicationSource::streamType() const
00176 {
00177 return d->appSrc() ? static_cast<AppStreamType>(gst_app_src_get_stream_type(d->appSrc()))
00178 : AppStreamTypeStream;
00179 }
00180
00181 void ApplicationSource::setStreamType(AppStreamType type)
00182 {
00183 d->lazyConstruct(this);
00184 if (d->appSrc()) {
00185 gst_app_src_set_stream_type(d->appSrc(), static_cast<GstAppStreamType>(type));
00186 }
00187 }
00188
00189 quint64 ApplicationSource::maxBytes() const
00190 {
00191 return d->appSrc() ? gst_app_src_get_max_bytes(d->appSrc()) : 0;
00192 }
00193
00194 void ApplicationSource::setMaxBytes(quint64 max)
00195 {
00196 d->lazyConstruct(this);
00197 if (d->appSrc()) {
00198 gst_app_src_set_max_bytes(d->appSrc(), max);
00199 }
00200 }
00201
00202 bool ApplicationSource::blockEnabled() const
00203 {
00204 return d->m_appsrc ? d->m_appsrc->property("block").toBool() : false;
00205 }
00206
00207 void ApplicationSource::enableBlock(bool enable)
00208 {
00209 d->lazyConstruct(this);
00210 if (d->m_appsrc) {
00211 d->m_appsrc->setProperty("block", enable);
00212 }
00213 }
00214
00215 bool ApplicationSource::isLive() const
00216 {
00217 return d->m_appsrc ? d->m_appsrc->property("is-live").toBool() : false;
00218 }
00219
00220 void ApplicationSource::setLive(bool islive)
00221 {
00222 d->lazyConstruct(this);
00223 if (d->m_appsrc) {
00224 d->m_appsrc->setProperty("is-live", islive);
00225 }
00226 }
00227
00228 uint ApplicationSource::minPercent() const
00229 {
00230 return d->m_appsrc ? d->m_appsrc->property("min-percent").toUInt() : 0;
00231 }
00232
00233 void ApplicationSource::setMinPercent(uint min)
00234 {
00235 d->lazyConstruct(this);
00236 if (d->m_appsrc) {
00237 d->m_appsrc->setProperty("min-percent", min);
00238 }
00239 }
00240
00241 Format ApplicationSource::format() const
00242 {
00243 return d->m_appsrc ? d->m_appsrc->property("format").get<Format>() : FormatBytes;
00244 }
00245
00246 void ApplicationSource::setFormat(Format f)
00247 {
00248 d->lazyConstruct(this);
00249 if (d->m_appsrc) {
00250 d->m_appsrc->setProperty("format", f);
00251 }
00252 }
00253
00254 FlowReturn ApplicationSource::pushBuffer(const BufferPtr & buffer)
00255 {
00256 if (d->appSrc()) {
00257 return static_cast<FlowReturn>(gst_app_src_push_buffer(d->appSrc(), gst_buffer_ref(buffer)));
00258 } else {
00259 return FlowWrongState;
00260 }
00261 }
00262
00263 FlowReturn ApplicationSource::endOfStream()
00264 {
00265 if (d->appSrc()) {
00266 return static_cast<FlowReturn>(gst_app_src_end_of_stream(d->appSrc()));
00267 } else {
00268 return FlowWrongState;
00269 }
00270 }
00271
00272 void ApplicationSource::needData(uint length)
00273 {
00274 Q_UNUSED(length);
00275 }
00276
00277 void ApplicationSource::enoughData()
00278 {
00279 }
00280
00281 bool ApplicationSource::seekData(quint64 offset)
00282 {
00283 Q_UNUSED(offset);
00284 return false;
00285 }
00286
00287 }
00288 }