mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-22 15:18:21 +00:00
multihandlesink: Only don't send HEADER buffers normally if they are actually streamheaders from the caps
And also consider HEADER buffers without DELTA_UNIT flag as sync points. This fixes sync-mode=2 with mpegtsmux for example, which has no streamheaders but puts the HEADER flag on its keyframes. https://bugzilla.gnome.org/show_bug.cgi?id=763278
This commit is contained in:
parent
916746e731
commit
1d4fb48718
2 changed files with 65 additions and 12 deletions
|
@ -114,6 +114,8 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define NOT_IMPLEMENTED 0
|
#define NOT_IMPLEMENTED 0
|
||||||
|
|
||||||
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
|
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
|
@ -1140,13 +1142,9 @@ gst_multi_handle_sink_client_queue_buffer (GstMultiHandleSink * mhsink,
|
||||||
static gboolean
|
static gboolean
|
||||||
is_sync_frame (GstMultiHandleSink * sink, GstBuffer * buffer)
|
is_sync_frame (GstMultiHandleSink * sink, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT)) {
|
if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_HEADER)) {
|
return TRUE;
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find the keyframe in the list of buffers starting the
|
/* find the keyframe in the list of buffers starting the
|
||||||
|
@ -1844,10 +1842,64 @@ restart:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
buffer_is_in_caps (GstMultiHandleSink * sink, GstBuffer * buf)
|
||||||
|
{
|
||||||
|
GstCaps *caps;
|
||||||
|
GstStructure *s;
|
||||||
|
const GValue *v;
|
||||||
|
|
||||||
|
caps = gst_pad_get_current_caps (GST_BASE_SINK_PAD (sink));
|
||||||
|
if (!caps)
|
||||||
|
return FALSE;
|
||||||
|
s = gst_caps_get_structure (caps, 0);
|
||||||
|
if (!gst_structure_has_field (s, "streamheader")) {
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = gst_structure_get_value (s, "streamheader");
|
||||||
|
if (GST_VALUE_HOLDS_ARRAY (v)) {
|
||||||
|
guint n = gst_value_array_get_size (v);
|
||||||
|
guint i;
|
||||||
|
GstMapInfo map;
|
||||||
|
|
||||||
|
gst_buffer_map (buf, &map, GST_MAP_READ);
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
const GValue *v2 = gst_value_array_get_value (v, i);
|
||||||
|
GstBuffer *buf2;
|
||||||
|
GstMapInfo map2;
|
||||||
|
|
||||||
|
if (!GST_VALUE_HOLDS_BUFFER (v2))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
buf2 = gst_value_get_buffer (v2);
|
||||||
|
if (buf == buf2) {
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
gst_buffer_map (buf2, &map2, GST_MAP_READ);
|
||||||
|
if (map.size == map2.size && memcmp (map.data, map2.data, map.size) == 0) {
|
||||||
|
gst_buffer_unmap (buf2, &map2);
|
||||||
|
gst_buffer_unmap (buf, &map);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
gst_buffer_unmap (buf2, &map2);
|
||||||
|
}
|
||||||
|
gst_buffer_unmap (buf, &map);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_multi_handle_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
gst_multi_handle_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
gboolean in_caps;
|
gboolean is_header, in_caps;
|
||||||
#if 0
|
#if 0
|
||||||
GstCaps *bufcaps, *padcaps;
|
GstCaps *bufcaps, *padcaps;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1868,8 +1920,9 @@ gst_multi_handle_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
goto no_caps;
|
goto no_caps;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* get IN_CAPS first, code below might mess with the flags */
|
/* get HEADER first, code below might mess with the flags */
|
||||||
in_caps = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_HEADER);
|
is_header = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_HEADER);
|
||||||
|
in_caps = is_header && buffer_is_in_caps (sink, buf);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* stamp the buffer with previous caps if no caps set */
|
/* stamp the buffer with previous caps if no caps set */
|
||||||
|
@ -1909,7 +1962,7 @@ gst_multi_handle_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
/* if we get IN_CAPS buffers, but the previous buffer was not IN_CAPS,
|
/* if we get IN_CAPS buffers, but the previous buffer was not IN_CAPS,
|
||||||
* it means we're getting new streamheader buffers, and we should clear
|
* it means we're getting new streamheader buffers, and we should clear
|
||||||
* the old ones */
|
* the old ones */
|
||||||
if (in_caps && !sink->previous_buffer_in_caps) {
|
if (is_header && !sink->previous_buffer_is_header) {
|
||||||
GST_DEBUG_OBJECT (sink,
|
GST_DEBUG_OBJECT (sink,
|
||||||
"receiving new HEADER buffers, clearing old streamheader");
|
"receiving new HEADER buffers, clearing old streamheader");
|
||||||
g_slist_foreach (sink->streamheader, (GFunc) gst_mini_object_unref, NULL);
|
g_slist_foreach (sink->streamheader, (GFunc) gst_mini_object_unref, NULL);
|
||||||
|
@ -1918,7 +1971,7 @@ gst_multi_handle_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save the current in_caps */
|
/* save the current in_caps */
|
||||||
sink->previous_buffer_in_caps = in_caps;
|
sink->previous_buffer_is_header = is_header;
|
||||||
|
|
||||||
/* if the incoming buffer is marked as IN CAPS, then we assume for now
|
/* if the incoming buffer is marked as IN CAPS, then we assume for now
|
||||||
* it's a streamheader that needs to be sent to each new client, so we
|
* it's a streamheader that needs to be sent to each new client, so we
|
||||||
|
|
|
@ -203,7 +203,7 @@ struct _GstMultiHandleSink {
|
||||||
GCancellable *cancellable;
|
GCancellable *cancellable;
|
||||||
|
|
||||||
GSList *streamheader; /* GSList of GstBuffers to use as streamheader */
|
GSList *streamheader; /* GSList of GstBuffers to use as streamheader */
|
||||||
gboolean previous_buffer_in_caps;
|
gboolean previous_buffer_is_header;
|
||||||
|
|
||||||
gint qos_dscp;
|
gint qos_dscp;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue