summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuis de Bethencourt <luis@debethencourt.com>2015-08-14 11:49:51 +0100
committerLuis de Bethencourt <luis@debethencourt.com>2015-08-14 12:00:23 +0100
commitfd665514ba9f998d55508cd681f2a9c02f0f96a1 (patch)
treeae9b5ca97448bca128d60f3898055d5b317ab6be
parent93edd99bf7fa481b4bebc9f05ab560111eeb397c (diff)
downloadgstreamer-plugins-bad-fd665514ba9f998d55508cd681f2a9c02f0f96a1.tar.gz
rtph265depay: copy metadata in the depayloader, but only the relevant ones
The payloader didn't copy anything so far, the depayloader copied every possible meta. Let's make it consistent and just copy all metas without tags or with only the video tag. https://bugzilla.gnome.org/show_bug.cgi?id=751774
-rw-r--r--gst/rtp/gstrtph265depay.c80
-rw-r--r--gst/rtp/gstrtph265depay.h9
2 files changed, 89 insertions, 0 deletions
diff --git a/gst/rtp/gstrtph265depay.c b/gst/rtp/gstrtph265depay.c
index 7d573fe9e..9718d5831 100644
--- a/gst/rtp/gstrtph265depay.c
+++ b/gst/rtp/gstrtph265depay.c
@@ -27,6 +27,7 @@
#include <gst/base/gstbitreader.h>
#include <gst/rtp/gstrtpbuffer.h>
+#include <gst/video/video.h>
#include "gstrtph265depay.h"
GST_DEBUG_CATEGORY_STATIC (rtph265depay_debug);
@@ -938,6 +939,60 @@ gst_rtp_h265_complete_au (GstRtpH265Depay * rtph265depay,
#define NAL_TYPE_IS_KEY(nt) (NAL_TYPE_IS_PARAMETER_SET(nt) || NAL_TYPE_IS_CODED_SLICE_SEGMENT(nt))
+static gboolean
+foreach_metadata_copy (GstBuffer * inbuf, GstMeta ** meta, gpointer user_data)
+{
+ CopyMetaData *data = user_data;
+ GstElement *element = data->element;
+ GstBuffer *outbuf = data->outbuf;
+ const GstMetaInfo *info = (*meta)->info;
+ const gchar *const *tags = gst_meta_api_type_get_tags (info->api);
+
+ if (!tags || (g_strv_length ((gchar **) tags) == 1
+ && gst_meta_api_type_has_tag (info->api,
+ g_quark_from_string (GST_META_TAG_VIDEO_STR)))) {
+ GstMetaTransformCopy copy_data = { FALSE, 0, -1 };
+ GST_DEBUG_OBJECT (element, "copy metadata %s", g_type_name (info->api));
+ /* simply copy then */
+ info->transform_func (outbuf, *meta, inbuf,
+ _gst_meta_transform_copy, &copy_data);
+ } else {
+ GST_DEBUG_OBJECT (element, "not copying metadata %s",
+ g_type_name (info->api));
+ }
+
+ return TRUE;
+}
+
+/* TODO: Should probably make copy_tag an array at some point */
+void
+gst_rtp_copy_meta (GstElement * element, GstBuffer * outbuf, GstBuffer * inbuf,
+ GQuark copy_tag)
+{
+ CopyMetaData data = { element, outbuf, copy_tag };
+
+ gst_buffer_foreach_meta (inbuf, foreach_metadata_copy, &data);
+}
+
+static gboolean
+foreach_metadata_drop (GstBuffer * inbuf, GstMeta ** meta, gpointer user_data)
+{
+ GstRtpH265Depay *depay = user_data;
+ const GstMetaInfo *info = (*meta)->info;
+ const gchar *const *tags = gst_meta_api_type_get_tags (info->api);
+
+ if (!tags || (g_strv_length ((gchar **) tags) == 1
+ && gst_meta_api_type_has_tag (info->api,
+ g_quark_from_string (GST_META_TAG_VIDEO_STR)))) {
+ GST_DEBUG_OBJECT (depay, "keeping metadata %s", g_type_name (info->api));
+ } else {
+ GST_DEBUG_OBJECT (depay, "dropping metadata %s", g_type_name (info->api));
+ *meta = NULL;
+ }
+
+ return TRUE;
+}
+
static GstBuffer *
gst_rtp_h265_depay_handle_nal (GstRtpH265Depay * rtph265depay, GstBuffer * nal,
GstClockTime in_timestamp, gboolean marker)
@@ -1037,12 +1092,17 @@ gst_rtp_h265_depay_handle_nal (GstRtpH265Depay * rtph265depay, GstBuffer * nal,
/* prepend codec_data */
if (rtph265depay->codec_data) {
GST_DEBUG_OBJECT (depayload, "prepending codec_data");
+ gst_rtp_copy_meta (GST_ELEMENT_CAST (rtph265depay),
+ rtph265depay->codec_data, outbuf,
+ g_quark_from_static_string (GST_META_TAG_VIDEO_STR));
outbuf = gst_buffer_append (rtph265depay->codec_data, outbuf);
rtph265depay->codec_data = NULL;
out_keyframe = TRUE;
}
outbuf = gst_buffer_make_writable (outbuf);
+ gst_buffer_foreach_meta (outbuf, foreach_metadata_drop, depayload);
+
GST_BUFFER_PTS (outbuf) = out_timestamp;
if (out_keyframe)
@@ -1108,6 +1168,7 @@ static GstBuffer *
gst_rtp_h265_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
{
GstRtpH265Depay *rtph265depay;
+ GstBuffer *buf;
GstBuffer *outbuf = NULL;
guint8 nal_unit_type;
@@ -1139,6 +1200,7 @@ gst_rtp_h265_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
payload_len = gst_rtp_buffer_get_payload_len (rtp);
payload = gst_rtp_buffer_get_payload (rtp);
+ buf = gst_rtp_buffer_get_payload_buffer (rtp);
marker = gst_rtp_buffer_get_marker (rtp);
GST_DEBUG_OBJECT (rtph265depay, "receiving %d bytes", payload_len);
@@ -1246,6 +1308,9 @@ gst_rtp_h265_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
memcpy (map.data + sizeof (sync_bytes), payload, nalu_size);
gst_buffer_unmap (outbuf, &map);
+ gst_rtp_copy_meta (GST_ELEMENT_CAST (rtph265depay), outbuf, buf,
+ g_quark_from_static_string (GST_META_TAG_VIDEO_STR));
+
gst_adapter_push (rtph265depay->adapter, outbuf);
payload += nalu_size;
@@ -1340,6 +1405,9 @@ gst_rtp_h265_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
map.data[sizeof (sync_bytes) + 1] = nal_header & 0xff;
gst_buffer_unmap (outbuf, &map);
+ gst_rtp_copy_meta (GST_ELEMENT_CAST (rtph265depay), outbuf, buf,
+ g_quark_from_static_string (GST_META_TAG_VIDEO_STR));
+
GST_DEBUG_OBJECT (rtph265depay, "queueing %d bytes", outsize);
/* and assemble in the adapter */
@@ -1357,6 +1425,9 @@ gst_rtp_h265_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
outbuf = gst_buffer_new_and_alloc (outsize);
gst_buffer_fill (outbuf, 0, payload, outsize);
+ gst_rtp_copy_meta (GST_ELEMENT_CAST (rtph265depay), outbuf, buf,
+ g_quark_from_static_string (GST_META_TAG_VIDEO_STR));
+
GST_DEBUG_OBJECT (rtph265depay, "queueing %d bytes", outsize);
/* and assemble in the adapter */
@@ -1400,6 +1471,9 @@ gst_rtp_h265_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
memcpy (map.data + sizeof (sync_bytes), payload, nalu_size);
gst_buffer_unmap (outbuf, &map);
+ gst_rtp_copy_meta (GST_ELEMENT_CAST (rtph265depay), outbuf, buf,
+ g_quark_from_static_string (GST_META_TAG_VIDEO_STR));
+
outbuf = gst_rtp_h265_depay_handle_nal (rtph265depay, outbuf, timestamp,
marker);
break;
@@ -1407,17 +1481,21 @@ gst_rtp_h265_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
}
}
+ gst_buffer_unref (buf);
+
return outbuf;
/* ERRORS */
empty_packet:
{
GST_DEBUG_OBJECT (rtph265depay, "empty packet");
+ gst_buffer_unref (buf);
return NULL;
}
waiting_start:
{
GST_DEBUG_OBJECT (rtph265depay, "waiting for start");
+ gst_buffer_unref (buf);
return NULL;
}
#if 0
@@ -1425,6 +1503,7 @@ not_implemented_donl_present:
{
GST_ELEMENT_ERROR (rtph265depay, STREAM, FORMAT,
(NULL), ("DONL field present not supported yet"));
+ gst_buffer_unref (buf);
return NULL;
}
#endif
@@ -1432,6 +1511,7 @@ not_implemented:
{
GST_ELEMENT_ERROR (rtph265depay, STREAM, FORMAT,
(NULL), ("NAL unit type %d not supported yet", nal_unit_type));
+ gst_buffer_unref (buf);
return NULL;
}
}
diff --git a/gst/rtp/gstrtph265depay.h b/gst/rtp/gstrtph265depay.h
index ed49329a3..9f50ac60e 100644
--- a/gst/rtp/gstrtph265depay.h
+++ b/gst/rtp/gstrtph265depay.h
@@ -87,6 +87,15 @@ struct _GstRtpH265DepayClass
GstRTPBaseDepayloadClass parent_class;
};
+typedef struct
+{
+ GstElement *element;
+ GstBuffer *outbuf;
+ GQuark copy_tag;
+} CopyMetaData;
+
+void gst_rtp_copy_meta (GstElement * element, GstBuffer *outbuf, GstBuffer *inbuf, GQuark copy_tag);
+
GType gst_rtp_h265_depay_get_type (void);
gboolean gst_rtp_h265_depay_plugin_init (GstPlugin * plugin);