* moved os_support.h into libavcodec
[libav.git] / libavformat / img.c
CommitLineData
de6d9b64
FB
1/*
2 * Image format
19720f15 3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
de6d9b64 4 *
19720f15
FB
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.
de6d9b64 9 *
19720f15 10 * This library is distributed in the hope that it will be useful,
de6d9b64 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19720f15
FB
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
de6d9b64 14 *
19720f15
FB
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
de6d9b64 18 */
38758ab0 19#include <unistd.h>
de6d9b64 20#include "avformat.h"
4a899dd6 21#include "os_support.h"
9b2e001f 22
de6d9b64
FB
23typedef struct {
24 int width;
25 int height;
26 int img_number;
27 int img_size;
87a0a681
FB
28 AVImageFormat *img_fmt;
29 int pix_fmt;
de6d9b64
FB
30 int is_pipe;
31 char path[1024];
87a0a681
FB
32 /* temporary usage */
33 void *ptr;
de6d9b64
FB
34} VideoData;
35
87a0a681 36static int image_probe(AVProbeData *p)
de6d9b64 37{
94d883e8 38 if (filename_number_test(p->filename) >= 0 && guess_image_format(p->filename))
87a0a681
FB
39 return AVPROBE_SCORE_MAX;
40 else
de6d9b64 41 return 0;
de6d9b64
FB
42}
43
87a0a681 44static int read_header_alloc_cb(void *opaque, AVImageInfo *info)
de6d9b64 45{
87a0a681 46 VideoData *s = opaque;
de6d9b64 47
87a0a681
FB
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;
de6d9b64
FB
53}
54
55static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap)
56{
c9a65ca8 57 VideoData *s = s1->priv_data;
87a0a681 58 int i, ret;
de6d9b64 59 char buf[1024];
de6d9b64
FB
60 ByteIOContext pb1, *f = &pb1;
61 AVStream *st;
62
c9a65ca8 63 st = av_new_stream(s1, 0);
de6d9b64 64 if (!st) {
1ea4f593 65 av_free(s);
de6d9b64
FB
66 return -ENOMEM;
67 }
c9a65ca8 68
87a0a681
FB
69 if (ap && ap->image_format)
70 s->img_fmt = ap->image_format;
71
de6d9b64
FB
72 strcpy(s->path, s1->filename);
73 s->img_number = 0;
74
75 /* find format */
c9a65ca8 76 if (s1->iformat->flags & AVFMT_NOFILE)
de6d9b64
FB
77 s->is_pipe = 0;
78 else
79 s->is_pipe = 1;
80
de6d9b64
FB
81 if (!s->is_pipe) {
82 /* try to find the first image */
83 for(i=0;i<5;i++) {
9150f42e
FB
84 if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0)
85 goto fail;
de6d9b64
FB
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
87a0a681
FB
96 ret = av_read_image(f, s1->filename, s->img_fmt, read_header_alloc_cb, s);
97 if (ret < 0)
98 goto fail1;
de6d9b64
FB
99
100 if (!s->is_pipe) {
101 url_fclose(f);
102 } else {
103 url_fseek(f, 0, SEEK_SET);
104 }
105
de6d9b64
FB
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;
87a0a681
FB
110 st->codec.pix_fmt = s->pix_fmt;
111 s->img_size = avpicture_get_size(s->pix_fmt, s->width, s->height);
112
14bea432
MN
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 }
de6d9b64
FB
120
121 return 0;
122 fail1:
123 if (!s->is_pipe)
124 url_fclose(f);
125 fail:
1ea4f593 126 av_free(s);
de6d9b64
FB
127 return -EIO;
128}
129
87a0a681 130static int read_packet_alloc_cb(void *opaque, AVImageInfo *info)
de6d9b64 131{
87a0a681
FB
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);
de6d9b64
FB
138 return 0;
139}
140
87a0a681 141static int img_read_packet(AVFormatContext *s1, AVPacket *pkt)
de6d9b64 142{
87a0a681
FB
143 VideoData *s = s1->priv_data;
144 char filename[1024];
145 int ret;
146 ByteIOContext f1, *f;
de6d9b64 147
87a0a681
FB
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 }
6775c758 160
87a0a681
FB
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);
6775c758
FB
168 }
169
87a0a681
FB
170 if (ret < 0) {
171 av_free_packet(pkt);
172 return -EIO; /* signal EOF */
173 } else {
14bea432 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;
87a0a681
FB
175 s->img_number++;
176 return 0;
177 }
6775c758
FB
178}
179
87a0a681 180static int img_read_close(AVFormatContext *s1)
de6d9b64 181{
de6d9b64
FB
182 return 0;
183}
184
87a0a681
FB
185/******************************************************/
186/* image output */
187
188static int img_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
ad436907 189{
87a0a681
FB
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;
ad436907 198 } else {
87a0a681 199 img_fmt = guess_image_format(s->filename);
ad436907 200 }
87a0a681
FB
201 if (!img_fmt)
202 return -1;
ad436907 203
87a0a681
FB
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;
ad436907 212 }
87a0a681
FB
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;
ad436907
HM
218 return 0;
219}
220
de6d9b64
FB
221static int img_write_header(AVFormatContext *s)
222{
c9a65ca8 223 VideoData *img = s->priv_data;
de6d9b64 224
de6d9b64
FB
225 img->img_number = 1;
226 strcpy(img->path, s->filename);
227
228 /* find format */
c9a65ca8 229 if (s->oformat->flags & AVFMT_NOFILE)
de6d9b64
FB
230 img->is_pipe = 0;
231 else
232 img->is_pipe = 1;
233
de6d9b64 234 return 0;
de6d9b64
FB
235}
236
237static int img_write_packet(AVFormatContext *s, int stream_index,
0c1a9eda 238 uint8_t *buf, int size, int force_pts)
de6d9b64
FB
239{
240 VideoData *img = s->priv_data;
241 AVStream *st = s->streams[stream_index];
242 ByteIOContext pb1, *pb;
87a0a681
FB
243 AVPicture *picture;
244 int width, height, ret;
de6d9b64 245 char filename[1024];
87a0a681 246 AVImageInfo info;
de6d9b64
FB
247
248 width = st->codec.width;
249 height = st->codec.height;
ad436907 250
87a0a681 251 picture = (AVPicture *)buf;
de6d9b64 252
de6d9b64 253 if (!img->is_pipe) {
87a0a681
FB
254 if (get_frame_filename(filename, sizeof(filename),
255 img->path, img->img_number) < 0)
256 return -EIO;
de6d9b64
FB
257 pb = &pb1;
258 if (url_fopen(pb, filename, URL_WRONLY) < 0)
259 return -EIO;
260 } else {
261 pb = &s->pb;
262 }
87a0a681
FB
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);
de6d9b64
FB
268 if (!img->is_pipe) {
269 url_fclose(pb);
270 }
271
272 img->img_number++;
273 return 0;
274}
275
276static int img_write_trailer(AVFormatContext *s)
277{
de6d9b64
FB
278 return 0;
279}
280
87a0a681 281/* input */
de6d9b64 282
87a0a681
FB
283static AVInputFormat image_iformat = {
284 "image",
285 "image sequence",
c9a65ca8 286 sizeof(VideoData),
87a0a681 287 image_probe,
de6d9b64
FB
288 img_read_header,
289 img_read_packet,
290 img_read_close,
291 NULL,
9150f42e 292 AVFMT_NOFILE | AVFMT_NEEDNUMBER,
de6d9b64
FB
293};
294
87a0a681
FB
295static AVInputFormat imagepipe_iformat = {
296 "imagepipe",
297 "piped image sequence",
c9a65ca8
FB
298 sizeof(VideoData),
299 NULL, /* no probe */
de6d9b64
FB
300 img_read_header,
301 img_read_packet,
302 img_read_close,
303 NULL,
de6d9b64
FB
304};
305
de6d9b64 306
87a0a681 307/* output */
6775c758 308
87a0a681
FB
309static AVOutputFormat image_oformat = {
310 "image",
311 "image sequence",
6775c758 312 "",
6775c758 313 "",
c9a65ca8 314 sizeof(VideoData),
6775c758
FB
315 CODEC_ID_NONE,
316 CODEC_ID_RAWVIDEO,
317 img_write_header,
318 img_write_packet,
319 img_write_trailer,
87a0a681
FB
320 AVFMT_NOFILE | AVFMT_NEEDNUMBER | AVFMT_RAWPICTURE,
321 img_set_parameters,
6775c758 322};
c9a65ca8 323
87a0a681
FB
324static AVOutputFormat imagepipe_oformat = {
325 "imagepipe",
326 "piped image sequence",
327 "",
ad436907 328 "",
ad436907
HM
329 sizeof(VideoData),
330 CODEC_ID_NONE,
331 CODEC_ID_RAWVIDEO,
332 img_write_header,
333 img_write_packet,
334 img_write_trailer,
94d883e8 335 AVFMT_RAWPICTURE,
87a0a681 336 img_set_parameters,
ad436907
HM
337};
338
c9a65ca8
FB
339int img_init(void)
340{
87a0a681
FB
341 av_register_input_format(&image_iformat);
342 av_register_output_format(&image_oformat);
c9a65ca8 343
87a0a681
FB
344 av_register_input_format(&imagepipe_iformat);
345 av_register_output_format(&imagepipe_oformat);
ad436907 346
c9a65ca8
FB
347 return 0;
348}