[FFmpeg-cvslog] lavf: add directory listing API
Lukasz Marek
git at videolan.org
Fri Mar 27 18:54:17 CET 2015
ffmpeg | branch: master | Lukasz Marek <lukasz.m.luki2 at gmail.com> | Sat Jul 5 18:11:59 2014 +0200| [184084c6998cd04c0afdda076d7c95be0d6b2d22] | committer: Michael Niedermayer
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.
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=184084c6998cd04c0afdda076d7c95be0d6b2d22
---
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 */
More information about the ffmpeg-cvslog
mailing list