]> git.sesse.net Git - ffmpeg/blob - libavformat/img2.c
Fix linking when RTP is disabled and libraries are dynamic
[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 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 #include "avformat.h"
23 #include "avstring.h"
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     { CODEC_ID_RAWVIDEO  , "y"},
54     { CODEC_ID_BMP       , "bmp"},
55     { CODEC_ID_GIF       , "gif"},
56     { CODEC_ID_TARGA     , "tga"},
57     { CODEC_ID_TIFF      , "tiff"},
58     { CODEC_ID_SGI       , "sgi"},
59     { CODEC_ID_PTX       , "ptx"},
60     {0, NULL}
61 };
62
63 static int sizes[][2] = {
64     { 640, 480 },
65     { 720, 480 },
66     { 720, 576 },
67     { 352, 288 },
68     { 352, 240 },
69     { 160, 128 },
70     { 512, 384 },
71     { 640, 352 },
72     { 640, 240 },
73 };
74
75 static int infer_size(int *width_ptr, int *height_ptr, int size)
76 {
77     int i;
78
79     for(i=0;i<sizeof(sizes)/sizeof(sizes[0]);i++) {
80         if ((sizes[i][0] * sizes[i][1]) == size) {
81             *width_ptr = sizes[i][0];
82             *height_ptr = sizes[i][1];
83             return 0;
84         }
85     }
86     return -1;
87 }
88 static enum CodecID av_str2id(const IdStrMap *tags, const char *str)
89 {
90     str= strrchr(str, '.');
91     if(!str) return CODEC_ID_NONE;
92     str++;
93
94     while (tags->id) {
95         int i;
96         for(i=0; toupper(tags->str[i]) == toupper(str[i]); i++){
97             if(tags->str[i]==0 && str[i]==0)
98                 return tags->id;
99         }
100
101         tags++;
102     }
103     return CODEC_ID_NONE;
104 }
105
106 /* return -1 if no image found */
107 static int find_image_range(int *pfirst_index, int *plast_index,
108                             const char *path)
109 {
110     char buf[1024];
111     int range, last_index, range1, first_index;
112
113     /* find the first image */
114     for(first_index = 0; first_index < 5; first_index++) {
115         if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0){
116             *pfirst_index =
117             *plast_index = 1;
118             return 0;
119         }
120         if (url_exist(buf))
121             break;
122     }
123     if (first_index == 5)
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;
135             if (av_get_frame_filename(buf, sizeof(buf), path,
136                                       last_index + range1) < 0)
137                 goto fail;
138             if (!url_exist(buf))
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  fail:
154     return -1;
155 }
156
157
158 static int image_probe(AVProbeData *p)
159 {
160     if (p->filename && av_str2id(img_tags, p->filename)) {
161         if (av_filename_number_test(p->filename))
162             return AVPROBE_SCORE_MAX;
163         else
164             return AVPROBE_SCORE_MAX/2;
165     }
166     return 0;
167 }
168
169 enum CodecID av_guess_image2_codec(const char *filename){
170     return av_str2id(img_tags, filename);
171 }
172
173 static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap)
174 {
175     VideoData *s = s1->priv_data;
176     int first_index, last_index;
177     AVStream *st;
178
179     s1->ctx_flags |= AVFMTCTX_NOHEADER;
180
181     st = av_new_stream(s1, 0);
182     if (!st) {
183         return AVERROR(ENOMEM);
184     }
185
186     av_strlcpy(s->path, s1->filename, sizeof(s->path));
187     s->img_number = 0;
188     s->img_count = 0;
189
190     /* find format */
191     if (s1->iformat->flags & AVFMT_NOFILE)
192         s->is_pipe = 0;
193     else{
194         s->is_pipe = 1;
195         st->need_parsing = AVSTREAM_PARSE_FULL;
196     }
197
198     if (!ap->time_base.num) {
199         av_set_pts_info(st, 60, 1, 25);
200     } else {
201         av_set_pts_info(st, 60, ap->time_base.num, ap->time_base.den);
202     }
203
204     if(ap->width && ap->height){
205         st->codec->width = ap->width;
206         st->codec->height= ap->height;
207     }
208
209     if (!s->is_pipe) {
210         if (find_image_range(&first_index, &last_index, s->path) < 0)
211             return AVERROR(EIO);
212         s->img_first = first_index;
213         s->img_last = last_index;
214         s->img_number = first_index;
215         /* compute duration */
216         st->start_time = 0;
217         st->duration = last_index - first_index + 1;
218     }
219
220     if(ap->video_codec_id){
221         st->codec->codec_type = CODEC_TYPE_VIDEO;
222         st->codec->codec_id = ap->video_codec_id;
223     }else if(ap->audio_codec_id){
224         st->codec->codec_type = CODEC_TYPE_AUDIO;
225         st->codec->codec_id = ap->audio_codec_id;
226     }else{
227         st->codec->codec_type = CODEC_TYPE_VIDEO;
228         st->codec->codec_id = av_str2id(img_tags, s->path);
229     }
230     if(st->codec->codec_type == CODEC_TYPE_VIDEO && ap->pix_fmt != PIX_FMT_NONE)
231         st->codec->pix_fmt = ap->pix_fmt;
232
233     return 0;
234 }
235
236 static int img_read_packet(AVFormatContext *s1, AVPacket *pkt)
237 {
238     VideoData *s = s1->priv_data;
239     char filename[1024];
240     int i;
241     int size[3]={0}, ret[3]={0};
242     ByteIOContext f1[3], *f[3]= {&f1[0], &f1[1], &f1[2]};
243     AVCodecContext *codec= s1->streams[0]->codec;
244
245     if (!s->is_pipe) {
246         /* loop over input */
247         if (s1->loop_input && s->img_number > s->img_last) {
248             s->img_number = s->img_first;
249         }
250         if (av_get_frame_filename(filename, sizeof(filename),
251                                   s->path, s->img_number)<0 && s->img_number > 1)
252             return AVERROR(EIO);
253         for(i=0; i<3; i++){
254             if (url_fopen(f[i], filename, URL_RDONLY) < 0)
255                 return AVERROR(EIO);
256             size[i]= url_fsize(f[i]);
257
258             if(codec->codec_id != CODEC_ID_RAWVIDEO)
259                 break;
260             filename[ strlen(filename) - 1 ]= 'U' + i;
261         }
262
263         if(codec->codec_id == CODEC_ID_RAWVIDEO && !codec->width)
264             infer_size(&codec->width, &codec->height, size[0]);
265     } else {
266         f[0] = &s1->pb;
267         if (url_feof(f[0]))
268             return AVERROR(EIO);
269         size[0]= 4096;
270     }
271
272     av_new_packet(pkt, size[0] + size[1] + size[2]);
273     pkt->stream_index = 0;
274     pkt->flags |= PKT_FLAG_KEY;
275
276     pkt->size= 0;
277     for(i=0; i<3; i++){
278         if(size[i]){
279             ret[i]= get_buffer(f[i], pkt->data + pkt->size, size[i]);
280             if (!s->is_pipe)
281                 url_fclose(f[i]);
282             if(ret[i]>0)
283                 pkt->size += ret[i];
284         }
285     }
286
287     if (ret[0] <= 0 || ret[1]<0 || ret[2]<0) {
288         av_free_packet(pkt);
289         return AVERROR(EIO); /* signal EOF */
290     } else {
291         s->img_count++;
292         s->img_number++;
293         return 0;
294     }
295 }
296
297 static int img_read_close(AVFormatContext *s1)
298 {
299     return 0;
300 }
301
302 #ifdef CONFIG_MUXERS
303 /******************************************************/
304 /* image output */
305
306 static int img_write_header(AVFormatContext *s)
307 {
308     VideoData *img = s->priv_data;
309
310     img->img_number = 1;
311     av_strlcpy(img->path, s->filename, sizeof(img->path));
312
313     /* find format */
314     if (s->oformat->flags & AVFMT_NOFILE)
315         img->is_pipe = 0;
316     else
317         img->is_pipe = 1;
318
319     return 0;
320 }
321
322 static int img_write_packet(AVFormatContext *s, AVPacket *pkt)
323 {
324     VideoData *img = s->priv_data;
325     ByteIOContext pb1[3], *pb[3]= {&pb1[0], &pb1[1], &pb1[2]};
326     char filename[1024];
327     AVCodecContext *codec= s->streams[ pkt->stream_index ]->codec;
328     int i;
329
330     if (!img->is_pipe) {
331         if (av_get_frame_filename(filename, sizeof(filename),
332                                   img->path, img->img_number) < 0 && img->img_number>1)
333             return AVERROR(EIO);
334         for(i=0; i<3; i++){
335             if (url_fopen(pb[i], filename, URL_WRONLY) < 0)
336                 return AVERROR(EIO);
337
338             if(codec->codec_id != CODEC_ID_RAWVIDEO)
339                 break;
340             filename[ strlen(filename) - 1 ]= 'U' + i;
341         }
342     } else {
343         pb[0] = &s->pb;
344     }
345
346     if(codec->codec_id == CODEC_ID_RAWVIDEO){
347         int ysize = codec->width * codec->height;
348         put_buffer(pb[0], pkt->data        , ysize);
349         put_buffer(pb[1], pkt->data + ysize, (pkt->size - ysize)/2);
350         put_buffer(pb[2], pkt->data + ysize +(pkt->size - ysize)/2, (pkt->size - ysize)/2);
351         put_flush_packet(pb[1]);
352         put_flush_packet(pb[2]);
353         url_fclose(pb[1]);
354         url_fclose(pb[2]);
355     }else{
356         put_buffer(pb[0], pkt->data, pkt->size);
357     }
358     put_flush_packet(pb[0]);
359     if (!img->is_pipe) {
360         url_fclose(pb[0]);
361     }
362
363     img->img_number++;
364     return 0;
365 }
366
367 static int img_write_trailer(AVFormatContext *s)
368 {
369     return 0;
370 }
371
372 #endif /* CONFIG_MUXERS */
373
374 /* input */
375 #ifdef CONFIG_IMAGE2_DEMUXER
376 AVInputFormat image2_demuxer = {
377     "image2",
378     "image2 sequence",
379     sizeof(VideoData),
380     image_probe,
381     img_read_header,
382     img_read_packet,
383     img_read_close,
384     NULL,
385     NULL,
386     AVFMT_NOFILE,
387 };
388 #endif
389 #ifdef CONFIG_IMAGE2PIPE_DEMUXER
390 AVInputFormat image2pipe_demuxer = {
391     "image2pipe",
392     "piped image2 sequence",
393     sizeof(VideoData),
394     NULL, /* no probe */
395     img_read_header,
396     img_read_packet,
397     img_read_close,
398     NULL,
399 };
400 #endif
401
402 /* output */
403 #ifdef CONFIG_IMAGE2_MUXER
404 AVOutputFormat image2_muxer = {
405     "image2",
406     "image2 sequence",
407     "",
408     "",
409     sizeof(VideoData),
410     CODEC_ID_NONE,
411     CODEC_ID_MJPEG,
412     img_write_header,
413     img_write_packet,
414     img_write_trailer,
415     AVFMT_NOFILE,
416 };
417 #endif
418 #ifdef CONFIG_IMAGE2PIPE_MUXER
419 AVOutputFormat image2pipe_muxer = {
420     "image2pipe",
421     "piped image2 sequence",
422     "",
423     "",
424     sizeof(VideoData),
425     CODEC_ID_NONE,
426     CODEC_ID_MJPEG,
427     img_write_header,
428     img_write_packet,
429     img_write_trailer,
430 };
431 #endif