diff options
author | Brian Olson <icic@bolson.org> | 2012-02-27 10:27:17 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-03-30 00:03:41 +0200 |
commit | 0be130e37bfafd6022edd27833f04a0b6cee2f02 (patch) | |
tree | 99a88346de3b702d8b183040f52b846d5542cd48 | |
parent | d61ef05bc527a9375de5b70acc7125d2bd1bd473 (diff) | |
download | ffmpeg-0be130e37bfafd6022edd27833f04a0b6cee2f02.tar.gz |
img2: glob matching for image series
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | doc/ffmpeg.texi | 6 | ||||
-rw-r--r-- | libavformat/img2dec.c | 72 |
3 files changed, 77 insertions, 3 deletions
@@ -1183,6 +1183,7 @@ HAVE_LIST=" GetProcessMemoryInfo GetProcessTimes getrusage + glob gnu_as ibm_asm inet_aton @@ -3075,6 +3076,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 37c941e67c..a9edad48cd 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -1077,7 +1077,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 +@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/img2dec.c b/libavformat/img2dec.c index e8b695f522..d10a7a4b6a 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -27,6 +27,25 @@ #include "libavutil/parseutils.h" #include "avformat.h" #include "internal.h" +#if HAVE_GLOB +#include <glob.h> + +/* 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 + +#endif /* HAVE_GLOB */ typedef struct { const AVClass *class; /**< Class for private options. */ @@ -41,6 +60,10 @@ typedef struct { char *video_size; /**< Set by a private option. */ char *framerate; /**< Set by a private option. */ int loop; + int use_glob; +#if HAVE_GLOB + glob_t globstate; +#endif } VideoDemuxData; static const int sizes[][2] = { @@ -69,6 +92,17 @@ static int infer_size(int *width_ptr, int *height_ptr, int size) return -1; } +static int is_glob(const char *path) +{ +#if HAVE_GLOB + size_t span = strcspn(path, "*?[]{}\\"); + /* Did we hit a glob char or get to the end? */ + return path[span] != '\0'; +#else + return 0; +#endif +} + /* return -1 if no image found */ static int find_image_range(int *pfirst_index, int *plast_index, const char *path) @@ -128,6 +162,8 @@ static int read_probe(AVProbeData *p) if (p->filename && ff_guess_image2_codec(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; } @@ -183,8 +219,21 @@ static int read_header(AVFormatContext *s1) } if (!s->is_pipe) { + s->use_glob = is_glob(s->path); + if (s->use_glob) { +#if HAVE_GLOB + int gerr; + gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC|GLOB_TILDE_CHECK, NULL, &s->globstate); + if (gerr != 0) { + return AVERROR(ENOENT); + } + first_index = 0; + last_index = 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; @@ -216,7 +265,8 @@ static int read_header(AVFormatContext *s1) static int read_packet(AVFormatContext *s1, AVPacket *pkt) { VideoDemuxData *s = s1->priv_data; - char filename[1024]; + char filename_bytes[1024]; + char *filename = filename_bytes; int i; int size[3]={0}, ret[3]={0}; AVIOContext *f[3]; @@ -229,9 +279,15 @@ 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), + if (s->use_glob) { +#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) { @@ -281,6 +337,17 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt) } } +static int read_close(struct AVFormatContext* s1) +{ + VideoDemuxData *s = s1->priv_data; +#if HAVE_GLOB + if (s->use_glob) { + globfree(&s->globstate); + } +#endif + return 0; +} + #define OFFSET(x) offsetof(VideoDemuxData, x) #define DEC AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { @@ -305,6 +372,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, }; |