diff --git a/gst/isomp4/fourcc.h b/gst/isomp4/fourcc.h index 6c425e6f98..17d31b2176 100644 --- a/gst/isomp4/fourcc.h +++ b/gst/isomp4/fourcc.h @@ -259,6 +259,7 @@ G_BEGIN_DECLS #define FOURCC_vmhd GST_MAKE_FOURCC('v','m','h','d') #define FOURCC_vp08 GST_MAKE_FOURCC('v','p','0','8') #define FOURCC_vp09 GST_MAKE_FOURCC('v','p','0','9') +#define FOURCC_vpcC GST_MAKE_FOURCC('v','p','c','C') #define FOURCC_xvid GST_MAKE_FOURCC('x','v','i','d') #define FOURCC_wave GST_MAKE_FOURCC('w','a','v','e') #define FOURCC_wide GST_MAKE_FOURCC('w','i','d','e') diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c index 3fa5fc7de8..acd4ec06a0 100644 --- a/gst/isomp4/qtdemux.c +++ b/gst/isomp4/qtdemux.c @@ -11859,6 +11859,156 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak) break; } + + /* TODO: Need to parse vpcC for VP8 codec too. + * Note that VPCodecConfigurationBox (vpcC) is defined for + * vp08, vp09, and vp10 fourcc. */ + case FOURCC_vp09: + { + gint len = QT_UINT32 (stsd_entry_data) - 0x56; + const guint8 *vpcc_data = stsd_entry_data + 0x56; + + /* find vpcC */ + while (len >= 0x8) { + gint size; + + if (QT_UINT32 (vpcc_data) <= len) + size = QT_UINT32 (vpcc_data) - 0x8; + else + size = len - 0x8; + + if (size < 1) + /* No real data, so break out */ + break; + + switch (QT_FOURCC (vpcc_data + 0x4)) { + case FOURCC_vpcC: + { + const gchar *profile_str = NULL; + const gchar *chroma_format_str = NULL; + guint8 profile; + guint8 bitdepth; + guint8 chroma_format; + GstVideoColorimetry cinfo; + + /* parse, if found */ + GST_DEBUG_OBJECT (qtdemux, + "found vp codec_data in stsd of size %d", size); + + /* the meaning of "size" is length of the atom body, excluding + * atom length and fourcc fields */ + if (size < 12) + break; + + /* Content is: + * 4 bytes: atom length + * 4 bytes: fourcc + * 1 byte: version + * 3 bytes: flags + * 1 byte: profile + * 1 byte: level + * 4 bits: bitDepth + * 3 bits: chromaSubsampling + * 1 bit: videoFullRangeFlag + * 1 byte: colourPrimaries + * 1 byte: transferCharacteristics + * 1 byte: matrixCoefficients + * 2 bytes: codecIntializationDataSize (should be zero for vp8 and vp9) + * rest: codecIntializationData (not used for vp8 and vp9) + */ + + if (vpcc_data[8] != 1) { + GST_WARNING_OBJECT (qtdemux, + "unknown vpcC version %d", vpcc_data[8]); + break; + } + + profile = vpcc_data[12]; + switch (profile) { + case 0: + profile_str = "0"; + break; + case 1: + profile_str = "1"; + break; + case 2: + profile_str = "2"; + break; + case 3: + profile_str = "3"; + break; + default: + break; + } + + if (profile_str) { + gst_caps_set_simple (entry->caps, + "profile", G_TYPE_STRING, profile_str, NULL); + } + + /* skip level, the VP9 spec v0.6 defines only one level atm, + * but webm spec define various ones. Add level to caps + * if we really need it then */ + + bitdepth = (vpcc_data[14] & 0xf0) >> 4; + if (bitdepth == 8 || bitdepth == 10 || bitdepth == 12) { + gst_caps_set_simple (entry->caps, + "bit-depth-luma", G_TYPE_UINT, bitdepth, + "bit-depth-chroma", G_TYPE_UINT, bitdepth, NULL); + } + + chroma_format = (vpcc_data[14] & 0xe) >> 1; + switch (chroma_format) { + case 0: + case 1: + chroma_format_str = "4:2:0"; + break; + case 2: + chroma_format_str = "4:2:2"; + break; + case 3: + chroma_format_str = "4:4:4"; + break; + default: + break; + } + + if (chroma_format_str) { + gst_caps_set_simple (entry->caps, + "chroma-format", G_TYPE_STRING, chroma_format_str, + NULL); + } + + if ((vpcc_data[14] & 0x1) != 0) + cinfo.range = GST_VIDEO_COLOR_RANGE_0_255; + else + cinfo.range = GST_VIDEO_COLOR_RANGE_16_235; + cinfo.primaries = + gst_video_color_primaries_from_iso (vpcc_data[15]); + cinfo.transfer = + gst_video_color_transfer_from_iso (vpcc_data[16]); + cinfo.matrix = + gst_video_color_matrix_from_iso (vpcc_data[17]); + + if (cinfo.primaries != GST_VIDEO_COLOR_PRIMARIES_UNKNOWN && + cinfo.transfer != GST_VIDEO_TRANSFER_UNKNOWN && + cinfo.matrix != GST_VIDEO_COLOR_MATRIX_UNKNOWN) { + /* set this only if all values are known, otherwise this + * might overwrite valid ones parsed from other color box */ + CUR_STREAM (stream)->colorimetry = cinfo; + } + break; + } + default: + break; + } + + len -= size + 8; + vpcc_data += size + 8; + } + + break; + } default: break; }