summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Schmidt <jan@centricular.com>2015-06-11 01:57:08 +1000
committerJan Schmidt <jan@centricular.com>2015-06-12 00:39:15 +1000
commite8908f5aeef952566f6bccde743c7735d3f8c6ef (patch)
treec212b4a335334fefc0fc4d4f21830eed8631cf71
parent5697b6b89b4b2a15c45bd47be940a17f4412ea11 (diff)
h264parse: Don't switch to passthrough on set_caps()
Wait until at least one keyframe has been parsed before deciding to switch to passthrough mode, in case the stream contains SEI messages that supplement the output caps - for example by providing stereoscopic information
-rw-r--r--gst/videoparsers/gsth264parse.c28
-rw-r--r--gst/videoparsers/gsth264parse.h2
2 files changed, 21 insertions, 9 deletions
diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c
index 76f768681..700f13e3d 100644
--- a/gst/videoparsers/gsth264parse.c
+++ b/gst/videoparsers/gsth264parse.c
@@ -352,8 +352,8 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format,
GstCaps * in_caps)
{
GstCaps *caps;
- guint format = GST_H264_PARSE_FORMAT_NONE;
- guint align = GST_H264_PARSE_ALIGN_NONE;
+ guint format = h264parse->format;
+ guint align = h264parse->align;
g_return_if_fail ((in_caps == NULL) || gst_caps_is_fixed (in_caps));
@@ -368,12 +368,15 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format,
caps);
}
+ h264parse->can_passthrough = FALSE;
+
if (in_caps && caps) {
if (gst_caps_can_intersect (in_caps, caps)) {
GST_DEBUG_OBJECT (h264parse, "downstream accepts upstream caps");
gst_h264_parse_format_from_caps (in_caps, &format, &align);
gst_caps_unref (caps);
caps = NULL;
+ h264parse->can_passthrough = TRUE;
}
}
@@ -2187,6 +2190,18 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
}
}
+ /* If SPS/PPS and a keyframe have been parsed, and we're not converting,
+ * we might switch to passthrough mode now on the basis that we've seen
+ * the SEI packets and know optional caps params (such as multiview).
+ * This is an efficiency optimisation that relies on stream properties
+ * remaining uniform in practice. */
+ if (h264parse->can_passthrough) {
+ if (h264parse->keyframe && h264parse->have_sps && h264parse->have_pps) {
+ GST_LOG_OBJECT (parse, "Switching to passthrough mode");
+ gst_base_parse_set_passthrough (parse, TRUE);
+ }
+ }
+
gst_h264_parse_reset_frame (h264parse);
return GST_FLOW_OK;
@@ -2373,13 +2388,8 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
}
if (format == h264parse->format && align == h264parse->align) {
- /* do not set CAPS and passthrough mode if SPS/PPS have not been parsed */
- if (h264parse->have_sps && h264parse->have_pps) {
- gst_base_parse_set_passthrough (parse, TRUE);
-
- /* we did parse codec-data and might supplement src caps */
- gst_h264_parse_update_src_caps (h264parse, caps);
- }
+ /* we did parse codec-data and might supplement src caps */
+ gst_h264_parse_update_src_caps (h264parse, caps);
} else if (format == GST_H264_PARSE_FORMAT_AVC
|| format == GST_H264_PARSE_FORMAT_AVC3) {
/* if input != output, and input is avc, must split before anything else */
diff --git a/gst/videoparsers/gsth264parse.h b/gst/videoparsers/gsth264parse.h
index e056ca2cd..abf8c830f 100644
--- a/gst/videoparsers/gsth264parse.h
+++ b/gst/videoparsers/gsth264parse.h
@@ -73,6 +73,8 @@ struct _GstH264Parse
guint align;
guint format;
gint current_off;
+ /* True if input format and alignment match negotiated output */
+ gboolean can_passthrough;
GstClockTime last_report;
gboolean push_codec;