Statistics
| Branch: | Revision:

ffmpeg / libav / jpeg.c @ 9150f42e

History | View | Annotate | Download (5.67 KB)

1
/*
2
 * JPEG based formats
3
 * Copyright (c) 2000, 2001 Gerard Lantau.
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program 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
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
 */
19
#include "avformat.h"
20

    
21
/* Multipart JPEG */
22

    
23
#define BOUNDARY_TAG "ffserver"
24

    
25
static int mpjpeg_write_header(AVFormatContext *s)
26
{
27
    UINT8 buf1[256];
28

    
29
    snprintf(buf1, sizeof(buf1), "--%s\n", BOUNDARY_TAG);
30
    put_buffer(&s->pb, buf1, strlen(buf1));
31
    put_flush_packet(&s->pb);
32
    return 0;
33
}
34

    
35
static int mpjpeg_write_packet(AVFormatContext *s, 
36
                               int stream_index, UINT8 *buf, int size)
37
{
38
    UINT8 buf1[256];
39

    
40
    snprintf(buf1, sizeof(buf1), "Content-type: image/jpeg\n\n");
41
    put_buffer(&s->pb, buf1, strlen(buf1));
42
    put_buffer(&s->pb, buf, size);
43

    
44
    snprintf(buf1, sizeof(buf1), "\n--%s\n", BOUNDARY_TAG);
45
    put_buffer(&s->pb, buf1, strlen(buf1));
46
    put_flush_packet(&s->pb);
47
    return 0;
48
}
49

    
50
static int mpjpeg_write_trailer(AVFormatContext *s)
51
{
52
    return 0;
53
}
54

    
55
AVFormat mpjpeg_format = {
56
    "mpjpeg",
57
    "Mime multipart JPEG format",
58
    "multipart/x-mixed-replace;boundary=" BOUNDARY_TAG,
59
    "mjpg",
60
    CODEC_ID_NONE,
61
    CODEC_ID_MJPEG,
62
    mpjpeg_write_header,
63
    mpjpeg_write_packet,
64
    mpjpeg_write_trailer,
65
};
66

    
67

    
68
/*************************************/
69
/* single frame JPEG */
70

    
71
static int single_jpeg_write_header(AVFormatContext *s)
72
{
73
    return 0;
74
}
75

    
76
static int single_jpeg_write_packet(AVFormatContext *s, int stream_index,
77
                            UINT8 *buf, int size)
78
{
79
    put_buffer(&s->pb, buf, size);
80
    put_flush_packet(&s->pb);
81
    return 1; /* no more data can be sent */
82
}
83

    
84
static int single_jpeg_write_trailer(AVFormatContext *s)
85
{
86
    return 0;
87
}
88

    
89
AVFormat single_jpeg_format = {
90
    "singlejpeg",
91
    "single JPEG image",
92
    "image/jpeg",
93
    "jpg,jpeg",
94
    CODEC_ID_NONE,
95
    CODEC_ID_MJPEG,
96
    single_jpeg_write_header,
97
    single_jpeg_write_packet,
98
    single_jpeg_write_trailer,
99
};
100

    
101
/*************************************/
102
/* multiple jpeg images */
103

    
104
typedef struct JpegContext {
105
    char path[1024];
106
    int img_number;
107
} JpegContext;
108

    
109
static int jpeg_write_header(AVFormatContext *s1)
110
{
111
    JpegContext *s;
112

    
113
    s = av_mallocz(sizeof(JpegContext));
114
    if (!s)
115
        return -1;
116
    s1->priv_data = s;
117
    nstrcpy(s->path, sizeof(s->path), s1->filename);
118
    s->img_number = 1;
119
    return 0;
120
}
121

    
122
static int jpeg_write_packet(AVFormatContext *s1, int stream_index,
123
                            UINT8 *buf, int size)
