QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
qt6glitem.cc
Go to the documentation of this file.
1/*
2 * GStreamer
3 * Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#ifdef HAVE_CONFIG_H
22#include "config.h"
23#endif
24
25#include <stdio.h>
26
27#include <gst/video/video.h>
28#include "qt6glitem.h"
29#include "gstqsg6glnode.h"
30#include "gstqt6glutility.h"
31
32#include <QtCore/QMutexLocker>
33#include <QtCore/QPointer>
34#include <QtGui/QGuiApplication>
35#include <QtQuick/QQuickWindow>
36#include <QtQuick/QSGSimpleTextureNode>
37
45#define GST_CAT_DEFAULT qt_item_debug
47
48#define DEFAULT_FORCE_ASPECT_RATIO TRUE
49#define DEFAULT_PAR_N 0
50#define DEFAULT_PAR_D 1
51
52enum
53{
57};
58
60{
61 GMutex lock;
62
63 /* properties */
65 gint par_n, par_d;
66
67 GWeakRef sink;
68
71
72 GstBuffer *buffer;
73 GstCaps *new_caps;
74 GstCaps *caps;
75 GstVideoInfo new_v_info;
76 GstVideoInfo v_info;
77
78 gboolean initted;
79 GstGLDisplay *display;
80 QOpenGLContext *qt_context;
81 GstGLContext *other_context;
82 GstGLContext *context;
83
84 /* buffers with textures that were bound by QML */
86 /* buffers that were previously bound but in the meantime a new one was
87 * bound so this one is most likely not used anymore
88 * FIXME: Ideally we would use fences for this but there seems to be no
89 * way to reliably "try wait" on a fence */
91
93};
94
95Qt6GLVideoItem::Qt6GLVideoItem()
96{
97 static gsize _debug;
98
99 if (g_once_init_enter (&_debug)) {
100 GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "qtglwidget", 0, "Qt GL Widget");
101 g_once_init_leave (&_debug, 1);
102 }
103
104 this->setFlag (QQuickItem::ItemHasContents, true);
105
106 this->priv = g_new0 (Qt6GLVideoItemPrivate, 1);
107
109 this->priv->par_n = DEFAULT_PAR_N;
110 this->priv->par_d = DEFAULT_PAR_D;
111
112 this->priv->initted = FALSE;
113
114 g_mutex_init (&this->priv->lock);
115
116 g_weak_ref_init (&priv->sink, NULL);
117
118 this->priv->display = gst_qml6_get_gl_display(TRUE);
119
120 connect(this, &QQuickItem::windowChanged, this, &Qt6GLVideoItem::handleWindowChanged);
121
122 this->proxy = QSharedPointer<Qt6GLVideoItemInterface>(new Qt6GLVideoItemInterface(this));
123
124 setFlag(ItemHasContents, true);
125 setAcceptedMouseButtons(Qt::AllButtons);
126 setAcceptHoverEvents(true);
127
128 setAcceptTouchEvents(true);
129
130 GST_DEBUG ("%p init Qt6 Video Item", this);
131}
132
133Qt6GLVideoItem::~Qt6GLVideoItem()
134{
135 GstBuffer *tmp_buffer;
136
137 /* Before destroying the priv info, make sure
138 * no qmlglsink's will call in again, and that
139 * any ongoing calls are done by invalidating the proxy
140 * pointer */
141 GST_INFO ("%p Destroying QtGLVideoItem and invalidating the proxy %p", this, proxy.data());
142 proxy->invalidateRef();
143 proxy.clear();
144
145 g_mutex_clear (&this->priv->lock);
146 if (this->priv->context)
147 gst_object_unref(this->priv->context);
148 if (this->priv->other_context)
149 gst_object_unref(this->priv->other_context);
150 if (this->priv->display)
151 gst_object_unref(this->priv->display);
152
153 while ((tmp_buffer = (GstBuffer*) g_queue_pop_head (&this->priv->potentially_unbound_buffers))) {
154 GST_TRACE ("old buffer %p should be unbound now, unreffing", tmp_buffer);
155 gst_buffer_unref (tmp_buffer);
156 }
157 while ((tmp_buffer = (GstBuffer*) g_queue_pop_head (&this->priv->bound_buffers))) {
158 GST_TRACE ("old buffer %p should be unbound now, unreffing", tmp_buffer);
159 gst_buffer_unref (tmp_buffer);
160 }
161
162 gst_buffer_replace (&this->priv->buffer, NULL);
163
164 gst_caps_replace (&this->priv->caps, NULL);
165 gst_caps_replace (&this->priv->new_caps, NULL);
166
167 g_weak_ref_clear (&this->priv->sink);
168
169 g_free (this->priv);
170 this->priv = NULL;
171}
172
173void
174Qt6GLVideoItem::setDAR(gint num, gint den)
175{
176 this->priv->par_n = num;
177 this->priv->par_d = den;
178}
179
180void
181Qt6GLVideoItem::getDAR(gint * num, gint * den)
182{
183 if (num)
184 *num = this->priv->par_n;
185 if (den)
186 *den = this->priv->par_d;
187}
188
189void
190Qt6GLVideoItem::setForceAspectRatio(bool force_aspect_ratio)
191{
192 this->priv->force_aspect_ratio = !!force_aspect_ratio;
193
194 emit forceAspectRatioChanged(force_aspect_ratio);
195}
196
197bool
198Qt6GLVideoItem::getForceAspectRatio()
199{
200 return this->priv->force_aspect_ratio;
201}
202
203bool
204Qt6GLVideoItem::itemInitialized()
205{
206 return this->priv->initted;
207}
208
209static gboolean
210_calculate_par (Qt6GLVideoItem * widget, GstVideoInfo * info)
211{
212 gboolean ok;
213 gint width, height;
214 gint par_n, par_d;
215 gint display_par_n, display_par_d;
216 guint display_ratio_num, display_ratio_den;
217
218 width = GST_VIDEO_INFO_WIDTH (info);
219 height = GST_VIDEO_INFO_HEIGHT (info);
220
221 par_n = GST_VIDEO_INFO_PAR_N (info);
222 par_d = GST_VIDEO_INFO_PAR_D (info);
223
224 if (!par_n)
225 par_n = 1;
226
227 /* get display's PAR */
228 if (widget->priv->par_n != 0 && widget->priv->par_d != 0) {
229 display_par_n = widget->priv->par_n;
230 display_par_d = widget->priv->par_d;
231 } else {
232 display_par_n = 1;
233 display_par_d = 1;
234 }
235
236 ok = gst_video_calculate_display_ratio (&display_ratio_num,
237 &display_ratio_den, width, height, par_n, par_d, display_par_n,
238 display_par_d);
239
240 if (!ok)
241 return FALSE;
242
243 widget->setImplicitWidth (width);
244 widget->setImplicitHeight (height);
245
246 GST_LOG ("%p PAR: %u/%u DAR:%u/%u", widget, par_n, par_d, display_par_n,
247 display_par_d);
248
249 if (height % display_ratio_den == 0) {
250 GST_DEBUG ("%p keeping video height", widget);
251 widget->priv->display_width = (guint)
252 gst_util_uint64_scale_int (height, display_ratio_num,
253 display_ratio_den);
254 widget->priv->display_height = height;
255 } else if (width % display_ratio_num == 0) {
256 GST_DEBUG ("%p keeping video width", widget);
257 widget->priv->display_width = width;
258 widget->priv->display_height = (guint)
259 gst_util_uint64_scale_int (width, display_ratio_den, display_ratio_num);
260 } else {
261 GST_DEBUG ("%p approximating while keeping video height", widget);
262 widget->priv->display_width = (guint)
263 gst_util_uint64_scale_int (height, display_ratio_num,
264 display_ratio_den);
265 widget->priv->display_height = height;
266 }
267 GST_DEBUG ("%p scaling to %dx%d", widget, widget->priv->display_width,
268 widget->priv->display_height);
269
270 return TRUE;
271}
272
273QSGNode *
275 UpdatePaintNodeData * updatePaintNodeData)
276{
277 GstBuffer *old_buffer;
278
279 if (!this->priv->initted)
280 return oldNode;
281
282 GstQSG6OpenGLNode *texNode = static_cast<GstQSG6OpenGLNode *> (oldNode);
283 GstVideoRectangle src, dst, result;
284
285 g_mutex_lock (&this->priv->lock);
286
287 GST_TRACE ("%p updatePaintNode", this);
288
289 if (gst_gl_context_get_current() == NULL)
290 gst_gl_context_activate (this->priv->other_context, TRUE);
291
292 if (!texNode) {
293 texNode = new GstQSG6OpenGLNode (this);
294 this->priv->m_node = texNode;
295 }
296
297 if ((old_buffer = texNode->getBuffer())) {
298 if (old_buffer == this->priv->buffer) {
299 /* same buffer */
300 gst_buffer_unref (old_buffer);
301 } else {
302 GstBuffer *tmp_buffer;
303
304 GST_TRACE ("old buffer %p was bound, queueing up for later", old_buffer);
305 /* Unref all buffers that were previously not bound anymore. At least
306 * one more buffer was bound in the meantime so this one is most likely
307 * not in use anymore. */
308 while ((tmp_buffer = (GstBuffer*) g_queue_pop_head (&this->priv->potentially_unbound_buffers))) {
309 GST_TRACE ("old buffer %p should be unbound now, unreffing", tmp_buffer);
310 gst_buffer_unref (tmp_buffer);
311 }
312
313 /* Move previous bound buffers to the next queue. We now know that
314 * another buffer was bound in the meantime and will free them on
315 * the next iteration above. */
316 while ((tmp_buffer = (GstBuffer*) g_queue_pop_head (&this->priv->bound_buffers))) {
317 GST_TRACE ("old buffer %p is potentially unbound now", tmp_buffer);
318 g_queue_push_tail (&this->priv->potentially_unbound_buffers, tmp_buffer);
319 }
320 g_queue_push_tail (&this->priv->bound_buffers, old_buffer);
321 }
322 old_buffer = NULL;
323 }
324
325 texNode->setCaps (this->priv->caps);
326 texNode->setBuffer (this->priv->buffer);
327
328 if (this->priv->force_aspect_ratio && this->priv->caps) {
329 src.w = this->priv->display_width;
330 src.h = this->priv->display_height;
331
332 dst.x = boundingRect().x();
333 dst.y = boundingRect().y();
334 dst.w = boundingRect().width();
335 dst.h = boundingRect().height();
336
337 gst_video_sink_center_rect (src, dst, &result, TRUE);
338 } else {
339 result.x = boundingRect().x();
340 result.y = boundingRect().y();
341 result.w = boundingRect().width();
342 result.h = boundingRect().height();
343 }
344
345 texNode->setRect (QRectF (result.x, result.y, result.w, result.h));
346
347 g_mutex_unlock (&this->priv->lock);
348
349 return texNode;
350}
351
352/* This method has to be invoked with the the priv->lock taken */
353void
354Qt6GLVideoItem::fitStreamToAllocatedSize(GstVideoRectangle * result)
355{
356 if (this->priv->force_aspect_ratio) {
357 GstVideoRectangle src, dst;
358
359 src.x = 0;
360 src.y = 0;
361 src.w = this->priv->display_width;
362 src.h = this->priv->display_height;
363
364 dst.x = 0;
365 dst.y = 0;
366 dst.w = width();
367 dst.h = height();
368
369 gst_video_sink_center_rect (src, dst, result, TRUE);
370 } else {
371 result->x = 0;
372 result->y = 0;
373 result->w = width();
374 result->h = height();
375 }
376}
377
378/* This method has to be invoked with the the priv->lock taken */
379QPointF
380Qt6GLVideoItem::mapPointToStreamSize(QPointF pos)
381{
382 gdouble stream_width, stream_height;
383 GstVideoRectangle result;
384 double stream_x, stream_y;
385 double x, y;
386
387 fitStreamToAllocatedSize(&result);
388
389 stream_width = (gdouble) GST_VIDEO_INFO_WIDTH (&this->priv->v_info);
390 stream_height = (gdouble) GST_VIDEO_INFO_HEIGHT (&this->priv->v_info);
391 x = pos.x();
392 y = pos.y();
393
394 /* from display coordinates to stream coordinates */
395 if (result.w > 0)
396 stream_x = (x - result.x) / result.w * stream_width;
397 else
398 stream_x = 0.;
399
400 /* clip to stream size */
401 stream_x = CLAMP(stream_x, 0., stream_width);
402
403 /* same for y-axis */
404 if (result.h > 0)
405 stream_y = (y - result.y) / result.h * stream_height;
406 else
407 stream_y = 0.;
408
409 stream_y = CLAMP(stream_y, 0., stream_height);
410 GST_TRACE ("transform %fx%f into %fx%f", x, y, stream_x, stream_y);
411
412 return QPointF(stream_x, stream_y);
413}
414
415void
416Qt6GLVideoItem::wheelEvent(QWheelEvent * event)
417{
418 // noop
419}
420
421void
423{
424 mouseHovering = true;
425}
426
427void
429{
430 mouseHovering = false;
431}
432
433void
435{
436 // noop
437}
438
439void
440Qt6GLVideoItem::touchEvent(QTouchEvent * event)
441{
442 // noop
443}
444
445void
446Qt6GLVideoItem::sendMouseEvent(QMouseEvent * event, gboolean is_press)
447{
448 // noop
449}
450
451void
453{
454 forceActiveFocus();
455 sendMouseEvent(event, TRUE);
456}
457
458void
460{
461 sendMouseEvent(event, FALSE);
462}
463
464void
466{
467 QMutexLocker locker(&lock);
468 if (qt_item == NULL)
469 return;
470
471 g_mutex_lock (&qt_item->priv->lock);
472 g_weak_ref_set (&qt_item->priv->sink, sink);
473 g_mutex_unlock (&qt_item->priv->lock);
474}
475
476void
478{
479 QMutexLocker locker(&lock);
480
481 if (qt_item == NULL) {
482 GST_WARNING ("%p actual item is NULL. setBuffer call ignored", this);
483 return;
484 }
485
486 if (!qt_item->priv->caps && !qt_item->priv->new_caps) {
487 GST_WARNING ("%p Got buffer on unnegotiated QtGLVideoItem. Dropping", this);
488 return;
489 }
490
491 g_mutex_lock (&qt_item->priv->lock);
492
493 if (qt_item->priv->new_caps) {
494 GST_DEBUG ("%p caps change from %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT,
495 this, qt_item->priv->caps, qt_item->priv->new_caps);
496 gst_caps_take (&qt_item->priv->caps, qt_item->priv->new_caps);
497 qt_item->priv->new_caps = NULL;
498 qt_item->priv->v_info = qt_item->priv->new_v_info;
499
500 if (!_calculate_par (qt_item, &qt_item->priv->v_info)) {
501 g_mutex_unlock (&qt_item->priv->lock);
502 return;
503 }
504 }
505
506 gst_buffer_replace (&qt_item->priv->buffer, buffer);
507
508 QMetaObject::invokeMethod(qt_item, "update", Qt::QueuedConnection);
509
510 g_mutex_unlock (&qt_item->priv->lock);
511}
512
513void
514Qt6GLVideoItem::onSceneGraphInitialized ()
515{
516 QSGRendererInterface *renderer;
517 QOpenGLContext *gl_context;
518
519 if (this->window() == NULL)
520 return;
521
522 renderer = this->window()->rendererInterface();
523 if (!renderer)
524 return;
525
526 if (renderer->graphicsApi() != QSGRendererInterface::GraphicsApi::OpenGL) {
527 GST_WARNING ("%p scene graph initialized with a non-OpenGL renderer interface", this);
528 return;
529 }
530
531 gl_context =
532 static_cast<QOpenGLContext *> (
533 renderer->getResource(
534 this->window(),
535 QSGRendererInterface::Resource::OpenGLContextResource));
536
537 GST_DEBUG ("%p scene graph initialization with Qt GL context %p", this,
538 gl_context);
539
540 if (this->priv->qt_context == gl_context)
541 return;
542
543 this->priv->qt_context = gl_context;
544 if (this->priv->qt_context == NULL) {
545 GST_ERROR ("%p failed to retrieve Qt GL context", this);
546 g_assert_not_reached ();
547 return;
548 }
549
550 this->priv->initted = gst_qml6_get_gl_wrapcontext (this->priv->display,
551 &this->priv->other_context, &this->priv->context);
552
553 GST_DEBUG ("%p created wrapped GL context %" GST_PTR_FORMAT, this,
554 this->priv->other_context);
555
557}
558
559void
560Qt6GLVideoItem::onSceneGraphInvalidated ()
561{
562 this->priv->m_node = nullptr;
563 GST_FIXME ("%p scene graph invalidated", this);
564}
565
570gboolean
572{
573 QMutexLocker locker(&lock);
574
575 GError *error = NULL;
576
577 if (qt_item == NULL)
578 return FALSE;
579
580 g_mutex_lock (&qt_item->priv->lock);
581
582 if (qt_item->priv->display && qt_item->priv->qt_context
583 && qt_item->priv->other_context && qt_item->priv->context) {
584 /* already have the necessary state */
585 g_mutex_unlock (&qt_item->priv->lock);
586 return TRUE;
587 }
588
589 if (!GST_IS_GL_DISPLAY (qt_item->priv->display)) {
590 GST_ERROR ("%p failed to retrieve display connection %" GST_PTR_FORMAT,
591 qt_item, qt_item->priv->display);
592 g_mutex_unlock (&qt_item->priv->lock);
593 return FALSE;
594 }
595
596 if (!GST_IS_GL_CONTEXT (qt_item->priv->other_context)) {
597 GST_ERROR ("%p failed to retrieve wrapped context %" GST_PTR_FORMAT, qt_item,
598 qt_item->priv->other_context);
599 g_mutex_unlock (&qt_item->priv->lock);
600 return FALSE;
601 }
602
603 qt_item->priv->context = gst_gl_context_new (qt_item->priv->display);
604
605 if (!qt_item->priv->context) {
606 g_mutex_unlock (&qt_item->priv->lock);
607 return FALSE;
608 }
609
610 if (!gst_gl_context_create (qt_item->priv->context, qt_item->priv->other_context,
611 &error)) {
612 GST_ERROR ("%s", error->message);
613 g_mutex_unlock (&qt_item->priv->lock);
614 return FALSE;
615 }
616
617 g_mutex_unlock (&qt_item->priv->lock);
618 return TRUE;
619}
620
621void
622Qt6GLVideoItem::handleWindowChanged (QQuickWindow * win)
623{
624 if (win) {
625 if (win->isSceneGraphInitialized ())
626 win->scheduleRenderJob (new RenderJob (std::
627 bind (&Qt6GLVideoItem::onSceneGraphInitialized, this)),
628 QQuickWindow::BeforeSynchronizingStage);
629 else
630 connect (win, SIGNAL (sceneGraphInitialized ()), this,
631 SLOT (onSceneGraphInitialized ()), Qt::DirectConnection);
632
633 connect (win, SIGNAL (sceneGraphInvalidated ()), this,
634 SLOT (onSceneGraphInvalidated ()), Qt::DirectConnection);
635 } else {
636 this->priv->qt_context = NULL;
637 this->priv->initted = FALSE;
638 }
639 this->priv->m_node = nullptr;
640}
641
642void
644{
645 this->priv->m_node = nullptr;
646}
647
648gboolean
650{
651 QMutexLocker locker(&lock);
652 GstVideoInfo v_info;
653
654 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
655 g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
656
657 if (qt_item == NULL)
658 return FALSE;
659
660 if (qt_item->priv->caps && gst_caps_is_equal_fixed (qt_item->priv->caps, caps))
661 return TRUE;
662
663 if (!gst_video_info_from_caps (&v_info, caps))
664 return FALSE;
665
666 g_mutex_lock (&qt_item->priv->lock);
667
668 GST_DEBUG ("%p set caps %" GST_PTR_FORMAT, qt_item, caps);
669
670 gst_caps_replace (&qt_item->priv->new_caps, caps);
671
672 qt_item->priv->new_v_info = v_info;
673
674 g_mutex_unlock (&qt_item->priv->lock);
675
676 return TRUE;
677}
678
679GstGLContext *
681{
682 QMutexLocker locker(&lock);
683
684 if (!qt_item || !qt_item->priv->other_context)
685 return NULL;
686
687 return (GstGLContext *) gst_object_ref (qt_item->priv->other_context);
688}
689
690GstGLContext *
692{
693 QMutexLocker locker(&lock);
694
695 if (!qt_item || !qt_item->priv->context)
696 return NULL;
697
698 return (GstGLContext *) gst_object_ref (qt_item->priv->context);
699}
700
701GstGLDisplay *
703{
704 QMutexLocker locker(&lock);
705
706 if (!qt_item || !qt_item->priv->display)
707 return NULL;
708
709 return (GstGLDisplay *) gst_object_ref (qt_item->priv->display);
710}
711
712void
714{
715 QMutexLocker locker(&lock);
716 if (!qt_item)
717 return;
718 qt_item->setDAR(num, den);
719}
720
721void
722Qt6GLVideoItemInterface::getDAR(gint * num, gint * den)
723{
724 QMutexLocker locker(&lock);
725 if (!qt_item)
726 return;
727 qt_item->getDAR (num, den);
728}
729
730void
732{
733 QMutexLocker locker(&lock);
734 if (!qt_item)
735 return;
736 qt_item->setForceAspectRatio(force_aspect_ratio);
737}
738
739bool
741{
742 QMutexLocker locker(&lock);
743 if (!qt_item)
744 return FALSE;
745 return qt_item->getForceAspectRatio();
746}
747
748void
750{
751 QMutexLocker locker(&lock);
752 qt_item = NULL;
753}
struct _GstElement GstElement
Error error
void setBuffer(GstBuffer *buffer)
GstBuffer * getBuffer()
void setCaps(GstCaps *caps)
GstGLDisplay * getDisplay()
Definition qt6glitem.cc:702
void getDAR(gint *, gint *)
Definition qt6glitem.cc:722
void setBuffer(GstBuffer *buffer)
Definition qt6glitem.cc:477
gboolean setCaps(GstCaps *caps)
Definition qt6glitem.cc:649
void setDAR(gint, gint)
Definition qt6glitem.cc:713
GstGLContext * getContext()
Definition qt6glitem.cc:691
void setForceAspectRatio(bool)
Definition qt6glitem.cc:731
void setSink(GstElement *sink)
Definition qt6glitem.cc:465
GstGLContext * getQtContext()
Definition qt6glitem.cc:680
void mouseReleaseEvent(QMouseEvent *) override
Definition qt6glitem.cc:459
void hoverEnterEvent(QHoverEvent *) override
Definition qt6glitem.cc:422
void hoverLeaveEvent(QHoverEvent *) override
Definition qt6glitem.cc:428
void mousePressEvent(QMouseEvent *) override
Definition qt6glitem.cc:452
QSGNode * updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) override
Definition qt6glitem.cc:274
void forceAspectRatioChanged(bool)
void itemInitializedChanged()
void wheelEvent(QWheelEvent *) override
Definition qt6glitem.cc:416
void hoverMoveEvent(QHoverEvent *) override
Definition qt6glitem.cc:434
void releaseResources() override
Definition qt6glitem.cc:643
void touchEvent(QTouchEvent *) override
Definition qt6glitem.cc:440
#define GST_CAT_DEFAULT
#define DEFAULT_PAR_D
#define DEFAULT_FORCE_ASPECT_RATIO
#define DEFAULT_PAR_N
gboolean gst_qml6_get_gl_wrapcontext(GstGLDisplay *display, GstGLContext **wrap_glcontext, GstGLContext **context)
GstGLDisplay * gst_qml6_get_gl_display(gboolean sink)
@ PROP_FORCE_ASPECT_RATIO
Definition qt6glitem.cc:55
@ PROP_PIXEL_ASPECT_RATIO
Definition qt6glitem.cc:56
@ PROP_0
Definition qt6glitem.cc:54
GST_DEBUG_CATEGORY_STATIC(qt_item_debug)
static gboolean _calculate_par(Qt6GLVideoItem *widget, GstVideoInfo *info)
Definition qt6glitem.cc:210
#define GST_CAT_DEFAULT
Definition qt6glitem.cc:45
GstQSG6OpenGLNode * m_node
Definition qt6glitem.cc:92
GstGLDisplay * display
Definition qt6glitem.cc:79
GstVideoInfo v_info
Definition qt6glitem.cc:76
GQueue potentially_unbound_buffers
Definition qt6glitem.cc:90
GstGLContext * other_context
Definition qt6glitem.cc:81
QOpenGLContext * qt_context
Definition qt6glitem.cc:80
gboolean force_aspect_ratio
Definition qt6glitem.cc:64
GstGLContext * context
Definition qt6glitem.cc:82
GstVideoInfo new_v_info
Definition qt6glitem.cc:75