diff options
author | Edward Hervey <edward@centricular.com> | 2018-03-08 14:34:13 +0100 |
---|---|---|
committer | Edward Hervey <bilboed@bilboed.com> | 2018-03-09 12:11:23 +0100 |
commit | a891137583db6adab820e3c6c1e38fe8c56d5f44 (patch) | |
tree | 0ee016f45b3cfd70282472c3c1754371744e0636 | |
parent | ac840248106c62cedc2814ca0fd43598968f3e13 (diff) |
qtdemux: More WIP CC support
-rw-r--r-- | gst/isomp4/qtdemux.c | 82 |
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; |