980f4f981bf27b8634350d79797864fbfc8b0568
[libav.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 }