[FFmpeg-devel] [PATCH 1/7] [GSoC] lavf: add directory listing API

Michael Niedermayer michaelni at gmx.at
Fri Mar 20 14:55:49 CET 2015


On Fri, Mar 20, 2015 at 03:01:56AM +0100, Mariusz Szczepańczyk wrote:
> From: Lukasz Marek <lukasz.m.luki2 at gmail.com>
> 
> API allows protocol implementations to provide API that
> allows to list directory content.
> API is similar to POSIX opendir/readdir/closedir.
> 
> Signed-off-by: Lukasz Marek <lukasz.m.luki2 at gmail.com>
> ---
>  libavformat/avio.c | 56 ++++++++++++++++++++++++++++++++++++++++++
>  libavformat/avio.h | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  libavformat/url.h  |  3 +++
>  3 files changed, 130 insertions(+), 1 deletion(-)
> 
> diff --git a/libavformat/avio.c b/libavformat/avio.c
> index 4896782..68c7114 100644
> --- a/libavformat/avio.c
> +++ b/libavformat/avio.c
> @@ -23,6 +23,7 @@
>  #include "libavutil/dict.h"
>  #include "libavutil/opt.h"
>  #include "libavutil/time.h"
> +#include "libavutil/avassert.h"
>  #include "os_support.h"
>  #include "avformat.h"
>  #if CONFIG_NETWORK
> @@ -418,6 +419,61 @@ int avio_check(const char *url, int flags)
>      return ret;
>  }
>  
> +int avio_open_dir(void **s, const char *url, AVDictionary **options)
> +{
> +    URLContext *h = NULL;
> +    int ret;
> +    av_assert0(s);
> +    if ((ret = ffurl_alloc(&h, url, AVIO_FLAG_READ, NULL)) < 0)
> +        goto fail;
> +
> +    if (h->prot->url_open_dir && h->prot->url_read_dir && h->prot->url_close_dir) {
> +        if (options && h->prot->priv_data_class &&
> +            (ret = av_opt_set_dict(h->priv_data, options)) < 0)
> +            goto fail;
> +        ret = h->prot->url_open_dir(h);
> +    }
> +    else
> +        ret = AVERROR(ENOSYS);
> +    if (ret < 0)
> +        goto fail;
> +    *s = h;
> +    return 0;
> +
> +  fail:
> +    *s = NULL;
> +    ffurl_close(h);
> +    return ret;
> +}
> +
> +int avio_read_dir(void *s, AVIODirEntry **next)
> +{
> +    URLContext *h = s;
> +    int ret;
> +    if ((ret = h->prot->url_read_dir(h, next)) < 0)
> +        avio_free_directory_entry(next);
> +    return ret;
> +}
> +
> +int avio_close_dir(void **s)
> +{
> +    URLContext *h;
> +    av_assert0(s);
> +    h = *s;
> +    h->prot->url_close_dir(h);
> +    ffurl_close(h);
> +    *s = NULL;
> +    return 0;
> +}
> +
> +void avio_free_directory_entry(AVIODirEntry **entry)
> +{
> +    if (!entry || !*entry)
> +        return;
> +    av_free((*entry)->name);
> +    av_freep(entry);
> +}
> +
>  int64_t ffurl_size(URLContext *h)
>  {
>      int64_t pos, size;
> diff --git a/libavformat/avio.h b/libavformat/avio.h
> index 8fc7e27..a6fdef1 100644
> --- a/libavformat/avio.h
> +++ b/libavformat/avio.h
> @@ -34,7 +34,6 @@
>  
>  #include "libavformat/version.h"
>  
> -
>  #define AVIO_SEEKABLE_NORMAL 0x0001 /**< Seeking works like for a local file */
>  
>  /**
> @@ -54,6 +53,41 @@ typedef struct AVIOInterruptCB {
>  } AVIOInterruptCB;
>  
>  /**
> + * Directory entry types.
> + */
> +enum AVIODirEntryType {
> +    AVIO_ENTRY_UNKNOWN,
> +    AVIO_ENTRY_BLOCK_DEVICE,
> +    AVIO_ENTRY_CHARACTER_DEVICE,
> +    AVIO_ENTRY_DIRECTORY,
> +    AVIO_ENTRY_NAMED_PIPE,
> +    AVIO_ENTRY_SYMBOLIC_LINK,
> +    AVIO_ENTRY_SOCKET,
> +    AVIO_ENTRY_FILE
> +};
> +
> +/**
> + * Describes single entry of the directory.
> + *
> + * Only name and type fileds are guaranteed be set.
> + * Rest of fields are protocol or/and platform dependent and might be unknown.

what values are the fields set to if "uknown"
this should be documented


> + */
> +typedef struct AVIODirEntry {
> +    char *name;                           /**< Filename */
> +    int utf8;                             /**< Set to 1 when name is encoded with UTF-8, 0 otherwise.
> +                                               Name can be encoded with UTF-8 eventhough 0 is set.
> +                                               Encoding might be unknown. */

> +    enum AVIODirEntryType type;           /**< Type of the entry */

enums should not be used in an API as their size can change depening
on the actual enum values defined


> +    int64_t size;                         /**< File size in bytes */
> +    int64_t modification_timestamp;       /**< Time of last modification in microseconds since unix epoch */
> +    int64_t access_timestamp;             /**< Time of last access in microseconds since unix epoch */
> +    int64_t status_change_timestamp;      /**< Time of last status change in microseconds since unix epoch */
> +    uint32_t user_id;                     /**< User ID of owner */
> +    uint32_t group_id;                    /**< Group ID of owner */
> +    uint32_t filemode;                    /**< Unix file mode */
> +} AVIODirEntry;
> +
> +/**
>   * Bytestream IO Context.
>   * New fields can be added to the end with minor version bumps.
>   * Removal, reordering and changes to existing fields require a major
> @@ -181,6 +215,42 @@ const char *avio_find_protocol_name(const char *url);
>  int avio_check(const char *url, int flags);
>  
>  /**
> + * Open directory for reading.
> + *
> + * @param s       directory read context. Pointer to a NULL pointer must be passed.
> + * @param url     directory to be listed.
> + * @param options protocol options.
> + * @return >=0 on success or negative on error.
> + */
> +int avio_open_dir(void **s, const char *url, AVDictionary **options);

why void ** ? and not a more specific type ?
a more specific type would allow the compiler to check types


> +
> +/**
> + * Get next directory entry.
> + *
> + * Returned entry must be freed with avio_free_directory_entry().
> + *
> + * @param s         directory read context.
> + * @param[out] next next entry or NULL when no more entries.
> + * @return >=0 on success or negative on error.
> + */
> +int avio_read_dir(void *s, AVIODirEntry **next);
> +
> +/**
> + * Close directory.
> + *
> + * @param s directory read context.
> + * @return >=0 on success or negative on error.
> + */
> +int avio_close_dir(void **s);
> +
> +/**
> + * Free entry allocated by avio_read_dir().
> + *
> + * @param entry entry to be freed.
> + */
> +void avio_free_directory_entry(AVIODirEntry **entry);

is this neccessary to be called or does a avio_close_dir() free them
as well or is it intended that one can keep AVIODirEntrys after
avio_close_dir()
?
this should be more clearly be documented


> +
> +/**
>   * Allocate and initialize an AVIOContext for buffered I/O. It must be later
>   * freed with av_free().
>   *
> diff --git a/libavformat/url.h b/libavformat/url.h
> index d0035f3..2816ac5 100644
> --- a/libavformat/url.h
> +++ b/libavformat/url.h
> @@ -87,6 +87,9 @@ typedef struct URLProtocol {
>      const AVClass *priv_data_class;
>      int flags;
>      int (*url_check)(URLContext *h, int mask);
> +    int (*url_open_dir)(URLContext *h);
> +    int (*url_read_dir)(URLContext *h, AVIODirEntry **next);
> +    int (*url_close_dir)(URLContext *h);
>  } URLProtocol;
>  
>  /**
> -- 
> 2.3.3
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

The real ebay dictionary, page 3
"Rare item" - "Common item with rare defect or maybe just a lie"
"Professional" - "'Toy' made in china, not functional except as doorstop"
"Experts will know" - "The seller hopes you are not an expert"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20150320/0c081d6e/attachment.asc>


More information about the ffmpeg-devel mailing list