Statistics
| Branch: | Revision:

ffmpeg / libavformat / img2.c @ f0a9978c

History | View | Annotate | Download (10.8 KB)

1
/*
2
 * Image format
3
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
4
 * Copyright (c) 2004 Michael Niedermayer
5
 *
6
 * This file is part of FFmpeg.
7
 *
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.
12
 *
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.
17
 *
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
21
 */
22
#include "avformat.h"
23
#include "avstring.h"
24

    
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
    { 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"},
53
    { CODEC_ID_RAWVIDEO  , "y"},
54
    { CODEC_ID_BMP       , "bmp"},
55
    { CODEC_ID_GIF       , "gif"},
56
    { CODEC_ID_TARGA     , "tga"},
57
    { CODEC_ID_TIFF      , "tiff"},
58
    { CODEC_ID_SGI       , "sgi"},
59
    { CODEC_ID_PTX       , "ptx"},
60
    {0, NULL}
61
};
62

    
63
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
static enum CodecID av_str2id(const IdStrMap *tags, const char *str)
89
{
90
    str= strrchr(str, '.');
91
    if(!str) return CODEC_ID_NONE;
92
    str++;
93

    
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
static int find_image_range(int *pfirst_index, int *plast_index,
108
                            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
        if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0){
116
            *pfirst_index =
117
            *plast_index = 1;
118
            return 0;
119
        }
120
        if (url_exist(buf))
121
            break;
122
    }
123
    if (first_index == 5)
124
        goto fail;
125

    
126
    /* 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
            if (av_get_frame_filename(buf, sizeof(buf), path,
136
                                      last_index + range1) < 0)
137
                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
    if (p->filename && av_str2id(img_tags, p->filename)) {
161
        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
}
168

    
169
enum CodecID av_guess_image2_codec(const char *filename){
170
    return av_str2id(img_tags, filename);
171
}
172

    
173
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
        return AVERROR(ENOMEM);
184
    }
185

    
186
    av_strlcpy(s->path, s1->filename, sizeof(s->path));
187
    s->img_number = 0;
188
    s->img_count = 0;
189

    
190
    /* find format */
191
    if (s1->iformat->flags & AVFMT_NOFILE)
192
        s->is_pipe = 0;
193
    else{
194
        s->is_pipe = 1;
195
        st->need_parsing = AVSTREAM_PARSE_FULL;
196
    }
197

    
198
    if (!ap->time_base.num) {
199
        av_set_pts_info(st, 60, 1, 25);
200
    } else {
201
        av_set_pts_info(st, 60, ap->time_base.num, ap->time_base.den);
202
    }
203

    
204
    if(ap->width && ap->height){
205
        st->codec->width = ap->width;
206
        st->codec->height= ap->height;
207
    }
208

    
209
    if (!s->is_pipe) {
210
        if (find_image_range(&first_index, &last_index, s->path) < 0)
211
            return AVERROR(EIO);
212
        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
        st->duration = last_index - first_index + 1;
218
    }
219

    
220
    if(ap->video_codec_id){
221
        st->codec->codec_type = CODEC_TYPE_VIDEO;
222
        st->codec->codec_id = ap->video_codec_id;
223
    }else if(ap->audio_codec_id){
224
        st->codec->codec_type = CODEC_TYPE_AUDIO;
225
        st->codec->codec_id = ap->audio_codec_id;
226
    }else{
227
        st->codec->codec_type = CODEC_TYPE_VIDEO;
228
        st->codec->codec_id = av_str2id(img_tags, s->path);
229
    }
230
    if(st->codec->codec_type == CODEC_TYPE_VIDEO && ap->pix_fmt != PIX_FMT_NONE)
231
        st->codec->pix_fmt = ap->pix_fmt;
232

    
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
    int i;
241
    int size[3]={0}, ret[3]={0};
242
    ByteIOContext f1[3], *f[3]= {&f1[0], &f1[1], &f1[2]};
243
    AVCodecContext *codec= s1->streams[0]->codec;
