diff options
Diffstat (limited to 'libavformat/img2dec.c')
-rw-r--r-- | libavformat/img2dec.c | 117 |
1 files changed, 105 insertions, 12 deletions
diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c index 8f30cd5..2844ae0 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -3,20 +3,20 @@ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard * Copyright (c) 2004 Michael Niedermayer * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -27,6 +27,19 @@ #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_BRACE +#define GLOB_BRACE 0 +#endif + +#endif /* HAVE_GLOB */ typedef struct { const AVClass *class; /**< Class for private options. */ @@ -35,11 +48,16 @@ typedef struct { int img_number; int img_count; int is_pipe; + int split_planes; /**< use independent file for each Y, U, V plane */ char path[1024]; char *pixel_format; /**< Set by a private option. */ 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 int start_number; } VideoDemuxData; @@ -69,6 +87,27 @@ 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 = 0; + const char *p = path; + + while (p = strchr(p, '%')) { + if (*(++p) == '%') { + ++p; + continue; + } + if (span = strspn(p, "*?[]{}")) + break; + } + /* Did we hit a glob char or get to the end? */ + return 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, int max_start) @@ -77,7 +116,7 @@ static int find_image_range(int *pfirst_index, int *plast_index, int range, last_index, range1, first_index; /* find the first image */ - for (first_index = 0; first_index < max_start; first_index++) { + for (first_index = max_start; first_index < max_start + 5; first_index++) { if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0){ *pfirst_index = *plast_index = 1; @@ -128,6 +167,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,9 +224,38 @@ static int read_header(AVFormatContext *s1) } if (!s->is_pipe) { - if (find_image_range(&first_index, &last_index, s->path, - FFMAX(s->start_number, 5)) < 0) - return AVERROR(ENOENT); + s->use_glob = is_glob(s->path); + if (s->use_glob) { +#if HAVE_GLOB + char *p = s->path, *q, *dup; + int gerr; + + dup = q = av_strdup(p); + while (*q) { + /* Do we have room for the next char and a \ insertion? */ + if ((p - s->path) >= (sizeof(s->path) - 2)) + break; + if (*q == '%' && strspn(q + 1, "%*?[]{}")) + ++q; + else if (strspn(q, "\\*?[]{}")) + *p++ = '\\'; + *p++ = *q++; + } + *p = 0; + av_free(dup); + + gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, 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, + s->start_number - 1) < 0) + return AVERROR(ENOENT); + } s->img_first = first_index; s->img_last = last_index; s->img_number = first_index; @@ -201,8 +271,12 @@ static int read_header(AVFormatContext *s1) st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = s1->audio_codec_id; }else{ + const char *str= strrchr(s->path, '.'); + s->split_planes = str && !av_strcasecmp(str + 1, "y"); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = ff_guess_image2_codec(s->path); + if (st->codec->codec_id == CODEC_ID_LJPEG) + st->codec->codec_id = CODEC_ID_MJPEG; } if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO && pix_fmt != PIX_FMT_NONE) st->codec->pix_fmt = pix_fmt; @@ -213,7 +287,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]; @@ -226,9 +301,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) { @@ -239,7 +320,7 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt) } size[i]= avio_size(f[i]); - if(codec->codec_id != CODEC_ID_RAWVIDEO) + if(!s->split_planes) break; filename[ strlen(filename) - 1 ]= 'U' + i; } @@ -248,7 +329,7 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt) infer_size(&codec->width, &codec->height, size[0]); } else { f[0] = s1->pb; - if (f[0]->eof_reached) + if (url_feof(f[0])) return AVERROR(EIO); size[0]= 4096; } @@ -278,6 +359,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[] = { @@ -303,6 +395,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, }; |