Statistics
| Branch: | Revision:

ffmpeg / libavformat / img.c @ d4ad24c1

History | View | Annotate | Download (8.05 KB)

1
/*
2
 * Image format
3
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
19
#include <unistd.h>
20
#include "avformat.h"
21
#include "../os_support.h"
22

    
23
typedef struct {
24
    int width;
25
    int height;
26
    int img_number;
27
    int img_size;
28
    AVImageFormat *img_fmt;
29
    int pix_fmt;
30
    int is_pipe;
31
    char path[1024];
32
    /* temporary usage */
33
    void *ptr;
34
} VideoData;
35

    
36
static int image_probe(AVProbeData *p)
37
{
38
    if (filename_number_test(p->filename) >= 0 && guess_image_format(p->filename))
39
        return AVPROBE_SCORE_MAX;
40
    else
41
        return 0;
42
}
43

    
44
static int read_header_alloc_cb(void *opaque, AVImageInfo *info)
45
{
46
    VideoData *s = opaque;
47

    
48
    s->width = info->width;
49
    s->height = info->height;
50
    s->pix_fmt = info->pix_fmt;
51
    /* stop image reading but no error */
52
    return 1;
53
}
54

    
55
static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap)
56
{
57
    VideoData *s = s1->priv_data;
58
    int i, ret;
59
    char buf[1024];
60
    ByteIOContext pb1, *f = &pb1;
61
    AVStream *st;
62

    
63
    st = av_new_stream(s1, 0);
64
    if (!st) {
65
        av_free(s);
66
        return -ENOMEM;
67
    }
68

    
69
    if (ap && ap->image_format)
70
        s->img_fmt = ap->image_format;
71

    
72
    strcpy(s->path, s1->filename);
73
    s->img_number = 0;
74

    
75
    /* find format */
76
    if (s1->iformat->flags & AVFMT_NOFILE)
77
        s->is_pipe = 0;
78
    else
79
        s->is_pipe = 1;
80
        
81
    if (!s->is_pipe) {
82
        /* try to find the first image */
83
        for(i=0;i<5;i++) {
84
            if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0)
85
                goto fail;
86
            if (url_fopen(f, buf, URL_RDONLY) >= 0)
87
                break;
88
            s->img_number++;
89
        }
90
        if (i == 5)
91
            goto fail;
92
    } else {
93
        f = &s1->pb;
94
    }
95
    
96
    ret = av_read_image(f, s1->filename, s->img_fmt, read_header_alloc_cb, s);
97
    if (ret < 0)
98
        goto fail1;
99

    
100
    if (!s->is_pipe) {
101
        url_fclose(f);
102
    } else {
103
        url_fseek(f, 0, SEEK_SET);
104
    }
105
    
106
    st->codec.codec_type = CODEC_TYPE_VIDEO;
107
    st->codec.codec_id = CODEC_ID_RAWVIDEO;
108
    st->codec.width = s->width;
109
    st->codec.height = s->height;
110
    st->codec.pix_fmt = s->pix_fmt;
111
    s->img_size = avpicture_get_size(s->pix_fmt, s->width, s->height);
112

    
113
    if (!ap || !ap->frame_rate){
114
        st->codec.frame_rate      = 25;
115
        st->codec.frame_rate_base = 1;
116
    }else{
117
        st->codec.frame_rate      = ap->frame_rate;
118
        st->codec.frame_rate_base = ap->frame_rate_base;
119
    }
120
    
121
    return 0;
122
 fail1:
123
    if (!s->is_pipe)
124
        url_fclose(f);
125
 fail:
126
    av_free(s);
127
    return -EIO;
