closedcaption: move cdp->cc_data into shared location
authorMatthew Waters <matthew@centricular.com>
Mon, 30 May 2022 11:39:13 +0000 (21:39 +1000)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Thu, 10 Nov 2022 00:52:14 +0000 (00:52 +0000)
So it can be used by both ccconverter and cccombiner

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3211>

subprojects/gst-plugins-bad/ext/closedcaption/ccutils.c
subprojects/gst-plugins-bad/ext/closedcaption/ccutils.h
subprojects/gst-plugins-bad/ext/closedcaption/gstcccombiner.c
subprojects/gst-plugins-bad/ext/closedcaption/gstccconverter.c

index fa2559d..cf1585b 100644 (file)
@@ -180,3 +180,156 @@ convert_cea708_cc_data_to_cdp (GstObject * dbg_obj, GstCCCDPMode cdp_mode,
 
   return len;
 }
+
+/* Converts CDP into raw CEA708 cc_data */
+guint
+convert_cea708_cdp_to_cc_data (GstObject * dbg_obj,
+    const guint8 * cdp, guint cdp_len, guint8 * cc_data,
+    GstVideoTimeCode * tc, const cdp_fps_entry ** out_fps_entry)
+{
+  GstByteReader br;
+  guint16 u16;
+  guint8 u8;
+  guint8 flags;
+  guint len = 0;
+  const struct cdp_fps_entry *fps_entry;
+
+  *out_fps_entry = &null_fps_entry;
+  memset (tc, 0, sizeof (*tc));
+
+  /* Header + footer length */
+  if (cdp_len < 11) {
+    GST_WARNING_OBJECT (dbg_obj, "cdp packet too short (%u). expected at "
+        "least %u", cdp_len, 11);
+    return 0;
+  }
+
+  gst_byte_reader_init (&br, cdp, cdp_len);
+  u16 = gst_byte_reader_get_uint16_be_unchecked (&br);
+  if (u16 != 0x9669) {
+    GST_WARNING_OBJECT (dbg_obj, "cdp packet does not have initial magic bytes "
+        "of 0x9669");
+    return 0;
+  }
+
+  u8 = gst_byte_reader_get_uint8_unchecked (&br);
+  if (u8 != cdp_len) {
+    GST_WARNING_OBJECT (dbg_obj, "cdp packet length (%u) does not match passed "
+        "in value (%u)", u8, cdp_len);
+    return 0;
+  }
+
+  u8 = gst_byte_reader_get_uint8_unchecked (&br);
+  fps_entry = cdp_fps_entry_from_id (u8);
+  if (!fps_entry || fps_entry->fps_n == 0) {
+    GST_WARNING_OBJECT (dbg_obj, "cdp packet does not have a valid framerate "
+        "id (0x%02x", u8);
+    return 0;
+  }
+
+  flags = gst_byte_reader_get_uint8_unchecked (&br);
+  /* No cc_data? */
+  if ((flags & 0x40) == 0) {
+    GST_DEBUG_OBJECT (dbg_obj, "cdp packet does have any cc_data");
+    return 0;
+  }
+
+  /* cdp_hdr_sequence_cntr */
+  gst_byte_reader_skip_unchecked (&br, 2);
+
+  /* time_code_present */
+  if (flags & 0x80) {
+    guint8 hours, minutes, seconds, frames, fields;
+    gboolean drop_frame;
+
+    if (gst_byte_reader_get_remaining (&br) < 5) {
+      GST_WARNING_OBJECT (dbg_obj, "cdp packet does not have enough data to "
+          "contain a timecode (%u). Need at least 5 bytes",
+          gst_byte_reader_get_remaining (&br));
+      return 0;
+    }
+    u8 = gst_byte_reader_get_uint8_unchecked (&br);
+    if (u8 != 0x71) {
+      GST_WARNING_OBJECT (dbg_obj, "cdp packet does not have timecode start "
+          "byte of 0x71, found 0x%02x", u8);
+      return 0;
+    }
+
+    u8 = gst_byte_reader_get_uint8_unchecked (&br);
+    if ((u8 & 0xc0) != 0xc0) {
+      GST_WARNING_OBJECT (dbg_obj, "reserved bits are not 0xc0, found 0x%02x",
+          u8);
+      return 0;
+    }
+
+    hours = ((u8 >> 4) & 0x3) * 10 + (u8 & 0xf);
+
+    u8 = gst_byte_reader_get_uint8_unchecked (&br);
+    if ((u8 & 0x80) != 0x80) {
+      GST_WARNING_OBJECT (dbg_obj, "reserved bit is not 0x80, found 0x%02x",
+          u8);
+      return 0;
+    }
+    minutes = ((u8 >> 4) & 0x7) * 10 + (u8 & 0xf);
+
+    u8 = gst_byte_reader_get_uint8_unchecked (&br);
+    if (u8 & 0x80)
+      fields = 2;
+    else
+      fields = 1;
+    seconds = ((u8 >> 4) & 0x7) * 10 + (u8 & 0xf);
+
+    u8 = gst_byte_reader_get_uint8_unchecked (&br);
+    if (u8 & 0x40) {
+      GST_WARNING_OBJECT (dbg_obj, "reserved bit is not 0x0, found 0x%02x", u8);
+      return 0;
+    }
+
+    drop_frame = !(!(u8 & 0x80));
+    frames = ((u8 >> 4) & 0x3) * 10 + (u8 & 0xf);
+
+    gst_video_time_code_init (tc, fps_entry->fps_n, fps_entry->fps_d, NULL,
+        drop_frame ? GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME :
+        GST_VIDEO_TIME_CODE_FLAGS_NONE, hours, minutes, seconds, frames,
+        fields);
+  }
+
+  /* ccdata_present */
+  if (flags & 0x40) {
+    guint8 cc_count;
+
+    if (gst_byte_reader_get_remaining (&br) < 2) {
+      GST_WARNING_OBJECT (dbg_obj, "not enough data to contain valid cc_data");
+      return 0;
+    }
+    u8 = gst_byte_reader_get_uint8_unchecked (&br);
+    if (u8 != 0x72) {
+      GST_WARNING_OBJECT (dbg_obj, "missing cc_data start code of 0x72, "
+          "found 0x%02x", u8);
+      return 0;
+    }
+
+    cc_count = gst_byte_reader_get_uint8_unchecked (&br);
+    if ((cc_count & 0xe0) != 0xe0) {
+      GST_WARNING_OBJECT (dbg_obj, "reserved bits are not 0xe0, found 0x%02x",
+          u8);
+      return 0;
+    }
+    cc_count &= 0x1f;
+
+    len = 3 * cc_count;
+    if (gst_byte_reader_get_remaining (&br) < len) {
+      GST_WARNING_OBJECT (dbg_obj, "not enough bytes (%u) left for the "
+          "number of byte triples (%u)", gst_byte_reader_get_remaining (&br),
+          cc_count);
+      return 0;
+    }
+
+    memcpy (cc_data, gst_byte_reader_get_data_unchecked (&br, len), len);
+  }
+
+  *out_fps_entry = fps_entry;
+
+  /* skip everything else we don't care about */
+  return len;
+}
index 1e3029e..391d12f 100644 (file)
@@ -60,6 +60,15 @@ guint           convert_cea708_cc_data_to_cdp  (GstObject * dbg_obj,
                                                 const GstVideoTimeCode * tc,
                                                 const struct cdp_fps_entry *fps_entry);
 
