1 /*
2 * Image format
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4 * Copyright (c) 2004 Michael Niedermayer
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
24 #include <sys/stat.h>
35
36 #if HAVE_GLOB
37 /* Locally define as 0 (bitwise-OR no-op) any missing glob options that
38 are non-posix glibc/bsd extensions. */
39 #ifndef GLOB_NOMAGIC
40 #define GLOB_NOMAGIC 0
41 #endif
42 #ifndef GLOB_BRACE
43 #define GLOB_BRACE 0
44 #endif
45
46 #endif /* HAVE_GLOB */
47
49 { 640, 480 },
50 { 720, 480 },
51 { 720, 576 },
52 { 352, 288 },
53 { 352, 240 },
54 { 160, 128 },
55 { 512, 384 },
56 { 640, 352 },
57 { 640, 240 },
58 };
59
61 {
62 int i;
63
66 *width_ptr =
sizes[i][0];
67 *height_ptr =
sizes[i][1];
68 return 0;
69 }
70 }
71
72 return -1;
73 }
74
76 {
77 #if HAVE_GLOB
78 size_t span = 0;
79 const char *p = path;
80
81 while (p = strchr(p, '%')) {
82 if (*(++p) == '%') {
83 ++p;
84 continue;
85 }
86 if (span = strspn(p, "*?[]{}"))
87 break;
88 }
89 /* Did we hit a glob char or get to the end? */
90 return span != 0;
91 #else
92 return 0;
93 #endif
94 }
95
96 /**
97 * Get index range of image files matched by path.
98 *
99 * @param pfirst_index pointer to index updated with the first number in the range
100 * @param plast_index pointer to index updated with the last number in the range
101 * @param path path which has to be matched by the image files in the range
102 * @param start_index minimum accepted value for the first index in the range
103 * @return -1 if no image file could be found
104 */
106 const char *path, int start_index, int start_index_range)
107 {
109 int range, last_index, range1, first_index;
110
111 /* find the first image */
112 for (first_index = start_index; first_index < start_index + start_index_range; first_index++) {
114 *pfirst_index =
115 *plast_index = 1;
117 return 0;
118 return -1;
119 }
121 break;
122 }
123 if (first_index == start_index + start_index_range)
124 goto fail;
125
126 /* find the last image */
127 last_index = first_index;
128 for (;;) {
129 range = 0;
130 for (;;) {
131 if (!range)
132 range1 = 1;
133 else
134 range1 = 2 * range;
136 last_index + range1) < 0)
137 goto fail;
139 break;
140 range = range1;
141 /* just in case... */
142 if (range >= (1 << 30))
143 goto fail;
144 }
145 /* we are sure than image last_index + range exists */
146 if (!range)
147 break;
148 last_index += range;
149 }
150 *pfirst_index = first_index;
151 *plast_index = last_index;
152 return 0;
153
154 fail:
155 return -1;
156 }
157
159 {
166 return 5;
167 else
169 }
170 return 0;
171 }
172
174 {
176 int first_index, last_index;
179
181
183 if (!st) {
185 }
186
192 }
193
197
198 /* find format */
201 else {
204 }
205
207 #if !HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
208 av_log(s1,
AV_LOG_ERROR,
"POSIX.1-2008 not supported, nanosecond file timestamps unavailable\n");
210 #endif
214 else
216
220 }
221
226 char *p = s->
path, *q, *dup;
227 int gerr;
228
230 "use pattern_type 'glob' instead\n");
231 #if HAVE_GLOB
233 while (*q) {
234 /* Do we have room for the next char and a \ insertion? */
235 if ((p - s->
path) >= (
sizeof(s->
path) - 2))
236 break;
237 if (*q == '%' && strspn(q + 1, "%*?[]{}"))
238 ++q;
239 else if (strspn(q, "\\*?[]{}"))
240 *p++ = '\\';
241 *p++ = *q++;
242 }
243 *p = 0;
245
246 gerr = glob(s->
path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate);
247 if (gerr != 0) {
249 }
250 first_index = 0;
251 last_index = s->globstate.gl_pathc - 1;
252 #endif
253 }
254 }
259 "Could find no file with path '%s' and index in the range %d-%d\n",
262 }
264 #if HAVE_GLOB
265 int gerr;
266 gerr = glob(s->
path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate);
267 if (gerr != 0) {
269 }
270 first_index = 0;
271 last_index = s->globstate.gl_pathc - 1;
273 #else
275 "Pattern type 'glob' was selected but globbing "
276 "is not supported by this libavformat build\n");
278 #endif
281 "Unknown value '%d' for pattern_type option\n", s->
pattern_type);
283 }
287 /* compute duration */
290 st->
duration = last_index - first_index + 1;
291 }
292 }
293
303 } else {
304 const char *str = strrchr(s->
path,
'.');
308 int probe_buffer_size = 2048;
312
313 if (!probe_buffer)
315
316 probe_buffer_size =
avio_read(s1->
pb, probe_buffer, probe_buffer_size);
317 if (probe_buffer_size < 0) {
319 return probe_buffer_size;
320 }
322
323 pd.
buf = probe_buffer;
326
332 continue;
335 break;
336 }
337 }
339 }
346 }
350
351 return 0;
352 }
353
355 {
357 char filename_bytes[1024];
358 char *filename = filename_bytes;
359 int i;
360 int size[3] = { 0 },
ret[3] = { 0 };
363
365 /* loop over input */
368 }
372 #if HAVE_GLOB
373 filename = s->globstate.gl_pathv[s->
img_number];
374 #endif
375 } else {
380 }
381 for (i = 0; i < 3; i++) {
384 if (i >= 1)
385 break;
387 filename);
389 }
391
393 break;
394 filename[strlen(filename) - 1] = 'U' + i;
395 }
396
402 int score = 0;
403
405 if (ret < 0)
407 memset(header + ret, 0, sizeof(header) - ret);
412
416 }
417
420 } else {
428 } else {
429 size[0] = 4096;
430 }
431 }
432
438 struct stat img_stat;
439 if (stat(filename, &img_stat))
441 pkt->
pts = (int64_t)img_stat.st_mtime;
442 #if HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
444 pkt->
pts = 1000000000*pkt->
pts + img_stat.st_mtim.tv_nsec;
445 #endif
449 }
450
452 for (i = 0; i < 3; i++) {
453 if (f[i]) {
459 }
460 }
461
462 if (
ret[0] <= 0 ||
ret[1] < 0 ||
ret[2] < 0) {
464 return AVERROR(EIO);
/* signal EOF */
465 } else {
469 return 0;
470 }
471 }
472
474 {
476 #if HAVE_GLOB
478 globfree(&s->globstate);
479 }
480 #endif
481 return 0;
482 }
483
485 {
488
491 if(index < 0)
492 return -1;
494 return 0;
495 }
496
498 return -1;
501 return 0;
502 }
503
504 #define OFFSET(x) offsetof(VideoDemuxData, x)
505 #define DEC AV_OPT_FLAG_DECODING_PARAM
509
510 {
"pattern_type",
"set pattern type",
OFFSET(pattern_type),
AV_OPT_TYPE_INT, {.i64=PT_GLOB_SEQUENCE}, 0, INT_MAX,
DEC,
"pattern_type"},
511 {
"glob_sequence",
"select glob/sequence pattern type", 0,
AV_OPT_TYPE_CONST, {.i64=PT_GLOB_SEQUENCE}, INT_MIN, INT_MAX,
DEC,
"pattern_type" },
512 {
"glob",
"select glob pattern type", 0,
AV_OPT_TYPE_CONST, {.i64=PT_GLOB }, INT_MIN, INT_MAX,
DEC,
"pattern_type" },
513 {
"sequence",
"select sequence pattern type", 0,
AV_OPT_TYPE_CONST, {.i64=PT_SEQUENCE }, INT_MIN, INT_MAX,
DEC,
"pattern_type" },
514
516 {
"start_number",
"set first number in the sequence",
OFFSET(start_number),
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX,
DEC },
517 {
"start_number_range",
"set range for looking at the first sequence number",
OFFSET(start_number_range),
AV_OPT_TYPE_INT, {.i64 = 5}, 1, INT_MAX,
DEC },
520 {
"ts_from_file",
"set frame timestamp from file's one",
OFFSET(ts_from_file),
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2,
DEC,
"ts_type" },
524 { NULL },
525 };
526
527 #if CONFIG_IMAGE2_DEMUXER
528 static const AVClass img2_class = {
533 };
544 .priv_class = &img2_class,
545 };
546 #endif
547 #if CONFIG_IMAGE2PIPE_DEMUXER
548 static const AVClass img2pipe_class = {
553 };
555 .
name =
"image2pipe",
560 .priv_class = &img2pipe_class,
561 };
562 #endif
563
565 {
567 int ihsize;
568
570 return 0;
571
573 if (ihsize < 12 || ihsize > 255)
574 return 0;
575
578 } else {
580 }
581 return 0;
582 }
583
585 {
587
590 return 0;
591 }
592
594 {
596
599 return 0;
600 }
601
603 {
605
606 if (
AV_RB64(b) == 0x0000000c6a502020 ||
609 return 0;
610 }
611
613 {
615
618 return 0;
619 }
620
622 {
624
625 if (
AV_RB64(b) == 0x89504e470d0a1a0a)
627 return 0;
628 }
629
631 {
633
635 (b[2] & ~1) == 0 &&
636 (b[3] & ~3) == 0 && b[3] &&
639 return 0;
640 }
641
643 {
645
648 return 0;
649 }
650
652 {
654
657 return 0;
658 }
659
660 #define IMAGEAUTO_DEMUXER(imgname, codecid)\
661 static const AVClass imgname ## _class = {\
662 .class_name = AV_STRINGIFY(imgname) " demuxer",\
663 .item_name = av_default_item_name,\
664 .option = options,\
665 .version = LIBAVUTIL_VERSION_INT,\
666 };\
667 AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\
668 .name = AV_STRINGIFY(imgname) "_pipe",\
669 .priv_data_size = sizeof(VideoDemuxData),\
670 .read_probe = imgname ## _probe,\
671 .read_header = ff_img_read_header,\
672 .read_packet = ff_img_read_packet,\
673 .priv_class = & imgname ## _class,\
674 .raw_codec_id = codecid,\
675 };
676