summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2008-09-03 12:39:35 +0000
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2008-09-03 12:39:35 +0000
commitbf5ffabf4cdd28a987829859c46c884dafb03d81 (patch)
tree397124b595d987f9eafac9c220b2574de348c3af
parentd64815f75f97e21e3e32701db509d2978c3940dc (diff)
downloadgstreamer-plugins-good-bf5ffabf4cdd28a987829859c46c884dafb03d81.tar.gz
gst/qtdemux/: Add support for video/mj2 mime-type and its additional atoms/boxes.
Original commit message from CVS: * gst/qtdemux/qtdemux.c: (gst_qtdemux_change_state), (gst_qtdemux_loop_state_header), (qtdemux_parse_node), (qtdemux_parse_trak), (qtdemux_video_caps): * gst/qtdemux/qtdemux.h: * gst/qtdemux/qtdemux_fourcc.h: * gst/qtdemux/qtdemux_types.c: Add support for video/mj2 mime-type and its additional atoms/boxes. Fixes #550646.
-rw-r--r--ChangeLog11
-rw-r--r--gst/qtdemux/qtdemux.c112
-rw-r--r--gst/qtdemux/qtdemux.h1
-rw-r--r--gst/qtdemux/qtdemux_fourcc.h10
-rw-r--r--gst/qtdemux/qtdemux_types.c6
5 files changed, 137 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index d7a23590b..d3837226e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2008-09-03 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
+
+ * gst/qtdemux/qtdemux.c: (gst_qtdemux_change_state),
+ (gst_qtdemux_loop_state_header), (qtdemux_parse_node),
+ (qtdemux_parse_trak), (qtdemux_video_caps):
+ * gst/qtdemux/qtdemux.h:
+ * gst/qtdemux/qtdemux_fourcc.h:
+ * gst/qtdemux/qtdemux_types.c:
+ Add support for video/mj2 mime-type and its additional atoms/boxes.
+ Fixes #550646.
+
2008-09-03 Stefan Kost <ensonic@users.sf.net>
* gst/debug/gsttaginject.c:
diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c
index 88d73ab68..cb4355356 100644
--- a/gst/qtdemux/qtdemux.c
+++ b/gst/qtdemux/qtdemux.c
@@ -259,7 +259,8 @@ static GstStaticPadTemplate gst_qtdemux_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/quicktime; audio/x-m4a; application/x-3gp")
+ GST_STATIC_CAPS ("video/quicktime; video/mj2; audio/x-m4a; "
+ "application/x-3gp")
);
static GstStaticPadTemplate gst_qtdemux_videosrc_template =
@@ -1032,6 +1033,7 @@ gst_qtdemux_change_state (GstElement * element, GstStateChange transition)
g_free (stream->segments);
g_free (stream);
}
+ qtdemux->major_brand = 0;
qtdemux->n_streams = 0;
qtdemux->n_video_streams = 0;
qtdemux->n_audio_streams = 0;
@@ -1131,6 +1133,25 @@ gst_qtdemux_loop_state_header (GstQTDemux * qtdemux)
qtdemux->state);
break;
}
+ case FOURCC_ftyp:
+ {
+ GstBuffer *ftyp;
+
+ /* extract major brand; might come in handy for ISO vs QT issues */
+ ret = gst_pad_pull_range (qtdemux->sinkpad, cur_offset, length, &ftyp);
+ if (ret != GST_FLOW_OK)
+ goto beach;
+ cur_offset += length;
+ qtdemux->offset += length;
+ /* only consider at least a sufficiently complete ftyp atom */
+ if (length >= 20) {
+ qtdemux->major_brand = QT_FOURCC (GST_BUFFER_DATA (ftyp) + 8);
+ GST_DEBUG_OBJECT (qtdemux, "major brand: %" GST_FOURCC_FORMAT,
+ GST_FOURCC_ARGS (qtdemux->major_brand));
+ }
+ gst_buffer_unref (ftyp);
+ break;
+ }
default:
{
GST_LOG_OBJECT (qtdemux,
@@ -2627,6 +2648,11 @@ qtdemux_parse_node (GstQTDemux * qtdemux, GNode * node, guint8 * buffer,
}
break;
}
+ case FOURCC_mjp2:
+ {
+ qtdemux_parse_container (qtdemux, node, buffer + 86, end);
+ break;
+ }
case FOURCC_meta:
{
GST_DEBUG_OBJECT (qtdemux, "parsing meta atom");
@@ -3256,8 +3282,12 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
if (!(mdia = qtdemux_tree_get_child_by_type (trak, FOURCC_mdia)))
goto corrupt_file;
- if (!(mdhd = qtdemux_tree_get_child_by_type (mdia, FOURCC_mdhd)))
- goto corrupt_file;
+ if (!(mdhd = qtdemux_tree_get_child_by_type (mdia, FOURCC_mdhd))) {
+ /* be nice for some crooked mjp2 files that use mhdr for mdhd */
+ if (qtdemux->major_brand != FOURCC_mjp2 ||
+ !(mdhd = qtdemux_tree_get_child_by_type (mdia, FOURCC_mhdr)))
+ goto corrupt_file;
+ }
version = QT_UINT32 ((guint8 *) mdhd->data + 8);
GST_LOG_OBJECT (qtdemux, "track version/flags: %08x", version);
@@ -3391,6 +3421,75 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
}
break;
}
+ case FOURCC_mjp2:
+ {
+ GNode *jp2h, *colr, *mjp2, *field, *prefix;
+ const guint8 *data;
+ guint32 fourcc = 0;
+
+ GST_DEBUG_OBJECT (qtdemux, "found mjp2");
+ /* some required atoms */
+ mjp2 = qtdemux_tree_get_child_by_type (stsd, FOURCC_mjp2);
+ if (!mjp2)
+ break;
+ jp2h = qtdemux_tree_get_child_by_type (mjp2, FOURCC_jp2h);
+ if (!jp2h)
+ break;
+ colr = qtdemux_tree_get_child_by_type (jp2h, FOURCC_colr);
+ if (!colr)
+ break;
+ GST_DEBUG_OBJECT (qtdemux, "found colr");
+ /* try to extract colour space info */
+ if (QT_UINT8 (colr->data + 8) == 1) {
+ switch (QT_UINT32 (colr->data + 11)) {
+ case 16:
+ fourcc = GST_MAKE_FOURCC ('s', 'R', 'G', 'B');
+ break;
+ case 17:
+ fourcc = GST_MAKE_FOURCC ('G', 'R', 'A', 'Y');
+ break;
+ case 18:
+ fourcc = GST_MAKE_FOURCC ('s', 'Y', 'U', 'V');
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (fourcc)
+ gst_caps_set_simple (stream->caps,
+ "fourcc", GST_TYPE_FOURCC, fourcc, NULL);
+
+ /* some optional atoms */
+ field = qtdemux_tree_get_child_by_type (mjp2, FOURCC_fiel);
+ prefix = qtdemux_tree_get_child_by_type (mjp2, FOURCC_jp2x);
+
+ /* indicate possible fields in caps */
+ if (field) {
+ data = field->data + 8;
+ if (*data != 1)
+ gst_caps_set_simple (stream->caps, "fields", G_TYPE_INT,
+ (gint) * data, NULL);
+ }
+ /* add codec_data if provided */
+ if (prefix) {
+ GstBuffer *buf;
+ gint len;
+
+ GST_DEBUG_OBJECT (qtdemux, "found prefix data in stsd");
+ data = prefix->data;
+ len = QT_UINT32 (data);
+ if (len > 0x8) {
+ len -= 0x8;
+ buf = gst_buffer_new_and_alloc (len);
+ memcpy (GST_BUFFER_DATA (buf), data + 8, len);
+ gst_caps_set_simple (stream->caps,
+ "codec_data", GST_TYPE_BUFFER, buf, NULL);
+ gst_buffer_unref (buf);
+ }
+ }
+ break;
+ }
case FOURCC_SVQ3:
case FOURCC_VP31:
{
@@ -3611,6 +3710,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
case FOURCC_QDMC:
{
gint len = QT_UINT32 (stsd_data);
+
/* seems to be always = 116 = 0x74 */
break;
}
@@ -4430,6 +4530,12 @@ qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
_codec ("Motion-JPEG format B");
caps = gst_caps_from_string ("video/x-mjpeg-b");
break;
+ case GST_MAKE_FOURCC ('m', 'j', 'p', '2'):
+ _codec ("JPEG-2000");
+ /* override to what it should be according to spec, avoid palette_data */
+ stream->bits_per_sample = 24;
+ caps = gst_caps_new_simple ("image/x-j2c", "fields", G_TYPE_INT, 1, NULL);
+ break;
case GST_MAKE_FOURCC ('S', 'V', 'Q', '3'):
_codec ("Sorensen video v.3");
caps = gst_caps_from_string ("video/x-svq, " "svqversion = (int) 3");
diff --git a/gst/qtdemux/qtdemux.h b/gst/qtdemux/qtdemux.h
index 984f26dcb..c887df7cd 100644
--- a/gst/qtdemux/qtdemux.h
+++ b/gst/qtdemux/qtdemux.h
@@ -59,6 +59,7 @@ struct _GstQTDemux {
gint n_video_streams;
gint n_audio_streams;
+ guint major_brand;
GNode *moov_node;
GNode *moov_node_compressed;
diff --git a/gst/qtdemux/qtdemux_fourcc.h b/gst/qtdemux/qtdemux_fourcc.h
index 96ee218e5..a030f1b62 100644
--- a/gst/qtdemux/qtdemux_fourcc.h
+++ b/gst/qtdemux/qtdemux_fourcc.h
@@ -24,6 +24,7 @@
G_BEGIN_DECLS
+#define FOURCC_ftyp GST_MAKE_FOURCC('f','t','y','p')
#define FOURCC_moov GST_MAKE_FOURCC('m','o','o','v')
#define FOURCC_mvhd GST_MAKE_FOURCC('m','v','h','d')
#define FOURCC_clip GST_MAKE_FOURCC('c','l','i','p')
@@ -133,6 +134,15 @@ G_BEGIN_DECLS
#define FOURCC_keyw GST_MAKE_FOURCC('k','e','y','w')
#define FOURCC_kywd GST_MAKE_FOURCC('k','y','w','d')
+/* ISO Motion JPEG 2000 fourcc */
+#define FOURCC_mjp2 GST_MAKE_FOURCC('m','j','p','2')
+#define FOURCC_jp2h GST_MAKE_FOURCC('j','p','2','h')
+#define FOURCC_colr GST_MAKE_FOURCC('c','o','l','r')
+#define FOURCC_fiel GST_MAKE_FOURCC('f','i','e','l')
+#define FOURCC_jp2x GST_MAKE_FOURCC('j','p','2','x')
+/* some buggy hardware's notion of mdhd */
+#define FOURCC_mhdr GST_MAKE_FOURCC('m','h','d','r')
+
/* Xiph fourcc */
#define FOURCC_XiTh GST_MAKE_FOURCC('X','i','T','h')
#define FOURCC_XdxT GST_MAKE_FOURCC('X','d','x','T')
diff --git a/gst/qtdemux/qtdemux_types.c b/gst/qtdemux/qtdemux_types.c
index 7e7807785..5a1afed99 100644
--- a/gst/qtdemux/qtdemux_types.c
+++ b/gst/qtdemux/qtdemux_types.c
@@ -78,6 +78,12 @@ static const QtNodeType qt_node_types[] = {
{FOURCC_hint, "hint", 0,},
{FOURCC_mp4a, "mp4a", 0,},
{FOURCC_mp4v, "mp4v", 0,},
+ {FOURCC_mjp2, "mjp2", 0,},
+ {FOURCC_mhdr, "mhdr", QT_FLAG_CONTAINER,},
+ {FOURCC_jp2h, "jp2h", QT_FLAG_CONTAINER,},
+ {FOURCC_colr, "colr", 0,},
+ {FOURCC_fiel, "fiel", 0,},
+ {FOURCC_jp2x, "jp2x", 0,},
{FOURCC_wave, "wave", QT_FLAG_CONTAINER},
{FOURCC_appl, "appl", QT_FLAG_CONTAINER},
{FOURCC_esds, "esds", 0},