summaryrefslogtreecommitdiff
path: root/libavformat/img2dec.c
diff options
context:
space:
mode:
authorBrian Olson <icic@bolson.org>2012-02-27 10:27:17 +0100
committerMichael Niedermayer <michaelni@gmx.at>2012-03-30 00:03:41 +0200
commit0be130e37bfafd6022edd27833f04a0b6cee2f02 (patch)
tree99a88346de3b702d8b183040f52b846d5542cd48 /libavformat/img2dec.c
parentd61ef05bc527a9375de5b70acc7125d2bd1bd473 (diff)
img2: glob matching for image series
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/img2dec.c')
-rw-r--r--libavformat/img2dec.c72
1 files changed, 70 insertions, 2 deletions
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,
};