3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
4 * Copyright (c) 2004 Michael Niedermayer
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 static const IdStrMap img_tags[] = {
37 { CODEC_ID_MJPEG , "jpeg"},
38 { CODEC_ID_MJPEG , "jpg"},
39 { CODEC_ID_LJPEG , "ljpg"},
40 { CODEC_ID_MPEG1VIDEO, "mpg1-img"},
41 { CODEC_ID_MPEG2VIDEO, "mpg2-img"},
42 { CODEC_ID_MPEG4 , "mpg4-img"},
43 { CODEC_ID_FFV1 , "ffv1-img"},
47 static enum CodecID av_str2id(const IdStrMap *tags, const char *str)
49 str= strrchr(str, '.');
50 if(!str) return CODEC_ID_NONE;
55 for(i=0; toupper(tags->str[i]) == toupper(str[i]); i++){
56 if(tags->str[i]==0 && str[i]==0)
65 static const char *av_id2str(const IdStrMap *tags, enum CodecID id)
75 /* return -1 if no image found */
76 static int find_image_range(int *pfirst_index, int *plast_index,
80 int range, last_index, range1, first_index;
82 /* find the first image */
83 for(first_index = 0; first_index < 5; first_index++) {
84 if (get_frame_filename(buf, sizeof(buf), path, first_index) < 0){
95 /* find the last image */
96 last_index = first_index;
104 if (get_frame_filename(buf, sizeof(buf), path,
105 last_index + range1) < 0)
110 /* just in case... */
111 if (range >= (1 << 30))
114 /* we are sure than image last_index + range exists */
119 *pfirst_index = first_index;
120 *plast_index = last_index;
127 static int image_probe(AVProbeData *p)
129 if (filename_number_test(p->filename) >= 0 && av_str2id(img_tags, p->filename))
130 return AVPROBE_SCORE_MAX;
135 static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap)
137 VideoData *s = s1->priv_data;
138 int first_index, last_index;
141 s1->ctx_flags |= AVFMTCTX_NOHEADER;
143 st = av_new_stream(s1, 0);
149 strcpy(s->path, s1->filename);
154 if (s1->iformat->flags & AVFMT_NOFILE)
159 if (!ap || !ap->frame_rate) {
160 st->codec.frame_rate = 25;
161 st->codec.frame_rate_base = 1;
163 st->codec.frame_rate = ap->frame_rate;
164 st->codec.frame_rate_base = ap->frame_rate_base;
168 if (find_image_range(&first_index, &last_index, s->path) < 0)
170 s->img_first = first_index;
171 s->img_last = last_index;
172 s->img_number = first_index;
173 /* compute duration */
175 st->duration = ((int64_t)AV_TIME_BASE *
176 (last_index - first_index + 1) *
177 st->codec.frame_rate_base) / st->codec.frame_rate;
180 st->codec.codec_type = CODEC_TYPE_VIDEO;
181 st->codec.codec_id = av_str2id(img_tags, s->path);
190 static int img_read_packet(AVFormatContext *s1, AVPacket *pkt)
192 VideoData *s = s1->priv_data;
195 ByteIOContext f1, *f;
198 /* loop over input */
199 /* if (loop_input && s->img_number > s->img_last) {
200 s->img_number = s->img_first;
202 if (get_frame_filename(filename, sizeof(filename),
203 s->path, s->img_number)<0 && s->img_number > 1)
206 if (url_fopen(f, filename, URL_RDONLY) < 0)
215 av_new_packet(pkt, 4096);
217 av_new_packet(pkt, url_filesize(url_fileno(f)));
219 pkt->stream_index = 0;
220 pkt->flags |= PKT_FLAG_KEY;
222 ret = get_buffer(f, pkt->data, pkt->size);
229 return AVERROR_IO; /* signal EOF */
237 static int img_read_close(AVFormatContext *s1)
242 /******************************************************/
245 static int img_write_header(AVFormatContext *s)
247 VideoData *img = s->priv_data;
250 strcpy(img->path, s->filename);
253 if (s->oformat->flags & AVFMT_NOFILE)
261 static int img_write_packet(AVFormatContext *s, AVPacket *pkt)
263 VideoData *img = s->priv_data;
264 ByteIOContext pb1, *pb;
268 if (get_frame_filename(filename, sizeof(filename),
269 img->path, img->img_number) < 0 && img->img_number>1)
272 if (url_fopen(pb, filename, URL_WRONLY) < 0)
278 put_buffer(pb, pkt->data, pkt->size);
279 put_flush_packet(pb);
288 static int img_write_trailer(AVFormatContext *s)
295 static AVInputFormat image2_iformat = {
308 static AVInputFormat image2pipe_iformat = {
310 "piped image2 sequence",
322 static AVOutputFormat image2_oformat = {
336 static AVOutputFormat image2pipe_oformat = {
338 "piped image2 sequence",
351 av_register_input_format(&image2_iformat);
352 av_register_output_format(&image2_oformat);
354 av_register_input_format(&image2pipe_iformat);
355 av_register_output_format(&image2pipe_oformat);