summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2009-04-30 14:22:27 +0200
committerWim Taymans <wim.taymans@collabora.co.uk>2009-04-30 14:22:27 +0200
commitb5d84439fd63e47f54fcbd281cd9f9aa89e756d0 (patch)
treee45430b83904bceeb7bbfb4b4d3bdc52d6bc1246
parent28afc6e59103f6f7c3d72ba7c74df3f6c883aaf4 (diff)
qtdemux: add support for subtitle pictures
Add support for subtitle pictures. Fixes #568278.
-rw-r--r--gst/qtdemux/qtdemux.c55
-rw-r--r--gst/qtdemux/qtdemux.h1
-rw-r--r--gst/qtdemux/qtdemux_fourcc.h1
3 files changed, 57 insertions, 0 deletions
diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c
index 64402051b..d18d4dfc8 100644
--- a/gst/qtdemux/qtdemux.c
+++ b/gst/qtdemux/qtdemux.c
@@ -269,12 +269,18 @@ GST_STATIC_PAD_TEMPLATE ("video_%02d",
static GstStaticPadTemplate gst_qtdemux_audiosrc_template =
GST_STATIC_PAD_TEMPLATE ("audio_%02d",
GST_PAD_SRC,
GST_PAD_SOMETIMES,
GST_STATIC_CAPS_ANY);
+static GstStaticPadTemplate gst_qtdemux_subpsrc_template =
+GST_STATIC_PAD_TEMPLATE ("subp_%02d",
+ GST_PAD_SRC,
+ GST_PAD_SOMETIMES,
+ GST_STATIC_CAPS_ANY);
+
static GstElementClass *parent_class = NULL;
static void gst_qtdemux_class_init (GstQTDemuxClass * klass);
static void gst_qtdemux_base_init (GstQTDemuxClass * klass);
static void gst_qtdemux_init (GstQTDemux * quicktime_demux);
static void gst_qtdemux_dispose (GObject * object);
@@ -300,12 +306,15 @@ static void gst_qtdemux_handle_esds (GstQTDemux * qtdemux,
static GstCaps *qtdemux_video_caps (GstQTDemux * qtdemux,
QtDemuxStream * stream, guint32 fourcc, const guint8 * stsd_data,
gchar ** codec_name);
static GstCaps *qtdemux_audio_caps (GstQTDemux * qtdemux,
QtDemuxStream * stream, guint32 fourcc, const guint8 * data, int len,
gchar ** codec_name);
+static GstCaps *qtdemux_subp_caps (GstQTDemux * qtdemux,
+ QtDemuxStream * stream, guint32 fourcc, const guint8 * data,
+ gchar ** codec_name);
GType
gst_qtdemux_get_type (void)
{
static GType qtdemux_type = 0;
@@ -1330,12 +1339,13 @@ gst_qtdemux_change_state (GstElement * element, GstStateChange transition)
g_free (stream);
}
qtdemux->major_brand = 0;
qtdemux->n_streams = 0;
qtdemux->n_video_streams = 0;
qtdemux->n_audio_streams = 0;
+ qtdemux->n_subp_streams = 0;
gst_segment_init (&qtdemux->segment, GST_FORMAT_TIME);
break;
}
default:
break;
}
@@ -3270,12 +3280,19 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux,
"rate", G_TYPE_INT, (int) stream->rate,
"channels", G_TYPE_INT, stream->n_channels, NULL);
}
qtdemux->n_audio_streams++;
} else if (stream->subtype == FOURCC_strm) {
GST_DEBUG_OBJECT (qtdemux, "stream type, not creating pad");
+ } else if (stream->subtype == FOURCC_subp) {
+ gchar *name = g_strdup_printf ("subp_%02d", qtdemux->n_subp_streams);
+
+ stream->pad =
+ gst_pad_new_from_static_template (&gst_qtdemux_subpsrc_template, name);
+ g_free (name);
+ qtdemux->n_subp_streams++;
} else {
GST_DEBUG_OBJECT (qtdemux, "unknown stream type");
goto done;
}
qtdemux->streams[qtdemux->n_streams] = stream;
@@ -4265,12 +4282,24 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
if (fourcc != FOURCC_rtsp) {
GST_INFO_OBJECT (qtdemux, "unhandled stream type %" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (fourcc));
goto unknown_stream;
}
stream->sampled = TRUE;
+ } else if (stream->subtype == FOURCC_subp) {
+ guint32 fourcc;
+
+ stream->sampled = TRUE;
+
+ offset = 16;
+ stream->fourcc = fourcc = QT_FOURCC (stsd_data + offset + 4);
+ GST_LOG_OBJECT (qtdemux, "st type: %" GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (fourcc));
+
+ stream->caps =
+ qtdemux_subp_caps (qtdemux, stream, fourcc, stsd_data, &codec);
} else {
goto unknown_stream;
}
/* promote to sampled format */
if (stream->fourcc == FOURCC_samr) {
@@ -5720,6 +5749,32 @@ qtdemux_audio_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
name = gst_structure_get_name (s);
if (g_str_has_prefix (name, "audio/x-raw-")) {
stream->need_clip = TRUE;
}
return caps;
}
+
+static GstCaps *
+qtdemux_subp_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
+ guint32 fourcc, const guint8 * stsd_data, gchar ** codec_name)
+{
+ GstCaps *caps;
+
+ GST_DEBUG_OBJECT (qtdemux, "resolve fourcc %08x", fourcc);
+
+ switch (fourcc) {
+ case GST_MAKE_FOURCC ('m', 'p', '4', 's'):
+ _codec ("DVD subtitle");
+ caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
+ break;
+ default:
+ {
+ char *s;
+
+ s = g_strdup_printf ("audio/x-gst-fourcc-%" GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (fourcc));
+ caps = gst_caps_new_simple (s, NULL);
+ break;
+ }
+ }
+ return caps;
+}
diff --git a/gst/qtdemux/qtdemux.h b/gst/qtdemux/qtdemux.h
index d227b7f1b..7b7c135f3 100644
--- a/gst/qtdemux/qtdemux.h
+++ b/gst/qtdemux/qtdemux.h
@@ -59,12 +59,13 @@ struct _GstQTDemux {
GstPad *sinkpad;
QtDemuxStream *streams[GST_QTDEMUX_MAX_STREAMS];
gint n_streams;
gint n_video_streams;
gint n_audio_streams;
+ gint n_subp_streams;
guint major_brand;
GNode *moov_node;
GNode *moov_node_compressed;
guint32 timescale;
diff --git a/gst/qtdemux/qtdemux_fourcc.h b/gst/qtdemux/qtdemux_fourcc.h
index aa9a1f2da..adae4fb9c 100644
--- a/gst/qtdemux/qtdemux_fourcc.h
+++ b/gst/qtdemux/qtdemux_fourcc.h
@@ -59,12 +59,13 @@ G_BEGIN_DECLS
#define FOURCC_stps GST_MAKE_FOURCC('s','t','p','s')
#define FOURCC_stsc GST_MAKE_FOURCC('s','t','s','c')
#define FOURCC_stsz GST_MAKE_FOURCC('s','t','s','z')
#define FOURCC_stco GST_MAKE_FOURCC('s','t','c','o')
#define FOURCC_vide GST_MAKE_FOURCC('v','i','d','e')
#define FOURCC_soun GST_MAKE_FOURCC('s','o','u','n')
+#define FOURCC_subp GST_MAKE_FOURCC('s','u','b','p')
#define FOURCC_strm GST_MAKE_FOURCC('s','t','r','m')
#define FOURCC_rtsp GST_MAKE_FOURCC('r','t','s','p')
#define FOURCC_co64 GST_MAKE_FOURCC('c','o','6','4')
#define FOURCC_cmov GST_MAKE_FOURCC('c','m','o','v')
#define FOURCC_dcom GST_MAKE_FOURCC('d','c','o','m')
#define FOURCC_cmvd GST_MAKE_FOURCC('c','m','v','d')