decoder: h264: fix memory leak in PPS.
[platform/upstream/gstreamer-vaapi.git] / patches / videoparsers / 0006-h264parse-improve-conditions-for-skipping-NAL-units.patch
1 From 2b3680eeaff91f611d8c8b0e74efc66b0d874c66 Mon Sep 17 00:00:00 2001
2 From: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
3 Date: Wed, 25 Jun 2014 13:14:10 +0200
4 Subject: [PATCH 6/8] h264parse: improve conditions for skipping NAL units.
5
6 Carefully track cases when skipping broken or invalid NAL units is
7 necessary. In particular, always allow NAL units to be processed
8 and let that gst_h264_parse_process_nal() function decide on whether
9 the current NAL needs to be dropped or not.
10
11 This fixes parsing of streams with SEI NAL buffering_period() message
12 inserted between SPS and PPS, or SPS-Ext NAL following a traditional
13 SPS NAL unit, among other cases too.
14
15 Practical examples from the H.264 AVC conformance suite include
16 alphaconformanceG, CVSE2_Sony_B, CVSE3_Sony_H, CVSEFDFT3_Sony_E
17 when parsing in stream-format=byte-stream,alignment=au mode.
18
19 https://bugzilla.gnome.org/show_bug.cgi?id=732203
20
21 Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
22 ---
23  gst/vaapi/gsth264parse.c |   43 +++++++++++++++++++++++++++++++------------
24  1 file changed, 31 insertions(+), 12 deletions(-)
25
26 diff --git a/gst/vaapi/gsth264parse.c b/gst/vaapi/gsth264parse.c
27 index 1542a82..805c55f 100644
28 --- a/gst/vaapi/gsth264parse.c
29 +++ b/gst/vaapi/gsth264parse.c
30 @@ -528,7 +528,7 @@ gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu)
31  }
32  
33  /* caller guarantees 2 bytes of nal payload */
34 -static void
35 +static gboolean
36  gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu)
37  {
38    guint nal_type;
39 @@ -540,7 +540,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu)
40    /* nothing to do for broken input */
41    if (G_UNLIKELY (nalu->size < 2)) {
42      GST_DEBUG_OBJECT (h264parse, "not processing nal size %u", nalu->size);
43 -    return;
44 +    return TRUE;
45    }
46  
47    /* we have a peek as well */
48 @@ -556,8 +556,10 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu)
49  
50        pres = gst_h264_parser_parse_sps (nalparser, nalu, &sps, TRUE);
51        /* arranged for a fallback sps.id, so use that one and only warn */
52 -      if (pres != GST_H264_PARSER_OK)
53 +      if (pres != GST_H264_PARSER_OK) {
54          GST_WARNING_OBJECT (h264parse, "failed to parse SPS:");
55 +        return FALSE;
56 +      }
57  
58        GST_DEBUG_OBJECT (h264parse, "triggering src caps check");
59        h264parse->update_caps = TRUE;
60 @@ -575,12 +577,18 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu)
61        h264parse->state |= GST_H264_PARSE_STATE_GOT_SPS;
62        break;
63      case GST_H264_NAL_PPS:
64 +      /* expected state: got-sps */
65        h264parse->state &= GST_H264_PARSE_STATE_GOT_SPS;
66 +      if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS))
67 +        return FALSE;
68  
69        pres = gst_h264_parser_parse_pps (nalparser, nalu, &pps);
70        /* arranged for a fallback pps.id, so use that one and only warn */
71 -      if (pres != GST_H264_PARSER_OK)
72 +      if (pres != GST_H264_PARSER_OK) {
73          GST_WARNING_OBJECT (h264parse, "failed to parse PPS:");
74 +        if (pres != GST_H264_PARSER_BROKEN_LINK)
75 +          return FALSE;
76 +      }
77  
78        /* parameters might have changed, force caps check */
79        if (!h264parse->have_pps) {
80 @@ -601,6 +609,10 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu)
81        h264parse->state |= GST_H264_PARSE_STATE_GOT_PPS;
82        break;
83      case GST_H264_NAL_SEI:
84 +      /* expected state: got-sps */
85 +      if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS))
86 +        return FALSE;
87 +
88        gst_h264_parse_process_sei (h264parse, nalu);
89        /* mark SEI pos */
90        if (h264parse->sei_pos == -1) {
91 @@ -618,7 +630,11 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu)
92      case GST_H264_NAL_SLICE_DPB:
93      case GST_H264_NAL_SLICE_DPC:
94      case GST_H264_NAL_SLICE_IDR:
95 +      /* expected state: got-sps|got-pps (valid picture headers) */
96        h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS;
97 +      if (!GST_H264_PARSE_STATE_VALID (h264parse,
98 +              GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS))
99 +        return FALSE;
100  
101        /* don't need to parse the whole slice (header) here */
102        if (*(nalu->data + nalu->offset + 1) & 0x80) {
103 @@ -668,7 +684,14 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu)
104        }
105        break;
106      default:
107 -      gst_h264_parser_parse_nal (nalparser, nalu);
108 +      /* drop anything before the initial SPS */
109 +      if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS))
110 +        return FALSE;
111 +
112 +      pres = gst_h264_parser_parse_nal (nalparser, nalu);
113 +      if (pres != GST_H264_PARSER_OK)
114 +        return FALSE;
115 +      break;
116    }
117  
118    /* if AVC output needed, collect properly prefixed nal in adapter,
119 @@ -681,6 +704,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu)
120          nalu->data + nalu->offset, nalu->size);
121      gst_adapter_push (h264parse->frame_out, buf);
122    }
123 +  return TRUE;
124  }
125  
126  /* caller guarantees at least 2 bytes of nal payload for each nal
127 @@ -988,14 +1012,9 @@ gst_h264_parse_handle_frame (GstBaseParse * parse,
128        }
129      }
130  
131 -    if (nalu.type == GST_H264_NAL_SPS ||
132 -        nalu.type == GST_H264_NAL_PPS ||
133 -        GST_H264_PARSE_STATE_VALID (h264parse,
134 -            GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS)) {
135 -      gst_h264_parse_process_nal (h264parse, &nalu);
136 -    } else {
137 +    if (!gst_h264_parse_process_nal (h264parse, &nalu)) {
138        GST_WARNING_OBJECT (h264parse,
139 -          "no SPS/PPS yet, nal Type: %d %s, Size: %u will be dropped",
140 +          "broken/invalid nal Type: %d %s, Size: %u will be dropped",
141            nalu.type, _nal_name (nalu.type), nalu.size);
142        *skipsize = nalu.size;
143        goto skip;
144 -- 
145 1.7.9.5
146