diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c index 8b7b0f5342..183f74cd77 100644 --- a/gst/isomp4/qtdemux.c +++ b/gst/isomp4/qtdemux.c @@ -10022,6 +10022,80 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak) } 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_VP31: {