+guint           convert_cea708_cdp_to_cc_data  (GstObject * dbg_obj,
+                                                const guint8 * cdp,
+                                                guint cdp_len,
+                                                guint8 *cc_data,
+                                                GstVideoTimeCode * tc,
+                                                const struct cdp_fps_entry **out_fps_entry);
+
+#define MAX_CDP_PACKET_LEN 256
+
 G_END_DECLS
 
 #endif
index b04b513..ddb4796 100644 (file)
@@ -109,88 +109,17 @@ gst_cc_combiner_finalize (GObject * object)
 
 #define GST_FLOW_NEED_DATA GST_FLOW_CUSTOM_SUCCESS
 
-static const guint8 *
-extract_cdp (const guint8 * cdp, guint cdp_len, guint * cc_data_len)
+static guint
+extract_cdp (GstCCCombiner * self, const guint8 * cdp, guint cdp_len,
+    guint8 * cc_data)
 {
-  GstByteReader br;
-  guint16 u16;
-  guint8 u8;
-  guint8 flags;
-  guint len = 0;
-  const guint8 *cc_data = NULL;
+  const struct cdp_fps_entry *out_fps_entry;
+  GstVideoTimeCode tc = GST_VIDEO_TIME_CODE_INIT;
 
-  *cc_data_len = 0;
-
-  /* Header + footer length */
-  if (cdp_len < 11) {
-    goto done;
-  }
-
-  gst_byte_reader_init (&br, cdp, cdp_len);
-  u16 = gst_byte_reader_get_uint16_be_unchecked (&br);
-  if (u16 != 0x9669) {
-    goto done;
-  }
-
-  u8 = gst_byte_reader_get_uint8_unchecked (&br);
-  if (u8 != cdp_len) {
-    goto done;
-  }
-
-  gst_byte_reader_skip_unchecked (&br, 1);
-
-  flags = gst_byte_reader_get_uint8_unchecked (&br);
-
-  /* No cc_data? */
-  if ((flags & 0x40) == 0) {
-    goto done;
-  }
-
-  /* cdp_hdr_sequence_cntr */
-  gst_byte_reader_skip_unchecked (&br, 2);
-
-  /* time_code_present */
-  if (flags & 0x80) {
-    if (gst_byte_reader_get_remaining (&br) < 5) {
-      goto done;
-    }
-    gst_byte_reader_skip_unchecked (&br, 5);
-  }
-
-  /* ccdata_present */
-  if (flags & 0x40) {
-    guint8 cc_count;
-
-    if (gst_byte_reader_get_remaining (&br) < 2) {
-      goto done;
-    }
-    u8 = gst_byte_reader_get_uint8_unchecked (&br);
-    if (u8 != 0x72) {
-      goto done;
-    }
-
-    cc_count = gst_byte_reader_get_uint8_unchecked (&br);
-    if ((cc_count & 0xe0) != 0xe0) {
-      goto done;
-    }
-    cc_count &= 0x1f;
-
-    if (cc_count == 0)
-      return 0;
-
-    len = 3 * cc_count;
-    if (gst_byte_reader_get_remaining (&br) < len)
-      goto done;
-
-    cc_data = gst_byte_reader_get_data_unchecked (&br, len);
-    *cc_data_len = len;
-  }
-
-done:
-  return cc_data;
+  return convert_cea708_cdp_to_cc_data (GST_OBJECT (self), cdp, cdp_len,
+      cc_data, &tc, &out_fps_entry);
 }
 
