Statistics
| Branch: | Revision:

ffmpeg / libavformat / img2.c @ 0ec12335

History | View | Annotate | Download (10.8 KB)

1 03cfe134 Michael Niedermayer
/*
2
 * Image format
3
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
4
 * Copyright (c) 2004 Michael Niedermayer
5
 *
6 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9 03cfe134 Michael Niedermayer
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
12 03cfe134 Michael Niedermayer
 *
13 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
14 03cfe134 Michael Niedermayer
 * 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.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
20 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 03cfe134 Michael Niedermayer
 */
22
#include "avformat.h"
23 75e61b0e Måns Rullgård
#include "avstring.h"
24 03cfe134 Michael Niedermayer
25
typedef struct {
26
    int img_first;
27
    int img_last;
28
    int img_number;
29
    int img_count;
30
    int is_pipe;
31
    char path[1024];
32
} VideoData;
33
34
typedef struct {
35
    enum CodecID id;
36
    const char *str;
37
} IdStrMap;
38
39
static const IdStrMap img_tags[] = {
40
    { CODEC_ID_MJPEG     , "jpeg"},
41
    { CODEC_ID_MJPEG     , "jpg"},
42
    { CODEC_ID_LJPEG     , "ljpg"},
43 4eff7cf4 Michael Niedermayer
    { CODEC_ID_PNG       , "png"},
44 5b6d5596 Michael Niedermayer
    { 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 03cfe134 Michael Niedermayer
    { CODEC_ID_MPEG1VIDEO, "mpg1-img"},
50
    { CODEC_ID_MPEG2VIDEO, "mpg2-img"},
51
    { CODEC_ID_MPEG4     , "mpg4-img"},
52
    { CODEC_ID_FFV1      , "ffv1-img"},
53 55cf1959 Michael Niedermayer
    { CODEC_ID_RAWVIDEO  , "y"},
54 9fa62f2a Måns Rullgård
    { CODEC_ID_BMP       , "bmp"},
55 6f9e492a Baptiste Coudurier
    { CODEC_ID_GIF       , "gif"},
56 79f7c32f Kostya Shishkov
    { CODEC_ID_TARGA     , "tga"},
57
    { CODEC_ID_TIFF      , "tiff"},
58 2d99eed1 Xiaohui Sun
    { CODEC_ID_SGI       , "sgi"},
59 8d2fb333 Ivo van Poorten
    { CODEC_ID_PTX       , "ptx"},
60 03cfe134 Michael Niedermayer
    {0, NULL}
61
};
62
63 55cf1959 Michael Niedermayer
static int sizes[][2] = {
64
    { 640, 480 },
65
    { 720, 480 },
66
    { 720, 576 },
67
    { 352, 288 },
68
    { 352, 240 },
69
    { 160, 128 },
70
    { 512, 384 },
71
    { 640, 352 },
72
    { 640, 240 },
73
};
74
75
static int infer_size(int *width_ptr, int *height_ptr, int size)
76
{
77
    int i;
78
79
    for(i=0;i<sizeof(sizes)/sizeof(sizes[0]);i++) {
80
        if ((sizes[i][0] * sizes[i][1]) == size) {
81
            *width_ptr = sizes[i][0];
82
            *height_ptr = sizes[i][1];
83
            return 0;
84
        }
85
    }
86
    return -1;
87
}
88 03cfe134 Michael Niedermayer
static enum CodecID av_str2id(const IdStrMap *tags, const char *str)
89
{
90 3ed02129 Michael Niedermayer
    str= strrchr(str, '.');
91
    if(!str) return CODEC_ID_NONE;
92
    str++;
93 03cfe134 Michael Niedermayer
94
    while (tags->id) {
95
        int i;
96
        for(i=0; toupper(tags->str[i]) == toupper(str[i]); i++){
97
            if(tags->str[i]==0 && str[i]==0)
98
                return tags->id;
99
        }
100
101
        tags++;
102
    }
103
    return CODEC_ID_NONE;
104
}
105
106
/* return -1 if no image found */
107 115329f1 Diego Biurrun
static int find_image_range(int *pfirst_index, int *plast_index,
108 03cfe134 Michael Niedermayer
                            const char *path)
109
{
110
    char buf[1024];
111
    int range, last_index, range1, first_index;
112
113
    /* find the first image */
114
    for(first_index = 0; first_index < 5; first_index++) {
115 5c07cf53 Michel Bardiaux
        if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0){
116 115329f1 Diego Biurrun
            *pfirst_index =
117 61fb3183 Michael Niedermayer
            *plast_index = 1;
118
            return 0;
119
        }
120 03cfe134 Michael Niedermayer
        if (url_exist(buf))
121
            break;
122
    }
123
    if (first_index == 5)
124
        goto fail;
125 115329f1 Diego Biurrun
126 03cfe134 Michael Niedermayer
    /* find the last image */
127
    last_index = first_index;
128
    for(;;) {
129
        range = 0;
130
        for(;;) {
131
            if (!range)
132
                range1 = 1;
133
            else
134
                range1 = 2 * range;
135 5c07cf53 Michel Bardiaux
            if (av_get_frame_filename(buf, sizeof(buf), path,
136
                                      last_index + range1) < 0)
137 03cfe134 Michael Niedermayer
                goto fail;
138
            if (!url_exist(buf))
139
                break;
140
            range = range1;
141
            /* just in case... */
142
            if (range >= (1 << 30))
143
                goto fail;
144
        }
145
        /* we are sure than image last_index + range exists */
146
        if (!range)
147
            break;
148
        last_index += range;
149
    }
150
    *pfirst_index = first_index;
151
    *plast_index = last_index;
152
    return 0;
153
 fail:
154
    return -1;
155
}
156
157
158
static int image_probe(AVProbeData *p)
159
{
160 e825b500 Joakim Plate
    if (p->filename && av_str2id(img_tags, p->filename)) {
161 d1e8675c Baptiste Coudurier
        if (av_filename_number_test(p->filename))
162
            return AVPROBE_SCORE_MAX;
163
        else
164
            return AVPROBE_SCORE_MAX/2;
165
    }
166
    return 0;
167 03cfe134 Michael Niedermayer
}
168
169 5b6d5596 Michael Niedermayer
enum CodecID av_guess_image2_codec(const char *filename){
170
    return av_str2id(img_tags, filename);
171
}
172
173 03cfe134 Michael Niedermayer
static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap)
174
{
175
    VideoData *s = s1->priv_data;
176
    int first_index, last_index;
177
    AVStream *st;
178
179
    s1->ctx_flags |= AVFMTCTX_NOHEADER;
180
181
    st = av_new_stream(s1, 0);
182
    if (!st) {
183 8fa36ae0 François Revol
        return AVERROR(ENOMEM);
184 03cfe134 Michael Niedermayer
    }
185
186 75e61b0e Måns Rullgård
    av_strlcpy(s->path, s1->filename, sizeof(s->path));
187 03cfe134 Michael Niedermayer
    s->img_number = 0;
188
    s->img_count = 0;
189 115329f1 Diego Biurrun
190 03cfe134 Michael Niedermayer
    /* find format */
191
    if (s1->iformat->flags & AVFMT_NOFILE)
192
        s->is_pipe = 0;
193 146210ca Michael Niedermayer
    else{
194 03cfe134 Michael Niedermayer
        s->is_pipe = 1;
195 57004ff1 Aurelien Jacobs
        st->need_parsing = AVSTREAM_PARSE_FULL;
196 146210ca Michael Niedermayer
    }
197 115329f1 Diego Biurrun
198 c04c3282 Michael Niedermayer
    if (!ap->time_base.num) {
199 c0df9d75 Michael Niedermayer
        av_set_pts_info(st, 60, 1, 25);
200 03cfe134 Michael Niedermayer
    } else {
201 c0df9d75 Michael Niedermayer
        av_set_pts_info(st, 60, ap->time_base.num, ap->time_base.den);
202 03cfe134 Michael Niedermayer
    }
203 115329f1 Diego Biurrun
204 c04c3282 Michael Niedermayer
    if(ap->width && ap->height){
205 01f4895c Michael Niedermayer
        st->codec->width = ap->width;
206
        st->codec->height= ap->height;
207 55cf1959 Michael Niedermayer
    }
208 115329f1 Diego Biurrun
209 03cfe134 Michael Niedermayer
    if (!s->is_pipe) {
210
        if (find_image_range(&first_index, &last_index, s->path) < 0)
211 6f3e0b21 Panagiotis Issaris
            return AVERROR(EIO);
212 03cfe134 Michael Niedermayer
        s->img_first = first_index;
213
        s->img_last = last_index;
214
        s->img_number = first_index;
215
        /* compute duration */
216
        st->start_time = 0;
217 c0df9d75 Michael Niedermayer
        st->duration = last_index - first_index + 1;
218 03cfe134 Michael Niedermayer
    }
219 115329f1 Diego Biurrun
220 5b6d5596 Michael Niedermayer
    if(ap->video_codec_id){
221 01f4895c Michael Niedermayer
        st->codec->codec_type = CODEC_TYPE_VIDEO;
222
        st->codec->codec_id = ap->video_codec_id;
223 5b6d5596 Michael Niedermayer
    }else if(ap->audio_codec_id){
224 01f4895c Michael Niedermayer
        st->codec->codec_type = CODEC_TYPE_AUDIO;
225
        st->codec->codec_id = ap->audio_codec_id;
226 5b6d5596 Michael Niedermayer
    }else{
227 01f4895c Michael Niedermayer
        st->codec->codec_type = CODEC_TYPE_VIDEO;
228
        st->codec->codec_id = av_str2id(img_tags, s->path);
229 5b6d5596 Michael Niedermayer
    }
230 01f4895c Michael Niedermayer
    if(st->codec->codec_type == CODEC_TYPE_VIDEO && ap->pix_fmt != PIX_FMT_NONE)
231
        st->codec->pix_fmt = ap->pix_fmt;
232 03cfe134 Michael Niedermayer
233
    return 0;
234
}
235
236
static int img_read_packet(AVFormatContext *s1, AVPacket *pkt)
237
{
238
    VideoData *s = s1->priv_data;
239
    char filename[1024];
240 55cf1959 Michael Niedermayer
    int i;
241
    int size[3]={0}, ret[3]={0};
242
    ByteIOContext f1[3], *f[3]= {&f1[0], &f1[1], &f1[2]};
243 01f4895c Michael Niedermayer
    AVCodecContext *codec= s1->streams[0]->codec;
244 03cfe134 Michael Niedermayer
245
    if (!s->is_pipe) {
246
        /* loop over input */
247 5894e1bb Víctor Paesa
        if (s1->loop_input && s->img_number > s->img_last) {
248 03cfe134 Michael Niedermayer
            s->img_number = s->img_first;
249 b339fb00 Michael Niedermayer
        }
250 5c07cf53 Michel Bardiaux
        if (av_get_frame_filename(filename, sizeof(filename),
251
                                  s->path, s->img_number)<0 && s->img_number > 1)
252 6f3e0b21 Panagiotis Issaris
            return AVERROR(EIO);
253 55cf1959 Michael Niedermayer
        for(i=0; i<3; i++){
254
            if (url_fopen(f[i], filename, URL_RDONLY) < 0)
255 6f3e0b21 Panagiotis Issaris
                return AVERROR(EIO);
256 a965c478 Aurelien Jacobs
            size[i]= url_fsize(f[i]);
257 115329f1 Diego Biurrun
258 55cf1959 Michael Niedermayer
            if(codec->codec_id != CODEC_ID_RAWVIDEO)
259
                break;
260
            filename[ strlen(filename) - 1 ]= 'U' + i;
261
        }
262 115329f1 Diego Biurrun
263 55cf1959 Michael Niedermayer
        if(codec->codec_id == CODEC_ID_RAWVIDEO && !codec->width)
264
            infer_size(&codec->width, &codec->height, size[0]);
265 03cfe134 Michael Niedermayer
    } else {
266 55cf1959 Michael Niedermayer
        f[0] = &s1->pb;
267
        if (url_feof(f[0]))
268 6f3e0b21 Panagiotis Issaris
            return AVERROR(EIO);
269 55cf1959 Michael Niedermayer
        size[0]= 4096;
270 03cfe134 Michael Niedermayer
    }
271
272 55cf1959 Michael Niedermayer
    av_new_packet(pkt, size[0] + size[1] + size[2]);
273 03cfe134 Michael Niedermayer
    pkt->stream_index = 0;
274
    pkt->flags |= PKT_FLAG_KEY;
275
276 55cf1959 Michael Niedermayer
    pkt->size= 0;
277
    for(i=0; i<3; i++){
278
        if(size[i]){
279
            ret[i]= get_buffer(f[i], pkt->data + pkt->size, size[i]);
280
            if (!s->is_pipe)
281
                url_fclose(f[i]);
282
            if(ret[i]>0)
283
                pkt->size += ret[i];
284
        }
285 03cfe134 Michael Niedermayer
    }
286
287 55cf1959 Michael Niedermayer
    if (ret[0] <= 0 || ret[1]<0 || ret[2]<0) {
288 03cfe134 Michael Niedermayer
        av_free_packet(pkt);
289 6f3e0b21 Panagiotis Issaris
        return AVERROR(EIO); /* signal EOF */
290 03cfe134 Michael Niedermayer
    } else {
291
        s->img_count++;
292
        s->img_number++;
293
        return 0;
294
    }
295
}
296
297
static int img_read_close(AVFormatContext *s1)
298
{
299
    return 0;
300
}
301
302 8228bff5 Diego Biurrun
#ifdef CONFIG_MUXERS
303 03cfe134 Michael Niedermayer
/******************************************************/
304
/* image output */
305
306
static int img_write_header(AVFormatContext *s)
307
{
308
    VideoData *img = s->priv_data;
309
310
    img->img_number = 1;
311 75e61b0e Måns Rullgård
    av_strlcpy(img->path, s->filename, sizeof(img->path));
312 03cfe134 Michael Niedermayer
313
    /* find format */
314
    if (s->oformat->flags & AVFMT_NOFILE)
315
        img->is_pipe = 0;
316
    else
317
        img->is_pipe = 1;
318 115329f1 Diego Biurrun
319 03cfe134 Michael Niedermayer
    return 0;
320
}
321
322
static int img_write_packet(AVFormatContext *s, AVPacket *pkt)
323
{
324
    VideoData *img = s->priv_data;
325 55cf1959 Michael Niedermayer
    ByteIOContext pb1[3], *pb[3]= {&pb1[0], &pb1[1], &pb1[2]};
326 03cfe134 Michael Niedermayer
    char filename[1024];
327 01f4895c Michael Niedermayer
    AVCodecContext *codec= s->streams[ pkt->stream_index ]->codec;
328 55cf1959 Michael Niedermayer
    int i;
329 03cfe134 Michael Niedermayer
330
    if (!img->is_pipe) {
331 5c07cf53 Michel Bardiaux
        if (av_get_frame_filename(filename, sizeof(filename),
332
                                  img->path, img->img_number) < 0 && img->img_number>1)
333 6f3e0b21 Panagiotis Issaris
            return AVERROR(EIO);
334 55cf1959 Michael Niedermayer
        for(i=0; i<3; i++){
335
            if (url_fopen(pb[i], filename, URL_WRONLY) < 0)
336 6f3e0b21 Panagiotis Issaris
                return AVERROR(EIO);
337 115329f1 Diego Biurrun
338 55cf1959 Michael Niedermayer
            if(codec->codec_id != CODEC_ID_RAWVIDEO)
339
                break;
340
            filename[ strlen(filename) - 1 ]= 'U' + i;
341
        }
342 03cfe134 Michael Niedermayer
    } else {
343 55cf1959 Michael Niedermayer
        pb[0] = &s->pb;
344 03cfe134 Michael Niedermayer
    }
345 115329f1 Diego Biurrun
346 55cf1959 Michael Niedermayer
    if(codec->codec_id == CODEC_ID_RAWVIDEO){
347 2c34596f Michael Niedermayer
        int ysize = codec->width * codec->height;
348
        put_buffer(pb[0], pkt->data        , ysize);
349
        put_buffer(pb[1], pkt->data + ysize, (pkt->size - ysize)/2);
350
        put_buffer(pb[2], pkt->data + ysize +(pkt->size - ysize)/2, (pkt->size - ysize)/2);
351 55cf1959 Michael Niedermayer
        put_flush_packet(pb[1]);
352
        put_flush_packet(pb[2]);
353
        url_fclose(pb[1]);
354
        url_fclose(pb[2]);
355
    }else{
356
        put_buffer(pb[0], pkt->data, pkt->size);
357
    }
358
    put_flush_packet(pb[0]);
359 03cfe134 Michael Niedermayer
    if (!img->is_pipe) {
360 55cf1959 Michael Niedermayer
        url_fclose(pb[0]);
361 03cfe134 Michael Niedermayer
    }
362
363
    img->img_number++;
364
    return 0;
365
}
366
367
static int img_write_trailer(AVFormatContext *s)
368
{
369
    return 0;
370
}
371
372 8228bff5 Diego Biurrun
#endif /* CONFIG_MUXERS */
373
374 03cfe134 Michael Niedermayer
/* input */
375 ff70e601 Måns Rullgård
#ifdef CONFIG_IMAGE2_DEMUXER
376
AVInputFormat image2_demuxer = {
377 03cfe134 Michael Niedermayer
    "image2",
378
    "image2 sequence",
379
    sizeof(VideoData),
380
    image_probe,
381
    img_read_header,
382
    img_read_packet,
383
    img_read_close,
384
    NULL,
385
    NULL,
386 61fb3183 Michael Niedermayer
    AVFMT_NOFILE,
387 03cfe134 Michael Niedermayer
};
388 ff70e601 Måns Rullgård
#endif
389
#ifdef CONFIG_IMAGE2PIPE_DEMUXER
390
AVInputFormat image2pipe_demuxer = {
391 03cfe134 Michael Niedermayer
    "image2pipe",
392
    "piped image2 sequence",
393
    sizeof(VideoData),
394
    NULL, /* no probe */
395
    img_read_header,
396
    img_read_packet,
397
    img_read_close,
398
    NULL,
399
};
400 ff70e601 Måns Rullgård
#endif
401 03cfe134 Michael Niedermayer
402
/* output */
403 ff70e601 Måns Rullgård
#ifdef CONFIG_IMAGE2_MUXER
404
AVOutputFormat image2_muxer = {
405 03cfe134 Michael Niedermayer
    "image2",
406
    "image2 sequence",
407
    "",
408
    "",
409
    sizeof(VideoData),
410
    CODEC_ID_NONE,
411
    CODEC_ID_MJPEG,
412
    img_write_header,
413
    img_write_packet,
414
    img_write_trailer,
415 61fb3183 Michael Niedermayer
    AVFMT_NOFILE,
416 03cfe134 Michael Niedermayer
};
417 ff70e601 Måns Rullgård
#endif
418
#ifdef CONFIG_IMAGE2PIPE_MUXER
419
AVOutputFormat image2pipe_muxer = {
420 03cfe134 Michael Niedermayer
    "image2pipe",
421
    "piped image2 sequence",
422
    "",
423
    "",
424
    sizeof(VideoData),
425
    CODEC_ID_NONE,
426
    CODEC_ID_MJPEG,
427
    img_write_header,
428
    img_write_packet,
429
    img_write_trailer,
430
};
431 8228bff5 Diego Biurrun
#endif