17 QGstAppSrc appsrc = QGstAppSrc::create(
"appsrc");
24QGstAppSource::QGstAppSource(QGstAppSrc appsrc,
QObject *parent)
27 m_appSrc.set(
"emit-signals",
false);
32 m_appSrc.setStateSync(GST_STATE_NULL);
34 qCDebug(qLcAppSrc) <<
"~QGstAppSrc";
41 if (m_appSrc.isNull())
48 callbacks.need_data = QGstAppSource::on_need_data;
49 callbacks.enough_data = QGstAppSource::on_enough_data;
50 callbacks.seek_data = QGstAppSource::on_seek_data;
52 m_appSrc.setCallbacks(
callbacks,
this,
nullptr);
54 GstAppSrc *appSrc = m_appSrc.appSrc();
55 m_maxBytes = gst_app_src_get_max_bytes(appSrc);
59 m_streamType = GST_APP_STREAM_TYPE_STREAM;
61 m_streamType = GST_APP_STREAM_TYPE_RANDOM_ACCESS;
62 gst_app_src_set_stream_type(appSrc, m_streamType);
63 gst_app_src_set_size(appSrc, m_sequential ? -1 : m_stream->
size() - m_offset);
80 m_appSrc.set(
"caps", caps);
81 m_appSrc.set(
"format", GST_FORMAT_TIME);
87 m_appSrc = std::move(appsrc);
98 m_dataRequestSize = 0;
115bool QGstAppSource::isStreamValid()
const
117 return m_stream !=
nullptr && m_stream->
isOpen();
129 qCDebug(qLcAppSrc) <<
"write" <<
size << m_noMoreData << m_dataRequestSize;
134 m_noMoreData =
false;
141 return m_noMoreData || m_dataRequestSize != 0;
157void QGstAppSource::onDataReady()
163void QGstAppSource::streamDestroyed()
165 qCDebug(qLcAppSrc) <<
"stream destroyed";
167 m_dataRequestSize = 0;
172void QGstAppSource::pushData()
174 if (m_appSrc.isNull() || !m_dataRequestSize || m_suspended) {
175 qCDebug(qLcAppSrc) <<
"push data: return immediately" << m_appSrc.isNull() << m_dataRequestSize << m_suspended;
179 qCDebug(qLcAppSrc) <<
"pushData" << (m_stream ? m_stream :
nullptr) << m_buffer.
size();
180 if ((m_stream && m_stream->
atEnd())) {
182 qCDebug(qLcAppSrc) <<
"end pushData" << (m_stream ? m_stream :
nullptr) << m_buffer.
size();
192 if (!m_dataRequestSize)
193 m_dataRequestSize = m_maxBytes;
195 qCDebug(qLcAppSrc) <<
" reading" <<
size <<
"bytes" <<
size << m_dataRequestSize;
197 GstBuffer*
buffer = gst_buffer_new_and_alloc(
size);
199 if (m_sequential || !m_stream)
200 buffer->offset = bytesReadSoFar;
208 GST_BUFFER_TIMESTAMP(
buffer) = gst_util_uint64_scale(streamedSamples, GST_SECOND, m_format.
sampleRate());
209 GST_BUFFER_DURATION(
buffer) = gst_util_uint64_scale(nSamples, GST_SECOND, m_format.
sampleRate());
210 streamedSamples += nSamples;
214 gst_buffer_map(
buffer, &mapInfo, GST_MAP_WRITE);
215 void* bufferData = mapInfo.data;
219 bytesRead = m_stream->
read((
char*)bufferData,
size);
221 bytesRead = m_buffer.
read((
char*)bufferData,
size);
223 bytesReadSoFar += bytesRead;
225 gst_buffer_unmap(
buffer, &mapInfo);
226 qCDebug(qLcAppSrc) <<
"pushing bytes into gstreamer" <<
buffer->offset << bytesRead;
227 if (bytesRead == 0) {
230 qCDebug(qLcAppSrc) <<
"end pushData" << (m_stream ? m_stream :
nullptr) << m_buffer.
size();
233 m_noMoreData =
false;
236 GstFlowReturn
ret = m_appSrc.pushBuffer(
buffer);
237 if (
ret == GST_FLOW_ERROR) {
238 qWarning() <<
"QGstAppSrc: push buffer error";
239 }
else if (
ret == GST_FLOW_FLUSHING) {
240 qWarning() <<
"QGstAppSrc: push buffer wrong state";
242 qCDebug(qLcAppSrc) <<
"end pushData" << (m_stream ? m_stream :
nullptr) << m_buffer.
size();
253gboolean QGstAppSource::on_seek_data(GstAppSrc *, guint64 arg0, gpointer userdata)
256 if (arg0 == std::numeric_limits<quint64>::max())
264 if (
self->m_sequential)
271void QGstAppSource::on_enough_data(GstAppSrc *, gpointer userdata)
273 qCDebug(qLcAppSrc) <<
"on_enough_data";
277 self->m_dataRequestSize = 0;
280void QGstAppSource::on_need_data(GstAppSrc *, guint arg0, gpointer userdata)
282 qCDebug(qLcAppSrc) <<
"on_need_data requesting bytes" << arg0;
286 self->m_dataRequestSize = arg0;
288 qCDebug(qLcAppSrc) <<
"done on_need_data";
291void QGstAppSource::sendEOS()
293 qCDebug(qLcAppSrc) <<
"sending EOS";
294 if (m_appSrc.isNull())
297 gst_app_src_end_of_stream(GST_APP_SRC(m_appSrc.element()));
300void QGstAppSource::eosOrIdle()
302 qCDebug(qLcAppSrc) <<
"eosOrIdle";
303 if (m_appSrc.isNull())
312 qCDebug(qLcAppSrc) <<
" idle!";
319#include "moc_qgstappsource_p.cpp"
void bytesProcessed(int bytes)
bool setup(QIODevice *stream=nullptr, qint64 offset=0)
void setAudioFormat(const QAudioFormat &f)
QGstElement element() const
void write(const char *data, qsizetype size)
void setExternalAppSrc(QGstAppSrc)
bool canAcceptMoreData() const
\inmodule QtCore \reentrant
void readyRead()
This signal is emitted once every time new data is available for reading from the device's current re...
virtual qint64 size() const
For open random-access devices, this function returns the size of the device.
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from.
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
bool isOpen() const
Returns true if the device is open; otherwise returns false.
virtual qint64 bytesAvailable() const
Returns the number of bytes that are available for reading.
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success,...
virtual bool atEnd() const
Returns true if the current read and write position is at the end of the device (i....
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
Q_CORE_EXPORT void append(const char *data, qint64 size)
Q_CORE_EXPORT qint64 read(char *data, qint64 maxLength)
QGstCaps capsForAudioFormat(const QAudioFormat &format)
Combined button and popup list for selecting options.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
QString errorMessageCannotFindElement(std::string_view element)
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
constexpr const T & qMin(const T &a, const T &b)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
PromiseCallbacks callbacks
myObject disconnect()
[26]