diff options
author | Jan Schmidt <jan@centricular.com> | 2015-06-11 01:57:08 +1000 |
---|---|---|
committer | Jan Schmidt <jan@centricular.com> | 2015-06-12 00:39:15 +1000 |
commit | e8908f5aeef952566f6bccde743c7735d3f8c6ef (patch) | |
tree | c212b4a335334fefc0fc4d4f21830eed8631cf71 /gst | |
parent | 5697b6b89b4b2a15c45bd47be940a17f4412ea11 (diff) | |
download | gstreamer-plugins-bad-e8908f5aeef952566f6bccde743c7735d3f8c6ef.tar.gz |
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
Diffstat (limited to 'gst')
-rw-r--r-- | gst/videoparsers/gsth264parse.c | 28 | ||||
-rw-r--r-- | gst/videoparsers/gsth264parse.h | 2 |
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; |