00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "applicationsink.h"
00019 #include "../elementfactory.h"
00020 #include <gst/app/gstappsink.h>
00021
00022 namespace QGst {
00023 namespace Utils {
00024
00025 #ifndef DOXYGEN_RUN
00026
00027 struct QTGSTREAMERUTILS_NO_EXPORT ApplicationSink::Priv
00028 {
00029 public:
00030 ElementPtr m_appsink;
00031
00032 void lazyConstruct(ApplicationSink *self);
00033 void setCallbacks(ApplicationSink *self);
00034
00035 inline GstAppSink *appSink()
00036 {
00037 return reinterpret_cast<GstAppSink*>(static_cast<GstElement*>(m_appsink));
00038 }
00039
00040 private:
00041 static void eos(GstAppSink *sink, gpointer user_data);
00042 static GstFlowReturn new_preroll(GstAppSink *sink, gpointer user_data);
00043 static GstFlowReturn new_buffer(GstAppSink *sink, gpointer user_data);
00044 static GstFlowReturn new_buffer_list(GstAppSink *sink, gpointer user_data);
00045
00046 static void eos_noop(GstAppSink*, gpointer) {}
00047 static GstFlowReturn new_preroll_noop(GstAppSink*, gpointer) { return GST_FLOW_OK; }
00048 static GstFlowReturn new_buffer_noop(GstAppSink*, gpointer) { return GST_FLOW_OK; }
00049 static GstFlowReturn new_buffer_list_noop(GstAppSink*, gpointer) { return GST_FLOW_OK; }
00050 };
00051
00052 void ApplicationSink::Priv::lazyConstruct(ApplicationSink *self)
00053 {
00054 if (!m_appsink) {
00055 m_appsink = QGst::ElementFactory::make("appsink");
00056 if (!m_appsink) {
00057 qWarning() << "Failed to construct appsink";
00058 }
00059 setCallbacks(self);
00060 }
00061 }
00062
00063 void ApplicationSink::Priv::setCallbacks(ApplicationSink *self)
00064 {
00065 if (m_appsink) {
00066 if (self) {
00067 static GstAppSinkCallbacks callbacks = { &eos, &new_preroll,
00068 &new_buffer, &new_buffer_list };
00069 gst_app_sink_set_callbacks(appSink(), &callbacks, self, NULL);
00070 } else {
00071 static GstAppSinkCallbacks callbacks = { &eos_noop, &new_preroll_noop,
00072 &new_buffer_noop, &new_buffer_list_noop };
00073 gst_app_sink_set_callbacks(appSink(), &callbacks, NULL, NULL);
00074 }
00075 }
00076 }
00077
00078 void ApplicationSink::Priv::eos(GstAppSink* sink, gpointer user_data)
00079 {
00080 Q_UNUSED(sink);
00081 static_cast<ApplicationSink*>(user_data)->eos();
00082 }
00083
00084 GstFlowReturn ApplicationSink::Priv::new_preroll(GstAppSink* sink, gpointer user_data)
00085 {
00086 Q_UNUSED(sink);
00087 return static_cast<GstFlowReturn>(static_cast<ApplicationSink*>(user_data)->newPreroll());
00088 }
00089
00090 GstFlowReturn ApplicationSink::Priv::new_buffer(GstAppSink* sink, gpointer user_data)
00091 {
00092 Q_UNUSED(sink);
00093 return static_cast<GstFlowReturn>(static_cast<ApplicationSink*>(user_data)->newBuffer());
00094 }
00095
00096 GstFlowReturn ApplicationSink::Priv::new_buffer_list(GstAppSink* sink, gpointer user_data)
00097 {
00098 Q_UNUSED(sink);
00099 return static_cast<GstFlowReturn>(static_cast<ApplicationSink*>(user_data)->newBufferList());
00100 }
00101
00102 #endif //DOXYGEN_RUN
00103
00104
00105 ApplicationSink::ApplicationSink()
00106 : d(new Priv)
00107 {
00108 }
00109
00110 ApplicationSink::~ApplicationSink()
00111 {
00112 d->setCallbacks(NULL);
00113 delete d;
00114 }
00115
00116 ElementPtr ApplicationSink::element() const
00117 {
00118 d->lazyConstruct(const_cast<ApplicationSink*>(this));
00119 return d->m_appsink;
00120 }
00121
00122 void ApplicationSink::setElement(const ElementPtr & appsink)
00123 {
00124 Q_ASSERT(QGlib::Type::fromInstance(appsink).isA(GST_TYPE_APP_SINK));
00125 d->setCallbacks(NULL);
00126 d->m_appsink = appsink;
00127 d->setCallbacks(this);
00128 }
00129
00130 CapsPtr ApplicationSink::caps() const
00131 {
00132 CapsPtr caps;
00133 if (d->appSink()) {
00134 caps = CapsPtr::wrap(gst_app_sink_get_caps(d->appSink()), false);
00135 }
00136 return caps;
00137 }
00138
00139 void ApplicationSink::setCaps(const CapsPtr & caps)
00140 {
00141 d->lazyConstruct(this);
00142 if (d->appSink()) {
00143 gst_app_sink_set_caps(d->appSink(), caps);
00144 }
00145 }
00146
00147 bool ApplicationSink::isEos() const
00148 {
00149 return d->appSink() ? gst_app_sink_is_eos(d->appSink()) : true;
00150 }
00151
00152 uint ApplicationSink::maxBuffers() const
00153 {
00154 return d->appSink() ? gst_app_sink_get_max_buffers(d->appSink()) : 0;
00155 }
00156
00157 void ApplicationSink::setMaxBuffers(uint maxbuffers)
00158 {
00159 d->lazyConstruct(this);
00160 if (d->appSink()) {
00161 gst_app_sink_set_max_buffers(d->appSink(), maxbuffers);
00162 }
00163 }
00164
00165 bool ApplicationSink::dropEnabled() const
00166 {
00167 return d->appSink() ? gst_app_sink_get_drop(d->appSink()) : false;
00168 }
00169
00170 void ApplicationSink::enableDrop(bool enable)
00171 {
00172 d->lazyConstruct(this);
00173 if (d->appSink()) {
00174 gst_app_sink_set_drop(d->appSink(), enable);
00175 }
00176 }
00177
00178 BufferPtr ApplicationSink::pullPreroll()
00179 {
00180 BufferPtr buf;
00181 if (d->appSink()) {
00182 buf = BufferPtr::wrap(gst_app_sink_pull_preroll(d->appSink()), false);
00183 }
00184 return buf;
00185 }
00186
00187 BufferPtr ApplicationSink::pullBuffer()
00188 {
00189 BufferPtr buf;
00190 if (d->appSink()) {
00191 buf = BufferPtr::wrap(gst_app_sink_pull_buffer(d->appSink()), false);
00192 }
00193 return buf;
00194 }
00195
00196 BufferListPtr ApplicationSink::pullBufferList()
00197 {
00198 BufferListPtr buf;
00199 if (d->appSink()) {
00200 buf = BufferListPtr::wrap(gst_app_sink_pull_buffer_list(d->appSink()), false);
00201 }
00202 return buf;
00203 }
00204
00205 void ApplicationSink::eos()
00206 {
00207 }
00208
00209 FlowReturn ApplicationSink::newPreroll()
00210 {
00211 return FlowOk;
00212 }
00213
00214 FlowReturn ApplicationSink::newBuffer()
00215 {
00216 return FlowOk;
00217 }
00218
00219 FlowReturn ApplicationSink::newBufferList()
00220 {
00221 return FlowOk;
00222 }
00223
00224
00225 }
00226 }