gst/h264parse/gsth264parse.c: Parse NAL units in forward mode to mark delta units...
authorJulien Moutte <julien@moutte.net>
Tue, 22 Jan 2008 17:43:35 +0000 (17:43 +0000)
committerJulien Moutte <julien@moutte.net>
Tue, 22 Jan 2008 17:43:35 +0000 (17:43 +0000)
Original commit message from CVS:
2008-01-22  Julien Moutte  <julien@fluendo.com>

* gst/h264parse/gsth264parse.c: (gst_h264_parse_chain_forward):
Parse NAL units in forward mode to mark delta units flags.

ChangeLog
gst/h264parse/gsth264parse.c

index 73151b8e54e3f3963d4ee602678162b6d909a36b..da151b47ba8af49e15d9132e64453adbe309a6aa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-01-22  Julien Moutte  <julien@fluendo.com>
+
+       * gst/h264parse/gsth264parse.c: (gst_h264_parse_chain_forward):
+       Parse NAL units in forward mode to mark delta units flags.
+
 2008-01-22  Stefan Kost  <ensonic@users.sf.net>
 
        * docs/plugins/gst-plugins-bad-plugins-docs.sgml:
index 241c4fd1ed5d2cb22456515b0f930d681068228f..f40d83cd48f15fba498702355e6276933c40bf58 100644 (file)
@@ -395,6 +395,7 @@ gst_h264_parse_chain_forward (GstH264Parse * h264parse, gboolean discont,
     gint next_nalu_pos = -1;
     guint32 nalu_size;
     gint avail;
+    gboolean delta_unit = TRUE;
 
     avail = gst_adapter_available (h264parse->adapter);
     if (avail < 5)
@@ -424,6 +425,59 @@ gst_h264_parse_chain_forward (GstH264Parse * h264parse, gboolean discont,
         next_nalu_pos = avail;
       }
     }
+    /* Figure out if this is a delta unit */
+    {
+      gint nal_type = (data[4] & 0x1f);
+      gint nal_ref_idc = (data[4] & 0x60) >> 5;
+
+      GST_DEBUG_OBJECT (h264parse, "NAL type: %d, ref_idc: %d", nal_type,
+          nal_ref_idc);
+
+      /* first parse some things needed to get to the frame type */
+      if (nal_type >= NAL_SLICE && nal_type <= NAL_SLICE_IDR) {
+        GstNalBs bs;
+        gint first_mb_in_slice, slice_type;
+        guint8 *bs_data = (guint8 *) data + 5;
+
+        gst_nal_bs_init (&bs, bs_data, avail - 5);
+
+        first_mb_in_slice = gst_nal_bs_read_ue (&bs);
+        slice_type = gst_nal_bs_read_ue (&bs);
+
+        GST_DEBUG_OBJECT (h264parse, "first MB: %d, slice type: %d",
+            first_mb_in_slice, slice_type);
+
+        switch (slice_type) {
+          case 0:
+          case 5:
+          case 3:
+          case 8:              /* SP */
+            /* P frames */
+            GST_DEBUG_OBJECT (h264parse, "we have a P slice");
+            delta_unit = TRUE;
+            break;
+          case 1:
+          case 6:
+            /* B frames */
+            GST_DEBUG_OBJECT (h264parse, "we have a B slice");
+            delta_unit = TRUE;
+            break;
+          case 2:
+          case 7:
+          case 4:
+          case 9:
+            /* I frames */
+            GST_DEBUG_OBJECT (h264parse, "we have an I slice");
+            delta_unit = FALSE;
+            break;
+        }
+      } else if (nal_type >= NAL_SPS && nal_type <= NAL_PPS) {
+        /* This can be considered as a non delta unit */
+        GST_DEBUG_OBJECT (h264parse, "we have a SPS or PPS NAL");
+        delta_unit = FALSE;
+      }
+    }
+
     /* we have a packet */
     if (next_nalu_pos > 0) {
       GstBuffer *outbuf;
@@ -439,6 +493,10 @@ gst_h264_parse_chain_forward (GstH264Parse * h264parse, gboolean discont,
         h264parse->discont = FALSE;
       }
 
+      if (delta_unit) {
+        GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
+      }
+
       gst_buffer_set_caps (outbuf, GST_PAD_CAPS (h264parse->srcpad));
       GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer);
       res = gst_pad_push (h264parse->srcpad, outbuf);