summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <edward@centricular.com>2018-03-08 14:34:13 +0100
committerEdward Hervey <bilboed@bilboed.com>2018-03-09 12:11:23 +0100
commita891137583db6adab820e3c6c1e38fe8c56d5f44 (patch)
tree0ee016f45b3cfd70282472c3c1754371744e0636
parentac840248106c62cedc2814ca0fd43598968f3e13 (diff)
qtdemux: More WIP CC support
-rw-r--r--gst/isomp4/qtdemux.c82
1 files changed, 70 insertions, 12 deletions
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index 94e908701..22959931d 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -5353,6 +5353,28 @@ gst_qtdemux_align_buffer (GstQTDemux * demux,
}
static guint8 *
+convert_to_ccdata (const guint8 * ccpair, guint8 ccpair_size, guint field,
+ gsize * res)
+{
+ guint8 *storage;
+ gsize i;
+
+ /* We are converting from pairs to triplets */
+ *res = ccpair_size / 2 * 3;
+ storage = g_malloc (*res);
+ for (i = 0; i * 2 < ccpair_size; i += 1) {
+ if (field == 1)
+ storage[i * 3] = 0xfc;
+ else
+ storage[i * 3] = 0xfd;
+ storage[i * 3 + 1] = ccpair[i * 2];
+ storage[i * 3 + 2] = ccpair[i * 2 + 1];
+ }
+
+ return storage;
+}
+
+static guint8 *
extract_cc_from_data (QtDemuxStream * stream, const guint8 * data, gsize size,
gsize * cclen)
{
@@ -5362,6 +5384,8 @@ extract_cc_from_data (QtDemuxStream * stream, const guint8 * data, gsize size,
GST_MEMDUMP ("caption atom", data, size);
+ /* There might be multiple atoms */
+
*cclen = 0;
if (size < 8)
goto invalid_cdat;
@@ -5370,17 +5394,52 @@ extract_cc_from_data (QtDemuxStream * stream, const guint8 * data, gsize size,
if (G_UNLIKELY (atom_length > size || atom_length == 8))
goto invalid_cdat;
+ GST_DEBUG_OBJECT (stream->pad, "here");
+
/* Check if we have somethig compatible */
stsd_entry = CUR_STREAM (stream);
switch (stsd_entry->fourcc) {
- case FOURCC_c608:
+ case FOURCC_c608:{
+ guint8 *cdat = NULL, *cdt2 = NULL;
+ gsize cdat_size = 0, cdt2_size = 0;
/* Should be cdat or cdt2 */
- if (fourcc != FOURCC_cdat || fourcc != FOURCC_cdt2) {
+ if (fourcc != FOURCC_cdat && fourcc != FOURCC_cdt2) {
GST_WARNING_OBJECT (stream->pad,
"Unknown data atom (%" GST_FOURCC_FORMAT ") for CEA608",
GST_FOURCC_ARGS (fourcc));
goto invalid_cdat;
}
+ /* Convert to cc_data triplet */
+ if (fourcc == FOURCC_cdat)
+ cdat = convert_to_ccdata (data + 8, atom_length - 8, 1, &cdat_size);
+ else
+ cdt2 = convert_to_ccdata (data + 8, atom_length - 8, 2, &cdt2_size);
+ GST_DEBUG_OBJECT (stream->pad, "size:%" G_GSIZE_FORMAT " atom_length:%u",
+ size, atom_length);
+ /* Check for another atom ? */
+ if (size > atom_length + 8) {
+ guint32 new_atom_length = QT_UINT32 (data + atom_length);
+ if (size <= atom_length + new_atom_length) {
+ fourcc = QT_FOURCC (data + atom_length + 4);
+ if (fourcc == FOURCC_cdat)
+ cdat =
+ convert_to_ccdata (data + atom_length + 8, new_atom_length - 8,
+ 1, &cdat_size);
+ else
+ cdt2 =
+ convert_to_ccdata (data + atom_length + 8, new_atom_length - 8,
+ 2, &cdt2_size);
+ }
+ }
+ *cclen = cdat_size + cdt2_size;
+ res = g_malloc (*cclen);
+ if (cdat_size)
+ memcpy (res, cdat, cdat_size);
+ if (cdt2_size)
+ memcpy (res + cdat_size, cdt2, cdt2_size);
+ g_free (cdat);
+ g_free (cdt2);
+ }
break;
case FOURCC_c708:
if (fourcc != FOURCC_ccdp) {
@@ -5389,6 +5448,8 @@ extract_cc_from_data (QtDemuxStream * stream, const guint8 * data, gsize size,
GST_FOURCC_ARGS (fourcc));
goto invalid_cdat;
}
+ *cclen = atom_length - 8;
+ res = g_memdup (data + 8, *cclen);
break;
default:
/* Keep this here in case other closed caption formats are added */
@@ -5396,14 +5457,7 @@ extract_cc_from_data (QtDemuxStream * stream, const guint8 * data, gsize size,
break;
}
-
- if (G_UNLIKELY (atom_length > size || atom_length == 8
- || fourcc != FOURCC_cdat))
- goto invalid_cdat;
-
- *cclen = atom_length - 8;
- res = g_memdup (data + 8, *cclen);
-
+ GST_MEMDUMP ("Output", res, *cclen);
return res;
/* Errors */
@@ -14610,12 +14664,16 @@ qtdemux_sub_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
break;
case FOURCC_c608:
_codec ("CEA 608 Closed Caption");
- caps = gst_caps_new_empty_simple ("closedcaption/x-cea-608");
+ caps =
+ gst_caps_new_simple ("closedcaption/x-cea-608", "format",
+ G_TYPE_STRING, "cc_data", NULL);
stream->need_process = TRUE;
break;
case FOURCC_c708:
_codec ("CEA 708 Closed Caption");
- caps = gst_caps_new_empty_simple ("closedcaption/x-cea-708");
+ caps =
+ gst_caps_new_simple ("closedcaption/x-cea-708", "format",
+ G_TYPE_STRING, "cdp", NULL);
stream->need_process = TRUE;
break;