On Thu, Mar 26, 2015 at 2:31 PM, Michael Niedermayer <michae...@gmx.at>
wrote:

> On Thu, Mar 26, 2015 at 01:25:17AM +0100, Mariusz Szczepańczyk wrote:
> > From: Lukasz Marek <lukasz.m.lu...@gmail.com>
> >
> > API allows protocol implementations to provide API that
> > allows to list directory content.
> > API is similar to POSIX opendir/readdir/closedir.
> > ---
> >  libavformat/avio.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++
> >  libavformat/avio.h | 84
> +++++++++++++++++++++++++++++++++++++++++++++++++++++-
> >  libavformat/url.c  | 16 +++++++++++
> >  libavformat/url.h  | 10 +++++++
> >  4 files changed, 183 insertions(+), 1 deletion(-)
> >
> > diff --git a/libavformat/avio.c b/libavformat/avio.c
> > index 4896782..51419cc 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,79 @@ int avio_check(const char *url, int flags)
> >      return ret;
> >  }
> >
> > +int avio_open_dir(AVIODirContext **s, const char *url, AVDictionary
> **options)
> > +{
> > +    URLContext *h = NULL;
> > +    AVIODirContext *ctx = NULL;
> > +    int ret;
> > +    av_assert0(s);
> > +
> > +    ctx = av_mallocz(sizeof(*ctx));
> > +    if (!ctx) {
> > +        ret = AVERROR(ENOMEM);
> > +        goto fail;
> > +    }
> > +
> > +    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;
> > +
> > +    ctx->url_context = h;
> > +    *s = ctx;
> > +    return 0;
> > +
> > +  fail:
> > +    av_free(ctx);
> > +    *s = NULL;
> > +    ffurl_close(h);
> > +    return ret;
> > +}
> > +
>
> > +int avio_read_dir(AVIODirContext *s, AVIODirEntry **next)
> > +{
> > +    URLContext *h;
> > +    int ret;
> > +
> > +    if (!s || !s->url_context)
> > +        return EINVAL;
>
> i assume this is intended to be AVERROR(EINVAL)
>

Yes, of course! Fixed.


>
>
> > +    h = s->url_context;
> > +    if ((ret = h->prot->url_read_dir(h, next)) < 0)
> > +        avio_free_directory_entry(next);
> > +    return ret;
> > +}
> > +
> > +int avio_close_dir(AVIODirContext **s)
> > +{
> > +    URLContext *h;
> > +
> > +    av_assert0(s);
> > +    if (!(*s) || !(*s)->url_context)
> > +        return EINVAL;
>
> same as previous
>

ditto


>
> [...]
>


Mariusz
From 628fa295d2710da56ba672ac0cb8502cafc27f82 Mon Sep 17 00:00:00 2001
From: Lukasz Marek <lukasz.m.lu...@gmail.com>
Date: Sat, 5 Jul 2014 18:11:59 +0200
Subject: [PATCH 1/4] lavf: add directory listing API

API allows protocol implementations to provide API that
allows to list directory content.
API is similar to POSIX opendir/readdir/closedir.
---
 libavformat/avio.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++
 libavformat/avio.h | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 libavformat/url.c  | 16 +++++++++++
 libavformat/url.h  | 10 +++++++
 4 files changed, 183 insertions(+), 1 deletion(-)

diff --git a/libavformat/avio.c b/libavformat/avio.c
index 4896782..a990ea2 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,79 @@ int avio_check(const char *url, int flags)
     return ret;
 }
 
