mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +00:00
pad-monitor: add check for getcaps proxying audio/video fields
Checks that the common audio/video fields are correctly proxied by the elements after a getcaps
This commit is contained in:
parent
694935fdea
commit
0aaf23cb0f
2 changed files with 144 additions and 0 deletions
|
@ -22,6 +22,7 @@
|
||||||
#include "gst-qa-pad-monitor.h"
|
#include "gst-qa-pad-monitor.h"
|
||||||
#include "gst-qa-element-monitor.h"
|
#include "gst-qa-element-monitor.h"
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gst-qa-pad-monitor
|
* SECTION:gst-qa-pad-monitor
|
||||||
|
@ -163,6 +164,147 @@ gst_qa_pad_monitor_check_caps_complete (GstQaPadMonitor * monitor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstCaps *
|
||||||
|
gst_qa_pad_monitor_get_othercaps (GstQaPadMonitor * monitor)
|
||||||
|
{
|
||||||
|
GstCaps *caps = gst_caps_new_empty ();
|
||||||
|
GstIterator *iter;
|
||||||
|
gboolean done;
|
||||||
|
GstPad *otherpad;
|
||||||
|
|
||||||
|
iter = gst_pad_iterate_internal_links (GST_QA_PAD_MONITOR_GET_PAD (monitor));
|
||||||
|
done = FALSE;
|
||||||
|
while (!done) {
|
||||||
|
switch (gst_iterator_next (iter, (gpointer *) & otherpad)) {
|
||||||
|
case GST_ITERATOR_OK:
|
||||||
|
|
||||||
|
/* TODO What would be the correct caps operation to merge the caps in
|
||||||
|
* case one sink is internally linked to multiple srcs? */
|
||||||
|
gst_caps_merge (caps, gst_pad_peer_get_caps_reffed (otherpad));
|
||||||
|
gst_object_unref (otherpad);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case GST_ITERATOR_RESYNC:
|
||||||
|
gst_iterator_resync (iter);
|
||||||
|
gst_caps_replace (&caps, gst_caps_new_empty ());
|
||||||
|
break;
|
||||||
|
case GST_ITERATOR_ERROR:
|
||||||
|
GST_WARNING_OBJECT (monitor, "Internal links pad iteration error");
|
||||||
|
done = TRUE;
|
||||||
|
break;
|
||||||
|
case GST_ITERATOR_DONE:
|
||||||
|
done = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gst_iterator_free (iter);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (monitor, "Otherpad caps: %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
|
return caps;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_structure_is_video (GstStructure * structure)
|
||||||
|
{
|
||||||
|
const gchar *name = gst_structure_get_name (structure);
|
||||||
|
|
||||||
|
return g_strstr_len (name, 6, "video/")
|
||||||
|
&& strcmp (name, "video/quicktime") != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_structure_is_audio (GstStructure * structure)
|
||||||
|
{
|
||||||
|
const gchar *name = gst_structure_get_name (structure);
|
||||||
|
|
||||||
|
return g_strstr_len (name, 6, "audio/") != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_qa_pad_monitor_pad_should_proxy_othercaps (GstQaPadMonitor * monitor)
|
||||||
|
{
|
||||||
|
GstQaMonitor *parent = GST_QA_MONITOR_GET_PARENT (monitor);
|
||||||
|
/* We only know how to handle othercaps checks for decoders so far */
|
||||||
|
return GST_QA_ELEMENT_MONITOR_ELEMENT_IS_DECODER (parent) ||
|
||||||
|
GST_QA_ELEMENT_MONITOR_ELEMENT_IS_ENCODER (parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_structures_field_match (GstStructure * s1, GstStructure * s2, const gchar * f)
|
||||||
|
{
|
||||||
|
const GValue *v1;
|
||||||
|
const GValue *v2;
|
||||||
|
|
||||||
|
v2 = gst_structure_get_value (s2, f);
|
||||||
|
if (!v2)
|
||||||
|
return TRUE; /* nothing to compare to */
|
||||||
|
|
||||||
|
v1 = gst_structure_get_value (s1, f);
|
||||||
|
if (!v1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return gst_value_compare (v1, v2) == GST_VALUE_EQUAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_qa_pad_monitor_check_caps_fields_proxied (GstQaPadMonitor * monitor,
|
||||||
|
GstCaps * caps)
|
||||||
|
{
|
||||||
|
GstStructure *structure;
|
||||||
|
GstStructure *otherstructure;
|
||||||
|
GstCaps *othercaps;
|
||||||
|
gint i, j;
|
||||||
|
|
||||||
|
if (!gst_qa_pad_monitor_pad_should_proxy_othercaps (monitor))
|
||||||
|
return;
|
||||||
|
|
||||||
|
othercaps = gst_qa_pad_monitor_get_othercaps (monitor);
|
||||||
|
|
||||||
|
for (i = 0; i < gst_caps_get_size (othercaps); i++) {
|
||||||
|
gboolean found = FALSE;
|
||||||
|
gboolean type_match = FALSE;
|
||||||
|
|
||||||
|
otherstructure = gst_caps_get_structure (othercaps, i);
|
||||||
|
|
||||||
|
if (_structure_is_video (otherstructure)) {
|
||||||
|
for (j = 0; j < gst_caps_get_size (caps); j++) {
|
||||||
|
structure = gst_caps_get_structure (caps, j);
|
||||||
|
if (_structure_is_video (structure)) {
|
||||||
|
type_match = TRUE;
|
||||||
|
if (_structures_field_match (structure, otherstructure, "width") &&
|
||||||
|
_structures_field_match (structure, otherstructure, "height") &&
|
||||||
|
_structures_field_match (structure, otherstructure, "framerate")
|
||||||
|
&& _structures_field_match (structure, otherstructure,
|
||||||
|
"pixel-aspect-ratio")) {
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (_structure_is_audio (otherstructure)) {
|
||||||
|
for (j = 0; j < gst_caps_get_size (caps); j++) {
|
||||||
|
structure = gst_caps_get_structure (caps, j);
|
||||||
|
if (_structure_is_audio (structure)) {
|
||||||
|
type_match = TRUE;
|
||||||
|
if (_structures_field_match (structure, otherstructure, "rate") &&
|
||||||
|
_structures_field_match (structure, otherstructure, "channels")) {
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type_match && !found) {
|
||||||
|
GST_QA_MONITOR_REPORT_WARNING (monitor, FALSE, CAPS_NEGOTIATION,
|
||||||
|
GET_CAPS,
|
||||||
|
"Peer pad structure %" GST_PTR_FORMAT " has no similar version "
|
||||||
|
"on pad's caps %" GST_PTR_FORMAT, otherstructure, caps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_parent_set_cb (GstObject * object, GstObject * parent, GstQaMonitor * monitor)
|
_parent_set_cb (GstObject * object, GstObject * parent, GstQaMonitor * monitor)
|
||||||
{
|
{
|
||||||
|
@ -870,6 +1012,7 @@ gst_qa_pad_monitor_getcaps_func (GstPad * pad)
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
gst_qa_pad_monitor_check_caps_complete (pad_monitor, ret);
|
gst_qa_pad_monitor_check_caps_complete (pad_monitor, ret);
|
||||||
|
gst_qa_pad_monitor_check_caps_fields_proxied (pad_monitor, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -81,6 +81,7 @@ typedef enum {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GST_QA_AREA_CAPS_NEGOTIATION_MISSING_FIELD,
|
GST_QA_AREA_CAPS_NEGOTIATION_MISSING_FIELD,
|
||||||
GST_QA_AREA_CAPS_NEGOTIATION_BAD_FIELD_TYPE,
|
GST_QA_AREA_CAPS_NEGOTIATION_BAD_FIELD_TYPE,
|
||||||
|
GST_QA_AREA_CAPS_NEGOTIATION_GET_CAPS,
|
||||||
|
|
||||||
GST_QA_AREA_CAPS_NEGOTIATION_NUM_ENTRIES
|
GST_QA_AREA_CAPS_NEGOTIATION_NUM_ENTRIES
|
||||||
} GstQaReportAreaCapsNegotiation;
|
} GstQaReportAreaCapsNegotiation;
|
||||||
|
|
Loading…
Reference in a new issue