Cleaner support for usleep()
[ffmpeg.git] / libavformat / img.c
1 /*
2  * Image format
3  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 #include <unistd.h>
20 #include "avformat.h"
21 #include "../os_support.h"
22
23 typedef struct {
24     int width;
25     int height;
26     int img_number;
27     int img_size;
28     AVImageFormat *img_fmt;
29     int pix_fmt;
30     int is_pipe;
31     char path[1024];
32     /* temporary usage */
33     void *ptr;
34 } VideoData;
35
36 static int image_probe(AVProbeData *p)
37 {
38     if (filename_number_test(p->filename) >= 0 && guess_image_format(p->filename))
39         return AVPROBE_SCORE_MAX;
40     else
41         return 0;
42 }
43
44 static int read_header_alloc_cb(void *opaque, AVImageInfo *info)
45 {
46     VideoData *s = opaque;
47
48     s->width = info->width;
49     s->height = info->height;
50     s->pix_fmt = info->pix_fmt;
51     /* stop image reading but no error */
52     return 1;
53 }
54
55 static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap)
56 {
57     VideoData *s = s1->priv_data;
58     int i, ret;
59     char buf[1024];
60     ByteIOContext pb1, *f = &pb1;
61     AVStream *st;
62
63     st = av_new_stream(s1, 0);
64     if (!st) {
65         av_free(s);
66         return -ENOMEM;
67     }
68
69     if (ap && ap->image_format)
70         s->img_fmt = ap->image_format;
71
72     strcpy(s->path, s1->filename);
73     s->img_number = 0;
74
75     /* find format */
76     if (s1->iformat->flags & AVFMT_NOFILE)
77         s->is_pipe = 0;
78     else
79         s->is_pipe = 1;
80         
81     if (!s->is_pipe) {
82         /* try to find the first image */
83         for(i=0;i<5;i++) {
84             if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0)
85                 goto fail;
86             if (url_fopen(f, buf, URL_RDONLY) >= 0)
87                 break;
88             s->img_number++;
89         }
90         if (i == 5)
91             goto fail;
92     } else {
93         f = &s1->pb;
94     }
95     
96     ret = av_read_image(f, s1->filename, s->img_fmt, read_header_alloc_cb, s);
97     if (ret < 0)
98         goto fail1;
99
100     if (!s->is_pipe) {
101         url_fclose(f);
102     } else {
103         url_fseek(f, 0, SEEK_SET);
104     }
105     
106     st->codec.codec_type = CODEC_TYPE_VIDEO;
107     st->codec.codec_id = CODEC_ID_RAWVIDEO;
108     st->codec.width = s->width;
109     st->codec.height = s->height;
110     st->codec.pix_fmt = s->pix_fmt;
111     s->img_size = avpicture_get_size(s->pix_fmt, s->width, s->height);
112
113     if (!ap || !ap->frame_rate){
114         st->codec.frame_rate      = 25;
115         st->codec.frame_rate_base = 1;
116     }else{
117         st->codec.frame_rate      = ap->frame_rate;
118         st->codec.frame_rate_base = ap->frame_rate_base;
119     }
120     
121     return 0;
122  fail1:
123     if (!s->is_pipe)
124         url_fclose(f);
125  fail:
126     av_free(s);
127     return -EIO;
128 }
129
130 static int read_packet_alloc_cb(void *opaque, AVImageInfo *info)
131 {
132     VideoData *s = opaque;
133
134     if (info->width != s->width ||
135         info->height != s->height)
136         return -1;
137     avpicture_fill(&info->pict, s->ptr, info->pix_fmt, info->width, info->height);
138     return 0;
139 }
140
141 static int img_read_packet(AVFormatContext *s1, AVPacket *pkt)
142 {
143     VideoData *s = s1->priv_data;
144     char filename[1024];
145     int ret;
146     ByteIOContext f1, *f;
147
148     if (!s->is_pipe) {
149         if (get_frame_filename(filename, sizeof(filename),
150                                s->path, s->img_number) < 0)
151             return -EIO;
152         f = &f1;
153         if (url_fopen(f, filename, URL_RDONLY) < 0)
154             return -EIO;
155     } else {
156         f = &s1->pb;
157         if (url_feof(f))
158             return -EIO;
159     }
160
161     av_new_packet(pkt, s->img_size);
162     pkt->stream_index = 0;
163
164     s->ptr = pkt->data;
165     ret = av_read_image(f, filename, s->img_fmt, read_packet_alloc_cb, s);
166     if (!s->is_pipe) {
167         url_fclose(f);
168     }
169
170     if (ret < 0) {
171         av_free_packet(pkt);
172         return -EIO; /* signal EOF */
173     } else {
174         pkt->pts = av_rescale((int64_t)s->img_number * s1->streams[0]->codec.frame_rate_base, s1->pts_den, s1->streams[0]->codec.frame_rate) / s1->pts_num;
175         s->img_number++;
176         return 0;
177     }
178 }
179
180 static int img_read_close(AVFormatContext *s1)
181 {
182     return 0;
183 }
184
185 /******************************************************/
186 /* image output */
187
188 static int img_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
189 {
190     VideoData *img = s->priv_data;
191     AVStream *st;
192     AVImageFormat *img_fmt;
193     int i;
194
195     /* find output image format */
196     if (ap && ap->image_format) {
197         img_fmt = ap->image_format;
198     } else {
199         img_fmt = guess_image_format(s->filename);
200     }
201     if (!img_fmt)
202         return -1;
203
204     if (s->nb_streams != 1)
205         return -1;
206     
207     st = s->streams[0];
208     /* we select the first matching format */
209     for(i=0;i<PIX_FMT_NB;i++) {
210         if (img_fmt->supported_pixel_formats & (1 << i))
211             break;
212     }
213     if (i >= PIX_FMT_NB)
214         return -1;
215     img->img_fmt = img_fmt;
216     img->pix_fmt = i;
217     st->codec.pix_fmt = img->pix_fmt;
218     return 0;
219 }
220
221 static int img_write_header(AVFormatContext *s)
222 {
223     VideoData *img = s->priv_data;
224
225     img->img_number = 1;
226     strcpy(img->path, s->filename);
227
228     /* find format */
229     if (s->oformat->flags & AVFMT_NOFILE)
230         img->is_pipe = 0;
231     else
232         img->is_pipe = 1;
233         
234     return 0;
235 }
236
237 static int img_write_packet(AVFormatContext *s, int stream_index,
238                             uint8_t *buf, int size, int force_pts)
239 {
240     VideoData *img = s->priv_data;
241     AVStream *st = s->streams[stream_index];
242     ByteIOContext pb1, *pb;
243     AVPicture *picture;
244     int width, height, ret;
245     char filename[1024];
246     AVImageInfo info;
247
248     width = st->codec.width;
249     height = st->codec.height;
250     
251     picture = (AVPicture *)buf;
252
253     if (!img->is_pipe) {
254         if (get_frame_filename(filename, sizeof(filename), 
255                                img->path, img->img_number) < 0)
256             return -EIO;
257         pb = &pb1;
258         if (url_fopen(pb, filename, URL_WRONLY) < 0)
259             return -EIO;
260     } else {
261         pb = &s->pb;
262     }
263     info.width = width;
264     info.height = height;
265     info.pix_fmt = st->codec.pix_fmt;
266     info.pict = *picture;
267     ret = av_write_image(pb, img->img_fmt, &info);
268     if (!img->is_pipe) {
269         url_fclose(pb);
270     }
271
272     img->img_number++;
273     return 0;
274 }
275
276 static int img_write_trailer(AVFormatContext *s)
277 {
278     return 0;
279 }
280
281 /* input */
282
283 static AVInputFormat image_iformat = {
284     "image",
285     "image sequence",
286     sizeof(VideoData),
287     image_probe,
288     img_read_header,
289     img_read_packet,
290     img_read_close,
291     NULL,
292     AVFMT_NOFILE | AVFMT_NEEDNUMBER,
293 };
294
295 static AVInputFormat imagepipe_iformat = {
296     "imagepipe",
297     "piped image sequence",
298     sizeof(VideoData),
299     NULL, /* no probe */
300     img_read_header,
301     img_read_packet,
302     img_read_close,
303     NULL,
304 };
305
306
307 /* output */
308
309 static AVOutputFormat image_oformat = {
310     "image",
311     "image sequence",
312     "",
313     "",
314     sizeof(VideoData),
315     CODEC_ID_NONE,
316     CODEC_ID_RAWVIDEO,
317     img_write_header,
318     img_write_packet,
319     img_write_trailer,
320     AVFMT_NOFILE | AVFMT_NEEDNUMBER | AVFMT_RAWPICTURE,
321     img_set_parameters,
322 };
323
324 static AVOutputFormat imagepipe_oformat = {
325     "imagepipe",
326     "piped image sequence",
327     "",
328     "",
329     sizeof(VideoData),
330     CODEC_ID_NONE,
331     CODEC_ID_RAWVIDEO,
332     img_write_header,
333     img_write_packet,
334     img_write_trailer,
335     AVFMT_RAWPICTURE,
336     img_set_parameters,
337 };
338
339 int img_init(void)
340 {
341     av_register_input_format(&image_iformat);
342     av_register_output_format(&image_oformat);
343
344     av_register_input_format(&imagepipe_iformat);
345     av_register_output_format(&imagepipe_oformat);
346     
347     return 0;
348 }