128
}
129

    
130
static int read_packet_alloc_cb(void *opaque, AVImageInfo *info)
131
{
132
    VideoData *s = opaque;
133

    
134
    if (info->width != s->width ||
135
        info->height != s->height)
136
        return -1;
137
    avpicture_fill(&info->pict, s->ptr, info->pix_fmt, info->width, info->height);
138
    return 0;
139
}
140

    
141
static int img_read_packet(AVFormatContext *s1, AVPacket *pkt)
142
{
143
    VideoData *s = s1->priv_data;
144
    char filename[1024];
145
    int ret;
146
    ByteIOContext f1, *f;
147

    
148
    if (!s->is_pipe) {
149
        if (get_frame_filename(filename, sizeof(filename),
150
                               s->path, s->img_number) < 0)
151
            return -EIO;
152
        f = &f1;
153
        if (url_fopen(f, filename, URL_RDONLY) < 0)
154
            return -EIO;
155
    } else {
156
        f = &s1->pb;
157
        if (url_feof(f))
158
            return -EIO;
159
    }
160

    
161
    av_new_packet(pkt, s->img_size);
162
    pkt->stream_index = 0;
163

    
164
    s->ptr = pkt->data;
165
    ret = av_read_image(f, filename, s->img_fmt, read_packet_alloc_cb, s);
166
    if (!s->is_pipe) {
167
        url_fclose(f);
168
    }
169

    
170
    if (ret < 0) {
171
        av_free_packet(pkt);
172
        return -EIO; /* signal EOF */
173
    } else {
174
        pkt->pts = av_rescale((int64_t)s->img_number * s1->streams[0]->codec.frame_rate_base, s1->pts_den, s1->streams[0]->codec.frame_rate) / s1->pts_num;
175
        s->img_number++;
176
        return 0;
177
    }
178
}
179

    
180
static int img_read_close(AVFormatContext *s1)
181
{
182
    return 0;
183
}
184

    
185
/******************************************************/
186
/* image output */
187

    
188
static int img_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
189
{
190
    VideoData *img = s->priv_data;
191
    AVStream *st;
192
    AVImageFormat *img_fmt;
193
    int i;
194

    
195
    /* find output image format */
196
    if (ap && ap->image_format) {
197
        img_fmt = ap->image_format;
198
    } else {
199
        img_fmt = guess_image_format(s->filename);
200
    }
201
    if (!img_fmt)
202
        return -1;
203

    
204
    if (s->nb_streams != 1)
205
        return -1;
206
    
207
    st = s->streams[0];
208
    /* we select the first matching format */
209
    for(i=0;i<PIX_FMT_NB;i++) {
210
        if (img_fmt->supported_pixel_formats & (1 << i))
211
            break;
212
    }
213
    if (i >= PIX_FMT_NB)
214
        return -1;
215
    img->img_fmt = img_fmt;
216
    img->pix_fmt = i;
217
    st->codec.pix_fmt = img->pix_fmt;
218
    return 0;
219
}
220

    
221
static int img_write_header(AVFormatContext *s)
222
{
223
    VideoData *img = s->priv_data;
224

    
225
    img->img_number = 1;
226
    strcpy(img->path, s->filename);
227

    
228
    /* find format */
229
    if (s->oformat->flags & AVFMT_NOFILE)
230
        img->is_pipe = 0;
231
    else
232
        img->is_pipe = 1;
233
        
234
    return 0;
235
}
236

    
237
static int img_write_packet(AVFormatContext *s, int stream_index,
238
                            uint8_t *buf, int size, int force_pts)
239
{
240
    VideoData *img = s->priv_data;
241
    AVStream *st = s->streams[stream_index];
242
    ByteIOContext pb1, *pb;
243
    AVPicture *picture;
244
    int width, height, ret;
245
    char filename[1024];
246
    AVImageInfo info;
247

    
248
    width = st->codec.width;
249
    height = st->codec.height;
250
    
251
    picture = (AVPicture *)buf;
252

    
253
    if (!img->is_pipe) {
254
        if (get_frame_filename(filename, sizeof(filename), 
255
                               img->path, img->img_number) < 0)
256
            return -EIO;
257
        pb = &pb1;
258
        if (url_fopen(pb, filename, URL_WRONLY) < 0)
259
            return -EIO;
260
    } else {
261
        pb = &s->pb;
262
    }
263
    info.width = width;
264
    info.height = height;
265
    info.pix_fmt = st->codec.pix_fmt;
266
    info.pict = *picture;
267
    ret = av_write_image(pb, img->img_fmt, &info);
268
    if (!img->is_pipe) {
269
        url_fclose(pb);
270
    }
271

    
272
    img->img_number++;
273
    return 0;
274
}
275

    
276
static int img_write_trailer(AVFormatContext *s)
277
{
278
    return 0;
279
}
280

    
281
/* input */
282

    
283
static AVInputFormat image_iformat = {
284
    "image",
285
    "image sequence",
286
    sizeof(VideoData),
287
    image_probe,
288
    img_read_header,
289
    img_read_packet,
290
    img_read_close,
291
    NULL,
292
    AVFMT_NOFILE | AVFMT_NEEDNUMBER,
293
};
294

    
295
static AVInputFormat imagepipe_iformat = {
296
    "imagepipe",
297
    "piped image sequence",
298
    sizeof(VideoData),
299
    NULL, /* no probe */
300
    img_read_header,
301
    img_read_packet,
302
    img_read_close,
303
    NULL,
304
};
305

    
306

    
307
/* output */
308

    
309
static AVOutputFormat image_oformat = {
310
    "image",
311
    "image sequence",
312
    "",
313
    "",
314
    sizeof(VideoData),
315
    CODEC_ID_NONE,
316
    CODEC_ID_RAWVIDEO,
317
    img_write_header,
318
    img_write_packet,
319
    img_write_trailer,
320
    AVFMT_NOFILE | AVFMT_NEEDNUMBER | AVFMT_RAWPICTURE,
321
    img_set_parameters,
322
};
323

    
324
static AVOutputFormat imagepipe_oformat = {
325
    "imagepipe",
326
    "piped image sequence",
327
    "",
328
    "",
329
    sizeof(VideoData),
330
    CODEC_ID_NONE,
331
    CODEC_ID_RAWVIDEO,
332
    img_write_header,
333
    img_write_packet,
334
    img_write_trailer,
335
    AVFMT_RAWPICTURE,
336
    img_set_parameters,
337
};
338

    
339
int img_init(void)
340
{
341
    av_register_input_format(&image_iformat);
342
    av_register_output_format(&image_oformat);
343

    
344
    av_register_input_format(&imagepipe_iformat);
345
    av_register_output_format(&imagepipe_oformat);
346
    
347
    return 0;
348
}