+int avio_open_dir(AVIODirContext **s, const char *url, AVDictionary **options)
+{
+    URLContext *h = NULL;
+    AVIODirContext *ctx = NULL;
+    int ret;
+    av_assert0(s);
+
+    ctx = av_mallocz(sizeof(*ctx));
+    if (!ctx) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    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;
+
+    ctx->url_context = h;
+    *s = ctx;
+    return 0;
+
+  fail:
+    av_free(ctx);
+    *s = NULL;
+    ffurl_close(h);
+    return ret;
+}
+
+int avio_read_dir(AVIODirContext *s, AVIODirEntry **next)
+{
+    URLContext *h;
+    int ret;
+
+    if (!s || !s->url_context)
+        return AVERROR(EINVAL);
+    h = s->url_context;
+    if ((ret = h->prot->url_read_dir(h, next)) < 0)
+        avio_free_directory_entry(next);
+    return ret;
+}
+
+int avio_close_dir(AVIODirContext **s)
+{
+    URLContext *h;
+
+    av_assert0(s);
+    if (!(*s) || !(*s)->url_context)
+        return AVERROR(EINVAL);
+    h = (*s)->url_context;
+    h->prot->url_close_dir(h);
+    ffurl_close(h);
+    av_freep(s);
+    *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..bbd482a 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,47 @@ 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 fields are guaranteed be set.
+ * Rest of fields are protocol or/and platform dependent and might be unknown.
+ */
+typedef struct AVIODirEntry {
+    char *name;                           /**< Filename */
+    int type;                             /**< Type of the entry */
+    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. */
+    int64_t size;                         /**< File size in bytes, -1 if unknown. */
+    int64_t modification_timestamp;       /**< Time of last modification in microseconds since unix
+                                               epoch, -1 if unknown. */
+    int64_t access_timestamp;             /**< Time of last access in microseconds since unix epoch,
+                                               -1 if unknown. */
+    int64_t status_change_timestamp;      /**< Time of last status change in microseconds since unix
+                                               epoch, -1 if unknown. */
+    int64_t user_id;                      /**< User ID of owner, -1 if unknown. */
+    int64_t group_id;                     /**< Group ID of owner, -1 if unknown. */
+    int64_t filemode;                     /**< Unix file mode, -1 if unknown. */
+} AVIODirEntry;
+
+typedef struct AVIODirContext {
+    struct URLContext *url_context;
+} AVIODirContext;
+
+/**
  * 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 +221,48 @@ 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 A dictionary filled with protocol-private options. On return
+ *                this parameter will be destroyed and replaced with a dictionary
+ *                containing options that were not found. May be NULL.
+ * @return >=0 on success or negative on error.
+ */
+int avio_open_dir(AVIODirContext **s, const char *url, AVDictionary **options);
+
+/**
+ * Get next directory entry.
+ *
+ * Returned entry must be freed with avio_free_directory_entry(). In particular
+ * it may outlive AVIODirContext.
+ *
+ * @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(AVIODirContext *s, AVIODirEntry **next);
+
+/**
+ * Close directory.
+ *
+ * @note Entries created using avio_read_dir() are not deleted and must be
+ * freeded with avio_free_directory_entry().
+ *
+ * @param s         directory read context.
+ * @return >=0 on success or negative on error.
+ */
+int avio_close_dir(AVIODirContext **s);
+
+/**
+ * Free entry allocated by avio_read_dir().
+ *
+ * @param entry entry to be freed.
+ */
+void avio_free_directory_entry(AVIODirEntry **entry);
+
+/**
  * Allocate and initialize an AVIOContext for buffered I/O. It must be later
  * freed with av_free().
  *
diff --git a/libavformat/url.c b/libavformat/url.c
index acfb0cf..3a2c78b 100644
--- a/libavformat/url.c
+++ b/libavformat/url.c
@@ -145,3 +145,19 @@ void ff_make_absolute_url(char *buf, int size, const char *base,
     }
     av_strlcat(buf, rel, size);
 }
+
+AVIODirEntry *ff_alloc_dir_entry(void)
+{
+    AVIODirEntry *entry = av_mallocz(sizeof(AVIODirEntry));
+    if (entry) {
+        entry->type = AVIO_ENTRY_UNKNOWN;
+        entry->size = -1;
+        entry->modification_timestamp = -1;
+        entry->access_timestamp = -1;
+        entry->status_change_timestamp = -1;
+        entry->user_id = -1;
+        entry->group_id = -1;
+        entry->filemode = -1;
+    }
+    return entry;
+}
diff --git a/libavformat/url.h b/libavformat/url.h
index d0035f3..1a845b7 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;
 
 /**
@@ -280,5 +283,12 @@ int ff_url_join(char *str, int size, const char *proto,
 void ff_make_absolute_url(char *buf, int size, const char *base,
                           const char *rel);
 
+/**
+ * Allocate directory entry with default values.
+ *
+ * @return entry or NULL on error
+ */
+AVIODirEntry *ff_alloc_dir_entry(void);
+
 
 #endif /* AVFORMAT_URL_H */
-- 
2.3.3

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to