libbluray | branch: master | hpi1 <[email protected]> | Thu Nov 25 16:16:36 2010 +0200| [4b2b944f14372743885a4844b5c1cadce2725a18] | committer: hpi1
updated xine plugin: merged navigation mode (menus) support Note: menus with still background won't work. > http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=4b2b944f14372743885a4844b5c1cadce2725a18 --- player_wrappers/xine/HOWTO | 10 +- player_wrappers/xine/input_bluray.c | 144 +++++++++++++++++++++++++++-------- 2 files changed, 116 insertions(+), 38 deletions(-) diff --git a/player_wrappers/xine/HOWTO b/player_wrappers/xine/HOWTO index 48b00d5..4c9c628 100644 --- a/player_wrappers/xine/HOWTO +++ b/player_wrappers/xine/HOWTO @@ -8,10 +8,10 @@ Tested with xine-lib 1.1.18 sudo make install -3. Run xine passing it a bluray:// url as follows: +3. Run xine passing it a bluray:// or bd:// mrl as follows: - xine bluray:/path/to/disc - - e.g. - xine bluray:/mnt/BLURAY_DISC + + or using BluRay disc menus: + + xine bd:/mnt/BLURAY_DISC diff --git a/player_wrappers/xine/input_bluray.c b/player_wrappers/xine/input_bluray.c index 704771b..3d40955 100644 --- a/player_wrappers/xine/input_bluray.c +++ b/player_wrappers/xine/input_bluray.c @@ -111,6 +111,10 @@ typedef struct { int current_clip; int error; int menu_open; + int pg_enable; + int pg_stream; + + int nav_mode; } bluray_input_plugin_t; @@ -147,6 +151,8 @@ static void overlay_proc(void *this_gen, const BD_OVERLAY * const ov) if (!this->osd) { this->osd = xine_osd_new(this->stream, 0, 0, 1920, 1080); } + if (!this->pg_enable) + _x_select_spu_channel(this->stream, -1); /* convert and set palette */ @@ -271,8 +277,28 @@ static void handle_libbluray_event(bluray_input_plugin_t *this, BD_EVENT ev) /* stream selection */ case BD_EVENT_AUDIO_STREAM: + lprintf("BD_EVENT_AUDIO_STREAM %d\n", ev.param); + xine_set_param(this->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, ev.param - 1); + break; + case BD_EVENT_PG_TEXTST: + lprintf("BD_EVENT_PG_TEXTST %s\n", ev.param ? "ON" : "OFF"); + this->pg_enable = ev.param; + if (!this->pg_enable) { + _x_select_spu_channel(this->stream, -2); + } else { + _x_select_spu_channel(this->stream, this->pg_stream); + } + break; + case BD_EVENT_PG_TEXTST_STREAM: + lprintf("BD_EVENT_PG_TEXTST_STREAM %d\n", ev.param); + this->pg_stream = ev.param - 1; + if (this->pg_enable) { + _x_select_spu_channel(this->stream, this->pg_stream); + } + break; + case BD_EVENT_IG_STREAM: case BD_EVENT_SECONDARY_AUDIO: case BD_EVENT_SECONDARY_AUDIO_STREAM: @@ -432,8 +458,18 @@ static off_t bluray_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) handle_events(this); - result = bd_read(this->bdh, (unsigned char *)buf, len); - handle_libbluray_events(this); + if (this->nav_mode) { + do { + BD_EVENT ev; + result = bd_read_ext (this->bdh, (unsigned char *)buf, len, &ev); + handle_libbluray_event(this, ev); + if (result == 0) + handle_events(this); + } while (!this->error && result == 0); + } else { + result = bd_read (this->bdh, (unsigned char *)buf, len); + handle_libbluray_events(this); + } if (result < 0) LOGMSG("bd_read() failed: %s (%d of %d)\n", strerror(errno), (int)result, (int)len); @@ -653,49 +689,83 @@ static void bluray_plugin_dispose (input_plugin_t *this_gen) free (this); } -static int bluray_plugin_open (input_plugin_t *this_gen) +static int parse_mrl(const char *mrl_in, char **path, int *title, int *chapter) { - bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; - int title = -1, chapter = 0; + int skip = 0; - lprintf("bluray_plugin_open\n"); + if (!strncasecmp(mrl_in, "bluray:", 7)) + skip = 7; + else if (!strncasecmp(mrl_in, "bd:", 3)) + skip = 3; + else + return -1; - /* validate mrl */ + char *mrl = strdup(mrl_in + skip); - if (strncasecmp (this->mrl, "bluray:", 7)) - return -1; + /* title[.chapter] given ? parse and drop it */ + if (mrl[strlen(mrl)-1] != '/') { + char *end = strrchr(mrl, '/'); + if (end && end[1]) { + if (sscanf(end, "/%d.%d", title, chapter) < 1) + *title = -1; + else + *end = 0; + } + } + lprintf(" -> title %d, chapter %d, mrl \'%s\'\n", *title, *chapter, mrl); - if (!strcasecmp (this->mrl, "bluray:") || - !strcasecmp (this->mrl, "bluray:/") || - !strcasecmp (this->mrl, "bluray://") || - !strcasecmp (this->mrl, "bluray:///")) { + if ((mrl[0] == 0) || + (mrl[1] == 0 && mrl[0] == '/') || + (mrl[2] == 0 && mrl[1] == '/' && mrl[0] == '/') || + (mrl[3] == 0 && mrl[2] == '/' && mrl[1] == '/' && mrl[0] == '/')){ - this->disc_root = strdup(this->class->mountpoint); + /* default device */ + *path = NULL; - } else if (!strncasecmp (this->mrl, "bluray:/", 8)) { + } else if (*mrl == '/') { - if (!strncasecmp (this->mrl, "bluray:///", 10)) - this->disc_root = strdup(this->mrl + 9); - else if (!strncasecmp (this->mrl, "bluray://", 9)) - this->disc_root = strdup(this->mrl + 8); - else - this->disc_root = strdup(this->mrl + 7); + /* strip extra slashes */ + char *start = mrl; + while (start[0] == '/' && start[1] == '/') + start++; - _x_mrl_unescape(this->disc_root); + *path = strdup(start); - if (this->disc_root[strlen(this->disc_root)-1] != '/') { - char *end = strrchr(this->disc_root, '/'); - if (end && end[1]) - if (sscanf(end, "/%d.%d", &title, &chapter) < 1) - title = -1; - *end = 0; - } + _x_mrl_unescape(*path); + + lprintf("non-defaut mount point \'%s\'\n", *path); } else { - return -1; + lprintf("invalid mrl \'%s\'\n", mrl_in); + free(mrl); + return 0; } + free(mrl); + + return 1; +} + +static int bluray_plugin_open (input_plugin_t *this_gen) +{ + bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; + int title = -1; + int chapter = 0; + + lprintf("bluray_plugin_open\n"); + + /* validate and parse mrl */ + if (!parse_mrl(this->mrl, &this->disc_root, &title, &chapter)) + return -1; + + if (!strncasecmp(this->mrl, "bd:", 3)) + this->nav_mode = 1; + + if (!this->disc_root) + this->disc_root = strdup(this->class->mountpoint); + /* open libbluray */ + if (! (this->bdh = bd_open (this->disc_root, NULL))) { LOGMSG("bd_open(\'%s\') failed: %s\n", this->disc_root, strerror(errno)); return -1; @@ -745,9 +815,15 @@ static int bluray_plugin_open (input_plugin_t *this_gen) bd_set_player_setting_str(this->bdh, BLURAY_PLAYER_SETTING_COUNTRY_CODE, this->class->country); /* open */ + if (this->nav_mode) { + if (bd_play(this->bdh) <= 0) { + LOGMSG("bd_play() failed\n"); + return -1; + } + this->current_title = -1; - if (open_title(this, title) <= 0 && - open_title(this, 0) <= 0) + } else if (open_title(this, title) <= 0 && + open_title(this, 0) <= 0) return -1; /* jump to chapter */ @@ -768,7 +844,7 @@ static input_plugin_t *bluray_class_get_instance (input_class_t *cls_gen, xine_s lprintf("bluray_class_get_instance\n"); - if (strncasecmp (mrl, "bluray:", 7)) + if (strncasecmp(mrl, "bluray:", 7) && strncasecmp(mrl, "bd:", 3)) return NULL; this = (bluray_input_plugin_t *) calloc(1, sizeof (bluray_input_plugin_t)); @@ -951,8 +1027,10 @@ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ #if INPUT_PLUGIN_IFACE_VERSION <= 17 { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 17, "BLURAY", XINE_VERSION_CODE, NULL, bluray_init_plugin }, + { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 17, "BD", XINE_VERSION_CODE, NULL, bluray_init_plugin }, #elif INPUT_PLUGIN_IFACE_VERSION >= 18 { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "BLURAY", XINE_VERSION_CODE, NULL, bluray_init_plugin }, + { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "BD", XINE_VERSION_CODE, NULL, bluray_init_plugin }, #endif { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; _______________________________________________ libbluray-devel mailing list [email protected] http://mailman.videolan.org/listinfo/libbluray-devel
