summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/plugins/gst_plugins_cache.json35
-rw-r--r--ext/closedcaption/gstccconverter.c132
-rw-r--r--ext/closedcaption/gstccconverter.h8
3 files changed, 162 insertions, 13 deletions
diff --git a/docs/plugins/gst_plugins_cache.json b/docs/plugins/gst_plugins_cache.json
index 5248eb83b..71d8f72c4 100644
--- a/docs/plugins/gst_plugins_cache.json
+++ b/docs/plugins/gst_plugins_cache.json
@@ -3346,7 +3346,20 @@
"presence": "always"
}
},
- "properties": {},
+ "properties": {
+ "cdp-mode": {
+ "blurb": "Select which CDP sections to store in CDP packets",
+ "conditionally-available": false,
+ "construct": false,
+ "construct-only": false,
+ "controllable": false,
+ "default": "cc-svc-info+cc-data+time-code",
+ "mutable": "null",
+ "readable": true,
+ "type": "GstCCConverterCDPMode",
+ "writable": true
+ }
+ },
"rank": "none"
},
"ccextractor": {
@@ -3470,6 +3483,26 @@
"filename": "gstclosedcaption",
"license": "LGPL",
"other-types": {
+ "GstCCConverterCDPMode": {
+ "kind": "flags",
+ "values": [
+ {
+ "desc": "Store time code information in CDP packets",
+ "name": "time-code",
+ "value": "0x00000001"
+ },
+ {
+ "desc": "Store CC data in CDP packets",
+ "name": "cc-data",
+ "value": "0x00000002"
+ },
+ {
+ "desc": "Store CC service information in CDP packets",
+ "name": "cc-svc-info",
+ "value": "0x00000004"
+ }
+ ]
+ },
"GstCeaCcOverlayWinHPos": {
"kind": "enum",
"values": [
diff --git a/ext/closedcaption/gstccconverter.c b/ext/closedcaption/gstccconverter.c
index 43073fb3f..fe6aadd4c 100644
--- a/ext/closedcaption/gstccconverter.c
+++ b/ext/closedcaption/gstccconverter.c
@@ -33,6 +33,23 @@
GST_DEBUG_CATEGORY_STATIC (gst_cc_converter_debug);
#define GST_CAT_DEFAULT gst_cc_converter_debug
+/**
+ * GstCCConverterCDPMode:
+ * @GST_CC_CONVERTER_CDP_MODE_TIME_CODE: Store time code information in CDP packets
+ * @GST_CC_CONVERTER_CDP_MODE_CC_DATA: Store CC data in CDP packets
+ * @GST_CC_CONVERTER_CDP_MODE_CC_SVC_INFO: Store CC service information in CDP packets
+ *
+ * Since: 1.20
+ */
+
+enum
+{
+ PROP_0,
+ PROP_CDP_MODE,
+};
+
+#define DEFAULT_CDP_MODE (GST_CC_CONVERTER_CDP_MODE_TIME_CODE | GST_CC_CONVERTER_CDP_MODE_CC_DATA | GST_CC_CONVERTER_CDP_MODE_CC_SVC_INFO)
+
/* Ordered by the amount of information they can contain */
#define CC_CAPS \
"closedcaption/x-cea-708,format=(string) cdp; " \
@@ -55,6 +72,32 @@ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
G_DEFINE_TYPE (GstCCConverter, gst_cc_converter, GST_TYPE_BASE_TRANSFORM);
#define parent_class gst_cc_converter_parent_class
+#define GST_TYPE_CC_CONVERTER_CDP_MODE (gst_cc_converter_cdp_mode_get_type())
+static GType
+gst_cc_converter_cdp_mode_get_type (void)
+{
+ static const GFlagsValue values[] = {
+ {GST_CC_CONVERTER_CDP_MODE_TIME_CODE,
+ "Store time code information in CDP packets", "time-code"},
+ {GST_CC_CONVERTER_CDP_MODE_CC_DATA, "Store CC data in CDP packets",
+ "cc-data"},
+ {GST_CC_CONVERTER_CDP_MODE_CC_SVC_INFO,
+ "Store CC service information in CDP packets", "cc-svc-info"},
+ {0, NULL, NULL}
+ };
+ static volatile GType id = 0;
+
+ if (g_once_init_enter ((gsize *) & id)) {
+ GType _id;
+
+ _id = g_flags_register_static ("GstCCConverterCDPMode", values);
+
+ g_once_init_leave ((gsize *) & id, _id);
+ }
+
+ return id;
+}
+
static gboolean
gst_cc_converter_transform_size (GstBaseTransform * base,
GstPadDirection direction,
@@ -1001,11 +1044,16 @@ convert_cea708_cc_data_cea708_cdp_internal (GstCCConverter * self,
cc_data_len = 3 * fps_entry->max_cc_count;
}
- /* ccdata_present | caption_service_active */
- flags = 0x42;
+ /* caption_service_active */
+ flags = 0x02;
+
+ /* ccdata_present */
+ if ((self->cdp_mode & GST_CC_CONVERTER_CDP_MODE_CC_DATA))
+ flags |= 0x40;
/* time_code_present */
- if (tc && tc->config.fps_n > 0)
+ if ((self->cdp_mode & GST_CC_CONVERTER_CDP_MODE_TIME_CODE) && tc
+ && tc->config.fps_n > 0)
flags |= 0x80;
/* reserved */
@@ -1015,7 +1063,8 @@ convert_cea708_cc_data_cea708_cdp_internal (GstCCConverter * self,
gst_byte_writer_put_uint16_be_unchecked (&bw, self->cdp_hdr_sequence_cntr);
- if (tc && tc->config.fps_n > 0) {
+ if ((self->cdp_mode & GST_CC_CONVERTER_CDP_MODE_TIME_CODE) && tc
+ && tc->config.fps_n > 0) {
guint8 u8;
gst_byte_writer_put_uint8_unchecked (&bw, 0x71);
@@ -1054,14 +1103,16 @@ convert_cea708_cc_data_cea708_cdp_internal (GstCCConverter * self,
gst_byte_writer_put_uint8_unchecked (&bw, u8);
}
- gst_byte_writer_put_uint8_unchecked (&bw, 0x72);
- gst_byte_writer_put_uint8_unchecked (&bw, 0xe0 | fps_entry->max_cc_count);
- gst_byte_writer_put_data_unchecked (&bw, cc_data, cc_data_len);
- while (fps_entry->max_cc_count > cc_data_len / 3) {
- gst_byte_writer_put_uint8_unchecked (&bw, 0xfa);
- gst_byte_writer_put_uint8_unchecked (&bw, 0x00);
- gst_byte_writer_put_uint8_unchecked (&bw, 0x00);
- cc_data_len += 3;
+ if ((self->cdp_mode & GST_CC_CONVERTER_CDP_MODE_CC_DATA)) {
+ gst_byte_writer_put_uint8_unchecked (&bw, 0x72);
+ gst_byte_writer_put_uint8_unchecked (&bw, 0xe0 | fps_entry->max_cc_count);
+ gst_byte_writer_put_data_unchecked (&bw, cc_data, cc_data_len);
+ while (fps_entry->max_cc_count > cc_data_len / 3) {
+ gst_byte_writer_put_uint8_unchecked (&bw, 0xfa);
+ gst_byte_writer_put_uint8_unchecked (&bw, 0x00);
+ gst_byte_writer_put_uint8_unchecked (&bw, 0x00);
+ cc_data_len += 3;
+ }
}
gst_byte_writer_put_uint8_unchecked (&bw, 0x74);
@@ -2436,14 +2487,68 @@ gst_cc_converter_stop (GstBaseTransform * base)
}
static void
+gst_cc_converter_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstCCConverter *filter = GST_CCCONVERTER (object);
+
+ switch (prop_id) {
+ case PROP_CDP_MODE:
+ filter->cdp_mode = g_value_get_flags (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_cc_converter_get_property (GObject * object, guint prop_id, GValue * value,
+ GParamSpec * pspec)
+{
+ GstCCConverter *filter = GST_CCCONVERTER (object);
+
+ switch (prop_id) {
+ case PROP_CDP_MODE:
+ g_value_set_flags (value, filter->cdp_mode);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
gst_cc_converter_class_init (GstCCConverterClass * klass)
{
+ GObjectClass *gobject_class;
GstElementClass *gstelement_class;
GstBaseTransformClass *basetransform_class;
+ gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
basetransform_class = (GstBaseTransformClass *) klass;
+ gobject_class->set_property = gst_cc_converter_set_property;
+ gobject_class->get_property = gst_cc_converter_get_property;
+
+ /**
+ * GstCCConverter:cdp-mode
+ *
+ * Only insert the selection sections into CEA 708 CDP packets.
+ *
+ * Various software does not handle any other information than CC data
+ * contained in CDP packets and might fail parsing the packets otherwise.
+ *
+ * Since: 1.20
+ */
+ g_object_class_install_property (G_OBJECT_CLASS (klass),
+ PROP_CDP_MODE, g_param_spec_flags ("cdp-mode",
+ "CDP Mode",
+ "Select which CDP sections to store in CDP packets",
+ GST_TYPE_CC_CONVERTER_CDP_MODE, DEFAULT_CDP_MODE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
gst_element_class_set_static_metadata (gstelement_class,
"Closed Caption Converter",
"Filter/ClosedCaption",
@@ -2472,9 +2577,12 @@ gst_cc_converter_class_init (GstCCConverterClass * klass)
GST_DEBUG_CATEGORY_INIT (gst_cc_converter_debug, "ccconverter",
0, "Closed Caption converter");
+
+ gst_type_mark_as_plugin_api (GST_TYPE_CC_CONVERTER_CDP_MODE, 0);
}
static void
gst_cc_converter_init (GstCCConverter * self)
{
+ self->cdp_mode = DEFAULT_CDP_MODE;
}
diff --git a/ext/closedcaption/gstccconverter.h b/ext/closedcaption/gstccconverter.h
index 7ed6e4285..752988917 100644
--- a/ext/closedcaption/gstccconverter.h
+++ b/ext/closedcaption/gstccconverter.h
@@ -43,10 +43,18 @@ typedef struct _GstCCConverterClass GstCCConverterClass;
#define MAX_CDP_PACKET_LEN 256
#define MAX_CEA608_LEN 32
+typedef enum {
+ GST_CC_CONVERTER_CDP_MODE_TIME_CODE = (1<<0),
+ GST_CC_CONVERTER_CDP_MODE_CC_DATA = (1<<1),
+ GST_CC_CONVERTER_CDP_MODE_CC_SVC_INFO = (1<<2)
+} GstCCConverterCDPMode;
+
struct _GstCCConverter
{
GstBaseTransform parent;
+ GstCCConverterCDPMode cdp_mode;
+
GstVideoCaptionType input_caption_type;
GstVideoCaptionType output_caption_type;