static const uint8_t mxf_apple_coll_max_cll[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x01 };
static const uint8_t mxf_apple_coll_max_fall[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x02 };
+static const uint8_t mxf_mastering_display_prefix[13] = { FF_MXF_MasteringDisplay_PREFIX };
+static const uint8_t mxf_mastering_display_uls[4][16] = {
+ FF_MXF_MasteringDisplayPrimaries,
+ FF_MXF_MasteringDisplayWhitePointChromaticity,
+ FF_MXF_MasteringDisplayMaximumLuminance,
+ FF_MXF_MasteringDisplayMinimumLuminance,
+};
+
#define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx)
rsiz == FF_PROFILE_JPEG2000_DCINEMA_4K)
descriptor->pix_fmt = AV_PIX_FMT_XYZ12;
}
- if (IS_KLV_KEY(uid, ff_mxf_mastering_display_prefix)) {
+ if (IS_KLV_KEY(uid, mxf_mastering_display_prefix)) {
if (!descriptor->mastering) {
descriptor->mastering = av_mastering_display_metadata_alloc();
if (!descriptor->mastering)
return AVERROR(ENOMEM);
}
- if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[0].uid)) {
+ if (IS_KLV_KEY(uid, mxf_mastering_display_uls[0])) {
for (int i = 0; i < 3; i++) {
/* Order: large x, large y, other (i.e. RGB) */
descriptor->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
if (descriptor->mastering->white_point[0].den != 0)
descriptor->mastering->has_primaries = 1;
}
- if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[1].uid)) {
+ if (IS_KLV_KEY(uid, mxf_mastering_display_uls[1])) {
descriptor->mastering->white_point[0] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
descriptor->mastering->white_point[1] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN);
/* Check we have seen mxf_mastering_display_primaries */
if (descriptor->mastering->display_primaries[0][0].den != 0)
descriptor->mastering->has_primaries = 1;
}
- if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[2].uid)) {
+ if (IS_KLV_KEY(uid, mxf_mastering_display_uls[2])) {
descriptor->mastering->max_luminance = av_make_q(avio_rb32(pb), FF_MXF_MASTERING_LUMA_DEN);
/* Check we have seen mxf_mastering_display_minimum_luminance */
if (descriptor->mastering->min_luminance.den != 0)
descriptor->mastering->has_luminance = 1;
}
- if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[3].uid)) {
+ if (IS_KLV_KEY(uid, mxf_mastering_display_uls[3])) {
descriptor->mastering->min_luminance = av_make_q(avio_rb32(pb), FF_MXF_MASTERING_LUMA_DEN);
/* Check we have seen mxf_mastering_display_maximum_luminance */
if (descriptor->mastering->max_luminance.den != 0)
return 0;
}
+static int mxf_version_to_str(uint16_t major, uint16_t minor, uint16_t tertiary,
+ uint16_t patch, uint16_t release, char **str)
+{
+ *str = av_asprintf("%d.%d.%d.%d.%d", major, minor, tertiary, patch, release);
+ if (!*str)
+ return AVERROR(ENOMEM);
+ return 0;
+}
+
static int mxf_add_umid_metadata(AVDictionary **pm, const char *key, MXFPackage* package)
{
char *str;
av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \
} while (0)
+#define SET_VERSION_METADATA(pb, name, major, minor, tertiary, patch, release, str) do { \
+ major = avio_rb16(pb); \
+ minor = avio_rb16(pb); \
+ tertiary = avio_rb16(pb); \
+ patch = avio_rb16(pb); \
+ release = avio_rb16(pb); \
+ if ((ret = mxf_version_to_str(major, minor, tertiary, patch, release, &str)) < 0) \
+ return ret; \
+ av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \
+} while (0)
+
#define SET_UID_METADATA(pb, name, var, str) do { \
avio_read(pb, var, 16); \
if ((ret = mxf_uid_to_str(var, &str)) < 0) \
UID uid = { 0 };
char *str = NULL;
uint64_t ts;
+ uint16_t major, minor, tertiary, patch, release;
switch (tag) {
case 0x3C01:
SET_STR_METADATA(pb, "company_name", str);
case 0x3C06:
SET_TS_METADATA(pb, "modification_date", ts, str);
break;
+ case 0x3C07:
+ SET_VERSION_METADATA(pb, "toolkit_version", major, minor, tertiary, patch, release, str);
+ break;
case 0x3C08:
SET_STR_METADATA(pb, "application_platform", str);
break;
int ret;
int tag = avio_rb16(pb);
int size = avio_rb16(pb); /* KLV specified by 0x53 */
- uint64_t next = avio_tell(pb) + size;
+ int64_t next = avio_tell(pb);
UID uid = {0};
+ if (next < 0 || next > INT64_MAX - size)
+ return next < 0 ? next : AVERROR_INVALIDDATA;
+ next += size;
av_log(mxf->fc, AV_LOG_TRACE, "local tag %#04x size %d\n", tag, size);
if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */