9#include <private/qplatformcamera_p.h>
11#include <private/qmediastoragelocation_p.h>
19#include <gst/gsttagsetter.h>
20#include <gst/gstversion.h>
21#include <gst/video/video.h>
22#include <gst/pbutils/encoding-profile.h>
30 audioPauseControl(*
this),
31 videoPauseControl(*
this)
33 signalDurationChangedTimer.setInterval(100);
34 signalDurationChangedTimer.callOnTimeout([
this](){ durationChanged(duration()); });
39 if (!gstPipeline.
isNull()) {
53 error(code, description);
71 if (msg.type() == GST_MESSAGE_ELEMENT) {
73 qCDebug(qLcMediaEncoderGst) <<
"received element message from" << msg.source().name() <<
s.name();
74 if (
s.name() ==
"GstBinForwarded")
80 if (msg.type() == GST_MESSAGE_EOS) {
81 qCDebug(qLcMediaEncoderGst) <<
"received EOS from" << msg.source().name();
86 if (msg.type() == GST_MESSAGE_ERROR) {
89 gst_message_parse_error(msg.rawMessage(), &err, &
debug);
103 return std::max(audioPauseControl.duration, videoPauseControl.duration);
113 GstEncodingContainerProfile *profile = (GstEncodingContainerProfile *)gst_encoding_container_profile_new(
115 (gchar *)
"custom container profile",
116 const_cast<GstCaps *
>(caps.get()),
129 GstEncodingVideoProfile *profile = gst_encoding_video_profile_new(
130 const_cast<GstCaps *
>(caps.get()),
135 gst_encoding_video_profile_set_pass(profile, 0);
136 gst_encoding_video_profile_set_variableframerate(profile, TRUE);
138 return (GstEncodingProfile *)profile;
149 GstEncodingProfile *profile = (GstEncodingProfile *)gst_encoding_audio_profile_new(
150 const_cast<GstCaps *
>(caps.get()),
162 if (!containerProfile) {
163 qWarning() <<
"QGstreamerMediaEncoder: failed to create container profile!";
168 GstEncodingProfile *videoProfile =
nullptr;
176 if (!gst_encoding_container_profile_add_profile(containerProfile, videoProfile)) {
177 qWarning() <<
"QGstreamerMediaEncoder: failed to add video profile!";
178 gst_encoding_profile_unref(videoProfile);
182 if (!gst_encoding_container_profile_add_profile(containerProfile, audioProfile)) {
183 qWarning() <<
"QGstreamerMediaEncoder: failed to add audio profile!";
184 gst_encoding_profile_unref(audioProfile);
188 return containerProfile;
191void QGstreamerMediaEncoder::PauseControl::reset()
194 pauseStartPts.reset();
196 firstBufferPts.reset();
199void QGstreamerMediaEncoder::PauseControl::installOn(
QGstPad pad)
201 pad.
addProbe<&QGstreamerMediaEncoder::PauseControl::processBuffer>(
this, GST_PAD_PROBE_TYPE_BUFFER);
204GstPadProbeReturn QGstreamerMediaEncoder::PauseControl::processBuffer(
QGstPad, GstPadProbeInfo *
info)
206 auto buffer = GST_PAD_PROBE_INFO_BUFFER(
info);
208 return GST_PAD_PROBE_OK;
213 return GST_PAD_PROBE_OK;
217 if (!GST_BUFFER_PTS_IS_VALID(
buffer))
218 return GST_PAD_PROBE_OK;
221 firstBufferPts = GST_BUFFER_PTS(
buffer);
225 pauseStartPts = GST_BUFFER_PTS(
buffer);
227 return GST_PAD_PROBE_DROP;
231 pauseOffsetPts += GST_BUFFER_PTS(
buffer) - *pauseStartPts;
232 pauseStartPts.reset();
234 GST_BUFFER_PTS(
buffer) -= pauseOffsetPts;
236 duration = (GST_BUFFER_PTS(
buffer) - *firstBufferPts) / GST_MSECOND;
238 return GST_PAD_PROBE_OK;
247 const auto hasAudio = m_session->
audioInput() !=
nullptr;
249 if (!hasVideo && !hasAudio) {
257 auto container =
settings.mimeType().preferredSuffix();
261 qCDebug(qLcMediaEncoderGst) <<
"recording new video to" << actualSink;
265 gstEncoder =
QGstElement(
"encodebin",
"encodebin");
268 g_object_set (gstEncoder.
object(),
"profile", encodingProfile,
nullptr);
269 gst_encoding_profile_unref(encodingProfile);
274 gstFileSink.
set(
"async",
false);
279 audioPauseControl.reset();
280 videoPauseControl.reset();
285 qWarning() <<
"Unsupported audio codec";
287 audioPauseControl.installOn(audioSink);
293 qWarning() <<
"Unsupported video codec";
295 videoPauseControl.installOn(videoSink);
298 gstPipeline.
add(gstEncoder, gstFileSink);
299 gstEncoder.
link(gstFileSink);
307 signalDurationChangedTimer.
start();
319 signalDurationChangedTimer.
stop();
329 signalDurationChangedTimer.
start();
337 qCDebug(qLcMediaEncoderGst) <<
"stop";
340 signalDurationChangedTimer.
stop();
342 qCDebug(qLcMediaEncoderGst) <<
">>>>>>>>>>>>> sending EOS";
346void QGstreamerMediaEncoder::finalize()
348 if (!m_session || gstEncoder.
isNull())
351 qCDebug(qLcMediaEncoderGst) <<
"finalize";
353 gstPipeline.
remove(gstEncoder);
354 gstPipeline.
remove(gstFileSink);
359 m_finalizing =
false;
378 if (m_session == captureSession)
393 m_session = captureSession;
397 gstPipeline = captureSession->gstPipeline;
398 gstPipeline.
set(
"message-forward",
true);
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
static QString currentPath()
Returns the absolute path of the application's current directory.
int exec(ProcessEventsFlags flags=AllEvents)
Enters the main event loop and waits until exit() is called.
static QByteArray encodeName(const QString &fileName)
Converts fileName to an 8-bit encoding that you can use in native APIs.
void remove(const QGstElement &element)
void add(const QGstElement &element)
QGstPad getRequestPad(const char *name) const
bool setStateSync(GstState state)
bool syncStateWithParent()
bool link(const QGstElement &next)
void set(const char *property, const char *str)
GstObject * object() const
void addProbe(T *instance, GstPadProbeType type)
void installMessageFilter(QGstreamerSyncMessageFilter *filter)
void dumpGraph(const char *fileName)
void removeMessageFilter(QGstreamerSyncMessageFilter *filter)
const GstStructure * structure
const QGstreamerFormatInfo * gstFormatsInfo() const
static QGstreamerIntegration * instance()
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
void stop()
Stops the timer.
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
QUrl resolved(const QUrl &relative) const
Returns the result of the merge of this URL with relative.
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
Combined button and popup list for selecting options.
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
GLuint GLsizei const GLchar * message
static QString toLocalFile(const QString &url)
QFileInfo info(fileName)
[8]
QSettings settings("MySoft", "Star Runner")
[0]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent