[FFmpeg-devel] [RFC] Browser remote content API
Nicolas George
george at nsup.org
Sun Feb 16 12:10:32 CET 2014
L'octidi 28 pluviôse, an CCXXII, Lukasz Marek a écrit :
> I've attached implementation of my proposal API.
>
> Second patch is just for testing purposes, but probably may be
> helpful for the student. Example may be also merged at some point
> when first protocol supports it.
>
> --
> Best Regards,
> Lukasz Marek
>
> When you look long into an abyss, the abyss looks into you. -
> Friedrich Nietzsche
> >From be932968c1ba2b9f4e34dd096f31df2ddba97249 Mon Sep 17 00:00:00 2001
> From: Lukasz Marek <lukasz.m.luki at gmail.com>
> Date: Sun, 16 Feb 2014 00:44:09 +0100
> Subject: [PATCH 1/2] lavf/avio: add directory list API
>
> TODO: minor bump and APIchnage update.
>
> This is preparation for GSoC project.
>
> Signed-off-by: Lukasz Marek <lukasz.m.luki at gmail.com>
> ---
> libavformat/avio.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> libavformat/avio.h | 49 +++++++++++++++++++++++++++++++++
> libavformat/url.h | 1 +
> 3 files changed, 130 insertions(+)
I believe the implementation could go in a separate file.
>
> diff --git a/libavformat/avio.c b/libavformat/avio.c
> index 225d982..1851654 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
> @@ -395,6 +396,85 @@ int avio_check(const char *url, int flags)
> return ret;
> }
>
> +void avio_free_dir_list(AVIODirEntryList **entries)
> +{
> + AVIODirEntryList *list;
> + int i;
> +
> + if (!entries || !(*entries))
> + return;
> + list = *entries;
> + for (i = 0; i < list->nb_entries; i++) {
> + if (list->enties[i]) {
> + av_free(list->enties[i]->name);
> + av_free(list->enties[i]);
> + }
> + }
> + av_free(list->enties);
> + av_freep(entries);
> +}
> +
> +static int cmp_dir_entires(AVIODirEntry *e1, AVIODirEntry *e2, int flags)
> +{
> + int ret = flags & AVIO_SORT_DESCENDING;
> + av_assert0(e1 && e2);
> + if ((flags & AVIO_SORT_DIRS_FIRST) && e1->type != e2->type)
> + return e1->type != AVIO_ENTRY_DIR;
> + if (flags & AVIO_SORT_BY_SIZE) {
> + if (e1->size != e2->size)
> + return e1->size > e2->size ? ret : !ret;
> + } else if (flags & AVIO_SORT_BY_CREATION_DATE) {
> + if (e1->creation_timestamp != e2->creation_timestamp)
> + return e1->creation_timestamp > e2->creation_timestamp ? ret : !ret;
> + } else if (flags & AVIO_SORT_BY_MODIFICATION_DATE) {
> + if (e1->modification_timestamp != e2->modification_timestamp)
> + return e1->modification_timestamp > e2->modification_timestamp ? ret : !ret;
> + }
> + return strcmp(e1->name, e2->name) < 0 ? ret : !ret;
> +}
> +
> +int avio_list_dir(const char *url, AVIODirEntryList **entries, int sort_flags,
> + AVDictionary **options)
> +{
> + int ret, i1, i2;
> + URLContext *h;
> + AVIODirEntryList *list;
> +
> + av_assert0(entries);
> + *entries = NULL;
> + if ((ret = ffurl_alloc(&h, url, 0, NULL)))
> + return ret;
> + if (!h->prot->url_list_dir) {
> + ret = AVERROR(ENOSYS);
> + goto fail;
> + }
> + if (options && h->prot->priv_data_class &&
> + (ret = av_opt_set_dict(h->priv_data, options)) < 0)
> + goto fail;
> +
Why not set directly options on h?
> + list = av_mallocz(sizeof(**entries));
sizeof(*list)?
> + if (!list) {
> + ret = AVERROR(ENOMEM);
> + goto fail;
> + }
> + *entries = list;
IMHO, should go when success is certain.
> + if ((ret = h->prot->url_list_dir(h, url, list)) < 0)
> + goto fail;
> +
> + for (i1 = 0; i1 < list->nb_entries - 1; i1++)
> + for (i2 = i1 + 1; i2 < list->nb_entries; i2++) {
> + if (cmp_dir_entires(list->enties[i1], list->enties[i2], sort_flags))
> + FFSWAP(AVIODirEntry *, list->enties[i1], list->enties[i2]);
> + }
I can see why you would do it (lack of extra argument to the sort function
of qsort), but I believe a custom local implementation of sort is not a good
idea. You can probably use Michael's AV_QSORT macro: since it is a macro,
calling the cmp function with an extra argument should be possible.
> +
> + ffurl_close(h);
> + return 0;
> + fail:
> + ffurl_close(h);
> + avio_free_dir_list(entries);
> + return ret;
> +}
> +
> int64_t ffurl_size(URLContext *h)
> {
> int64_t pos, size;
> diff --git a/libavformat/avio.h b/libavformat/avio.h
> index 4f4ac3c..ff8ec22 100644
> --- a/libavformat/avio.h
> +++ b/libavformat/avio.h
> @@ -53,6 +53,32 @@ typedef struct AVIOInterruptCB {
> void *opaque;
> } AVIOInterruptCB;
>
> +enum AVIODirEntryType {
> + AVIO_ENTRY_UNKNOWN,
> + AVIO_ENTRY_DIR,
> + AVIO_ENTRY_FILE
> +};
> +
> +/**
> + * Describes single entry of the directory.
> + */
> +typedef struct AVIODirEntry {
> + char *name; /**< filename */
> + enum AVIODirEntryType type; /**< one of AVIO_ENTRY_* value */
Very minor nit: putting the fields with smaller type after the bigger ones
is better for packing.
> + int64_t size; /**< file size */
> + int64_t creation_timestamp; /**< creation timestamp */
ANy reason to include this one and not atime and ctime which are much more
common?
> + int64_t modification_timestamp; /**< modification timestamp */
Also: I suppose this is in AV_TIME_BASE (microseconds) since the Unix epoch.
Maybe the doxy should state it. As is, the doxy for the fields could be
completely removed.
> +} AVIODirEntry;
> +
> +/**
> + * List of directory entries.
> + * @see avio_list_dir()
> + */
> +typedef struct AVIODirEntryList {
> + AVIODirEntry **enties;
> + int nb_entries;
> +} AVIODirEntryList;
> +
> /**
> * Bytestream IO Context.
> * New fields can be added to the end with minor version bumps.
> @@ -164,6 +190,29 @@ typedef struct AVIOContext {
> */
> int avio_check(const char *url, int flags);
>
> +#define AVIO_SORT_DESCENDING 0x001 /**< use descending mode instead of ascending */
> +#define AVIO_SORT_DIRS_FIRST 0x002 /**< move all dir names (sorted) in front of the list */
> +#define AVIO_SORT_BY_SIZE 0x004 /**< sort by size before sorting by name */
> +#define AVIO_SORT_BY_CREATION_DATE 0x008 /**< sort by creation date before sorting by name */
> +#define AVIO_SORT_BY_MODIFICATION_DATE 0x010 /**< sort by modification date before sorting by name */
Inconsistent naming: time / date.
> +
> +/**
> + * Allow to read content of the directory.
> + *
> + * @param url directory to be listed.
> + * @param[out] entries sorted directory entries.
> + * @param sort_flags combination of AVIO_SORT_* flags.
> + * @param options protocol options.
> + * @return 0 on success or <0 on error.
> + */
> +int avio_list_dir(const char *url, AVIODirEntryList **entries, int sort_flags,
> + AVDictionary **options);
> +
> +/**
> + * Free directory entries list.
> + */
> +void avio_free_dir_list(AVIODirEntryList **entries);
> +
> /**
> * 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..f64f34d 100644
> --- a/libavformat/url.h
> +++ b/libavformat/url.h
> @@ -89,6 +89,7 @@ typedef struct URLProtocol {
> const AVClass *priv_data_class;
> int flags;
> int (*url_check)(URLContext *h, int mask);
> + int (*url_list_dir)(URLContext *h, const char *dir, AVIODirEntryList *entries);
> } URLProtocol;
>
> /**
Regards,
--
Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140216/a6adc223/attachment.asc>
More information about the ffmpeg-devel
mailing list