QtGStreamer  0.10.2
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
applicationsource.cpp
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 Lesser 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