QtGStreamer 0.10.1
|
00001 /* 00002 Copyright (C) 2011 Collabora Ltd. <info@collabora.co.uk> 00003 @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk> 00004 00005 This library is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU Lesser General Public License as published 00007 by the Free Software Foundation; either version 2.1 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public License 00016 along with this program. If not, see <http://www.gnu.org/licenses/>. 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); //remove the callbacks from the source 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); //remove the callbacks from the previous source 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 } //namespace Utils 00288 } //namespace QGst