vlc | branch: master | Petri Hintukainen <[email protected]> | Sun Jan 17 19:26:06 2016 +0200| [b6d31b98a797894941fbcd6e3e36d2028138f8f0] | committer: Jean-Baptiste Kempf
bluray: add support for stream input Enable playback of BluRay disc images over smb/ssh/... Signed-off-by: Jean-Baptiste Kempf <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b6d31b98a797894941fbcd6e3e36d2028138f8f0 --- modules/access/bluray.c | 140 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 126 insertions(+), 14 deletions(-) diff --git a/modules/access/bluray.c b/modules/access/bluray.c index 75a2aa0..241f10f 100644 --- a/modules/access/bluray.c +++ b/modules/access/bluray.c @@ -96,6 +96,15 @@ vlc_module_begin () add_shortcut("bluray", "file") set_callbacks(blurayOpen, blurayClose) + + /* demux module */ + add_submodule() + set_description( "BluRay demuxer" ) + set_category( CAT_INPUT ) + set_subcategory( SUBCAT_INPUT_DEMUX ) + set_capability( "demux", 5 ) + set_callbacks( blurayOpen, blurayClose ) + vlc_module_end () /* libbluray's overlay.h defines 2 types of overlay (bd_overlay_plane_e). */ @@ -171,6 +180,9 @@ struct demux_sys_t bool b_flushed; bool b_pl_playing; /* true when playing playlist */ + /* stream input */ + vlc_mutex_t read_block_lock; + /* Used to store bluray disc path */ char *psz_bd_path; }; @@ -460,19 +472,94 @@ static void attachThumbnail(demux_t *p_demux) } /***************************************************************************** + * stream input + *****************************************************************************/ + +static int probeStream(demux_t *p_demux) +{ + /* input must be seekable */ + bool b_canseek = false; + stream_Control( p_demux->s, STREAM_CAN_SEEK, &b_canseek ); + if (!b_canseek) { + return VLC_EGENERIC; + } + + /* first sector(s) should be filled with zeros */ + size_t i_peek; + const uint8_t *p_peek; + i_peek = stream_Peek( p_demux->s, &p_peek, 2048 ); + if( i_peek < 512 ) { + return VLC_EGENERIC; + } + while (i_peek > 0) { + if (p_peek[ --i_peek ]) { + return VLC_EGENERIC; + } + } + + return VLC_SUCCESS; +} + +static int blurayReadBlock(void *object, void *buf, int lba, int num_blocks) +{ + int result = -1; + + if (object) { + demux_t *p_demux = (demux_t*)object; + demux_sys_t *p_sys = p_demux->p_sys; + + assert(p_demux->s != NULL); + + vlc_mutex_lock(&p_sys->read_block_lock); + + if (stream_Seek( p_demux->s, (int64_t)lba * 2048 ) == VLC_SUCCESS) { + size_t req = (size_t)2048 * num_blocks; + ssize_t got; + + got = stream_Read( p_demux->s, buf, req); + if (got < 0 || (size_t)got != req) { + msg_Err(p_demux, "read from lba %d failed: got %zd/%zu", lba, got, req); + } + if (got > 0) { + result = got / 2048; + } + } else { + msg_Err(p_demux, "seek to lba %d failed", lba); + } + vlc_mutex_unlock(&p_sys->read_block_lock); + } + + return result; +} + +/***************************************************************************** * blurayOpen: module init function *****************************************************************************/ static int blurayOpen(vlc_object_t *object) { demux_t *p_demux = (demux_t*)object; demux_sys_t *p_sys; + bool forced; + int64_t i_init_pos = 0; const char *error_msg = NULL; #define BLURAY_ERROR(s) do { error_msg = s; goto error; } while(0) - if (strcmp(p_demux->psz_access, "bluray")) { - // TODO BDMV support, once we figure out what to do in libbluray - return VLC_EGENERIC; + forced = !strcasecmp(p_demux->psz_access, "bluray"); + + if (p_demux->s) { + if (p_demux->psz_access == NULL || !strcasecmp(p_demux->psz_access, "file")) { + /* use access_demux for local files */ + return VLC_EGENERIC; + } + + if (probeStream(p_demux) != VLC_SUCCESS) { + return VLC_EGENERIC; + } + } else { + if (!forced || !p_demux->psz_file) { + return VLC_EGENERIC; + } } /* */ @@ -493,18 +580,30 @@ static int blurayOpen(vlc_object_t *object) TAB_INIT(p_sys->i_title, p_sys->pp_title); TAB_INIT(p_sys->i_attachments, p_sys->attachments); - /* store current bd path */ - if (p_demux->psz_file) - p_sys->psz_bd_path = strdup(p_demux->psz_file); - - /* If we're passed a block device, try to convert it to the mount point. */ - FindMountPoint(&p_sys->psz_bd_path); - vlc_mutex_init(&p_sys->pl_info_lock); vlc_mutex_init(&p_sys->bdj_overlay_lock); + vlc_mutex_init(&p_sys->read_block_lock); /* used during bd_open_stream() */ + var_AddCallback( p_demux->p_input, "intf-event", onIntfEvent, p_demux ); - p_sys->bluray = bd_open(p_sys->psz_bd_path, NULL); + /* Open BluRay */ + if (p_demux->s) { + i_init_pos = stream_Tell(p_demux->s); + + p_sys->bluray = bd_init(); + if (!bd_open_stream(p_sys->bluray, p_demux, blurayReadBlock)) { + bd_close(p_sys->bluray); + p_sys->bluray = NULL; + } + } else { + /* store current bd path */ + p_sys->psz_bd_path = strdup(p_demux->psz_file); + + /* If we're passed a block device, try to convert it to the mount point. */ + FindMountPoint(&p_sys->psz_bd_path); + + p_sys->bluray = bd_open(p_sys->psz_bd_path, NULL); + } if (!p_sys->bluray) { goto error; } @@ -513,8 +612,12 @@ static int blurayOpen(vlc_object_t *object) const BLURAY_DISC_INFO *disc_info = bd_get_disc_info(p_sys->bluray); /* Is it a bluray? */ - if (!disc_info->bluray_detected) - BLURAY_ERROR(_("Path doesn't appear to be a Blu-ray")); + if (!disc_info->bluray_detected) { + if (forced) { + BLURAY_ERROR(_("Path doesn't appear to be a Blu-ray")); + } + goto error; + } msg_Info(p_demux, "First play: %i, Top menu: %i\n" "HDMV Titles: %i, BD-J Titles: %i, Other: %i", @@ -647,6 +750,14 @@ error: if (error_msg) dialog_Fatal(p_demux, _("Blu-ray error"), "%s", error_msg); blurayClose(object); + + if (p_demux->s != NULL && i_init_pos >= 0) { + /* restore stream position */ + if (stream_Seek(p_demux->s, i_init_pos) ) { + msg_Err(p_demux, "Failed to seek back to stream start"); + } + } + return VLC_EGENERIC; #undef BLURAY_ERROR } @@ -693,6 +804,7 @@ static void blurayClose(vlc_object_t *object) vlc_mutex_destroy(&p_sys->pl_info_lock); vlc_mutex_destroy(&p_sys->bdj_overlay_lock); + vlc_mutex_destroy(&p_sys->read_block_lock); free(p_sys->psz_bd_path); free(p_sys); @@ -1703,7 +1815,7 @@ static int blurayControl(demux_t *p_demux, int query, va_list args) p_sys->attachments[p_sys->i_cover_idx]->psz_name ); vlc_meta_Set( p_meta, vlc_meta_ArtworkURL, psz_url ); } - else if (meta->thumb_count > 0 && meta->thumbnails) { + else if (meta->thumb_count > 0 && meta->thumbnails && p_sys->psz_bd_path) { char *psz_thumbpath; if (asprintf(&psz_thumbpath, "%s" DIR_SEP "BDMV" DIR_SEP "META" DIR_SEP "DL" DIR_SEP "%s", p_sys->psz_bd_path, meta->thumbnails[0].path) > 0) { _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
