summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2009-10-08 13:39:25 +0200
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2009-10-09 17:49:10 +0200
commit674b0c4289fcdab6fdf8d6a7ccf2921931e2524b (patch)
treed3335133d4075623f4d27e011dfba742069c2d7e
parentb2d70862e8c642ddf7c7d4af73ead3f168b55810 (diff)
qtdemux: extract palette data for dvd subpicture streams
... and send it downstream using custom dvd event
-rw-r--r--gst/qtdemux/qtdemux.c63
1 files changed, 62 insertions, 1 deletions
diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c
index fcedaf95..f41c71e8 100644
--- a/gst/qtdemux/qtdemux.c
+++ b/gst/qtdemux/qtdemux.c
@@ -245,6 +245,8 @@ struct _QtDemuxStream
gboolean sent_eos;
GstTagList *pending_tags;
gboolean send_global_tags;
+
+ GstEvent *pending_event;
};
enum QtDemuxState
@@ -2263,8 +2265,18 @@ gst_qtdemux_process_buffer (GstQTDemux * qtdemux, QtDemuxStream * stream,
size = GST_BUFFER_SIZE (buf);
/* not many cases for now */
- if (stream->fourcc != FOURCC_tx3g)
+ if (G_UNLIKELY (stream->fourcc == FOURCC_mp4s)) {
+ /* send a one time dvd clut event */
+ if (stream->pending_event && stream->pad)
+ gst_pad_push_event (stream->pad, stream->pending_event);
+ stream->pending_event = NULL;
+ /* no further processing needed */
+ stream->need_process = FALSE;
+ }
+
+ if (G_UNLIKELY (stream->fourcc != FOURCC_tx3g)) {
return buf;
+ }
if (G_LIKELY (size >= 2)) {
nsize = GST_READ_UINT16_BE (data);
@@ -4839,6 +4851,55 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
g_free (codec);
codec = NULL;
}
+
+ /* hunt for sort-of codec data */
+ switch (fourcc) {
+ case FOURCC_mp4s:
+ {
+ guint len;
+ const guint8 *data;
+
+ /* look for palette */
+ /* target mp4s atom */
+ len = QT_UINT32 (stsd_data + offset);
+ data = stsd_data + offset;
+ /* verify sufficient length,
+ * and esds present with decConfigDescr of expected size and position */
+ if ((len >= 106 + 8) && (QT_FOURCC (data + 8 + 8 + 4) == FOURCC_esds) &&
+ (QT_UINT16 (data + 8 + 40) == 0x0540)) {
+ GstStructure *s;
+ guint32 clut[16];
+ gint i;
+
+ /* move to decConfigDescr data */
+ data = data + 8 + 42;
+ for (i = 0; i < 16; i++) {
+ clut[i] = QT_UINT32 (data);
+ data += 4;
+ }
+
+ s = gst_structure_new ("application/x-gst-dvd", "event",
+ G_TYPE_STRING, "dvd-spu-clut-change",
+ "clut00", G_TYPE_INT, clut[0], "clut01", G_TYPE_INT, clut[1],
+ "clut02", G_TYPE_INT, clut[2], "clut03", G_TYPE_INT, clut[3],
+ "clut04", G_TYPE_INT, clut[4], "clut05", G_TYPE_INT, clut[5],
+ "clut06", G_TYPE_INT, clut[6], "clut07", G_TYPE_INT, clut[7],
+ "clut08", G_TYPE_INT, clut[8], "clut09", G_TYPE_INT, clut[9],
+ "clut10", G_TYPE_INT, clut[10], "clut11", G_TYPE_INT, clut[11],
+ "clut12", G_TYPE_INT, clut[12], "clut13", G_TYPE_INT, clut[13],
+ "clut14", G_TYPE_INT, clut[14], "clut15", G_TYPE_INT, clut[15],
+ NULL);
+
+ /* store event and trigger custom processing */
+ stream->pending_event =
+ gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
+ stream->need_process = TRUE;
+ }
+ break;
+ }
+ default:
+ break;
+ }
} else {
goto unknown_stream;
}