9#include <QtCore/qdebug.h>
10#include <QtMultimedia/qcameradevice.h>
42#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
82 if (!G_VALUE_HOLDS_BOOLEAN(
value))
84 return g_value_get_boolean(
value);
89 if (!G_VALUE_HOLDS_INT(
value))
91 return g_value_get_int(
value);
96 if (!G_VALUE_HOLDS_INT64(
value))
98 return g_value_get_int64(
value);
103 return value ? g_value_get_string(
value) :
nullptr;
108 if (!GST_VALUE_HOLDS_FRACTION(
value))
110 return (
float)gst_value_get_fraction_numerator(
value)
111 / (float)gst_value_get_fraction_denominator(
value);
116 if (!GST_VALUE_HOLDS_FRACTION_RANGE(
value))
120 return QGRange<float>{ *min.getFraction(), *max.
getFraction() };
125 if (!GST_VALUE_HOLDS_INT_RANGE(
value))
127 return QGRange<int>{ gst_value_get_int_range_min(
value), gst_value_get_int_range_max(
value) };
132 if (!
value || !GST_VALUE_HOLDS_STRUCTURE(
value))
151 return gst_value_list_get_size(
value);
166 gst_structure_free(
const_cast<GstStructure *
>(
structure));
177 return gst_structure_get_name(
structure);
196 && gst_structure_get_int(
structure,
"height", &
h)) {
211 if (gst_structure_has_name(
structure,
"video/x-raw")) {
212 const gchar *
s = gst_structure_get_string(
structure,
"format");
214 GstVideoFormat
format = gst_video_format_from_string(
s);
220 }
else if (gst_structure_has_name(
structure,
"image/jpeg")) {
235 auto extractFraction = [](
const GValue *
v) ->
float {
236 return (
float)gst_value_get_fraction_numerator(
v)
237 / (float)gst_value_get_fraction_denominator(
v);
239 auto extractFrameRate = [&](
const GValue *
v) {
240 auto insert = [&](
float min,
float max) {
247 if (GST_VALUE_HOLDS_FRACTION(
v)) {
248 float rate = extractFraction(
v);
250 }
else if (GST_VALUE_HOLDS_FRACTION_RANGE(
v)) {
251 auto *min = gst_value_get_fraction_range_max(
v);
252 auto *max = gst_value_get_fraction_range_max(
v);
253 insert(extractFraction(min), extractFraction(max));
257 const GValue *gstFrameRates = gst_structure_get_value(
structure,
"framerate");
259 if (GST_VALUE_HOLDS_LIST(gstFrameRates)) {
260 guint nFrameRates = gst_value_list_get_size(gstFrameRates);
261 for (guint
f = 0;
f < nFrameRates; ++
f) {
262 extractFrameRate(gst_value_list_get_value(gstFrameRates,
f));
265 extractFrameRate(gstFrameRates);
268 const GValue *min = gst_structure_get_value(
structure,
"min-framerate");
269 const GValue *max = gst_structure_get_value(
structure,
"max-framerate");
271 minRate = extractFraction(min);
272 maxRate = extractFraction(max);
276 return { minRate, maxRate };
282 gst_structure_get(
structure,
"message", GST_TYPE_MESSAGE, &
message,
nullptr);
290 if (gst_structure_get_fraction(
structure,
"pixel-aspect-ratio", &numerator, &denominator)) {
304 if (par.numerator == par.denominator || par.numerator < 1 || par.denominator < 1)
308 resolution.
width() * par.numerator / par.denominator,
316 if (!
size.isValid()) {
331 GstVideoInfo vidInfo;
333 bool success = gst_video_info_from_caps(&vidInfo,
get());
337 int index = indexOfVideoFormat(vidInfo.finfo->format);
342 qt_videoFormatLookup[
index].pixelFormat);
344 if (vidInfo.fps_d > 0)
345 format.setStreamFrameRate(
qreal(vidInfo.fps_n) / vidInfo.fps_d);
348 switch (vidInfo.colorimetry.range) {
349 case GST_VIDEO_COLOR_RANGE_UNKNOWN:
351 case GST_VIDEO_COLOR_RANGE_0_255:
354 case GST_VIDEO_COLOR_RANGE_16_235:
361 switch (vidInfo.colorimetry.matrix) {
362 case GST_VIDEO_COLOR_MATRIX_UNKNOWN:
363 case GST_VIDEO_COLOR_MATRIX_RGB:
364 case GST_VIDEO_COLOR_MATRIX_FCC:
366 case GST_VIDEO_COLOR_MATRIX_BT709:
369 case GST_VIDEO_COLOR_MATRIX_BT601:
372 case GST_VIDEO_COLOR_MATRIX_SMPTE240M:
375 case GST_VIDEO_COLOR_MATRIX_BT2020:
379 format.setColorSpace(colorSpace);
382 switch (vidInfo.colorimetry.transfer) {
383 case GST_VIDEO_TRANSFER_UNKNOWN:
385 case GST_VIDEO_TRANSFER_GAMMA10:
388 case GST_VIDEO_TRANSFER_GAMMA22:
389 case GST_VIDEO_TRANSFER_SMPTE240M:
390 case GST_VIDEO_TRANSFER_SRGB:
391 case GST_VIDEO_TRANSFER_ADOBERGB:
394 case GST_VIDEO_TRANSFER_GAMMA18:
395 case GST_VIDEO_TRANSFER_GAMMA20:
397 case GST_VIDEO_TRANSFER_BT709:
398 case GST_VIDEO_TRANSFER_BT2020_12:
401 case GST_VIDEO_TRANSFER_GAMMA28:
404 case GST_VIDEO_TRANSFER_LOG100:
405 case GST_VIDEO_TRANSFER_LOG316:
407#if GST_CHECK_VERSION(1, 18, 0)
408 case GST_VIDEO_TRANSFER_SMPTE2084:
411 case GST_VIDEO_TRANSFER_ARIB_STD_B67:
414 case GST_VIDEO_TRANSFER_BT2020_10:
417 case GST_VIDEO_TRANSFER_BT601:
422 format.setColorTransfer(transfer);
431 const char *modifier)
433 if (!gst_caps_is_writable(
get()))
434 *
this =
QGstCaps(gst_caps_make_writable(
release()), QGstCaps::RefMode::HasRef);
437 g_value_init(&
list, GST_TYPE_LIST);
445 g_value_init(&
item, G_TYPE_STRING);
446 g_value_set_string(&
item,
447 gst_video_format_to_string(qt_videoFormatLookup[
index].gstFormat));
448 gst_value_list_append_value(&
list, &
item);
449 g_value_unset(&
item);
452 auto *structure = gst_structure_new(
"video/x-raw",
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
453 INT_MAX, 1,
"width", GST_TYPE_INT_RANGE, 1, INT_MAX,
454 "height", GST_TYPE_INT_RANGE, 1, INT_MAX,
nullptr);
455 gst_structure_set_value(structure,
"format", &
list);
456 gst_caps_append_structure(
get(), structure);
457 g_value_unset(&
list);
460 gst_caps_set_features(
get(),
size() - 1, gst_caps_features_from_string(modifier));
467 g_value_init(&
width, G_TYPE_INT);
470 g_value_init(&
height, G_TYPE_INT);
473 gst_caps_set_value(
caps(),
"width", &
width);
474 gst_caps_set_value(
caps(),
"height", &
height);
480 GstStructure *structure =
nullptr;
482 structure = gst_structure_new(
"image/jpeg",
"width", G_TYPE_INT,
size.width(),
"height",
483 G_TYPE_INT,
size.height(),
nullptr);
485 int index = indexOfVideoFormat(
format.pixelFormat());
488 auto gstFormat = qt_videoFormatLookup[
index].gstFormat;
489 structure = gst_structure_new(
"video/x-raw",
"format", G_TYPE_STRING,
490 gst_video_format_to_string(gstFormat),
"width", G_TYPE_INT,
491 size.width(),
"height", G_TYPE_INT,
size.height(),
nullptr);
494 gst_caps_append_structure(
caps.get(), structure);
501 gst_caps_copy(
caps()),
508 auto *features = gst_caps_get_features(
get(), 0);
509 if (gst_caps_features_contains(features,
"memory:GLMemory"))
511 if (gst_caps_features_contains(features,
"memory:DMABuf"))
518 return int(gst_caps_get_size(
get()));
523 return gst_caps_get_structure(
get(),
index);
592 GstStructure *
s =
nullptr;
648 GstObject *
o =
nullptr;
658 g_signal_connect(
get(),
name, callback, userData),
664 g_signal_handler_disconnect(
get(), handlerId);
669 return G_OBJECT_TYPE(
get());
674 return g_type_name(
type());
684 return get() ? GST_OBJECT_NAME(
get()) :
"(null)";
699 object.disconnect(handlerId);
701 handlerId = invalidHandlerId;
754 return gst_pad_is_linked(
pad());
759 return gst_pad_link(
pad(),
sink.pad()) == GST_PAD_LINK_OK;
764 return gst_pad_unlink(
pad(),
sink.pad());
784 return qGstCheckedCast<GstPad>(
object());
789 return gst_pad_get_sticky_event(
pad(),
type, 0);
794 return gst_pad_send_event(
pad(),
event);
817 return qGstCheckedCast<GstClock>(
object());
822 return gst_clock_get_time(
clock());
915#if GST_CHECK_VERSION(1, 19, 1)
924 return gst_element_release_request_pad(
element(), pad.
pad());
929 using namespace std::chrono_literals;
932 GstStateChangeReturn change =
935 if (
Q_UNLIKELY(change == GST_STATE_CHANGE_ASYNC))
936 qWarning() <<
"QGstElement::state detected an asynchronous state change. Return value not "
949 if (
state == GST_STATE_NULL) {
954 if (qIsGstObjectOfType<GstBin>(
element()))
958 GstStateChangeReturn change = gst_element_set_state(
element(),
state);
959 if (change == GST_STATE_CHANGE_ASYNC)
962 if (change != GST_STATE_CHANGE_SUCCESS && change != GST_STATE_CHANGE_NO_PREROLL) {
966 return change == GST_STATE_CHANGE_SUCCESS;
972 return gst_element_sync_state_with_parent(
element()) == TRUE;
978 GstStateChangeReturn change =
981 if (change != GST_STATE_CHANGE_SUCCESS && change != GST_STATE_CHANGE_NO_PREROLL) {
985 return change == GST_STATE_CHANGE_SUCCESS;
990 gst_element_set_locked_state(
element(), locked);
995 return gst_element_is_locked_state(
element());
1010 return gst_element_get_base_time(
element());
1020 return GST_ELEMENT_CAST(
get());
1026 qGstCheckedCast<GstElement>(gst_element_get_parent(
object())),
1036 if (greatAncestor) {
1037 ancestor = std::move(greatAncestor);
1042 qGstSafeCast<GstPipeline>(ancestor.element()),
1076 const char *
name,
bool ghostUnlinkedPads)
1082 bool ghostUnlinkedPads)
1087 gst_parse_bin_from_description_full(pipelineDescription, ghostUnlinkedPads,
1088 nullptr, GST_PARSE_FLAG_NONE, &
error);
1091 qWarning() <<
"Failed to make element from pipeline description" << pipelineDescription
1115 return qGstCheckedCast<GstBin>(
object());
1125 gst_element_add_pad(
element(), gst_ghost_pad_new(
name, pad.
pad()));
1130 return gst_bin_sync_children_states(
bin());
1138 GST_DEBUG_BIN_TO_DOT_FILE(
bin(), GST_DEBUG_GRAPH_SHOW_VERBOSE, fileNamePrefix);
1144 gst_bin_get_by_name(
bin(),
name),
1161 gst_base_sink_set_sync(
baseSink(),
arg ? TRUE : FALSE);
1166 return qGstCheckedCast<GstBaseSink>(
element());
1181 return qGstCheckedCast<GstBaseSrc>(
element());
1184#if QT_CONFIG(gstreamer_app)
1188QGstAppSink::QGstAppSink(GstAppSink *element, RefMode
mode)
1196QGstAppSink QGstAppSink::create(
const char *
name)
1200 qGstCheckedCast<GstAppSink>(created.
element()),
1201 QGstAppSink::NeedsRef,
1205GstAppSink *QGstAppSink::appSink()
const
1207 return qGstCheckedCast<GstAppSink>(element());
1210# if GST_CHECK_VERSION(1, 24, 0)
1211void QGstAppSink::setMaxBufferTime(std::chrono::nanoseconds
ns)
1217void QGstAppSink::setMaxBuffers(
int n)
1219 gst_app_sink_set_max_buffers(appSink(),
n);
1222void QGstAppSink::setCaps(
const QGstCaps &caps)
1224 gst_app_sink_set_caps(appSink(), caps.
caps());
1228 GDestroyNotify notify)
1236 gst_app_sink_pull_sample(appSink()),
1243QGstAppSrc::QGstAppSrc(GstAppSrc *element, RefMode
mode)
1251QGstAppSrc QGstAppSrc::create(
const char *
name)
1255 qGstCheckedCast<GstAppSrc>(created.
element()),
1256 QGstAppSrc::NeedsRef,
1260GstAppSrc *QGstAppSrc::appSrc()
const
1262 return qGstCheckedCast<GstAppSrc>(element());
1266 GDestroyNotify notify)
1271GstFlowReturn QGstAppSrc::pushBuffer(GstBuffer *
buffer)
1273 return gst_app_src_push_buffer(appSrc(),
buffer);
IOBluetoothDevice * device
QGObjectHandlerConnection()=default
~QGObjectHandlerScopedConnection()
QGObjectHandlerScopedConnection()=default
std::optional< int > toInt64() const
std::optional< QGRange< int > > toIntRange() const
std::optional< int > toInt() const
std::optional< QGRange< float > > getFractionRange() const
const char * toString() const
QGstStructure toStructure() const
std::optional< float > getFraction() const
QGValue at(int index) const
std::optional< bool > toBool() const
QGstBaseSink(GstBaseSink *, RefMode)
GstBaseSink * baseSink() const
QGstBaseSrc(GstBaseSrc *, RefMode)
GstBaseSrc * baseSrc() const
void dumpGraph(const char *fileNamePrefix)
QGstElement findByName(const char *)
static QGstBin create(const char *name)
void addGhostPad(const QGstElement &child, const char *name)
QGstBin(const QGstBin &)=default
static QGstBin createFromFactory(const char *factory, const char *name)
static QGstBin createFromPipelineDescription(const QByteArray &pipelineDescription, const char *name=nullptr, bool ghostUnlinkedPads=false)
void addPixelFormats(const QList< QVideoFrameFormat::PixelFormat > &formats, const char *modifier=nullptr)
MemoryFormat memoryFormat() const
std::optional< std::pair< QVideoFrameFormat, GstVideoInfo > > formatAndVideoInfo() const
static QGstCaps fromCameraFormat(const QCameraFormat &format)
void setResolution(QSize)
QGstStructure at(int index) const
QGstCaps(const QGstCaps &)=default
GstClockTime time() const
void setBaseTime(GstClockTime time) const
GstStateChangeReturn setState(GstState state)
static QGstElement createFromDevice(const QGstDeviceHandle &, const char *name=nullptr)
GstElement * element() const
void lockState(bool locked)
QGstElement(const QGstElement &)=default
QGstPad getRequestPad(const char *name) const
bool finishStateChange(std::chrono::nanoseconds timeout=std::chrono::seconds(5))
bool setStateSync(GstState state, std::chrono::nanoseconds timeout=std::chrono::seconds(1))
bool isStateLocked() const
void sendEvent(GstEvent *event) const
void dumpPipelineGraph(const char *filename) const
GstClockTime baseTime() const
void releaseRequestPad(const QGstPad &pad) const
bool syncStateWithParent()
QGstPad staticPad(const char *name) const
static QGstElement createFromFactory(const char *factory, const char *name=nullptr)
QGstElement getParent() const
QGstPipeline getPipeline() const
static QGstElement createFromPipelineDescription(const char *)
GstState state(std::chrono::nanoseconds timeout=std::chrono::seconds(0)) const
QGstStructure getStructure(const char *property) const
QGObjectHandlerConnection connect(const char *name, GCallback callback, gpointer userData)
double getDouble(const char *property) const
const char * name() const
int getInt(const char *property) const
QGString getString(const char *property) const
void disconnect(gulong handlerId)
const char * typeName() const
QGstObject getObject(const char *property) const
void set(const char *property, const char *str)
bool getBool(const char *property) const
QGstObject(const QGstObject &)=default
quint64 getUInt64(const char *property) const
qint64 getInt64(const char *property) const
float getFloat(const char *property) const
uint getUInt(const char *property) const
GstObject * object() const
bool link(const QGstPad &sink) const
GstEvent * stickyEvent(GstEventType type)
QGstPad(const QGstPad &)=default
QGstCaps queryCaps() const
bool sendEvent(GstEvent *event)
QGstCaps currentCaps() const
QGstElement parent() const
bool unlink(const QGstPad &sink) const
void dumpGraph(const char *fileName)
QGstStructure copy() const
QGstreamerMessage getMessage()
const GstStructure * structure
QGRange< float > frameRateRange() const
std::optional< Fraction > pixelAspectRatio() const
QByteArrayView name() const
QGValue operator[](const char *name) const
QVideoFrameFormat::PixelFormat pixelFormat() const
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
constexpr bool isValid() const noexcept
Returns true if both the width and height is equal to or greater than 0; otherwise returns false.
const QChar * constData() const
Returns a pointer to the data stored in the QString.
cache insert(employee->id(), employee)
Combined button and popup list for selecting options.
constexpr std::array< VideoFormat, 19 > qt_videoFormatLookup
int indexOfVideoFormat(QVideoFrameFormat::PixelFormat format)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void * user_data
DBusConnection const char DBusError * error
DBusConnection * connection
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage return DBusPendingCall * pending
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static QSize qCalculateFrameSizeGStreamer(QSize resolution, Fraction par)
DestinationType * qGstCheckedCast(SourceType *arg)
GstClockTime qGstClockTimeFromChrono(std::chrono::nanoseconds ns)
DestinationType * qGstSafeCast(SourceType *arg)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLbitfield GLuint64 timeout
[4]
GLuint GLsizei const GLchar * message
GLint GLsizei GLsizei GLenum format
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLenum GLboolean sink
PromiseCallbacks callbacks
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept
unsigned long long quint64
QItemEditorFactory * factory