Mercurial > libavformat.hg
comparison jpeg.c @ 0:05318cf2e886 libavformat
renamed libav to libavformat
author | bellard |
---|---|
date | Mon, 25 Nov 2002 19:07:40 +0000 |
parents | |
children | 39c4c4336486 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:05318cf2e886 |
---|---|
1 /* | |
2 * JPEG based formats | |
3 * Copyright (c) 2000, 2001 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 "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, int stream_index, | |
36 UINT8 *buf, int size, int force_pts) | |
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 static AVOutputFormat mpjpeg_format = { | |
56 "mpjpeg", | |
57 "Mime multipart JPEG format", | |
58 "multipart/x-mixed-replace;boundary=" BOUNDARY_TAG, | |
59 "mjpg", | |
60 0, | |
61 CODEC_ID_NONE, | |
62 CODEC_ID_MJPEG, | |
63 mpjpeg_write_header, | |
64 mpjpeg_write_packet, | |
65 mpjpeg_write_trailer, | |
66 }; | |
67 | |
68 | |
69 /*************************************/ | |
70 /* single frame JPEG */ | |
71 | |
72 static int single_jpeg_write_header(AVFormatContext *s) | |
73 { | |
74 return 0; | |
75 } | |
76 | |
77 static int single_jpeg_write_packet(AVFormatContext *s, int stream_index, | |
78 UINT8 *buf, int size, int force_pts) | |
79 { | |
80 put_buffer(&s->pb, buf, size); | |
81 put_flush_packet(&s->pb); | |
82 return 1; /* no more data can be sent */ | |
83 } | |
84 | |
85 static int single_jpeg_write_trailer(AVFormatContext *s) | |
86 { | |
87 return 0; | |
88 } | |
89 | |
90 static AVOutputFormat single_jpeg_format = { | |
91 "singlejpeg", | |
92 "single JPEG image", | |
93 "image/jpeg", | |
94 NULL, /* note: no extension to favorize jpeg multiple images match */ | |
95 0, | |
96 CODEC_ID_NONE, | |
97 CODEC_ID_MJPEG, | |
98 single_jpeg_write_header, | |
99 single_jpeg_write_packet, | |
100 single_jpeg_write_trailer, | |
101 }; | |
102 | |
103 /*************************************/ | |
104 /* multiple jpeg images */ | |
105 | |
106 typedef struct JpegContext { | |
107 char path[1024]; | |
108 int img_number; | |
109 } JpegContext; | |
110 | |
111 static int jpeg_write_header(AVFormatContext *s1) | |
112 { | |
113 JpegContext *s; | |
114 | |
115 s = av_mallocz(sizeof(JpegContext)); | |
116 if (!s) | |
117 return -1; | |
118 s1->priv_data = s; | |
119 pstrcpy(s->path, sizeof(s->path), s1->filename); | |
120 s->img_number = 1; | |
121 return 0; | |
122 } | |
123 | |
124 static int jpeg_write_packet(AVFormatContext *s1, int stream_index, | |
125 UINT8 *buf, int size, int force_pts) | |
126 { | |
127 JpegContext *s = s1->priv_data; | |
128 char filename[1024]; | |
129 ByteIOContext f1, *pb = &f1; | |
130 | |
131 if (get_frame_filename(filename, sizeof(filename), | |
132 s->path, s->img_number) < 0) | |
133 return -EIO; | |
134 if (url_fopen(pb, filename, URL_WRONLY) < 0) | |
135 return -EIO; | |
136 | |
137 put_buffer(pb, buf, size); | |
138 put_flush_packet(pb); | |
139 | |
140 url_fclose(pb); | |
141 s->img_number++; | |
142 | |
143 return 0; | |
144 } | |
145 | |
146 static int jpeg_write_trailer(AVFormatContext *s1) | |
147 { | |
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 pstrcpy(s->path, sizeof(s->path), s1->filename); | |
166 | |
167 s1->nb_streams = 1; | |
168 st = av_mallocz(sizeof(AVStream)); | |
169 if (!st) { | |
170 av_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 av_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 return 0; | |
230 } | |
231 | |
232 static AVInputFormat jpeg_iformat = { | |
233 "jpeg", | |
234 "JPEG image", | |
235 sizeof(JpegContext), | |
236 NULL, | |
237 jpeg_read_header, | |
238 jpeg_read_packet, | |
239 jpeg_read_close, | |
240 NULL, | |
241 .flags = AVFMT_NOFILE | AVFMT_NEEDNUMBER, | |
242 .extensions = "jpg,jpeg", | |
243 }; | |
244 | |
245 static AVOutputFormat jpeg_oformat = { | |
246 "jpeg", | |
247 "JPEG image", | |
248 "image/jpeg", | |
249 "jpg,jpeg", | |
250 sizeof(JpegContext), | |
251 CODEC_ID_NONE, | |
252 CODEC_ID_MJPEG, | |
253 jpeg_write_header, | |
254 jpeg_write_packet, | |
255 jpeg_write_trailer, | |
256 .flags = AVFMT_NOFILE | AVFMT_NEEDNUMBER, | |
257 }; | |
258 | |
259 int jpeg_init(void) | |
260 { | |
261 av_register_output_format(&mpjpeg_format); | |
262 av_register_output_format(&single_jpeg_format); | |
263 av_register_input_format(&jpeg_iformat); | |
264 av_register_output_format(&jpeg_oformat); | |
265 return 0; | |
266 } |