[FFmpeg-devel] [PATCH 1/6] lavf: add directory listing API
Lukasz Marek
lukasz.m.luki2 at gmail.com
Sat Jul 5 18:11:59 CEST 2014
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 0a2a0a9..465befe 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
@@ -416,6 +417,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 4004b6f..5bc2856 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.
+ */
+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 */
+ 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);
+
+/**
+ * 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);
+
+/**
* 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 712ea0f..97da17c 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -89,6 +89,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;
/**
--
1.9.1
More information about the ffmpeg-devel
mailing list