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