3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
4 * Copyright (c) 2004 Michael Niedermayer
6 * This file is part of FFmpeg.
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.
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.
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
23 #include "libavutil/intreadwrite.h"
24 #include "libavutil/avstring.h"
42 static const IdStrMap img_tags
[] = {
43 { CODEC_ID_MJPEG
, "jpeg"},
44 { CODEC_ID_MJPEG
, "jpg"},
45 { CODEC_ID_LJPEG
, "ljpg"},
46 { CODEC_ID_PNG
, "png"},
47 { CODEC_ID_PNG
, "mng"},
48 { CODEC_ID_PPM
, "ppm"},
49 { CODEC_ID_PPM
, "pnm"},
50 { CODEC_ID_PGM
, "pgm"},
51 { CODEC_ID_PGMYUV
, "pgmyuv"},
52 { CODEC_ID_PBM
, "pbm"},
53 { CODEC_ID_PAM
, "pam"},
54 { CODEC_ID_MPEG1VIDEO
, "mpg1-img"},
55 { CODEC_ID_MPEG2VIDEO
, "mpg2-img"},
56 { CODEC_ID_MPEG4
, "mpg4-img"},
57 { CODEC_ID_FFV1
, "ffv1-img"},
58 { CODEC_ID_RAWVIDEO
, "y"},
59 { CODEC_ID_BMP
, "bmp"},
60 { CODEC_ID_GIF
, "gif"},
61 { CODEC_ID_TARGA
, "tga"},
62 { CODEC_ID_TIFF
, "tiff"},
63 { CODEC_ID_TIFF
, "tif"},
64 { CODEC_ID_SGI
, "sgi"},
65 { CODEC_ID_PTX
, "ptx"},
66 { CODEC_ID_PCX
, "pcx"},
67 { CODEC_ID_SUNRAST
, "sun"},
68 { CODEC_ID_SUNRAST
, "ras"},
69 { CODEC_ID_SUNRAST
, "rs"},
70 { CODEC_ID_SUNRAST
, "im1"},
71 { CODEC_ID_SUNRAST
, "im8"},
72 { CODEC_ID_SUNRAST
, "im24"},
73 { CODEC_ID_SUNRAST
, "sunras"},
74 { CODEC_ID_JPEG2000
, "jp2"},
75 { CODEC_ID_NONE
, NULL
}
78 static const int sizes
[][2] = {
90 static int infer_size(int *width_ptr
, int *height_ptr
, int size
)
94 for(i
=0;i
<FF_ARRAY_ELEMS(sizes
);i
++) {
95 if ((sizes
[i
][0] * sizes
[i
][1]) == size
) {
96 *width_ptr
= sizes
[i
][0];
97 *height_ptr
= sizes
[i
][1];
103 static enum CodecID
av_str2id(const IdStrMap
*tags
, const char *str
)
105 str
= strrchr(str
, '.');
106 if(!str
) return CODEC_ID_NONE
;
110 if (!strcasecmp(str
, tags
->str
))
115 return CODEC_ID_NONE
;
118 /* return -1 if no image found */
119 static int find_image_range(int *pfirst_index
, int *plast_index
,
123 int range
, last_index
, range1
, first_index
;
125 /* find the first image */
126 for(first_index
= 0; first_index
< 5; first_index
++) {
127 if (av_get_frame_filename(buf
, sizeof(buf
), path
, first_index
) < 0){
135 if (first_index
== 5)
138 /* find the last image */
139 last_index
= first_index
;
147 if (av_get_frame_filename(buf
, sizeof(buf
), path
,
148 last_index
+ range1
) < 0)
153 /* just in case... */
154 if (range
>= (1 << 30))
157 /* we are sure than image last_index + range exists */
162 *pfirst_index
= first_index
;
163 *plast_index
= last_index
;
170 static int image_probe(AVProbeData
*p
)
172 if (p
->filename
&& av_str2id(img_tags
, p
->filename
)) {
173 if (av_filename_number_test(p
->filename
))
174 return AVPROBE_SCORE_MAX
;
176 return AVPROBE_SCORE_MAX
/2;
181 enum CodecID
av_guess_image2_codec(const char *filename
){
182 return av_str2id(img_tags
, filename
);
185 static int img_read_header(AVFormatContext
*s1
, AVFormatParameters
*ap
)
187 VideoData
*s
= s1
->priv_data
;
188 int first_index
, last_index
;
191 s1
->ctx_flags
|= AVFMTCTX_NOHEADER
;
193 st
= av_new_stream(s1
, 0);
195 return AVERROR(ENOMEM
);
198 av_strlcpy(s
->path
, s1
->filename
, sizeof(s
->path
));
203 if (s1
->iformat
->flags
& AVFMT_NOFILE
)
207 st
->need_parsing
= AVSTREAM_PARSE_FULL
;
210 if (!ap
->time_base
.num
) {
211 av_set_pts_info(st
, 60, 1, 25);
213 av_set_pts_info(st
, 60, ap
->time_base
.num
, ap
->time_base
.den
);
216 if(ap
->width
&& ap
->height
){
217 st
->codec
->width
= ap
->width
;
218 st
->codec
->height
= ap
->height
;
222 if (find_image_range(&first_index
, &last_index
, s
->path
) < 0)
224 s
->img_first
= first_index
;
225 s
->img_last
= last_index
;
226 s
->img_number
= first_index
;
227 /* compute duration */
229 st
->duration
= last_index
- first_index
+ 1;
232 if(ap
->video_codec_id
){
233 st
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
234 st
->codec
->codec_id
= ap
->video_codec_id
;
235 }else if(ap
->audio_codec_id
){
236 st
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
237 st
->codec
->codec_id
= ap
->audio_codec_id
;
239 st
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
240 st
->codec
->codec_id
= av_str2id(img_tags
, s
->path
);
242 if(st
->codec
->codec_type
== CODEC_TYPE_VIDEO
&& ap
->pix_fmt
!= PIX_FMT_NONE
)
243 st
->codec
->pix_fmt
= ap
->pix_fmt
;
248 static int img_read_packet(AVFormatContext
*s1
, AVPacket
*pkt
)
250 VideoData
*s
= s1
->priv_data
;
253 int size
[3]={0}, ret
[3]={0};
255 AVCodecContext
*codec
= s1
->streams
[0]->codec
;
258 /* loop over input */
259 if (s1
->loop_input
&& s
->img_number
> s
->img_last
) {
260 s
->img_number
= s
->img_first
;
262 if (av_get_frame_filename(filename
, sizeof(filename
),
263 s
->path
, s
->img_number
)<0 && s
->img_number
> 1)
266 if (url_fopen(&f
[i
], filename
, URL_RDONLY
) < 0)
268 size
[i
]= url_fsize(f
[i
]);
270 if(codec
->codec_id
!= CODEC_ID_RAWVIDEO
)
272 filename
[ strlen(filename
) - 1 ]= 'U' + i
;
275 if(codec
->codec_id
== CODEC_ID_RAWVIDEO
&& !codec
->width
)
276 infer_size(&codec
->width
, &codec
->height
, size
[0]);
284 av_new_packet(pkt
, size
[0] + size
[1] + size
[2]);
285 pkt
->stream_index
= 0;
286 pkt
->flags
|= PKT_FLAG_KEY
;
291 ret
[i
]= get_buffer(f
[i
], pkt
->data
+ pkt
->size
, size
[i
]);
299 if (ret
[0] <= 0 || ret
[1]<0 || ret
[2]<0) {
301 return AVERROR(EIO
); /* signal EOF */
309 #if CONFIG_IMAGE2_MUXER || CONFIG_IMAGE2PIPE_MUXER
310 /******************************************************/
313 static int img_write_header(AVFormatContext
*s
)
315 VideoData
*img
= s
->priv_data
;
318 av_strlcpy(img
->path
, s
->filename
, sizeof(img
->path
));
321 if (s
->oformat
->flags
& AVFMT_NOFILE
)
329 static int img_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
331 VideoData
*img
= s
->priv_data
;
332 ByteIOContext
*pb
[3];
334 AVCodecContext
*codec
= s
->streams
[ pkt
->stream_index
]->codec
;
338 if (av_get_frame_filename(filename
, sizeof(filename
),
339 img
->path
, img
->img_number
) < 0 && img
->img_number
>1)
342 if (url_fopen(&pb
[i
], filename
, URL_WRONLY
) < 0)
345 if(codec
->codec_id
!= CODEC_ID_RAWVIDEO
)
347 filename
[ strlen(filename
) - 1 ]= 'U' + i
;
353 if(codec
->codec_id
== CODEC_ID_RAWVIDEO
){
354 int ysize
= codec
->width
* codec
->height
;
355 put_buffer(pb
[0], pkt
->data
, ysize
);
356 put_buffer(pb
[1], pkt
->data
+ ysize
, (pkt
->size
- ysize
)/2);
357 put_buffer(pb
[2], pkt
->data
+ ysize
+(pkt
->size
- ysize
)/2, (pkt
->size
- ysize
)/2);
358 put_flush_packet(pb
[1]);
359 put_flush_packet(pb
[2]);
363 put_buffer(pb
[0], pkt
->data
, pkt
->size
);
365 put_flush_packet(pb
[0]);
374 #endif /* CONFIG_IMAGE2_MUXER || CONFIG_IMAGE2PIPE_MUXER */
377 #if CONFIG_IMAGE2_DEMUXER
378 AVInputFormat image2_demuxer
= {
380 NULL_IF_CONFIG_SMALL("image2 sequence"),
391 #if CONFIG_IMAGE2PIPE_DEMUXER
392 AVInputFormat image2pipe_demuxer
= {
394 NULL_IF_CONFIG_SMALL("piped image2 sequence"),
403 #if CONFIG_IMAGE2_MUXER
404 AVOutputFormat image2_muxer
= {
406 NULL_IF_CONFIG_SMALL("image2 sequence"),
408 "bmp,jpeg,jpg,ljpg,pam,pbm,pgm,pgmyuv,png,ppm,sgi,tif,tiff",
415 .flags
= AVFMT_NOTIMESTAMPS
| AVFMT_NOFILE
418 #if CONFIG_IMAGE2PIPE_MUXER
419 AVOutputFormat image2pipe_muxer
= {
421 NULL_IF_CONFIG_SMALL("piped image2 sequence"),
429 .flags
= AVFMT_NOTIMESTAMPS