summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Santos <thiago.sousa.santos@collabora.co.uk>2009-10-29 08:29:38 -0300
committerThiago Santos <thiago.sousa.santos@collabora.co.uk>2009-11-18 16:41:50 -0300
commite35085e5b5191e66efeaa807b877f501d2a26363 (patch)
tree29dac95deea7accb7302426e8c876c0ca3e8ae02
parentf2f75d7fd9732b51dfab2601855e8c49e581f3f6 (diff)
qtdemux: Add more fields to SVQ3 caps
qtdemux only added the whole stsd atom as 'codec_data' in its output caps for SVQ3. This patch makes it add the SEQH (inside a SMI atom) and a gamma field (taken from the gama atom) if available. Fixes #587922
-rw-r--r--gst/qtdemux/qtdemux.c105
-rw-r--r--gst/qtdemux/qtdemux_fourcc.h5
2 files changed, 109 insertions, 1 deletions
diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c
index 720f68c43..cf13a22b9 100644
--- a/gst/qtdemux/qtdemux.c
+++ b/gst/qtdemux/qtdemux.c
@@ -4281,6 +4281,96 @@ done:
return TRUE;
}
+/*
+ * Parses the stsd atom of a svq3 trak looking for
+ * the SMI and gama atoms.
+ */
+static void
+qtdemux_parse_svq3_stsd_data (GstQTDemux * qtdemux, GNode * stsd,
+ guint8 ** gamma, GstBuffer ** seqh)
+{
+ guint8 *_gamma = NULL;
+ GstBuffer *_seqh = NULL;
+ guint8 *stsd_data = stsd->data;
+ guint32 length = QT_UINT32 (stsd_data);
+ guint16 version;
+
+ if (length < 32) {
+ GST_WARNING_OBJECT (qtdemux, "stsd too short");
+ goto end;
+ }
+
+ stsd_data += 32;
+ length -= 32;
+ version = QT_UINT16 (stsd_data);
+ if (version == 3) {
+ if (length >= 70) {
+ length -= 70;
+ stsd_data += 70;
+ while (length > 8) {
+ guint32 fourcc, size;
+ guint8 *data;
+ size = QT_UINT32 (stsd_data);
+ fourcc = QT_FOURCC (stsd_data + 4);
+ data = stsd_data + 8;
+
+ switch (fourcc) {
+ case FOURCC_gama:{
+ if (size == 12) {
+ _gamma = data;
+ } else {
+ GST_WARNING_OBJECT (qtdemux, "Unexpected size %" G_GUINT32_FORMAT
+ " for gama atom, expected 12", size);
+ }
+ break;
+ }
+ case FOURCC_SMI_:{
+ if (size > 16 && QT_FOURCC (data) == FOURCC_SEQH) {
+ guint32 seqh_size;
+ if (_seqh != NULL) {
+ GST_WARNING_OBJECT (qtdemux, "Unexpected second SEQH SMI atom "
+ " found, ignoring");
+ } else {
+ seqh_size = QT_UINT32 (data + 4);
+ if (seqh_size > 0) {
+ _seqh = gst_buffer_new_and_alloc (seqh_size);
+ memcpy (GST_BUFFER_DATA (_seqh), data + 8, seqh_size);
+ }
+ }
+ }
+ break;
+ }
+ default:{
+ GST_WARNING_OBJECT (qtdemux, "Unhandled atom %" GST_FOURCC_FORMAT
+ " in SVQ3 entry in stsd atom", GST_FOURCC_ARGS (fourcc));
+ }
+ }
+
+ if (size <= length) {
+ length -= size;
+ stsd_data += size;
+ }
+ }
+ } else {
+ GST_WARNING_OBJECT (qtdemux, "SVQ3 entry too short in stsd atom");
+ }
+ } else {
+ GST_WARNING_OBJECT (qtdemux, "Unexpected version for SVQ3 entry %"
+ G_GUINT16_FORMAT, version);
+ goto end;
+ }
+
+end:
+ if (gamma) {
+ *gamma = _gamma;
+ }
+ if (seqh) {
+ *seqh = _seqh;
+ } else if (_seqh) {
+ gst_buffer_unref (_seqh);
+ }
+}
+
/* parse the traks.
* With each track we associate a new QtDemuxStream that contains all the info
* about the trak.
@@ -4722,10 +4812,23 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
case FOURCC_VP31:
{
GstBuffer *buf;
+ GstBuffer *seqh = NULL;
+ guint8 *gamma_data = NULL;
gint len = QT_UINT32 (stsd_data);
- GST_DEBUG_OBJECT (qtdemux, "found codec_data in stsd");
+ qtdemux_parse_svq3_stsd_data (qtdemux, stsd, &gamma_data, &seqh);
+ if (gamma_data) {
+ gst_caps_set_simple (stream->caps, "applied-gamma", G_TYPE_DOUBLE,
+ QT_FP32 (gamma_data), NULL);
+ }
+ if (seqh) {
+ /* sorry for the bad name, but we don't know what this is, other
+ * than its own fourcc */
+ gst_caps_set_simple (stream->caps, "seqh", GST_TYPE_BUFFER, seqh,
+ NULL);
+ }
+ GST_DEBUG_OBJECT (qtdemux, "found codec_data in stsd");
buf = gst_buffer_new_and_alloc (len);
memcpy (GST_BUFFER_DATA (buf), stsd_data, len);
gst_caps_set_simple (stream->caps,
diff --git a/gst/qtdemux/qtdemux_fourcc.h b/gst/qtdemux/qtdemux_fourcc.h
index 952d07969..053341740 100644
--- a/gst/qtdemux/qtdemux_fourcc.h
+++ b/gst/qtdemux/qtdemux_fourcc.h
@@ -149,6 +149,11 @@ G_BEGIN_DECLS
#define FOURCC_text GST_MAKE_FOURCC('t','e','x','t')
#define FOURCC_tx3g GST_MAKE_FOURCC('t','x','3','g')
#define FOURCC_mp4s GST_MAKE_FOURCC('m','p','4','s')
+#define FOURCC_gama GST_MAKE_FOURCC('g','a','m','a')
+
+/* SVQ3 fourcc */
+#define FOURCC_SEQH GST_MAKE_FOURCC('S','E','Q','H')
+#define FOURCC_SMI_ GST_MAKE_FOURCC('S','M','I',' ')
/* 3gpp asset meta data fourcc */
#define FOURCC_titl GST_MAKE_FOURCC('t','i','t','l')