Mercurial > libavformat.hg
annotate img.c @ 1510:d68525fe36da libavformat
rename HAVE_DLFCN to HAVE_DLFCN_H
author | mru |
---|---|
date | Tue, 14 Nov 2006 23:53:37 +0000 |
parents | 0899bfe4105c |
children |
rev | line source |
---|---|
0 | 1 /* |
2 * Image format | |
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. | |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1291
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1291
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1291
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1291
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1291
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1291
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
885
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 20 */ |
21 #include "avformat.h" | |
11
932b59c66c60
mingw patch by (Bill Eldridge <bill at rfa dot org>)
michaelni
parents:
10
diff
changeset
|
22 |
0 | 23 typedef struct { |
24 int width; | |
25 int height; | |
199
66a05c4f8350
suppressed frame number modulus hack - added loop_input hack which I find easier to understand
bellard
parents:
189
diff
changeset
|
26 int img_first; |
66a05c4f8350
suppressed frame number modulus hack - added loop_input hack which I find easier to understand
bellard
parents:
189
diff
changeset
|
27 int img_last; |
0 | 28 int img_number; |
199
66a05c4f8350
suppressed frame number modulus hack - added loop_input hack which I find easier to understand
bellard
parents:
189
diff
changeset
|
29 int img_count; |
0 | 30 int img_size; |
20 | 31 AVImageFormat *img_fmt; |
32 int pix_fmt; | |
0 | 33 int is_pipe; |
34 char path[1024]; | |
20 | 35 /* temporary usage */ |
36 void *ptr; | |
0 | 37 } VideoData; |
38 | |
189 | 39 |
40 /* return -1 if no image found */ | |
885 | 41 static int find_image_range(int *pfirst_index, int *plast_index, |
189 | 42 const char *path) |
43 { | |
44 char buf[1024]; | |
45 int range, last_index, range1, first_index; | |
46 | |
47 /* find the first image */ | |
48 for(first_index = 0; first_index < 5; first_index++) { | |
1291
185190bdc185
Clarified API for numbered sequences, patch by Michel Bardiaux % mbardiaux A mediaxim P be %
gpoirier
parents:
1175
diff
changeset
|
49 if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0) |
189 | 50 goto fail; |
51 if (url_exist(buf)) | |
52 break; | |
53 } | |
54 if (first_index == 5) | |
55 goto fail; | |
885 | 56 |
189 | 57 /* find the last image */ |
58 last_index = first_index; | |
59 for(;;) { | |
60 range = 0; | |
61 for(;;) { | |
62 if (!range) | |
63 range1 = 1; | |
64 else | |
65 range1 = 2 * range; | |
1291
185190bdc185
Clarified API for numbered sequences, patch by Michel Bardiaux % mbardiaux A mediaxim P be %
gpoirier
parents:
1175
diff
changeset
|
66 if (av_get_frame_filename(buf, sizeof(buf), path, |
185190bdc185
Clarified API for numbered sequences, patch by Michel Bardiaux % mbardiaux A mediaxim P be %
gpoirier
parents:
1175
diff
changeset
|
67 last_index + range1) < 0) |
189 | 68 goto fail; |
69 if (!url_exist(buf)) | |
70 break; | |
71 range = range1; | |
72 /* just in case... */ | |
73 if (range >= (1 << 30)) | |
74 goto fail; | |
75 } | |
76 /* we are sure than image last_index + range exists */ | |
77 if (!range) | |
78 break; | |
79 last_index += range; | |
80 } | |
81 *pfirst_index = first_index; | |
82 *plast_index = last_index; | |
83 return 0; | |
84 fail: | |
85 return -1; | |
86 } | |
87 | |
88 | |
20 | 89 static int image_probe(AVProbeData *p) |
0 | 90 { |
1291
185190bdc185
Clarified API for numbered sequences, patch by Michel Bardiaux % mbardiaux A mediaxim P be %
gpoirier
parents:
1175
diff
changeset
|
91 if (av_filename_number_test(p->filename) && guess_image_format(p->filename)) |
582 | 92 return AVPROBE_SCORE_MAX-1; |
20 | 93 else |
94 return 0; | |
0 | 95 } |
96 | |
20 | 97 static int read_header_alloc_cb(void *opaque, AVImageInfo *info) |
0 | 98 { |
20 | 99 VideoData *s = opaque; |
100 | |
101 s->width = info->width; | |
102 s->height = info->height; | |
103 s->pix_fmt = info->pix_fmt; | |
104 /* stop image reading but no error */ | |
105 return 1; | |
0 | 106 } |
107 | |
20 | 108 static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) |
0 | 109 { |
20 | 110 VideoData *s = s1->priv_data; |
189 | 111 int ret, first_index, last_index; |
20 | 112 char buf[1024]; |
113 ByteIOContext pb1, *f = &pb1; | |
114 AVStream *st; | |
115 | |
116 st = av_new_stream(s1, 0); | |
117 if (!st) { | |
118 return -ENOMEM; | |
119 } | |
120 | |
1003 | 121 if (ap->image_format) |
20 | 122 s->img_fmt = ap->image_format; |
123 | |
639 | 124 pstrcpy(s->path, sizeof(s->path), s1->filename); |
20 | 125 s->img_number = 0; |
199
66a05c4f8350
suppressed frame number modulus hack - added loop_input hack which I find easier to understand
bellard
parents:
189
diff
changeset
|
126 s->img_count = 0; |
885 | 127 |
20 | 128 /* find format */ |
129 if (s1->iformat->flags & AVFMT_NOFILE) | |
130 s->is_pipe = 0; | |
131 else | |
132 s->is_pipe = 1; | |
743 | 133 |
1003 | 134 if (!ap->time_base.num) { |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
135 st->codec->time_base= (AVRational){1,25}; |
189 | 136 } else { |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
137 st->codec->time_base= ap->time_base; |
189 | 138 } |
885 | 139 |
20 | 140 if (!s->is_pipe) { |
189 | 141 if (find_image_range(&first_index, &last_index, s->path) < 0) |
142 goto fail; | |
199
66a05c4f8350
suppressed frame number modulus hack - added loop_input hack which I find easier to understand
bellard
parents:
189
diff
changeset
|
143 s->img_first = first_index; |
66a05c4f8350
suppressed frame number modulus hack - added loop_input hack which I find easier to understand
bellard
parents:
189
diff
changeset
|
144 s->img_last = last_index; |
189 | 145 s->img_number = first_index; |
146 /* compute duration */ | |
147 st->start_time = 0; | |
743 | 148 st->duration = last_index - first_index + 1; |
1291
185190bdc185
Clarified API for numbered sequences, patch by Michel Bardiaux % mbardiaux A mediaxim P be %
gpoirier
parents:
1175
diff
changeset
|
149 if (av_get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0) |
189 | 150 goto fail; |
151 if (url_fopen(f, buf, URL_RDONLY) < 0) | |
20 | 152 goto fail; |
153 } else { | |
154 f = &s1->pb; | |
0 | 155 } |
885 | 156 |
20 | 157 ret = av_read_image(f, s1->filename, s->img_fmt, read_header_alloc_cb, s); |
158 if (ret < 0) | |
159 goto fail1; | |
160 | |
161 if (!s->is_pipe) { | |
162 url_fclose(f); | |
163 } else { | |
164 url_fseek(f, 0, SEEK_SET); | |
165 } | |
885 | 166 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
167 st->codec->codec_type = CODEC_TYPE_VIDEO; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
168 st->codec->codec_id = CODEC_ID_RAWVIDEO; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
169 st->codec->width = s->width; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
170 st->codec->height = s->height; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
171 st->codec->pix_fmt = s->pix_fmt; |
459 | 172 s->img_size = avpicture_get_size(s->pix_fmt, (s->width+15)&(~15), (s->height+15)&(~15)); |
20 | 173 |
0 | 174 return 0; |
20 | 175 fail1: |
176 if (!s->is_pipe) | |
177 url_fclose(f); | |
178 fail: | |
482 | 179 return AVERROR_IO; |
0 | 180 } |
181 | |
20 | 182 static int read_packet_alloc_cb(void *opaque, AVImageInfo *info) |
0 | 183 { |
20 | 184 VideoData *s = opaque; |
0 | 185 |
20 | 186 if (info->width != s->width || |
187 info->height != s->height) | |
188 return -1; | |
459 | 189 avpicture_fill(&info->pict, s->ptr, info->pix_fmt, (info->width+15)&(~15), (info->height+15)&(~15)); |
0 | 190 return 0; |
191 } | |
192 | |
193 static int img_read_packet(AVFormatContext *s1, AVPacket *pkt) | |
194 { | |
195 VideoData *s = s1->priv_data; | |
196 char filename[1024]; | |
197 int ret; | |
198 ByteIOContext f1, *f; | |
199 | |
200 if (!s->is_pipe) { | |
199
66a05c4f8350
suppressed frame number modulus hack - added loop_input hack which I find easier to understand
bellard
parents:
189
diff
changeset
|
201 /* loop over input */ |
1175
8b53c0f3e7ad
add loop_input to AVFormatContext, getting rid of old hack
mru
parents:
1169
diff
changeset
|
202 if (s1->loop_input && s->img_number > s->img_last) { |
199
66a05c4f8350
suppressed frame number modulus hack - added loop_input hack which I find easier to understand
bellard
parents:
189
diff
changeset
|
203 s->img_number = s->img_first; |
66a05c4f8350
suppressed frame number modulus hack - added loop_input hack which I find easier to understand
bellard
parents:
189
diff
changeset
|
204 } |
1291
185190bdc185
Clarified API for numbered sequences, patch by Michel Bardiaux % mbardiaux A mediaxim P be %
gpoirier
parents:
1175
diff
changeset
|
205 if (av_get_frame_filename(filename, sizeof(filename), |
185190bdc185
Clarified API for numbered sequences, patch by Michel Bardiaux % mbardiaux A mediaxim P be %
gpoirier
parents:
1175
diff
changeset
|
206 s->path, s->img_number) < 0) |
482 | 207 return AVERROR_IO; |
0 | 208 f = &f1; |
209 if (url_fopen(f, filename, URL_RDONLY) < 0) | |
482 | 210 return AVERROR_IO; |
0 | 211 } else { |
212 f = &s1->pb; | |
213 if (url_feof(f)) | |
482 | 214 return AVERROR_IO; |
0 | 215 } |
216 | |
217 av_new_packet(pkt, s->img_size); | |
218 pkt->stream_index = 0; | |
219 | |
20 | 220 s->ptr = pkt->data; |
221 ret = av_read_image(f, filename, s->img_fmt, read_packet_alloc_cb, s); | |
0 | 222 if (!s->is_pipe) { |
223 url_fclose(f); | |
224 } | |
225 | |
226 if (ret < 0) { | |
227 av_free_packet(pkt); | |
482 | 228 return AVERROR_IO; /* signal EOF */ |
0 | 229 } else { |
199
66a05c4f8350
suppressed frame number modulus hack - added loop_input hack which I find easier to understand
bellard
parents:
189
diff
changeset
|
230 /* XXX: computing this pts is not necessary as it is done in |
66a05c4f8350
suppressed frame number modulus hack - added loop_input hack which I find easier to understand
bellard
parents:
189
diff
changeset
|
231 the generic code too */ |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
232 pkt->pts = av_rescale((int64_t)s->img_count * s1->streams[0]->codec->time_base.num, s1->streams[0]->time_base.den, s1->streams[0]->codec->time_base.den) / s1->streams[0]->time_base.num; |
199
66a05c4f8350
suppressed frame number modulus hack - added loop_input hack which I find easier to understand
bellard
parents:
189
diff
changeset
|
233 s->img_count++; |
0 | 234 s->img_number++; |
235 return 0; | |
236 } | |
237 } | |
238 | |
239 static int img_read_close(AVFormatContext *s1) | |
240 { | |
241 return 0; | |
242 } | |
243 | |
244 /******************************************************/ | |
245 /* image output */ | |
246 | |
20 | 247 static int img_set_parameters(AVFormatContext *s, AVFormatParameters *ap) |
0 | 248 { |
20 | 249 VideoData *img = s->priv_data; |
250 AVStream *st; | |
251 AVImageFormat *img_fmt; | |
0 | 252 int i; |
253 | |
20 | 254 /* find output image format */ |
1003 | 255 if (ap->image_format) { |
20 | 256 img_fmt = ap->image_format; |
257 } else { | |
258 img_fmt = guess_image_format(s->filename); | |
259 } | |
260 if (!img_fmt) | |
261 return -1; | |
0 | 262 |
20 | 263 if (s->nb_streams != 1) |
264 return -1; | |
885 | 265 |
20 | 266 st = s->streams[0]; |
267 /* we select the first matching format */ | |
268 for(i=0;i<PIX_FMT_NB;i++) { | |
269 if (img_fmt->supported_pixel_formats & (1 << i)) | |
270 break; | |
0 | 271 } |
20 | 272 if (i >= PIX_FMT_NB) |
273 return -1; | |
274 img->img_fmt = img_fmt; | |
275 img->pix_fmt = i; | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
276 st->codec->pix_fmt = img->pix_fmt; |
0 | 277 return 0; |
278 } | |
279 | |
280 static int img_write_header(AVFormatContext *s) | |
281 { | |
282 VideoData *img = s->priv_data; | |
283 | |
284 img->img_number = 1; | |
639 | 285 pstrcpy(img->path, sizeof(img->path), s->filename); |
0 | 286 |
287 /* find format */ | |
288 if (s->oformat->flags & AVFMT_NOFILE) | |
289 img->is_pipe = 0; | |
290 else | |
291 img->is_pipe = 1; | |
885 | 292 |
0 | 293 return 0; |
294 } | |
295 | |
468 | 296 static int img_write_packet(AVFormatContext *s, AVPacket *pkt) |
0 | 297 { |
298 VideoData *img = s->priv_data; | |
468 | 299 AVStream *st = s->streams[pkt->stream_index]; |
0 | 300 ByteIOContext pb1, *pb; |
20 | 301 AVPicture *picture; |
302 int width, height, ret; | |
0 | 303 char filename[1024]; |
20 | 304 AVImageInfo info; |
0 | 305 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
306 width = st->codec->width; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
307 height = st->codec->height; |
885 | 308 |
468 | 309 picture = (AVPicture *)pkt->data; |
0 | 310 |
20 | 311 if (!img->is_pipe) { |
1291
185190bdc185
Clarified API for numbered sequences, patch by Michel Bardiaux % mbardiaux A mediaxim P be %
gpoirier
parents:
1175
diff
changeset
|
312 if (av_get_frame_filename(filename, sizeof(filename), |
185190bdc185
Clarified API for numbered sequences, patch by Michel Bardiaux % mbardiaux A mediaxim P be %
gpoirier
parents:
1175
diff
changeset
|
313 img->path, img->img_number) < 0) |
482 | 314 return AVERROR_IO; |
0 | 315 pb = &pb1; |
316 if (url_fopen(pb, filename, URL_WRONLY) < 0) | |
482 | 317 return AVERROR_IO; |
0 | 318 } else { |
319 pb = &s->pb; | |
320 } | |
20 | 321 info.width = width; |
322 info.height = height; | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
743
diff
changeset
|
323 info.pix_fmt = st->codec->pix_fmt; |
280 | 324 info.interleaved = 0; /* FIXME: there should be a way to set it right */ |
20 | 325 info.pict = *picture; |
326 ret = av_write_image(pb, img->img_fmt, &info); | |
0 | 327 if (!img->is_pipe) { |
328 url_fclose(pb); | |
329 } | |
330 | |
331 img->img_number++; | |
332 return 0; | |
333 } | |
334 | |
335 static int img_write_trailer(AVFormatContext *s) | |
336 { | |
337 return 0; | |
338 } | |
339 | |
20 | 340 /* input */ |
1169 | 341 #ifdef CONFIG_IMAGE_DEMUXER |
342 AVInputFormat image_demuxer = { | |
20 | 343 "image", |
344 "image sequence", | |
0 | 345 sizeof(VideoData), |
20 | 346 image_probe, |
0 | 347 img_read_header, |
348 img_read_packet, | |
349 img_read_close, | |
350 NULL, | |
439 | 351 NULL, |
0 | 352 AVFMT_NOFILE | AVFMT_NEEDNUMBER, |
353 }; | |
1169 | 354 #endif |
355 #ifdef CONFIG_IMAGEPIPE_DEMUXER | |
356 AVInputFormat imagepipe_demuxer = { | |
20 | 357 "imagepipe", |
358 "piped image sequence", | |
0 | 359 sizeof(VideoData), |
360 NULL, /* no probe */ | |
361 img_read_header, | |
362 img_read_packet, | |
363 img_read_close, | |
364 NULL, | |
365 }; | |
1169 | 366 #endif |
20 | 367 |
368 /* output */ | |
1169 | 369 #ifdef CONFIG_IMAGE_MUXER |
370 AVOutputFormat image_muxer = { | |
20 | 371 "image", |
372 "image sequence", | |
0 | 373 "", |
20 | 374 "", |
0 | 375 sizeof(VideoData), |
376 CODEC_ID_NONE, | |
377 CODEC_ID_RAWVIDEO, | |
378 img_write_header, | |
379 img_write_packet, | |
380 img_write_trailer, | |
20 | 381 AVFMT_NOFILE | AVFMT_NEEDNUMBER | AVFMT_RAWPICTURE, |
382 img_set_parameters, | |
0 | 383 }; |
1169 | 384 #endif |
385 #ifdef CONFIG_IMAGEPIPE_MUXER | |
386 AVOutputFormat imagepipe_muxer = { | |
20 | 387 "imagepipe", |
388 "piped image sequence", | |
0 | 389 "", |
20 | 390 "", |
0 | 391 sizeof(VideoData), |
392 CODEC_ID_NONE, | |
393 CODEC_ID_RAWVIDEO, | |
394 img_write_header, | |
395 img_write_packet, | |
396 img_write_trailer, | |
21 | 397 AVFMT_RAWPICTURE, |
20 | 398 img_set_parameters, |
0 | 399 }; |
1169 | 400 #endif |