diff options
author | Matthieu Bouron <matthieu.bouron@gmail.com> | 2013-03-29 14:09:31 +0100 |
---|---|---|
committer | Matthieu Bouron <matthieu.bouron@gmail.com> | 2013-04-08 11:16:56 +0200 |
commit | 25b143aa7bd60d348a449be64dadab61f0c7d068 (patch) | |
tree | fef6301aa25b48f20755e582a17f10630475d020 /libavformat | |
parent | 018cc6f0266a2ca5cae507491aeeb37834a144b7 (diff) | |
download | ffmpeg-25b143aa7bd60d348a449be64dadab61f0c7d068.tar.gz |
lavf/mxfdec: handle identification metadata
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/mxfdec.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 4580e1be38..ac3f13c680 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1619,6 +1619,120 @@ fail_and_free: return ret; } +static int mxf_read_utf16_string(AVIOContext *pb, int size, char** str) +{ + int ret; + size_t buf_size; + + if (size < 0) + return AVERROR(EINVAL); + + buf_size = size + size/2 + 1; + *str = av_malloc(buf_size); + if (!*str) + return AVERROR(ENOMEM); + + if ((ret = avio_get_str16be(pb, size, *str, buf_size)) < 0) { + av_freep(str); + return ret; + } + + return ret; +} + +static int mxf_uid_to_str(UID uid, char **str) +{ + int i; + char *p; + p = *str = av_mallocz(sizeof(UID) * 2 + 4 + 1); + if (!p) + return AVERROR(ENOMEM); + for (i = 0; i < sizeof(UID); i++) { + snprintf(p, 2 + 1, "%.2x", uid[i]); + p += 2; + if (i == 3 || i == 5 || i == 7 || i == 9) { + snprintf(p, 1 + 1, "-"); + p++; + } + } + return 0; +} + +static int mxf_timestamp_to_str(uint64_t timestamp, char **str) +{ + struct tm time; + time.tm_year = (timestamp >> 48) - 1900; + time.tm_mon = (timestamp >> 48 & 0xF) - 1; + time.tm_mday = (timestamp >> 32 & 0xF); + time.tm_hour = (timestamp >> 24 & 0XF); + time.tm_min = (timestamp >> 16 & 0xF); + time.tm_sec = (timestamp >> 8 & 0xF); + + *str = av_mallocz(32); + if (!*str) + return AVERROR(ENOMEM); + strftime(*str, 32, "%F %T", &time); + + return 0; +} + +#define SET_STR_METADATA(pb, name, str) do { \ + if ((ret = mxf_read_utf16_string(pb, size, &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) \ + return ret; \ + av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \ +} while (0) + +#define SET_TS_METADATA(pb, name, var, str) do { \ + var = avio_rb64(pb); \ + if ((ret = mxf_timestamp_to_str(var, &str)) < 0) \ + return ret; \ + av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \ +} while (0) + +static int mxf_read_identification_metadata(void *arg, AVIOContext *pb, int tag, int size, UID _uid, int64_t klv_offset) +{ + MXFContext *mxf = arg; + AVFormatContext *s = mxf->fc; + int ret; + UID uid = { 0 }; + char *str = NULL; + uint64_t ts; + switch (tag) { + case 0x3C01: + SET_STR_METADATA(pb, "company_name", str); + break; + case 0x3C02: + SET_STR_METADATA(pb, "product_name", str); + break; + case 0x3C04: + SET_STR_METADATA(pb, "product_version", str); + break; + case 0x3C05: + SET_UID_METADATA(pb, "product_uid", uid, str); + break; + case 0x3C06: + SET_TS_METADATA(pb, "modification_date", ts, str); + break; + case 0x3C08: + SET_STR_METADATA(pb, "application_platform", str); + break; + case 0x3C09: + SET_UID_METADATA(pb, "generation_uid", uid, str); + break; + case 0x3C0A: + SET_UID_METADATA(pb, "uid", uid, str); + break; + } + return 0; +} + static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = { { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }, mxf_read_primer_pack }, { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }, mxf_read_partition_pack }, @@ -1631,6 +1745,7 @@ static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = { { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x04,0x00 }, mxf_read_partition_pack }, { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x02,0x00 }, mxf_read_partition_pack }, { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }, mxf_read_partition_pack }, + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x30,0x00 }, mxf_read_identification_metadata }, { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_content_storage, 0, AnyType }, { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_source_package, sizeof(MXFPackage), SourcePackage }, { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_material_package, sizeof(MXFPackage), MaterialPackage }, |