1
0
Fork 0

Add support for parsing (and dumping) Static Metadata extension (extension 3.5)

This commit is contained in:
rapperskull 2020-05-01 23:41:44 +02:00 committed by hpi1
parent 9795d2e10f
commit 483c5b0b2f
3 changed files with 135 additions and 5 deletions

View File

@ -372,6 +372,35 @@ _show_pip_metadata(MPLS_PL *pl, int level)
}
}
static void
_show_static_metadata_entry(MPLS_STATIC_METADATA *entry, int level)
{
indent_printf(level, "Dynamic Range Type: %d", entry->dynamic_range_type);
indent_printf(level, "Mastering Display Primary R (X, Y): (%f, %f)", (float)entry->display_primaries_x[primary_red]/50000L, (float)entry->display_primaries_y[primary_red]/50000L);
indent_printf(level, "Mastering Display Primary G (X, Y): (%f, %f)", (float)entry->display_primaries_x[primary_green]/50000L, (float)entry->display_primaries_y[primary_green]/50000L);
indent_printf(level, "Mastering Display Primary B (X, Y): (%f, %f)", (float)entry->display_primaries_x[primary_blue]/50000L, (float)entry->display_primaries_y[primary_blue]/50000L);
indent_printf(level, "White Point (X, Y): (%f, %f)", (float)entry->white_point_x/50000L, (float)entry->white_point_y/50000L);
indent_printf(level, "Display Mastering Luminance (min, max): (%.4f, %.4f)", (float)entry->min_display_mastering_luminance/10000L, (float)entry->max_display_mastering_luminance);
indent_printf(level, "Maximum Frame Average Light Level (MaxFALL): %d", entry->max_CLL);
indent_printf(level, "Maximum Content Light Level (MaxCLL): %d", entry->max_FALL);
}
static void
_show_static_metadata(MPLS_PL *pl, int level)
{
int ii;
for (ii = 0; ii < pl->ext_static_metadata_count; ii++) {
MPLS_STATIC_METADATA *data;
data = &pl->ext_static_metadata[ii];
indent_printf(level, "Static metadata entry %d:", ii);
_show_static_metadata_entry(data, level+1);
}
printf("\n");
}
static void
_show_sub_paths(MPLS_PL *pl, int level)
{
@ -400,6 +429,7 @@ _show_sub_paths_ss(MPLS_PL *pl, int level)
indent_printf(level, "Extension Sub Path %d:", ss);
_show_sub_path(sub, level+1);
}
printf("\n");
}
static uint32_t
@ -490,7 +520,7 @@ _filter_repeats(MPLS_PL *pl, int repeats)
return 1;
}
static int clip_list = 0, playlist_info = 0, chapter_marks = 0, sub_paths = 0, pip_metadata = 0;
static int clip_list = 0, playlist_info = 0, chapter_marks = 0, sub_paths = 0, pip_metadata = 0, static_metadata = 0;
static int repeats = 0, seconds = 0, dups = 0;
static MPLS_PL*
@ -551,6 +581,9 @@ _process_file(char *name, MPLS_PL *pl_list[], int pl_count)
_show_sub_paths(pl, 1);
_show_sub_paths_ss(pl, 1);
}
if (static_metadata) {
_show_static_metadata(pl, 1);
}
return pl;
}
@ -567,6 +600,7 @@ _usage(char *cmd)
" c - Show chapter marks\n"
" p - Show sub paths\n"
" P - Show picture-in-picture metadata\n"
" S - Show static metadata\n"
" r <N> - Filter out titles that have >N repeating clips\n"
" d - Filter out duplicate titles\n"
" s <seconds> - Filter out short titles\n"
@ -576,7 +610,7 @@ _usage(char *cmd)
exit(EXIT_FAILURE);
}
#define OPTS "vlicpPfr:ds:"
#define OPTS "vlicpPSfr:ds:"
static int
_qsort_str_cmp(const void *a, const void *b)
@ -628,6 +662,10 @@ main(int argc, char *argv[])
pip_metadata = 1;
break;
case 'S':
static_metadata = 1;
break;
case 'd':
dups = 1;
break;

