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
This commit is contained in:
Thiago Santos 2009-10-29 08:29:38 -03:00
parent f2f75d7fd9
commit e35085e5b5
2 changed files with 109 additions and 1 deletions

View file

@ -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,

View file

@ -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')