158bf485a12736cfde7d461206bca9941656f777
[libav.git] / libavformat / img2.c
1 /*
2 * Image format
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
4 * Copyright (c) 2004 Michael Niedermayer
5 *
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.
10 *
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.
15 *
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
19 */
20 #include "avformat.h"
21
22 /* XXX: this is a hack */
23 extern int loop_input;
24
25 typedef struct {
26 int img_first;
27 int img_last;
28 int img_number;
29 int img_count;
30 int is_pipe;
31 char path[1024];
32 } VideoData;
33
34 typedef struct {
35 enum CodecID id;
36 const char *str;
37 } IdStrMap;
38
39 static const IdStrMap img_tags[] = {
40 { CODEC_ID_MJPEG , "jpeg"},
41 { CODEC_ID_MJPEG , "jpg"},
42 { CODEC_ID_LJPEG , "ljpg"},
43 { CODEC_ID_PNG , "png"},
44 { CODEC_ID_PPM , "ppm"},
45 { CODEC_ID_PGM , "pgm"},
46 { CODEC_ID_PGMYUV , "pgmyuv"},
47 { CODEC_ID_PBM , "pbm"},
48 { CODEC_ID_PAM , "pam"},
49 { CODEC_ID_MPEG1VIDEO, "mpg1-img"},
50 { CODEC_ID_MPEG2VIDEO, "mpg2-img"},
51 { CODEC_ID_MPEG4 , "mpg4-img"},
52 { CODEC_ID_FFV1 , "ffv1-img"},
53 {0, NULL}
54 };
55
56 static enum CodecID av_str2id(const IdStrMap *tags, const char *str)
57 {
58 str= strrchr(str, '.');
59 if(!str) return CODEC_ID_NONE;
60 str++;
61
62 while (tags->id) {
63 int i;
64 for(i=0; toupper(tags->str[i]) == toupper(str[i]); i++){
65 if(tags->str[i]==0 && str[i]==0)
66 return tags->id;
67 }
68
69 tags++;
70 }
71 return CODEC_ID_NONE;
72 }
73
74 static const char *av_id2str(const IdStrMap *tags, enum CodecID id)
75 {
76 while (tags->id) {
77 if(tags->id == id)
78 return tags->str;
79 tags++;
80 }
81 return NULL;
82 }
83
84 /* return -1 if no image found */
85 static int find_image_range(int *pfirst_index, int *plast_index,
86 const char *path)
87 {
88 char buf[1024];
89 int range, last_index, range1, first_index;
90
91 /* find the first image */
92 for(first_index = 0; first_index < 5; first_index++) {
93 if (get_frame_filename(buf, sizeof(buf), path, first_index) < 0){
94 *pfirst_index =
95 *plast_index = 1;
96 return 0;
97 }
98 if (url_exist(buf))
99 break;
100 }
101 if (first_index == 5)
102 goto fail;
103
104 /* find the last image */
105 last_index = first_index;
106 for(;;) {
107 range = 0;
108 for(;;) {
109 if (!range)
110 range1 = 1;
111 else
112 range1 = 2 * range;
113 if (get_frame_filename(buf, sizeof(buf), path,
114 last_index + range1) < 0)
115 goto fail;
116 if (!url_exist(buf))
117 break;
118 range = range1;
119 /* just in case... */
120 if (range >= (1 << 30))
121 goto fail;
122 }
123 /* we are sure than image last_index + range exists */
124 if (!range)
125 break;
126 last_index += range;
127 }
128 *pfirst_index = first_index;
129 *plast_index = last_index;
130 return 0;
131 fail:
132 return -1;
133 }
134
135
136 static int image_probe(AVProbeData *p)
137 {
138 if (filename_number_test(p->filename) >= 0 && av_str2id(img_tags, p->filename))
139 return AVPROBE_SCORE_MAX;
140 else
141 return 0;
142 }
143
144 enum CodecID av_guess_image2_codec(const char *filename){
145 return av_str2id(img_tags, filename);
146 }
147
148 static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap)
149 {
150 VideoData *s = s1->priv_data;
151 int first_index, last_index;
152 AVStream *st;
153
154 s1->ctx_flags |= AVFMTCTX_NOHEADER;
155
156 st = av_new_stream(s1, 0);
157 if (!st) {
158 av_free(s);
159 return -ENOMEM;
160 }
161
162 strcpy(s->path, s1->filename);
163 s->img_number = 0;
164 s->img_count = 0;
165
166 /* find format */
167 if (s1->iformat->flags & AVFMT_NOFILE)
168 s->is_pipe = 0;
169 else{
170 s->is_pipe = 1;
171 st->need_parsing= 1;
172 }
173
174 if (!ap || !ap->frame_rate) {
175 st->codec.frame_rate = 25;
176 st->codec.frame_rate_base = 1;
177 } else {
178 st->codec.frame_rate = ap->frame_rate;
179 st->codec.frame_rate_base = ap->frame_rate_base;
180 }
181
182 if (!s->is_pipe) {
183 if (find_image_range(&first_index, &last_index, s->path) < 0)
184 goto fail;
185 s->img_first = first_index;
186 s->img_last = last_index;
187 s->img_number = first_index;
188 /* compute duration */
189 st->start_time = 0;
190 st->duration = ((int64_t)AV_TIME_BASE *
191 (last_index - first_index + 1) *
192 st->codec.frame_rate_base) / st->codec.frame_rate;
193 }
194
195 if(ap->video_codec_id){
196 st->codec.codec_type = CODEC_TYPE_VIDEO;
197 st->codec.codec_id = ap->video_codec_id;
198 }else if(ap->audio_codec_id){
199 st->codec.codec_type = CODEC_TYPE_AUDIO;
200 st->codec.codec_id = ap->audio_codec_id;
201 }else{
202 st->codec.codec_type = CODEC_TYPE_VIDEO;
203 st->codec.codec_id = av_str2id(img_tags, s->path);
204 }
205
206 return 0;
207
208 fail:
209 av_free(s);
210 return AVERROR_IO;
211 }
212
213 static int img_read_packet(AVFormatContext *s1, AVPacket *pkt)
214 {
215 VideoData *s = s1->priv_data;
216 char filename[1024];
217 int ret;
218 ByteIOContext f1, *f;
219
220 if (!s->is_pipe) {
221 /* loop over input */
222 if (loop_input && s->img_number > s->img_last) {
223 s->img_number = s->img_first;
224 }
225 if (get_frame_filename(filename, sizeof(filename),
226 s->path, s->img_number)<0 && s->img_number > 1)
227 return AVERROR_IO;
228 f = &f1;
229 if (url_fopen(f, filename, URL_RDONLY) < 0)
230 return AVERROR_IO;
231 } else {
232 f = &s1->pb;
233 if (url_feof(f))
234 return AVERROR_IO;
235 }
236
237 if (s->is_pipe) {
238 av_new_packet(pkt, 4096);
239 }else{
240 av_new_packet(pkt, url_filesize(url_fileno(f)));
241 }
242 pkt->stream_index = 0;
243 pkt->flags |= PKT_FLAG_KEY;
244
245 ret = get_buffer(f, pkt->data, pkt->size);
246 if (!s->is_pipe) {
247 url_fclose(f);
248 }
249
250 if (ret <= 0) {
251 av_free_packet(pkt);
252 return AVERROR_IO; /* signal EOF */
253 } else {
254 pkt->size = ret;
255 s->img_count++;
256 s->img_number++;
257 return 0;
258 }
259 }
260
261 static int img_read_close(AVFormatContext *s1)
262 {
263 return 0;
264 }
265
266 /******************************************************/
267 /* image output */
268
269 static int img_write_header(AVFormatContext *s)
270 {
271 VideoData *img = s->priv_data;
272
273 img->img_number = 1;
274 strcpy(img->path, s->filename);
275
276 /* find format */
277 if (s->oformat->flags & AVFMT_NOFILE)
278 img->is_pipe = 0;
279 else
280 img->is_pipe = 1;
281
282 return 0;
283 }
284
285 static int img_write_packet(AVFormatContext *s, AVPacket *pkt)
286 {
287 VideoData *img = s->priv_data;
288 ByteIOContext pb1, *pb;
289 char filename[1024];
290
291 if (!img->is_pipe) {
292 if (get_frame_filename(filename, sizeof(filename),
293 img->path, img->img_number) < 0 && img->img_number>1)
294 return AVERROR_IO;
295 pb = &pb1;
296 if (url_fopen(pb, filename, URL_WRONLY) < 0)
297 return AVERROR_IO;
298 } else {
299 pb = &s->pb;
300 }
301
302 put_buffer(pb, pkt->data, pkt->size);
303 put_flush_packet(pb);
304 if (!img->is_pipe) {
305 url_fclose(pb);
306 }
307
308 img->img_number++;
309 return 0;
310 }
311
312 static int img_write_trailer(AVFormatContext *s)
313 {
314 return 0;
315 }
316
317 /* input */
318
319 static AVInputFormat image2_iformat = {
320 "image2",
321 "image2 sequence",
322 sizeof(VideoData),
323 image_probe,
324 img_read_header,
325 img_read_packet,
326 img_read_close,
327 NULL,
328 NULL,
329 AVFMT_NOFILE,
330 };
331
332 static AVInputFormat image2pipe_iformat = {
333 "image2pipe",
334 "piped image2 sequence",
335 sizeof(VideoData),
336 NULL, /* no probe */
337 img_read_header,
338 img_read_packet,
339 img_read_close,
340 NULL,
341 };
342
343
344 /* output */
345
346 static AVOutputFormat image2_oformat = {
347 "image2",
348 "image2 sequence",
349 "",
350 "",
351 sizeof(VideoData),
352 CODEC_ID_NONE,
353 CODEC_ID_MJPEG,
354 img_write_header,
355 img_write_packet,
356 img_write_trailer,
357 AVFMT_NOFILE,
358 };
359
360 static AVOutputFormat image2pipe_oformat = {
361 "image2pipe",
362 "piped image2 sequence",
363 "",
364 "",
365 sizeof(VideoData),
366 CODEC_ID_NONE,
367 CODEC_ID_MJPEG,
368 img_write_header,
369 img_write_packet,
370 img_write_trailer,
371 };
372
373 int img2_init(void)
374 {
375 av_register_input_format(&image2_iformat);
376 av_register_output_format(&image2_oformat);
377
378 av_register_input_format(&image2pipe_iformat);
379 av_register_output_format(&image2pipe_oformat);
380
381 return 0;
382 }