From 6d6caf17c965295419d7d9e21645760e05a43c1c Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Thu, 26 Jun 2014 14:45:34 +0200 Subject: [PATCH] h264parse: introduce new state tracking variables. Improve parser state tracking by introducing new flags reflecting it: "got-sps", "got-pps" and "got-slice". This is an addition for robustness purposes. Older have_sps and have_pps variables are kept because they have a different meaning. i.e. they are used for deciding on when to submit updated caps or not, and rather mean "have new SPS/PPS to be submitted?" --- ...rse-add-initial-support-for-MVC-NAL-units.patch | 23 +++- ...se-introduce-new-state-tracking-variables.patch | 135 +++++++++++++++++++++ patches/videoparsers/series.frag | 1 + 3 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 patches/videoparsers/0005-h264parse-introduce-new-state-tracking-variables.patch diff --git a/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch b/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch index 9316510..656349b 100644 --- a/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch +++ b/patches/videoparsers/0003-h264parse-add-initial-support-for-MVC-NAL-units.patch @@ -27,19 +27,34 @@ index 7c970ee..e9b9481 100644 store_size = GST_H264_MAX_SPS_COUNT; store = h264parse->sps_nals; GST_DEBUG_OBJECT (h264parse, "storing sps %u", id); -@@ -534,6 +534,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) +@@ -551,10 +551,16 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + nal_type, _nal_name (nal_type), nalu->size); switch (nal_type) { - case GST_H264_NAL_SPS: + case GST_H264_NAL_SUBSET_SPS: ++ if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS)) ++ return FALSE; ++ goto process_sps; ++ + case GST_H264_NAL_SPS: + /* reset state, everything else is obsolete */ + h264parse->state = 0; + ++ process_sps: pres = gst_h264_parser_parse_sps (nalparser, nalu, &sps, TRUE); /* arranged for a fallback sps.id, so use that one and only warn */ - if (pres != GST_H264_PARSER_OK) -@@ -594,14 +595,17 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + if (pres != GST_H264_PARSER_OK) { +@@ -631,6 +637,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) case GST_H264_NAL_SLICE_DPB: case GST_H264_NAL_SLICE_DPC: case GST_H264_NAL_SLICE_IDR: + case GST_H264_NAL_SLICE_EXT: + h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS; + + /* don't need to parse the whole slice (header) here */ +@@ -638,13 +645,15 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + return FALSE; + /* don't need to parse the whole slice (header) here */ - if (*(nalu->data + nalu->offset + 1) & 0x80) { + if (*(nalu->data + nalu->offset + nalu->header_bytes) & 0x80) { diff --git a/patches/videoparsers/0005-h264parse-introduce-new-state-tracking-variables.patch b/patches/videoparsers/0005-h264parse-introduce-new-state-tracking-variables.patch new file mode 100644 index 0000000..772aa38 --- /dev/null +++ b/patches/videoparsers/0005-h264parse-introduce-new-state-tracking-variables.patch @@ -0,0 +1,135 @@ +From fcdf7736ca43b9847b22100042e19bf64005ee39 Mon Sep 17 00:00:00 2001 +From: Gwenole Beauchesne +Date: Wed, 25 Jun 2014 11:06:41 +0200 +Subject: [PATCH 5/8] h264parse: introduce new state tracking variables. + +Improve parser state tracking by introducing new flags reflecting +it: "got-sps", "got-pps" and "got-slice". This is an addition for +robustness purposes. + +Older have_sps and have_pps variables are kept because they have +a different meaning. i.e. they are used for deciding on when to +submit updated caps or not, and rather mean "have new SPS/PPS to +be submitted?" + +Signed-off-by: Gwenole Beauchesne +--- + gst/vaapi/gsth264parse.c | 30 +++++++++++++++++++++++++++++- + gst/vaapi/gsth264parse.h | 3 +++ + 2 files changed, 32 insertions(+), 1 deletion(-) + +diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c +index 4800c2b..1542a82 100644 +--- a/gst/vaapi/gsth264parse.c ++++ b/gst/vaapi/gsth264parse.c +@@ -61,6 +61,22 @@ enum + GST_H264_PARSE_ALIGN_AU + }; + ++enum ++{ ++ GST_H264_PARSE_STATE_GOT_SPS = 1 << 0, ++ GST_H264_PARSE_STATE_GOT_PPS = 1 << 1, ++ GST_H264_PARSE_STATE_GOT_SLICE = 1 << 2, ++ ++ GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS = (GST_H264_PARSE_STATE_GOT_SPS | ++ GST_H264_PARSE_STATE_GOT_PPS), ++ GST_H264_PARSE_STATE_VALID_PICTURE = ++ (GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS | ++ GST_H264_PARSE_STATE_GOT_SLICE) ++}; ++ ++#define GST_H264_PARSE_STATE_VALID(parse, expected_state) \ ++ (((parse)->state & (expected_state)) == (expected_state)) ++ + static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, +@@ -535,6 +551,9 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + + switch (nal_type) { + case GST_H264_NAL_SPS: ++ /* reset state, everything else is obsolete */ ++ h264parse->state = 0; ++ + pres = gst_h264_parser_parse_sps (nalparser, nalu, &sps, TRUE); + /* arranged for a fallback sps.id, so use that one and only warn */ + if (pres != GST_H264_PARSER_OK) +@@ -553,8 +572,11 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + } + + gst_h264_parser_store_nal (h264parse, sps.id, nal_type, nalu); ++ h264parse->state |= GST_H264_PARSE_STATE_GOT_SPS; + break; + case GST_H264_NAL_PPS: ++ h264parse->state &= GST_H264_PARSE_STATE_GOT_SPS; ++ + pres = gst_h264_parser_parse_pps (nalparser, nalu, &pps); + /* arranged for a fallback pps.id, so use that one and only warn */ + if (pres != GST_H264_PARSER_OK) +@@ -576,6 +598,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + } + + gst_h264_parser_store_nal (h264parse, pps.id, nal_type, nalu); ++ h264parse->state |= GST_H264_PARSE_STATE_GOT_PPS; + break; + case GST_H264_NAL_SEI: + gst_h264_parse_process_sei (h264parse, nalu); +@@ -595,6 +618,8 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + case GST_H264_NAL_SLICE_DPB: + case GST_H264_NAL_SLICE_DPC: + case GST_H264_NAL_SLICE_IDR: ++ h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS; ++ + /* don't need to parse the whole slice (header) here */ + if (*(nalu->data + nalu->offset + 1) & 0x80) { + /* means first_mb_in_slice == 0 */ +@@ -615,6 +640,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) + if (GST_H264_IS_I_SLICE (&slice) || GST_H264_IS_SI_SLICE (&slice)) + h264parse->keyframe |= TRUE; + ++ h264parse->state |= GST_H264_PARSE_STATE_GOT_SLICE; + h264parse->field_pic_flag = slice.field_pic_flag; + } + } +@@ -964,7 +990,8 @@ gst_h264_parse_handle_frame (GstBaseParse * parse, + + if (nalu.type == GST_H264_NAL_SPS || + nalu.type == GST_H264_NAL_PPS || +- (h264parse->have_sps && h264parse->have_pps)) { ++ GST_H264_PARSE_STATE_VALID (h264parse, ++ GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS)) { + gst_h264_parse_process_nal (h264parse, &nalu); + } else { + GST_WARNING_OBJECT (h264parse, +@@ -1761,6 +1788,7 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) + h264parse->push_codec = FALSE; + h264parse->have_sps = FALSE; + h264parse->have_pps = FALSE; ++ h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS; + } + } + +diff --git a/gst/vaapi/gsth264parse.h b/gst/vaapi/gsth264parse.h +index 4c3fdd4..c9d188b 100644 +--- a/gst/vaapi/gsth264parse.h ++++ b/gst/vaapi/gsth264parse.h +@@ -69,12 +69,15 @@ struct _GstH264Parse + + /* state */ + GstH264NalParser *nalparser; ++ guint state; + guint align; + guint format; + gint current_off; + + GstClockTime last_report; + gboolean push_codec; ++ /* The following variables have a meaning in context of "have ++ * SPS/PPS to push downstream", e.g. to update caps */ + gboolean have_sps; + gboolean have_pps; + +-- +1.7.9.5 + diff --git a/patches/videoparsers/series.frag b/patches/videoparsers/series.frag index 778bd50..44a77d6 100644 --- a/patches/videoparsers/series.frag +++ b/patches/videoparsers/series.frag @@ -5,5 +5,6 @@ videoparsers_patches_base = \ 0002-h264parse-fix-build-with-GStreamer-1.2.patch \ 0003-h264parse-fix-and-optimize-NAL-collection-function.patch \ 0004-h264parse-default-to-byte-stream-nalu-format-Annex-B.patch \ + 0005-h264parse-introduce-new-state-tracking-variables.patch \ 0003-h264parse-add-initial-support-for-MVC-NAL-units.patch \ $(NULL) -- 2.7.4