-#define MAX_CDP_PACKET_LEN 256
 #define MAX_CEA608_LEN 32
 #define CDP_MODE (GST_CC_CDP_MODE_CC_DATA | GST_CC_CDP_MODE_TIME_CODE)
 
@@ -331,11 +260,12 @@ static void
 schedule_cdp (GstCCCombiner * self, const GstVideoTimeCode * tc,
     const guint8 * data, guint len, GstClockTime pts, GstClockTime duration)
 {
-  const guint8 *cc_data;
+  guint8 cc_data[MAX_CDP_PACKET_LEN];
   guint cc_data_len;
   gboolean inject = FALSE;
 
-  if ((cc_data = extract_cdp (data, len, &cc_data_len))) {
+  cc_data_len = extract_cdp (self, data, len, cc_data);
+  if (cc_data_len > 0) {
     guint8 i;
 
     for (i = 0; i < cc_data_len / 3; i++) {
index 9fcbc89..c87aeab 100644 (file)
@@ -1119,155 +1119,6 @@ convert_cea708_cc_data_cea708_cdp_internal (GstCCConverter * self,
   return ret;
 }
 
-/* Converts CDP into raw CEA708 cc_data */
-static guint
-convert_cea708_cdp_cea708_cc_data_internal (GstCCConverter * self,
-    const guint8 * cdp, guint cdp_len, guint8 cc_data[MAX_CDP_PACKET_LEN],
-    GstVideoTimeCode * tc, const struct cdp_fps_entry **out_fps_entry)
-{
-  GstByteReader br;
-  guint16 u16;
-  guint8 u8;
-  guint8 flags;
-  guint len = 0;
-  const struct cdp_fps_entry *fps_entry;
-
-  *out_fps_entry = &null_fps_entry;
-  memset (tc, 0, sizeof (*tc));
-
-  /* Header + footer length */
-  if (cdp_len < 11) {
-    GST_WARNING_OBJECT (self, "cdp packet too short (%u). expected at "
-        "least %u", cdp_len, 11);
-    return 0;
-  }
-
-  gst_byte_reader_init (&br, cdp, cdp_len);
-  u16 = gst_byte_reader_get_uint16_be_unchecked (&br);
-  if (u16 != 0x9669) {
-    GST_WARNING_OBJECT (self, "cdp packet does not have initial magic bytes "
-        "of 0x9669");
-    return 0;
-  }
-
-  u8 = gst_byte_reader_get_uint8_unchecked (&br);
-  if (u8 != cdp_len) {
-    GST_WARNING_OBJECT (self, "cdp packet length (%u) does not match passed "
-        "in value (%u)", u8, cdp_len);
-    return 0;
-  }
-
-  u8 = gst_byte_reader_get_uint8_unchecked (&br);
-  fps_entry = cdp_fps_entry_from_id (u8);
-  if (!fps_entry || fps_entry->fps_n == 0) {
-    GST_WARNING_OBJECT (self, "cdp packet does not have a valid framerate "
-        "id (0x%02x", u8);
-    return 0;
-  }
-
-  flags = gst_byte_reader_get_uint8_unchecked (&br);
-  /* No cc_data? */
-  if ((flags & 0x40) == 0) {
-    GST_DEBUG_OBJECT (self, "cdp packet does have any cc_data");
-    return 0;
-  }
-
-  /* cdp_hdr_sequence_cntr */
-  gst_byte_reader_skip_unchecked (&br, 2);
-
-  /* time_code_present */
-  if (flags & 0x80) {
-    guint8 hours, minutes, seconds, frames, fields;
-    gboolean drop_frame;
-
-    if (gst_byte_reader_get_remaining (&br) < 5) {
-      GST_WARNING_OBJECT (self, "cdp packet does not have enough data to "
-          "contain a timecode (%u). Need at least 5 bytes",
-          gst_byte_reader_get_remaining (&br));
-      return 0;
-    }
-    u8 = gst_byte_reader_get_uint8_unchecked (&br);
-    if (u8 != 0x71) {
-      GST_WARNING_OBJECT (self, "cdp packet does not have timecode start byte "
-          "of 0x71, found 0x%02x", u8);
-      return 0;
-    }
-
-    u8 = gst_byte_reader_get_uint8_unchecked (&br);
-    if ((u8 & 0xc0) != 0xc0) {
-      GST_WARNING_OBJECT (self, "reserved bits are not 0xc0, found 0x%02x", u8);
-      return 0;
-    }
-
-    hours = ((u8 >> 4) & 0x3) * 10 + (u8 & 0xf);
-
-    u8 = gst_byte_reader_get_uint8_unchecked (&br);
-    if ((u8 & 0x80) != 0x80) {
-      GST_WARNING_OBJECT (self, "reserved bit is not 0x80, found 0x%02x", u8);
-      return 0;
-    }
-    minutes = ((u8 >> 4) & 0x7) * 10 + (u8 & 0xf);
-
-    u8 = gst_byte_reader_get_uint8_unchecked (&br);
-    if (u8 & 0x80)
-      fields = 2;
-    else
-      fields = 1;
-    seconds = ((u8 >> 4) & 0x7) * 10 + (u8 & 0xf);
-
-    u8 = gst_byte_reader_get_uint8_unchecked (&br);
-    if (u8 & 0x40) {
-      GST_WARNING_OBJECT (self, "reserved bit is not 0x0, found 0x%02x", u8);
-      return 0;
-    }
-
-    drop_frame = !(!(u8 & 0x80));
-    frames = ((u8 >> 4) & 0x3) * 10 + (u8 & 0xf);
-
-    gst_video_time_code_init (tc, fps_entry->fps_n, fps_entry->fps_d, NULL,
-        drop_frame ? GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME :
-        GST_VIDEO_TIME_CODE_FLAGS_NONE, hours, minutes, seconds, frames,
-        fields);
-  }
-
-  /* ccdata_present */
-  if (flags & 0x40) {
-    guint8 cc_count;
-
-    if (gst_byte_reader_get_remaining (&br) < 2) {
-      GST_WARNING_OBJECT (self, "not enough data to contain valid cc_data");
-      return 0;
-    }
-    u8 = gst_byte_reader_get_uint8_unchecked (&br);
-    if (u8 != 0x72) {
-      GST_WARNING_OBJECT (self, "missing cc_data start code of 0x72, "
-          "found 0x%02x", u8);
-      return 0;
-    }
-
-    cc_count = gst_byte_reader_get_uint8_unchecked (&br);
-    if ((cc_count & 0xe0) != 0xe0) {
-      GST_WARNING_OBJECT (self, "reserved bits are not 0xe0, found 0x%02x", u8);
-      return 0;
-    }
-    cc_count &= 0x1f;
-
-    len = 3 * cc_count;
-    if (gst_byte_reader_get_remaining (&br) < len) {
-      GST_WARNING_OBJECT (self, "not enough bytes (%u) left for the number of "
-          "byte triples (%u)", gst_byte_reader_get_remaining (&br), cc_count);
-      return 0;
-    }
-
-    memcpy (cc_data, gst_byte_reader_get_data_unchecked (&br, len), len);
-  }
-
-  *out_fps_entry = fps_entry;
-
-  /* skip everything else we don't care about */
-  return len;
-}
-
 static gboolean
 copy_from_stored_data (GstCCConverter * self, guint8 * out_ccp,
     guint * ccp_size, guint8 * cea608_1, guint * cea608_1_len,
@@ -1464,7 +1315,7 @@ cdp_to_cea608_cc_data (GstCCConverter * self, GstBuffer * inbuf,
     gst_buffer_map (inbuf, &in, GST_MAP_READ);
 
     cc_data_len =
-        convert_cea708_cdp_cea708_cc_data_internal (self, in.data, in.size,
+        convert_cea708_cdp_to_cc_data (GST_OBJECT (self), in.data, in.size,
         cc_data, out_tc, in_fps_entry);
 
     gst_buffer_unmap (inbuf, &in);