244

    
245
    if (!s->is_pipe) {
246
        /* loop over input */
247
        if (s1->loop_input && s->img_number > s->img_last) {
248
            s->img_number = s->img_first;
249
        }
250
        if (av_get_frame_filename(filename, sizeof(filename),
251
                                  s->path, s->img_number)<0 && s->img_number > 1)
252
            return AVERROR(EIO);
253
        for(i=0; i<3; i++){
254
            if (url_fopen(f[i], filename, URL_RDONLY) < 0)
255
                return AVERROR(EIO);
256
            size[i]= url_fsize(f[i]);
257

    
258
            if(codec->codec_id != CODEC_ID_RAWVIDEO)
259
                break;
260
            filename[ strlen(filename) - 1 ]= 'U' + i;
261
        }
262

    
263
        if(codec->codec_id == CODEC_ID_RAWVIDEO && !codec->width)
264
            infer_size(&codec->width, &codec->height, size[0]);
265
    } else {
266
        f[0] = &s1->pb;
267
        if (url_feof(f[0]))
268
            return AVERROR(EIO);
269
        size[0]= 4096;
270
    }
271

    
272
    av_new_packet(pkt, size[0] + size[1] + size[2]);
273
    pkt->stream_index = 0;
274
    pkt->flags |= PKT_FLAG_KEY;
275

    
276
    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
    }
286

    
287
    if (ret[0] <= 0 || ret[1]<0 || ret[2]<0) {
288
        av_free_packet(pkt);
289
        return AVERROR(EIO); /* signal EOF */
290
    } 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
#ifdef CONFIG_MUXERS
303
/******************************************************/
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
    av_strlcpy(img->path, s->filename, sizeof(img->path));
312

    
313
    /* find format */
314
    if (s->oformat->flags & AVFMT_NOFILE)
315
        img->is_pipe = 0;
316
    else
317
        img->is_pipe = 1;
318

    
319
    return 0;
320
}
321

    
322
static int img_write_packet(AVFormatContext *s, AVPacket *pkt)
323
{
324
    VideoData *img = s->priv_data;
325
    ByteIOContext pb1[3], *pb[3]= {&pb1[0], &pb1[1], &pb1[2]};
326
    char filename[1024];
327
    AVCodecContext *codec= s->streams[ pkt->stream_index ]->codec;
328
    int i;
329

    
330
    if (!img->is_pipe) {
331
        if (av_get_frame_filename(filename, sizeof(filename),
332
                                  img->path, img->img_number) < 0 && img->img_number>1)
333
            return AVERROR(EIO);
334
        for(i=0; i<3; i++){
335
            if (url_fopen(pb[i], filename, URL_WRONLY) < 0)
336
                return AVERROR(EIO);
337

    
338
            if(codec->codec_id != CODEC_ID_RAWVIDEO)
339
                break;
340
            filename[ strlen(filename) - 1 ]= 'U' + i;
341
        }
342
    } else {
343
        pb[0] = &s->pb;
344
    }
345

    
346
    if(codec->codec_id == CODEC_ID_RAWVIDEO){
347
        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
        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
    if (!img->is_pipe) {
360
        url_fclose(pb[0]);
361
    }
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
#endif /* CONFIG_MUXERS */
373

    
374
/* input */
375
#ifdef CONFIG_IMAGE2_DEMUXER
376
AVInputFormat image2_demuxer = {
377
    "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
    AVFMT_NOFILE,
387
};
388
#endif
389
#ifdef CONFIG_IMAGE2PIPE_DEMUXER
390
AVInputFormat image2pipe_demuxer = {
391
    "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
#endif
401

    
402
/* output */
403
#ifdef CONFIG_IMAGE2_MUXER
404
AVOutputFormat image2_muxer = {
405
    "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
    AVFMT_NOFILE,
416
};
417
#endif
418
#ifdef CONFIG_IMAGE2PIPE_MUXER
419
AVOutputFormat image2pipe_muxer = {
420
    "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
#endif