Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
| ... | ... |
@@ -1183,6 +1183,7 @@ HAVE_LIST=" |
| 1183 | 1183 |
GetProcessMemoryInfo |
| 1184 | 1184 |
GetProcessTimes |
| 1185 | 1185 |
getrusage |
| 1186 |
+ glob |
|
| 1186 | 1187 |
gnu_as |
| 1187 | 1188 |
ibm_asm |
| 1188 | 1189 |
inet_aton |
| ... | ... |
@@ -3075,6 +3076,7 @@ check_func_headers windows.h GetProcessAffinityMask |
| 3075 | 3075 |
check_func_headers windows.h GetProcessTimes |
| 3076 | 3076 |
check_func_headers windows.h MapViewOfFile |
| 3077 | 3077 |
check_func_headers windows.h VirtualAlloc |
| 3078 |
+check_func_headers glob.h glob |
|
| 3078 | 3079 |
|
| 3079 | 3080 |
check_header dlfcn.h |
| 3080 | 3081 |
check_header dxva2api.h -D_WIN32_WINNT=0x0600 |
| ... | ... |
@@ -1077,7 +1077,11 @@ ffmpeg -f image2 -i foo-%03d.jpeg -r 12 -s WxH foo.avi |
| 1077 | 1077 |
The syntax @code{foo-%03d.jpeg} specifies to use a decimal number
|
| 1078 | 1078 |
composed of three digits padded with zeroes to express the sequence |
| 1079 | 1079 |
number. It is the same syntax supported by the C printf function, but |
| 1080 |
-only formats accepting a normal integer are suitable. |
|
| 1080 |
+only formats accepting a normal integer are suitable. When importing |
|
| 1081 |
+an image sequence, -i also accepts shell-like wildcard patterns such as |
|
| 1082 |
+@code{foo-*.jpeg}, @code{foo-???.jpeg} or @code{foo-00[234]*.jpeg}.
|
|
| 1083 |
+It will probably be necessary to escape these patterns so they do not |
|
| 1084 |
+get interpreted by your shell. |
|
| 1081 | 1085 |
|
| 1082 | 1086 |
@item |
| 1083 | 1087 |
You can put many streams of the same type in the output: |
| ... | ... |
@@ -27,6 +27,25 @@ |
| 27 | 27 |
#include "libavutil/parseutils.h" |
| 28 | 28 |
#include "avformat.h" |
| 29 | 29 |
#include "internal.h" |
| 30 |
+#if HAVE_GLOB |
|
| 31 |
+#include <glob.h> |
|
| 32 |
+ |
|
| 33 |
+/* Locally define as 0 (bitwise-OR no-op) any missing glob options that |
|
| 34 |
+ are non-posix glibc/bsd extensions. */ |
|
| 35 |
+#ifndef GLOB_NOMAGIC |
|
| 36 |
+#define GLOB_NOMAGIC 0 |
|
| 37 |
+#endif |
|
| 38 |
+#ifndef GLOB_TILDE |
|
| 39 |
+#define GLOB_TILDE 0 |
|
| 40 |
+#endif |
|
| 41 |
+#ifndef GLOB_TILDE_CHECK |
|
| 42 |
+#define GLOB_TILDE_CHECK GLOB_TILDE |
|
| 43 |
+#endif |
|
| 44 |
+#ifndef GLOB_BRACE |
|
| 45 |
+#define GLOB_BRACE 0 |
|
| 46 |
+#endif |
|
| 47 |
+ |
|
| 48 |
+#endif /* HAVE_GLOB */ |
|
| 30 | 49 |
|
| 31 | 50 |
typedef struct {
|
| 32 | 51 |
const AVClass *class; /**< Class for private options. */ |
| ... | ... |
@@ -41,6 +60,10 @@ typedef struct {
|
| 41 | 41 |
char *video_size; /**< Set by a private option. */ |
| 42 | 42 |
char *framerate; /**< Set by a private option. */ |
| 43 | 43 |
int loop; |
| 44 |
+ int use_glob; |
|
| 45 |
+#if HAVE_GLOB |
|
| 46 |
+ glob_t globstate; |
|
| 47 |
+#endif |
|
| 44 | 48 |
} VideoDemuxData; |
| 45 | 49 |
|
| 46 | 50 |
static const int sizes[][2] = {
|
| ... | ... |
@@ -69,6 +92,17 @@ static int infer_size(int *width_ptr, int *height_ptr, int size) |
| 69 | 69 |
return -1; |
| 70 | 70 |
} |
| 71 | 71 |
|
| 72 |
+static int is_glob(const char *path) |
|
| 73 |
+{
|
|
| 74 |
+#if HAVE_GLOB |
|
| 75 |
+ size_t span = strcspn(path, "*?[]{}\\");
|
|
| 76 |
+ /* Did we hit a glob char or get to the end? */ |
|
| 77 |
+ return path[span] != '\0'; |
|
| 78 |
+#else |
|
| 79 |
+ return 0; |
|
| 80 |
+#endif |
|
| 81 |
+} |
|
| 82 |
+ |
|
| 72 | 83 |
/* return -1 if no image found */ |
| 73 | 84 |
static int find_image_range(int *pfirst_index, int *plast_index, |
| 74 | 85 |
const char *path) |
| ... | ... |
@@ -128,6 +162,8 @@ static int read_probe(AVProbeData *p) |
| 128 | 128 |
if (p->filename && ff_guess_image2_codec(p->filename)) {
|
| 129 | 129 |
if (av_filename_number_test(p->filename)) |
| 130 | 130 |
return AVPROBE_SCORE_MAX; |
| 131 |
+ else if (is_glob(p->filename)) |
|
| 132 |
+ return AVPROBE_SCORE_MAX; |
|
| 131 | 133 |
else |
| 132 | 134 |
return AVPROBE_SCORE_MAX/2; |
| 133 | 135 |
} |
| ... | ... |
@@ -183,8 +219,21 @@ static int read_header(AVFormatContext *s1) |
| 183 | 183 |
} |
| 184 | 184 |
|
| 185 | 185 |
if (!s->is_pipe) {
|
| 186 |
+ s->use_glob = is_glob(s->path); |
|
| 187 |
+ if (s->use_glob) {
|
|
| 188 |
+#if HAVE_GLOB |
|
| 189 |
+ int gerr; |
|
| 190 |
+ gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC|GLOB_TILDE_CHECK, NULL, &s->globstate); |
|
| 191 |
+ if (gerr != 0) {
|
|
| 192 |
+ return AVERROR(ENOENT); |
|
| 193 |
+ } |
|
| 194 |
+ first_index = 0; |
|
| 195 |
+ last_index = s->globstate.gl_pathc - 1; |
|
| 196 |
+#endif |
|
| 197 |
+ } else {
|
|
| 186 | 198 |
if (find_image_range(&first_index, &last_index, s->path) < 0) |
| 187 | 199 |
return AVERROR(ENOENT); |
| 200 |
+ } |
|
| 188 | 201 |
s->img_first = first_index; |
| 189 | 202 |
s->img_last = last_index; |
| 190 | 203 |
s->img_number = first_index; |
| ... | ... |
@@ -216,7 +265,8 @@ static int read_header(AVFormatContext *s1) |
| 216 | 216 |
static int read_packet(AVFormatContext *s1, AVPacket *pkt) |
| 217 | 217 |
{
|
| 218 | 218 |
VideoDemuxData *s = s1->priv_data; |
| 219 |
- char filename[1024]; |
|
| 219 |
+ char filename_bytes[1024]; |
|
| 220 |
+ char *filename = filename_bytes; |
|
| 220 | 221 |
int i; |
| 221 | 222 |
int size[3]={0}, ret[3]={0};
|
| 222 | 223 |
AVIOContext *f[3]; |
| ... | ... |
@@ -229,9 +279,15 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt) |
| 229 | 229 |
} |
| 230 | 230 |
if (s->img_number > s->img_last) |
| 231 | 231 |
return AVERROR_EOF; |
| 232 |
- if (av_get_frame_filename(filename, sizeof(filename), |
|
| 232 |
+ if (s->use_glob) {
|
|
| 233 |
+#if HAVE_GLOB |
|
| 234 |
+ filename = s->globstate.gl_pathv[s->img_number]; |
|
| 235 |
+#endif |
|
| 236 |
+ } else {
|
|
| 237 |
+ if (av_get_frame_filename(filename_bytes, sizeof(filename_bytes), |
|
| 233 | 238 |
s->path, s->img_number)<0 && s->img_number > 1) |
| 234 | 239 |
return AVERROR(EIO); |
| 240 |
+ } |
|
| 235 | 241 |
for(i=0; i<3; i++){
|
| 236 | 242 |
if (avio_open2(&f[i], filename, AVIO_FLAG_READ, |
| 237 | 243 |
&s1->interrupt_callback, NULL) < 0) {
|
| ... | ... |
@@ -281,6 +337,17 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt) |
| 281 | 281 |
} |
| 282 | 282 |
} |
| 283 | 283 |
|
| 284 |
+static int read_close(struct AVFormatContext* s1) |
|
| 285 |
+{
|
|
| 286 |
+ VideoDemuxData *s = s1->priv_data; |
|
| 287 |
+#if HAVE_GLOB |
|
| 288 |
+ if (s->use_glob) {
|
|
| 289 |
+ globfree(&s->globstate); |
|
| 290 |
+ } |
|
| 291 |
+#endif |
|
| 292 |
+ return 0; |
|
| 293 |
+} |
|
| 294 |
+ |
|
| 284 | 295 |
#define OFFSET(x) offsetof(VideoDemuxData, x) |
| 285 | 296 |
#define DEC AV_OPT_FLAG_DECODING_PARAM |
| 286 | 297 |
static const AVOption options[] = {
|
| ... | ... |
@@ -305,6 +372,7 @@ AVInputFormat ff_image2_demuxer = {
|
| 305 | 305 |
.read_probe = read_probe, |
| 306 | 306 |
.read_header = read_header, |
| 307 | 307 |
.read_packet = read_packet, |
| 308 |
+ .read_close = read_close, |
|
| 308 | 309 |
.flags = AVFMT_NOFILE, |
| 309 | 310 |
.priv_class = &img2_class, |
| 310 | 311 |
}; |