mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
qtdemux: extract interlaced information from jpeg video
This information is hidden in a small chunk of data. Format found at https://developer.apple.com/standards/qtff-2001.pdf, page 92, "Video Sample Description", under table 3.1. https://bugzilla.gnome.org/show_bug.cgi?id=767771
This commit is contained in:
parent
d94287c047
commit
5a889647ba
1 changed files with 74 additions and 0 deletions
|
@ -10022,6 +10022,80 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case FOURCC_jpeg:
|
||||||
|
{
|
||||||
|
/* https://developer.apple.com/standards/qtff-2001.pdf,
|
||||||
|
* page 92, "Video Sample Description", under table 3.1 */
|
||||||
|
GstByteReader br;
|
||||||
|
|
||||||
|
const off_t compressor_offset =
|
||||||
|
16 + 4 + 4 * 3 + 2 * 2 + 2 * 4 + 4 + 2;
|
||||||
|
const off_t min_size = compressor_offset + 32 + 2 + 2;
|
||||||
|
GNode *jpeg;
|
||||||
|
guint32 len;
|
||||||
|
guint16 color_table_id;
|
||||||
|
gboolean ok;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (qtdemux, "found jpeg");
|
||||||
|
|
||||||
|
/* recover information on interlaced/progressive */
|
||||||
|
jpeg = qtdemux_tree_get_child_by_type (stsd, FOURCC_jpeg);
|
||||||
|
if (!jpeg)
|
||||||
|
break;
|
||||||
|
|
||||||
|
len = QT_UINT32 (jpeg->data);
|
||||||
|
GST_DEBUG_OBJECT (qtdemux, "Found jpeg: len %u, need %lu", len,
|
||||||
|
min_size);
|
||||||
|
if (len >= min_size) {
|
||||||
|
gst_byte_reader_init (&br, jpeg->data, len);
|
||||||
|
|
||||||
|
gst_byte_reader_skip (&br, compressor_offset + 32 + 2);
|
||||||
|
gst_byte_reader_get_uint16_le (&br, &color_table_id);
|
||||||
|
if (color_table_id != 0) {
|
||||||
|
/* the spec says there can be concatenated chunks in the data, and we want
|
||||||
|
* to find one called field. Walk through them. */
|
||||||
|
off_t offset = min_size;
|
||||||
|
while (offset + 8 < len) {
|
||||||
|
guint32 size, tag;
|
||||||
|
ok = gst_byte_reader_get_uint32_le (&br, &size);
|
||||||
|
ok &= gst_byte_reader_get_uint32_le (&br, &tag);
|
||||||
|
if (!ok || size < 8) {
|
||||||
|
GST_WARNING_OBJECT (qtdemux,
|
||||||
|
"Failed to walk optional chunk list");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
GST_DEBUG_OBJECT (qtdemux,
|
||||||
|
"Found optional %4.4s chunk, size %u", (const char *) &tag,
|
||||||
|
size);
|
||||||
|
if (tag == FOURCC_fiel) {
|
||||||
|
guint8 n_fields, ordering;
|
||||||
|
gst_byte_reader_get_uint8 (&br, &n_fields);
|
||||||
|
gst_byte_reader_get_uint8 (&br, &ordering);
|
||||||
|
if (n_fields == 1 || n_fields == 2) {
|
||||||
|
GST_DEBUG_OBJECT (qtdemux,
|
||||||
|
"Found fiel tag with %u fields, ordering %u", n_fields,
|
||||||
|
ordering);
|
||||||
|
if (n_fields == 2)
|
||||||
|
gst_caps_set_simple (stream->caps, "interlace-mode",
|
||||||
|
G_TYPE_STRING, "interleaved", NULL);
|
||||||
|
} else {
|
||||||
|
GST_WARNING_OBJECT (qtdemux,
|
||||||
|
"Found fiel tag with invalid fields (%u)", n_fields);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GST_DEBUG_OBJECT (qtdemux,
|
||||||
|
"Color table ID is 0, not trying to get interlacedness");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GST_WARNING_OBJECT (qtdemux,
|
||||||
|
"Length of jpeg chunk is too small, not trying to get interlacedness");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case FOURCC_SVQ3:
|
case FOURCC_SVQ3:
|
||||||
case FOURCC_VP31:
|
case FOURCC_VP31:
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue