lavf/mxfdec: handle identification metadata

This commit is contained in:
Matthieu Bouron 2013-03-29 14:09:31 +01:00
parent 018cc6f026
commit 25b143aa7b
1 changed files with 115 additions and 0 deletions

View File

@ -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 },