[vlc-devel] [PATCH v4] bluray: add support for stream input

Petri Hintukainen phintuka at gmail.com
Tue Jan 19 09:49:57 CET 2016


On ma, 2016-01-18 at 11:45 +0200, Rémi Denis-Courmont wrote:
> Le 2016-01-17 19:26, Petri Hintukainen a écrit :
> > Enable playback of BluRay disc images over smb/ssh/...
> > ---
> >  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..98a2389 100644
> > --- a/modules/access/bluray.c
> > +++ b/modules/access/bluray.c
> > @@ -96,6 +96,15 @@ vlc_module_begin ()
> >      add_shortcut("bluray", "file")
> 
> Remove "file" ?

Unrelated

> > 
> >      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 ) {
> 
> AFAIK, stream_Peek() cannot return less than asked unless the 
> end-of-stream or error. So this does not make much sense.

Changed to != 2048

> > +        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) {
> 
> Tautology?

Removed

> > +        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) {
> 
> lba * INT64_C(2048) ?
>
> > +            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) {
> 
> Ain't i_init_pos >= 0 a tautology?

Removed.

Can we assume initial position is always 0 (stream start) ?

> > +        /* 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_ETIMEOUT?

Ok, this seems to avoid probing other plugins.

> > +        }
> > +    }
> > +
> >      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) {
> 


More information about the vlc-devel mailing list