[libbluray-devel] Parse PiP metadata from playlist file extension data
hpi1
git at videolan.org
Fri Jan 11 21:53:02 CET 2013
libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Fri Jan 11 22:50:06 2013 +0200| [b6ba998da8cbedcbe321d36ac9a8117aab11b70e] | committer: hpi1
Parse PiP metadata from playlist file extension data
> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=b6ba998da8cbedcbe321d36ac9a8117aab11b70e
---
src/examples/mpls_dump.c | 50 +++++++++++++++++++-
src/libbluray/bdnav/mpls_parse.c | 95 ++++++++++++++++++++++++++++++++++++++
src/libbluray/bdnav/mpls_parse.h | 24 ++++++++++
3 files changed, 167 insertions(+), 2 deletions(-)
diff --git a/src/examples/mpls_dump.c b/src/examples/mpls_dump.c
index 7079dcb..fd117e9 100644
--- a/src/examples/mpls_dump.c
+++ b/src/examples/mpls_dump.c
@@ -363,6 +363,44 @@ _show_sub_path(MPLS_SUB *sub, int level)
}
static void
+_show_pip_metadata_block(MPLS_PIP_METADATA *block, int level)
+{
+ int ii;
+
+ indent_printf(level, "Clip ref: %d", block->clip_ref);
+ indent_printf(level, "Secondary video ref: %d", block->secondary_video_ref);
+ indent_printf(level, "Timeline type: %d", block->timeline_type);
+ indent_printf(level, "Luma key flag: %d", block->luma_key_flag);
+ if (block->luma_key_flag) {
+ indent_printf(level, "Upper limit luma key: %d", block->upper_limit_luma_key);
+ }
+ indent_printf(level, "Trick play flag: %d", block->trick_play_flag);
+
+ for (ii = 0; ii < block->data_count; ii++) {
+ indent_printf(level, "data block %d:", ii);
+ indent_printf(level+1, "Timestamp: %d", block->data[ii].time);
+ indent_printf(level+1, "Horizontal position %d", block->data[ii].xpos);
+ indent_printf(level+1, "Vertical position: %d", block->data[ii].ypos);
+ indent_printf(level+1, "Scaling factor: %d", block->data[ii].scale_factor);
+ }
+}
+
+static void
+_show_pip_metadata(MPLS_PL *pl, int level)
+{
+ int ii;
+
+ for (ii = 0; ii < pl->ext_pip_data_count; ii++) {
+ MPLS_PIP_METADATA *data;
+
+ data = &pl->ext_pip_data[ii];
+
+ indent_printf(level, "PiP metadata block %d:", ii);
+ _show_pip_metadata_block(data, level+1);
+ }
+}
+
+static void
_show_sub_paths(MPLS_PL *pl, int level)
{
int ss;
@@ -480,7 +518,7 @@ _filter_repeats(MPLS_PL *pl, int repeats)
return 1;
}
-static int clip_list = 0, playlist_info = 0, chapter_marks = 0, sub_paths = 0;
+static int clip_list = 0, playlist_info = 0, chapter_marks = 0, sub_paths = 0, pip_metadata = 0;
static int repeats = 0, seconds = 0, dups = 0;
static MPLS_PL*
@@ -530,6 +568,9 @@ _process_file(char *name, MPLS_PL *pl_list[], int pl_count)
if (chapter_marks) {
_show_marks(pl, 1);
}
+ if (pip_metadata) {
+ _show_pip_metadata(pl, 1);
+ }
if (clip_list) {
_show_clip_list(pl, 1);
}
@@ -552,6 +593,7 @@ _usage(char *cmd)
" i - Dumps detailed information about each clip\n"
" c - Show chapter marks\n"
" p - Show sub paths\n"
+" P - Show picture-in-picture 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"
@@ -561,7 +603,7 @@ _usage(char *cmd)
exit(EXIT_FAILURE);
}
-#define OPTS "vlicpfr:ds:"
+#define OPTS "vlicpPfr:ds:"
static int
_qsort_str_cmp(const void *a, const void *b)
@@ -609,6 +651,10 @@ main(int argc, char *argv[])
sub_paths = 1;
break;
+ case 'P':
+ pip_metadata = 1;
+ break;
+
case 'd':
dups = 1;
break;
diff --git a/src/libbluray/bdnav/mpls_parse.c b/src/libbluray/bdnav/mpls_parse.c
index 2ae1e73..e4d161e 100644
--- a/src/libbluray/bdnav/mpls_parse.c
+++ b/src/libbluray/bdnav/mpls_parse.c
@@ -1,6 +1,7 @@
/*
* This file is part of libbluray
* Copyright (C) 2009-2010 John Stebbins
+ * Copyright (C) 2012 Petri Hintukainen <phintuka at users.sourceforge.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -742,6 +743,93 @@ mpls_free(MPLS_PL *pl)
}
static int
+_parse_pip_data(BITSTREAM *bits, MPLS_PIP_METADATA *block)
+{
+ MPLS_PIP_DATA *data;
+ unsigned ii;
+
+ uint16_t entries = bs_read(bits, 16);
+ if (entries < 1) {
+ return 1;
+ }
+
+ data = calloc(entries, sizeof(MPLS_PIP_DATA));
+ for (ii = 0; ii < entries; ii++) {
+
+ data[ii].time = bs_read(bits, 32);
+ data[ii].xpos = bs_read(bits, 12);
+ data[ii].ypos = bs_read(bits, 12);
+ data[ii].scale_factor = bs_read(bits, 4);
+ bs_skip(bits, 4);
+ }
+
+ block->data_count = entries;
+ block->data = data;
+
+ return 1;
+}
+
+static int
+_parse_pip_metadata_block(BITSTREAM *bits, uint32_t start_address, MPLS_PIP_METADATA *data)
+{
+ uint32_t data_address, pos;
+ int result;
+
+ data->clip_ref = bs_read(bits, 16);
+ data->secondary_video_ref = bs_read(bits, 8);
+ bs_skip(bits, 8);
+ data->timeline_type = bs_read(bits, 4);
+ data->luma_key_flag = bs_read(bits, 1);
+ data->trick_play_flag = bs_read(bits, 1);
+ bs_skip(bits, 10);
+ if (data->luma_key_flag) {
+ bs_skip(bits, 8);
+ data->upper_limit_luma_key = bs_read(bits, 8);
+ } else {
+ bs_skip(bits, 16);
+ }
+ bs_skip(bits, 16);
+
+ data_address = bs_read(bits, 32);
+
+ pos = bs_pos(bits) / 8;
+ bs_seek_byte(bits, start_address + data_address);
+ result = _parse_pip_data(bits, data);
+ bs_seek_byte(bits, pos);
+
+ return result;
+}
+
+static int
+_parse_pip_metadata_extension(BITSTREAM *bits, MPLS_PL *pl)
+{
+ MPLS_PIP_METADATA *data;
+ int ii;
+
+ uint32_t start_address = bs_pos(bits) / 8;
+ uint32_t len = bs_read(bits, 32);
+ int entries = bs_read(bits, 16);
+
+ if (len < 1 || entries < 1) {
+ return 0;
+ }
+
+ data = calloc(entries, sizeof(MPLS_PIP_METADATA));
+ for (ii = 0; ii < entries; ii++) {
+ if (!_parse_pip_metadata_block(bits, start_address, data)) {
+ X_FREE(data);
+ fprintf(stderr, "error parsing pip metadata extension\n");
+ return 0;
+ }
+ }
+
+ pl->ext_pip_data_count = entries;
+ pl->ext_pip_data = data;
+
+ return 1;
+}
+
+static int
_parse_subpath_extension(BITSTREAM *bits, MPLS_PL *pl)
{
MPLS_SUB *sub_path;
@@ -773,6 +861,13 @@ _parse_mpls_extension(BITSTREAM *bits, int id1, int id2, void *handle)
{
MPLS_PL *pl = (MPLS_PL*)handle;
+ if (id1 == 1) {
+ if (id2 == 1) {
+ // PiP metadata extension
+ return _parse_pip_metadata_extension(bits, pl);
+ }
+ }
+
if (id1 == 2) {
if (id2 == 2) {
// SubPath entries extension
diff --git a/src/libbluray/bdnav/mpls_parse.h b/src/libbluray/bdnav/mpls_parse.h
index 549fa2e..588fff8 100644
--- a/src/libbluray/bdnav/mpls_parse.h
+++ b/src/libbluray/bdnav/mpls_parse.h
@@ -131,6 +131,25 @@ typedef struct
MPLS_SUB_PI *sub_play_item;
} MPLS_SUB;
+typedef struct {
+ uint32_t time;
+ uint16_t xpos;
+ uint16_t ypos;
+ uint8_t scale_factor;
+} MPLS_PIP_DATA;
+
+typedef struct {
+ uint16_t clip_ref;
+ uint8_t secondary_video_ref;
+ uint8_t timeline_type;
+ uint8_t luma_key_flag;
+ uint8_t upper_limit_luma_key;
+ uint8_t trick_play_flag;
+
+ uint16_t data_count;
+ MPLS_PIP_DATA *data;
+} MPLS_PIP_METADATA;
+
typedef struct
{
uint32_t type_indicator;
@@ -149,6 +168,11 @@ typedef struct
// extension data (profile 5, version 2.4)
uint16_t ext_sub_count;
MPLS_SUB *ext_sub_path; // sub path entries extension
+
+ // extension data (Picture-In-Picture metadata)
+ uint16_t ext_pip_data_count;
+ MPLS_PIP_METADATA *ext_pip_data; // pip metadata extension
+
} MPLS_PL;
More information about the libbluray-devel
mailing list