View File

@ -173,6 +173,25 @@ typedef struct {
MPLS_PIP_DATA *data;
} MPLS_PIP_METADATA;
typedef enum {
primary_green,
primary_blue,
primary_red
} mpls_static_primaries; /* They are stored as GBR, we would like to show them as RGB */
typedef struct mpls_static_metadata
{
uint8_t dynamic_range_type;
uint16_t display_primaries_x[3];
uint16_t display_primaries_y[3];
uint16_t white_point_x;
uint16_t white_point_y;
uint16_t max_display_mastering_luminance;
uint16_t min_display_mastering_luminance;
uint16_t max_CLL;
uint16_t max_FALL;
} MPLS_STATIC_METADATA;
typedef struct mpls_pl
{
uint32_t type_indicator; /* 'MPLS' */
@ -196,6 +215,10 @@ typedef struct mpls_pl
uint16_t ext_pip_data_count;
MPLS_PIP_METADATA *ext_pip_data; // pip metadata extension
// extension data (Static Metadata)
uint8_t ext_static_metadata_count;
MPLS_STATIC_METADATA *ext_static_metadata;
} MPLS_PL;
#endif // BLURAY_MPLS_DATA_H_

View File

@ -960,6 +960,77 @@ _parse_subpath_extension(BITSTREAM *bits, MPLS_PL *pl)
return 0;
}
static int
_parse_static_metadata(BITSTREAM *bits, MPLS_STATIC_METADATA *data)
{
int ii;
if (bs_avail(bits) < 28 * 8) {
BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_static_metadata: unexpected end of file\n");
return 0;
}
data->dynamic_range_type = bs_read(bits, 4);
bs_skip(bits,4);
bs_skip(bits,24);
for(ii = 0; ii < 3; ii++){
data->display_primaries_x[ii] = bs_read(bits, 16);
data->display_primaries_y[ii] = bs_read(bits, 16);
}
data->white_point_x = bs_read(bits, 16);
data->white_point_y = bs_read(bits, 16);
data->max_display_mastering_luminance = bs_read(bits, 16);
data->min_display_mastering_luminance = bs_read(bits, 16);
data->max_CLL = bs_read(bits, 16);
data->max_FALL = bs_read(bits, 16);
return 1;
}
static int
_parse_static_metadata_extension(BITSTREAM *bits, MPLS_PL *pl)
{
MPLS_STATIC_METADATA *static_metadata;
uint32_t len;
int ii;
len = bs_read(bits, 32);
if (len < 32) { // At least one static metadata entry
return 0;
}
if (bs_avail(bits) < len * 8) {
BD_DEBUG(DBG_NAV | DBG_CRIT, "_parse_static_metadata_extension: unexpected end of file\n");
return 0;
}
uint8_t sm_count = bs_read(bits, 8);
if (sm_count < 1) {
return 0;
}
bs_skip(bits, 24);
static_metadata = calloc(sm_count, sizeof(MPLS_STATIC_METADATA));
if (!static_metadata) {
BD_DEBUG(DBG_CRIT, "out of memory\n");
return 0;
}
for (ii = 0; ii < sm_count; ii++) {
if (!_parse_static_metadata(bits, &static_metadata[ii])) {
goto error;
}
}
pl->ext_static_metadata = static_metadata;
pl->ext_static_metadata_count = sm_count;
return 1;
error:
BD_DEBUG(DBG_NAV | DBG_CRIT, "error parsing static metadata extension\n");
X_FREE(static_metadata);
return 0;
}
static int
_parse_mpls_extension(BITSTREAM *bits, int id1, int id2, void *handle)
{
@ -984,9 +1055,7 @@ _parse_mpls_extension(BITSTREAM *bits, int id1, int id2, void *handle)
if (id1 == 3) {
if (id2 == 5) {
// UHD extension
BD_DEBUG(DBG_NAV, "_parse_mpls_extension(): unhandled extension %d.%d\n", id1, id2);
return 0;
return _parse_static_metadata_extension(bits, pl);
}
}