[vlc-devel] [PATCH 03/48] hls: Fix relative url

Jean-Paul Saman jpsaman at videolan.org
Tue Jan 10 11:16:54 CET 2012


Please provide a test sample that needs this patch to work.

Kind regards,

Jean-Paul Saman

On Mon, Jan 9, 2012 at 4:16 PM, Hugo Beauzée-Luyssen <beauze.h at gmail.com> wrote:
> From: Luc Saillard <luc.saillard at sfr.com>
>
> Don't add current directory, when the url is relative to the root server
> ---
>  modules/stream_filter/httplive.c |  142 ++++++++++++++------------------------
>  1 files changed, 53 insertions(+), 89 deletions(-)
>
> diff --git a/modules/stream_filter/httplive.c b/modules/stream_filter/httplive.c
> index 20e2821..f7aeab1 100644
> --- a/modules/stream_filter/httplive.c
> +++ b/modules/stream_filter/httplive.c
> @@ -89,7 +89,7 @@ typedef struct hls_stream_s
>
>  struct stream_sys_t
>  {
> -    vlc_url_t     m3u8;         /* M3U8 url */
> +    char         *m3u8_playlist;/* M3U8 url */
>     vlc_thread_t  reload;       /* HLS m3u8 reload thread */
>     vlc_thread_t  thread;       /* HLS segment download thread */
>
> @@ -139,8 +139,8 @@ static int  Read   (stream_t *, void *p_read, unsigned int i_read);
>  static int  Peek   (stream_t *, const uint8_t **pp_peek, unsigned int i_peek);
>  static int  Control(stream_t *, int i_query, va_list);
>
> -static ssize_t read_M3U8_from_stream(stream_t *s, uint8_t **buffer);
> -static ssize_t read_M3U8_from_url(stream_t *s, vlc_url_t *url, uint8_t **buffer);
> +static ssize_t read_M3U8(stream_t *s, const char *psz_url, uint8_t **buffer);
> +static ssize_t ReadM3U8(stream_t *s, uint8_t **buffer);
>  static char *ReadLine(uint8_t *buffer, uint8_t **pos, size_t len);
>
>  static int hls_Download(stream_t *s, segment_t *segment);
> @@ -461,46 +461,52 @@ static char *parse_Attributes(const char *line, const char *attr)
>     return NULL;
>  }
>
> -static char *relative_URI(stream_t *s, const char *uri, const char *path)
> +/*
> + * Return an uri, that must be free with free().
> + */
> +static char *relative_URI(const char *uri, const char *parent_uri)
>  {
> -    stream_sys_t *p_sys = s->p_sys;
> +    char *p;
> +    char *parent_uri_base;
> +    char *new_uri;
>
> -    char *p = strchr(uri, ':');
> +    /* is address absolute (aka http://xxxx) ? */
> +    p = strstr(uri, "://");
>     if (p != NULL)
> -        return NULL;
> -
> -    if (p_sys->m3u8.psz_path == NULL)
> -        return NULL;
> +      return strdup(uri);
>
> -    char *psz_path = strdup(p_sys->m3u8.psz_path);
> -    if (psz_path == NULL) return NULL;
> -    p = strrchr(psz_path, '/');
> -    if (p) *p = '\0';
> -
> -    char *psz_uri = NULL;
> -    if (p_sys->m3u8.psz_password || p_sys->m3u8.psz_username)
> +    if (*uri == '/')
>     {
> -        if (asprintf(&psz_uri, "%s://%s:%s@%s:%d%s/%s", p_sys->m3u8.psz_protocol,
> -                     p_sys->m3u8.psz_username, p_sys->m3u8.psz_password,
> -                     p_sys->m3u8.psz_host, p_sys->m3u8.i_port,
> -                     path ? path : psz_path, uri) < 0)
> -            goto fail;
> +        /* This url is relative to the root of the server */
> +        parent_uri_base = strdup(parent_uri);
> +        p = strstr(parent_uri_base, "://");
> +        if (p)
> +        {
> +            p = strchr(p+3, '/');
> +            if (p)
> +                *p = 0;
> +        }
>     }
>     else
>     {
> -        if (asprintf(&psz_uri, "%s://%s:%d%s/%s", p_sys->m3u8.psz_protocol,
> -                     p_sys->m3u8.psz_host, p_sys->m3u8.i_port,
> -                     path ? path : psz_path, uri) < 0)
> -           goto fail;
> +        /* This url is relative to the current dir of the server */
> +        parent_uri_base = strdup(parent_uri);
> +        p = strrchr(parent_uri_base, '/');
> +        if (p)
> +            p[1] = 0;
>     }
> -    free(psz_path);
> -    return psz_uri;
>
> -fail:
> -    free(psz_path);
> -    return NULL;
> +    if (asprintf(&new_uri, "%s%s", parent_uri_base, uri) < 0)
> +    {
> +        free(parent_uri_base);
> +        return NULL;
> +    }
> +
> +    free(parent_uri_base);
> +    return new_uri;
>  }
>
> +
>  static char *ConstructUrl(vlc_url_t *url)
>  {
>     if ((url->psz_protocol == NULL) ||
> @@ -586,18 +592,7 @@ static int parse_AddSegment(stream_t *s, hls_stream_t *hls, const int duration,
>     assert(hls);
>     assert(uri);
>
> -    /* Store segment information */
> -    char *psz_path = NULL;
> -    if (hls->url.psz_path != NULL)
> -    {
> -        psz_path = strdup(hls->url.psz_path);
> -        if (psz_path == NULL)
> -            return VLC_ENOMEM;
> -        char *p = strrchr(psz_path, '/');
> -        if (p) *p = '\0';
> -    }
> -    char *psz_uri = relative_URI(s, uri, psz_path);
> -    free(psz_path);
> +    char *psz_uri = relative_URI(uri, hls->uri);
>
>     vlc_mutex_lock(&hls->lock);
>     segment_t *segment = segment_New(hls, duration, psz_uri ? psz_uri : uri);
> @@ -661,7 +656,7 @@ static int parse_StreamInformation(stream_t *s, vlc_array_t **hls_stream,
>
>     msg_Info(s, "bandwidth adaptation detected (program-id=%d, bandwidth=%"PRIu64").", id, bw);
>
> -    char *psz_uri = relative_URI(s, uri, NULL);
> +    char *psz_uri = relative_URI(uri, s->p_sys->m3u8_playlist);
>
>     *hls = hls_New(*hls_stream, id, bw, psz_uri ? psz_uri : uri);
>
> @@ -893,7 +888,7 @@ static int parse_M3U8(stream_t *s, vlc_array_t *streams, uint8_t *buffer, const
>
>                     /* Download playlist file from server */
>                     uint8_t *buf = NULL;
> -                    ssize_t len = read_M3U8_from_url(s, &hls->url, &buf);
> +                    ssize_t len = read_M3U8(s, hls->url, &buf);
>                     if (len < 0)
>                         err = VLC_EGENERIC;
>                     else
> @@ -1007,43 +1002,17 @@ static int get_HTTPLiveMetaPlaylist(stream_t *s, vlc_array_t **streams)
>  {
>     stream_sys_t *p_sys = s->p_sys;
>     assert(*streams);
> -    int err = VLC_EGENERIC;
> -
> -    /* Duplicate HLS stream META information */
> -    for (int i = 0; i < vlc_array_count(p_sys->hls_stream); i++)
> -    {
> -        hls_stream_t *src, *dst;
> -        src = (hls_stream_t *)vlc_array_item_at_index(p_sys->hls_stream, i);
> -        if (src == NULL)
> -            return VLC_EGENERIC;
> -
> -        dst = hls_Copy(src, false);
> -        if (dst == NULL)
> -            return VLC_ENOMEM;
> -
> -        vlc_array_append(*streams, dst);
> -    }
> +    int     err = VLC_SUCCESS;
>
>     /* Download new playlist file from server */
> -    for (int i = 0; i < vlc_array_count(*streams); i++)
> -    {
> -        hls_stream_t *hls;
> -        hls = (hls_stream_t *)vlc_array_item_at_index(*streams, i);
> -        if (hls == NULL)
> -            return VLC_EGENERIC;
> +    uint8_t *buffer = NULL;
> +    ssize_t len = read_M3U8(s, p_sys->m3u8_playlist, &buffer);
> +    if (len < 0)
> +        return VLC_EGENERIC;
> +
> +    err = parse_M3U8(s, *streams, buffer, len);
> +    free(buffer);
>
> -        /* Download playlist file from server */
> -        uint8_t *buf = NULL;
> -        ssize_t len = read_M3U8_from_url(s, &hls->url, &buf);
> -        if (len < 0)
> -            err = VLC_EGENERIC;
> -        else
> -        {
> -            /* Parse HLS m3u8 content. */
> -            err = parse_M3U8(s, *streams, buf, len);
> -            free(buf);
> -        }
> -    }
>     return err;
>  }
>
> @@ -1530,7 +1499,6 @@ static int hls_Download(stream_t *s, segment_t *segment)
>     return VLC_SUCCESS;
>  }
>
> -/* Read M3U8 file */
>  static ssize_t read_M3U8_from_stream(stream_t *s, uint8_t **buffer)
>  {
>     int64_t total_bytes = 0;
> @@ -1642,14 +1610,12 @@ static int Open(vlc_object_t *p_this)
>     if (p_sys == NULL)
>         return VLC_ENOMEM;
>
> -    char *psz_uri = NULL;
> -    if (asprintf(&psz_uri,"%s://%s", s->psz_access, s->psz_path) < 0)
> +    p_sys->m3u8_playlist = NULL;
> +    if (asprintf(&p_sys->m3u8_playlist,"%s://%s", s->psz_access, s->psz_path) < 0)
>     {
>         free(p_sys);
>         return VLC_ENOMEM;
>     }
> -    vlc_UrlParse(&p_sys->m3u8, psz_uri, 0);
> -    free(psz_uri);
>
>     p_sys->bandwidth = 0;
>     p_sys->b_live = true;
> @@ -1659,7 +1625,7 @@ static int Open(vlc_object_t *p_this)
>     p_sys->hls_stream = vlc_array_new();
>     if (p_sys->hls_stream == NULL)
>     {
> -        vlc_UrlClean(&p_sys->m3u8);
> +        free(p_sys->m3u8_playlist);
>         free(p_sys);
>         return VLC_ENOMEM;
>     }
> @@ -1742,7 +1708,7 @@ fail:
>     vlc_array_destroy(p_sys->hls_stream);
>
>     /* */
> -    vlc_UrlClean(&p_sys->m3u8);
> +    free(p_sys->m3u8_playlist);
>     free(p_sys);
>     return VLC_EGENERIC;
>  }
> @@ -1779,9 +1745,7 @@ static void Close(vlc_object_t *p_this)
>     vlc_array_destroy(p_sys->hls_stream);
>
>     /* */
> -    vlc_UrlClean(&p_sys->m3u8);
> -    if (p_sys->peeked)
> -        block_Release (p_sys->peeked);
> +    free(p_sys->m3u8_playlist);
>     free(p_sys);
>  }
>
> --
> 1.7.8.3
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> http://mailman.videolan.org/listinfo/vlc-devel



More information about the vlc-devel mailing list