[FFmpeg-devel] [patch] glob matching for image series
Clément Bœsch
ubitux at gmail.com
Mon Jan 9 07:38:22 CET 2012
On Sun, Jan 08, 2012 at 08:17:06PM -0500, Brian Olson wrote:
> To make a singular net diff, here's the output of `git diff master mybranch` (also attached if that's easier to parse):
>
Please do not gzip it; "git format-patch master" from mybranch should
generate a proper patch (assuming master is up-to-date and mybranch
correctly rebased with "git rebase master").
> diff --git a/configure b/configure
> index 43b63bb..47146d8 100755
> --- a/configure
> +++ b/configure
> @@ -1179,6 +1179,7 @@ HAVE_LIST="
> GetProcessMemoryInfo
> GetProcessTimes
> getrusage
> + glob
Isn't your mailer breaking the indent?
> gnu_as
> ibm_asm
> inet_aton
> @@ -3021,6 +3022,7 @@ check_func_headers windows.h GetProcessAffinityMask
> check_func_headers windows.h GetProcessTimes
> check_func_headers windows.h MapViewOfFile
> check_func_headers windows.h VirtualAlloc
> +check_func_headers glob.h glob
>
> check_header dlfcn.h
> check_header dxva2api.h -D_WIN32_WINNT=0x0600
> diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
> index 83a45a8..ded3098 100644
> --- a/doc/ffmpeg.texi
> +++ b/doc/ffmpeg.texi
> @@ -1226,7 +1226,11 @@ ffmpeg -f image2 -i foo-%03d.jpeg -r 12 -s WxH foo.avi
> The syntax @code{foo-%03d.jpeg} specifies to use a decimal number
> composed of three digits padded with zeroes to express the sequence
> number. It is the same syntax supported by the C printf function, but
> -only formats accepting a normal integer are suitable.
> +only formats accepting a normal integer are suitable. When importing
> +an image sequence, -i also accepts shell-like wildcard patterns such as
> + at code{foo-*.jpeg}, @code{foo-???.jpeg} or @code{foo-00[234]*.jpeg}.
> +It will probably be necessary to escape these patterns so they do not
> +get interpreted by your shell.
>
> @item
> You can put many streams of the same type in the output:
> diff --git a/libavformat/img2.c b/libavformat/img2.c
> index bc35591..7f94a1f 100644
> --- a/libavformat/img2.c
> +++ b/libavformat/img2.c
> @@ -29,6 +29,9 @@
> #include "avformat.h"
> #include "avio_internal.h"
> #include "internal.h"
> +#if HAVE_GLOB
> +#include <glob.h>
> +#endif
>
> typedef struct {
> const AVClass *class; /**< Class for private options. */
> @@ -44,6 +47,10 @@ typedef struct {
> char *framerate; /**< Set by a private option. */
> int loop;
> int updatefirst;
> +#if HAVE_GLOB
> + int use_glob;
> + glob_t globstate;
> +#endif
> } VideoData;
>
> typedef struct {
> @@ -133,6 +140,38 @@ static enum CodecID av_str2id(const IdStrMap *tags, const char *str)
> return CODEC_ID_NONE;
> }
>
> +#if HAVE_GLOB
> +static int glob_errfunc(const char* epath, int glob_error) {
> + return 0;
> +}
tab are not allowed in FFmpeg; a hook will reject the patch. Also a few
hint about the coding style:
- "\n" before the '{' for a function
- stick the '*' to the variable name
More insight in doc/developer.texi, Coding Rules section.
> +static int is_glob(const char* path) {
> + while (*path != '\0') {
> + switch (*path) {
> + case '*':
> + case '?':
> + case '[':
> + case ']':
> + case '{':
> + case '}':
> + case '\\':
> + return 1;
> + }
> + path++;
> + }
> + return 0;
> +}
strchr?
> +static int use_glob(VideoData *s) {
> + return s->use_glob;
> +}
> +#else
> +static int is_glob(const char* path) {
> + return 0;
> +}
> +static int use_glob(VideoData *s) {
> + return 0;
> +}
> +#endif
> +
Please add some spacing between the functions.
> /* return -1 if no image found */
> static int find_image_range(int *pfirst_index, int *plast_index,
> const char *path)
> @@ -192,6 +231,8 @@ static int read_probe(AVProbeData *p)
> if (p->filename && av_str2id(img_tags, p->filename)) {
> if (av_filename_number_test(p->filename))
> return AVPROBE_SCORE_MAX;
> + else if (is_glob(p->filename))
> + return AVPROBE_SCORE_MAX;
> else
> return AVPROBE_SCORE_MAX/2;
> }
> @@ -263,10 +304,42 @@ static int read_header(AVFormatContext *s1, AVFormatParameters *ap)
> }
>
> if (!s->is_pipe) {
> - if (find_image_range(&first_index, &last_index, s->path) < 0)
> - return AVERROR(ENOENT);
> - s->img_first = first_index;
> - s->img_last = last_index;
> + if (is_glob(s->path)) {
> +#if HAVE_GLOB
> + int gerr;
> + s->use_glob = 1;
> +/* Locally define as 0 (bitwise-OR no-op) any missing glob options that
> + are non-posix glibc/bsd extensions. */
> +#ifndef GLOB_NOMAGIC
> +#define GLOB_NOMAGIC 0
> +#endif
> +#ifndef GLOB_TILDE
> +#define GLOB_TILDE 0
> +#endif
> +#ifndef GLOB_TILDE_CHECK
> +#define GLOB_TILDE_CHECK GLOB_TILDE
> +#endif
> +#ifndef GLOB_BRACE
> +#define GLOB_BRACE 0
> +#endif
> + gerr = glob(
> + s->path,
> + GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC|GLOB_TILDE_CHECK,
> + glob_errfunc,
> + &s->globstate);
Please do not break the line like this; also that part has some tabs too.
> + if (gerr != 0) {
> + return AVERROR(ENOENT);
> + }
> + s->img_first = 0;
> + s->img_last = s->globstate.gl_pathc - 1;
> +#endif
> + } else {
> + if (find_image_range(&first_index, &last_index, s->path) < 0) {
> + return AVERROR(ENOENT);
> + }
> + s->img_first = first_index;
> + s->img_last = last_index;
> + }
> s->img_number = first_index;
> /* compute duration */
> st->start_time = 0;
> @@ -296,7 +369,8 @@ static int read_header(AVFormatContext *s1, AVFormatParameters *ap)
> static int read_packet(AVFormatContext *s1, AVPacket *pkt)
> {
> VideoData *s = s1->priv_data;
> - char filename[1024];
> + char filename_bytes[1024];
> + char* filename = filename_bytes;
char *filename
> int i;
> int size[3]={0}, ret[3]={0};
> AVIOContext *f[3];
> @@ -309,9 +383,17 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt)
> }
> if (s->img_number > s->img_last)
> return AVERROR_EOF;
> - if (av_get_frame_filename(filename, sizeof(filename),
> - s->path, s->img_number)<0 && s->img_number > 1)
> - return AVERROR(EIO);
> + if (use_glob(s)) {
> +#if HAVE_GLOB
> + filename = s->globstate.gl_pathv[s->img_number];
> +#endif
> + } else {
> + if (av_get_frame_filename(
> + filename_bytes, sizeof(filename_bytes),
> + s->path, s->img_number)<0 &&
> + s->img_number > 1)
> + return AVERROR(EIO);
> + }
> for(i=0; i<3; i++){
> if (avio_open2(&f[i], filename, AVIO_FLAG_READ,
> &s1->interrupt_callback, NULL) < 0) {
> @@ -361,6 +443,16 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt)
> }
> }
>
> +static int read_close(struct AVFormatContext* s1) {
> + VideoData *s = s1->priv_data;
> +#if HAVE_GLOB
> + if (s->use_glob) {
> + globfree(&s->globstate);
> + }
> +#endif
> + return 0;
> +}
> +
> #if CONFIG_IMAGE2_MUXER || CONFIG_IMAGE2PIPE_MUXER
> /******************************************************/
> /* image output */
> @@ -494,6 +586,7 @@ AVInputFormat ff_image2_demuxer = {
> .read_probe = read_probe,
> .read_header = read_header,
> .read_packet = read_packet,
> + .read_close = read_close,
> .flags = AVFMT_NOFILE,
> .priv_class = &img2_class,
> };
>
>
>
>
> On Jan 8, 2012, at 12:50 PM, Nicolas George wrote:
>
> > The preferred way for external contributors (and most internal ones too, in
> > fact) is to use git send-email, or the equivalent using git format-patch.
> > You will probably need to squash your patches together into a single one.
> > The patch then gets reviewed inline.
>
Also, please do not top post.
--
Clément B.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20120109/f3a88dea/attachment.asc>
More information about the ffmpeg-devel
mailing list