124
{
125
    JpegContext *s = s1->priv_data;
126
    char filename[1024];
127
    ByteIOContext f1, *pb = &f1;
128

    
129
    if (get_frame_filename(filename, sizeof(filename), 
130
                           s->path, s->img_number) < 0)
131
        return -EIO;
132
    if (url_fopen(pb, filename, URL_WRONLY) < 0)
133
        return -EIO;
134

    
135
    put_buffer(pb, buf, size);
136
    put_flush_packet(pb);
137

    
138
    url_fclose(pb);
139
    s->img_number++;
140

    
141
    return 0;
142
}
143

    
144
static int jpeg_write_trailer(AVFormatContext *s1)
145
{
146
    JpegContext *s = s1->priv_data;
147
    free(s);
148
    return 0;
149
}
150

    
151
/***/
152

    
153
static int jpeg_read_header(AVFormatContext *s1, AVFormatParameters *ap)
154
{
155
    JpegContext *s;
156
    int i;
157
    char buf[1024];
158
    ByteIOContext pb1, *f = &pb1;
159
    AVStream *st;
160

    
161
    s = av_mallocz(sizeof(JpegContext));
162
    if (!s)
163
        return -1;
164
    s1->priv_data = s;
165
    nstrcpy(s->path, sizeof(s->path), s1->filename);
166

    
167
    s1->nb_streams = 1;
168
    st = av_mallocz(sizeof(AVStream));
169
    if (!st) {
170
        free(s);
171
        return -ENOMEM;
172
    }
173
    s1->streams[0] = st;
174
    s->img_number = 0;
175

    
176
    /* try to find the first image */
177
    for(i=0;i<5;i++) {
178
        if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0)
179
            goto fail;
180
        if (url_fopen(f, buf, URL_RDONLY) >= 0)
181
            break;
182
        s->img_number++;
183
    }
184
    if (i == 5)
185
        goto fail;
186
    url_fclose(f);
187
    st->codec.codec_type = CODEC_TYPE_VIDEO;
188
    st->codec.codec_id = CODEC_ID_MJPEG;
189
    
190
    if (!ap || !ap->frame_rate)
191
        st->codec.frame_rate = 25 * FRAME_RATE_BASE;
192
    else
193
        st->codec.frame_rate = ap->frame_rate;
194
    return 0;
195
 fail:
196
    free(s);
197
    return -EIO;
198
}
199

    
200
static int jpeg_read_packet(AVFormatContext *s1, AVPacket *pkt)
201
{
202
    JpegContext *s = s1->priv_data;
203
    char filename[1024];
204
    int size;
205
    ByteIOContext f1, *f = &f1;
206

    
207
    if (get_frame_filename(filename, sizeof(filename), 
208
                           s->path, s->img_number) < 0)
209
        return -EIO;
210
    
211
    f = &f1;
212
    if (url_fopen(f, filename, URL_RDONLY) < 0)
213
        return -EIO;
214
    
215
    size = url_seek(url_fileno(f), 0, SEEK_END);
216
    url_seek(url_fileno(f), 0, SEEK_SET);
217

    
218
    av_new_packet(pkt, size);
219
    pkt->stream_index = 0;
220
    get_buffer(f, pkt->data, size);
221

    
222
    url_fclose(f);
223
    s->img_number++;
224
    return 0;
225
}
226

    
227
static int jpeg_read_close(AVFormatContext *s1)
228
{
229
    JpegContext *s = s1->priv_data;
230
    free(s);
231
    return 0;
232
}
233

    
234
AVFormat jpeg_format = {
235
    "jpeg",
236
    "JPEG image",
237
    "image/jpeg",
238
    "jpg,jpeg",
239
    CODEC_ID_NONE,
240
    CODEC_ID_MJPEG,
241
    jpeg_write_header,
242
    jpeg_write_packet,
243
    jpeg_write_trailer,
244

    
245
    jpeg_read_header,
246
    jpeg_read_packet,
247
    jpeg_read_close,
248
    NULL,
249
    AVFMT_NOFILE | AVFMT_NEEDNUMBER,
250
};