3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
4 * Copyright (c) 2004 Michael Niedermayer
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /* XXX: this is a hack */
23 extern int loop_input
;
39 static const IdStrMap img_tags
[] = {
40 { CODEC_ID_MJPEG
, "jpeg"},
41 { CODEC_ID_MJPEG
, "jpg"},
42 { CODEC_ID_LJPEG
, "ljpg"},
43 { CODEC_ID_PNG
, "png"},
44 { CODEC_ID_PPM
, "ppm"},
45 { CODEC_ID_PGM
, "pgm"},
46 { CODEC_ID_PGMYUV
, "pgmyuv"},
47 { CODEC_ID_PBM
, "pbm"},
48 { CODEC_ID_PAM
, "pam"},
49 { CODEC_ID_MPEG1VIDEO
, "mpg1-img"},
50 { CODEC_ID_MPEG2VIDEO
, "mpg2-img"},
51 { CODEC_ID_MPEG4
, "mpg4-img"},
52 { CODEC_ID_FFV1
, "ffv1-img"},
56 static enum CodecID
av_str2id(const IdStrMap
*tags
, const char *str
)
58 str
= strrchr(str
, '.');
59 if(!str
) return CODEC_ID_NONE
;
64 for(i
=0; toupper(tags
->str
[i
]) == toupper(str
[i
]); i
++){
65 if(tags
->str
[i
]==0 && str
[i
]==0)
74 static const char *av_id2str(const IdStrMap
*tags
, enum CodecID id
)
84 /* return -1 if no image found */
85 static int find_image_range(int *pfirst_index
, int *plast_index
,
89 int range
, last_index
, range1
, first_index
;
91 /* find the first image */
92 for(first_index
= 0; first_index
< 5; first_index
++) {
93 if (get_frame_filename(buf
, sizeof(buf
), path
, first_index
) < 0){
101 if (first_index
== 5)
104 /* find the last image */
105 last_index
= first_index
;
113 if (get_frame_filename(buf
, sizeof(buf
), path
,
114 last_index
+ range1
) < 0)
119 /* just in case... */
120 if (range
>= (1 << 30))
123 /* we are sure than image last_index + range exists */
128 *pfirst_index
= first_index
;
129 *plast_index
= last_index
;
136 static int image_probe(AVProbeData
*p
)
138 if (filename_number_test(p
->filename
) >= 0 && av_str2id(img_tags
, p
->filename
))
139 return AVPROBE_SCORE_MAX
;
144 enum CodecID
av_guess_image2_codec(const char *filename
){
145 return av_str2id(img_tags
, filename
);
148 static int img_read_header(AVFormatContext
*s1
, AVFormatParameters
*ap
)
150 VideoData
*s
= s1
->priv_data
;
151 int first_index
, last_index
;
154 s1
->ctx_flags
|= AVFMTCTX_NOHEADER
;
156 st
= av_new_stream(s1
, 0);
161 strcpy(s
->path
, s1
->filename
);
166 if (s1
->iformat
->flags
& AVFMT_NOFILE
)
173 if (!ap
|| !ap
->frame_rate
) {
174 st
->codec
.frame_rate
= 25;
175 st
->codec
.frame_rate_base
= 1;
177 st
->codec
.frame_rate
= ap
->frame_rate
;
178 st
->codec
.frame_rate_base
= ap
->frame_rate_base
;
182 if (find_image_range(&first_index
, &last_index
, s
->path
) < 0)
184 s
->img_first
= first_index
;
185 s
->img_last
= last_index
;
186 s
->img_number
= first_index
;
187 /* compute duration */
189 st
->duration
= ((int64_t)AV_TIME_BASE
*
190 (last_index
- first_index
+ 1) *
191 st
->codec
.frame_rate_base
) / st
->codec
.frame_rate
;
194 if(ap
->video_codec_id
){
195 st
->codec
.codec_type
= CODEC_TYPE_VIDEO
;
196 st
->codec
.codec_id
= ap
->video_codec_id
;
197 }else if(ap
->audio_codec_id
){
198 st
->codec
.codec_type
= CODEC_TYPE_AUDIO
;
199 st
->codec
.codec_id
= ap
->audio_codec_id
;
201 st
->codec
.codec_type
= CODEC_TYPE_VIDEO
;
202 st
->codec
.codec_id
= av_str2id(img_tags
, s
->path
);
208 static int img_read_packet(AVFormatContext
*s1
, AVPacket
*pkt
)
210 VideoData
*s
= s1
->priv_data
;
213 ByteIOContext f1
, *f
;
216 /* loop over input */
217 if (loop_input
&& s
->img_number
> s
->img_last
) {
218 s
->img_number
= s
->img_first
;
220 if (get_frame_filename(filename
, sizeof(filename
),
221 s
->path
, s
->img_number
)<0 && s
->img_number
> 1)
224 if (url_fopen(f
, filename
, URL_RDONLY
) < 0)
233 av_new_packet(pkt
, 4096);
235 av_new_packet(pkt
, url_filesize(url_fileno(f
)));
237 pkt
->stream_index
= 0;
238 pkt
->flags
|= PKT_FLAG_KEY
;
240 ret
= get_buffer(f
, pkt
->data
, pkt
->size
);
247 return AVERROR_IO
; /* signal EOF */
256 static int img_read_close(AVFormatContext
*s1
)
261 /******************************************************/
264 static int img_write_header(AVFormatContext
*s
)
266 VideoData
*img
= s
->priv_data
;
269 strcpy(img
->path
, s
->filename
);
272 if (s
->oformat
->flags
& AVFMT_NOFILE
)
280 static int img_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
282 VideoData
*img
= s
->priv_data
;
283 ByteIOContext pb1
, *pb
;
287 if (get_frame_filename(filename
, sizeof(filename
),
288 img
->path
, img
->img_number
) < 0 && img
->img_number
>1)
291 if (url_fopen(pb
, filename
, URL_WRONLY
) < 0)
297 put_buffer(pb
, pkt
->data
, pkt
->size
);
298 put_flush_packet(pb
);
307 static int img_write_trailer(AVFormatContext
*s
)
314 static AVInputFormat image2_iformat
= {
327 static AVInputFormat image2pipe_iformat
= {
329 "piped image2 sequence",
341 static AVOutputFormat image2_oformat
= {
355 static AVOutputFormat image2pipe_oformat
= {
357 "piped image2 sequence",
370 av_register_input_format(&image2_iformat
);
371 av_register_output_format(&image2_oformat
);
373 av_register_input_format(&image2pipe_iformat
);
374 av_register_output_format(&image2pipe_oformat
);