Mercurial > libavcodec.hg
annotate mjpeg.c @ 229:f418b5c5ff67 libavcodec
PATCH by Rik Snel <rsnel@cube.dyndns.org>
this patch enhances the jpeg header writer. It can be asked to omit
quantisation and huffman tables and it can write different horizontal and
vertical sampling factors. (the last thing is useless for libavcodec
itself (because libavcodec only handles YUV420P at ecoder level), but the
values are initialized so that operation of libavcodec is not impaired)
author | arpi_esp |
---|---|
date | Sat, 09 Feb 2002 01:23:41 +0000 |
parents | 5784987c3940 |
children | 5fc0c3af3fe4 |
rev | line source |
---|---|
0 | 1 /* |
23 | 2 * MJPEG encoder and decoder |
3 * Copyright (c) 2000, 2001 Gerard Lantau. | |
0 | 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 */ | |
76 | 19 //#define DEBUG |
0 | 20 #include "avcodec.h" |
21 #include "dsputil.h" | |
22 #include "mpegvideo.h" | |
23 | |
24 typedef struct MJpegContext { | |
25 UINT8 huff_size_dc_luminance[12]; | |
26 UINT16 huff_code_dc_luminance[12]; | |
27 UINT8 huff_size_dc_chrominance[12]; | |
28 UINT16 huff_code_dc_chrominance[12]; | |
29 | |
30 UINT8 huff_size_ac_luminance[256]; | |
31 UINT16 huff_code_ac_luminance[256]; | |
32 UINT8 huff_size_ac_chrominance[256]; | |
33 UINT16 huff_code_ac_chrominance[256]; | |
34 } MJpegContext; | |
35 | |
36 #define SOF0 0xc0 | |
37 #define SOI 0xd8 | |
38 #define EOI 0xd9 | |
39 #define DQT 0xdb | |
40 #define DHT 0xc4 | |
41 #define SOS 0xda | |
42 | |
43 #if 0 | |
44 /* These are the sample quantization tables given in JPEG spec section K.1. | |
45 * The spec says that the values given produce "good" quality, and | |
46 * when divided by 2, "very good" quality. | |
47 */ | |
48 static const unsigned char std_luminance_quant_tbl[64] = { | |
49 16, 11, 10, 16, 24, 40, 51, 61, | |
50 12, 12, 14, 19, 26, 58, 60, 55, | |
51 14, 13, 16, 24, 40, 57, 69, 56, | |
52 14, 17, 22, 29, 51, 87, 80, 62, | |
53 18, 22, 37, 56, 68, 109, 103, 77, | |
54 24, 35, 55, 64, 81, 104, 113, 92, | |
55 49, 64, 78, 87, 103, 121, 120, 101, | |
56 72, 92, 95, 98, 112, 100, 103, 99 | |
57 }; | |
58 static const unsigned char std_chrominance_quant_tbl[64] = { | |
59 17, 18, 24, 47, 99, 99, 99, 99, | |
60 18, 21, 26, 66, 99, 99, 99, 99, | |
61 24, 26, 56, 99, 99, 99, 99, 99, | |
62 47, 66, 99, 99, 99, 99, 99, 99, | |
63 99, 99, 99, 99, 99, 99, 99, 99, | |
64 99, 99, 99, 99, 99, 99, 99, 99, | |
65 99, 99, 99, 99, 99, 99, 99, 99, | |
66 99, 99, 99, 99, 99, 99, 99, 99 | |
67 }; | |
68 #endif | |
69 | |
70 /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ | |
71 /* IMPORTANT: these are only valid for 8-bit data precision! */ | |
72 static const UINT8 bits_dc_luminance[17] = | |
73 { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; | |
74 static const UINT8 val_dc_luminance[] = | |
75 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; | |
76 | |
77 static const UINT8 bits_dc_chrominance[17] = | |
78 { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; | |
79 static const UINT8 val_dc_chrominance[] = | |
80 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; | |
81 | |
82 static const UINT8 bits_ac_luminance[17] = | |
83 { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; | |
84 static const UINT8 val_ac_luminance[] = | |
85 { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, | |
86 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, | |
87 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, | |
88 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, | |
89 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, | |
90 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, | |
91 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, | |
92 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, | |
93 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, | |
94 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, | |
95 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, | |
96 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, | |
97 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, | |
98 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, | |
99 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, | |
100 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, | |
101 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, | |
102 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, | |
103 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, | |
104 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, | |
105 0xf9, 0xfa | |
106 }; | |
107 | |
108 static const UINT8 bits_ac_chrominance[17] = | |
109 { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; | |
110 | |
111 static const UINT8 val_ac_chrominance[] = | |
112 { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, | |
113 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, | |
114 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, | |
115 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, | |
116 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, | |
117 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, | |
118 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, | |
119 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, | |
120 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, | |
121 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, | |
122 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, | |
123 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, | |
124 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, | |
125 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, | |
126 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, | |
127 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, | |
128 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, | |
129 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, | |
130 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, | |
131 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, | |
132 0xf9, 0xfa | |
133 }; | |
134 | |
135 | |
136 /* isn't this function nicer than the one in the libjpeg ? */ | |
137 static void build_huffman_codes(UINT8 *huff_size, UINT16 *huff_code, | |
138 const UINT8 *bits_table, const UINT8 *val_table) | |
139 { | |
140 int i, j, k,nb, code, sym; | |
141 | |
142 code = 0; | |
143 k = 0; | |
144 for(i=1;i<=16;i++) { | |
145 nb = bits_table[i]; | |
146 for(j=0;j<nb;j++) { | |
147 sym = val_table[k++]; | |
148 huff_size[sym] = i; | |
149 huff_code[sym] = code; | |
150 code++; | |
151 } | |
152 code <<= 1; | |
153 } | |
154 } | |
155 | |
156 int mjpeg_init(MpegEncContext *s) | |
157 { | |
158 MJpegContext *m; | |
159 | |
160 m = malloc(sizeof(MJpegContext)); | |
161 if (!m) | |
162 return -1; | |
163 | |
164 /* build all the huffman tables */ | |
165 build_huffman_codes(m->huff_size_dc_luminance, | |
166 m->huff_code_dc_luminance, | |
167 bits_dc_luminance, | |
168 val_dc_luminance); | |
169 build_huffman_codes(m->huff_size_dc_chrominance, | |
170 m->huff_code_dc_chrominance, | |
171 bits_dc_chrominance, | |
172 val_dc_chrominance); | |
173 build_huffman_codes(m->huff_size_ac_luminance, | |
174 m->huff_code_ac_luminance, | |
175 bits_ac_luminance, | |
176 val_ac_luminance); | |
177 build_huffman_codes(m->huff_size_ac_chrominance, | |
178 m->huff_code_ac_chrominance, | |
179 bits_ac_chrominance, | |
180 val_ac_chrominance); | |
181 | |
182 s->mjpeg_ctx = m; | |
183 return 0; | |
184 } | |
185 | |
186 void mjpeg_close(MpegEncContext *s) | |
187 { | |
188 free(s->mjpeg_ctx); | |
189 } | |
190 | |
191 static inline void put_marker(PutBitContext *p, int code) | |
192 { | |
193 put_bits(p, 8, 0xff); | |
194 put_bits(p, 8, code); | |
195 } | |
196 | |
197 /* table_class: 0 = DC coef, 1 = AC coefs */ | |
198 static int put_huffman_table(MpegEncContext *s, int table_class, int table_id, | |
199 const UINT8 *bits_table, const UINT8 *value_table) | |
200 { | |
201 PutBitContext *p = &s->pb; | |
202 int n, i; | |
203 | |
204 put_bits(p, 4, table_class); | |
205 put_bits(p, 4, table_id); | |
206 | |
207 n = 0; | |
208 for(i=1;i<=16;i++) { | |
209 n += bits_table[i]; | |
210 put_bits(p, 8, bits_table[i]); | |
211 } | |
212 | |
213 for(i=0;i<n;i++) | |
214 put_bits(p, 8, value_table[i]); | |
215 | |
216 return n + 17; | |
217 } | |
218 | |
219 static void jpeg_table_header(MpegEncContext *s) | |
220 { | |
221 PutBitContext *p = &s->pb; | |
37 | 222 int i, j, size; |
0 | 223 UINT8 *ptr; |
224 | |
225 /* quant matrixes */ | |
226 put_marker(p, DQT); | |
227 put_bits(p, 16, 2 + 1 * (1 + 64)); | |
228 put_bits(p, 4, 0); /* 8 bit precision */ | |
229 put_bits(p, 4, 0); /* table 0 */ | |
230 for(i=0;i<64;i++) { | |
37 | 231 j = zigzag_direct[i]; |
232 put_bits(p, 8, s->intra_matrix[j]); | |
0 | 233 } |
234 #if 0 | |
235 put_bits(p, 4, 0); /* 8 bit precision */ | |
236 put_bits(p, 4, 1); /* table 1 */ | |
237 for(i=0;i<64;i++) { | |
37 | 238 j = zigzag_direct[i]; |
239 put_bits(p, 8, s->chroma_intra_matrix[j]); | |
0 | 240 } |
241 #endif | |
242 | |
243 /* huffman table */ | |
244 put_marker(p, DHT); | |
245 flush_put_bits(p); | |
246 ptr = p->buf_ptr; | |
247 put_bits(p, 16, 0); /* patched later */ | |
248 size = 2; | |
249 size += put_huffman_table(s, 0, 0, bits_dc_luminance, val_dc_luminance); | |
250 size += put_huffman_table(s, 0, 1, bits_dc_chrominance, val_dc_chrominance); | |
251 | |
252 size += put_huffman_table(s, 1, 0, bits_ac_luminance, val_ac_luminance); | |
253 size += put_huffman_table(s, 1, 1, bits_ac_chrominance, val_ac_chrominance); | |
254 ptr[0] = size >> 8; | |
255 ptr[1] = size; | |
256 } | |
257 | |
258 void mjpeg_picture_header(MpegEncContext *s) | |
259 { | |
260 put_marker(&s->pb, SOI); | |
261 | |
229 | 262 if (s->mjpeg_write_tables) jpeg_table_header(s); |
0 | 263 |
264 put_marker(&s->pb, SOF0); | |
265 | |
266 put_bits(&s->pb, 16, 17); | |
267 put_bits(&s->pb, 8, 8); /* 8 bits/component */ | |
268 put_bits(&s->pb, 16, s->height); | |
269 put_bits(&s->pb, 16, s->width); | |
270 put_bits(&s->pb, 8, 3); /* 3 components */ | |
271 | |
272 /* Y component */ | |
273 put_bits(&s->pb, 8, 1); /* component number */ | |
229 | 274 put_bits(&s->pb, 4, s->mjpeg_hsample[0]); /* H factor */ |
275 put_bits(&s->pb, 4, s->mjpeg_vsample[0]); /* V factor */ | |
0 | 276 put_bits(&s->pb, 8, 0); /* select matrix */ |
277 | |
278 /* Cb component */ | |
279 put_bits(&s->pb, 8, 2); /* component number */ | |
229 | 280 put_bits(&s->pb, 4, s->mjpeg_hsample[1]); /* H factor */ |
281 put_bits(&s->pb, 4, s->mjpeg_vsample[1]); /* V factor */ | |
0 | 282 put_bits(&s->pb, 8, 0); /* select matrix */ |
283 | |
284 /* Cr component */ | |
285 put_bits(&s->pb, 8, 3); /* component number */ | |
229 | 286 put_bits(&s->pb, 4, s->mjpeg_hsample[2]); /* H factor */ |
287 put_bits(&s->pb, 4, s->mjpeg_vsample[2]); /* V factor */ | |
0 | 288 put_bits(&s->pb, 8, 0); /* select matrix */ |
289 | |
290 /* scan header */ | |
291 put_marker(&s->pb, SOS); | |
292 put_bits(&s->pb, 16, 12); /* length */ | |
293 put_bits(&s->pb, 8, 3); /* 3 components */ | |
294 | |
295 /* Y component */ | |
296 put_bits(&s->pb, 8, 1); /* index */ | |
297 put_bits(&s->pb, 4, 0); /* DC huffman table index */ | |
298 put_bits(&s->pb, 4, 0); /* AC huffman table index */ | |
299 | |
300 /* Cb component */ | |
301 put_bits(&s->pb, 8, 2); /* index */ | |
302 put_bits(&s->pb, 4, 1); /* DC huffman table index */ | |
303 put_bits(&s->pb, 4, 1); /* AC huffman table index */ | |
304 | |
305 /* Cr component */ | |
306 put_bits(&s->pb, 8, 3); /* index */ | |
307 put_bits(&s->pb, 4, 1); /* DC huffman table index */ | |
308 put_bits(&s->pb, 4, 1); /* AC huffman table index */ | |
309 | |
310 put_bits(&s->pb, 8, 0); /* Ss (not used) */ | |
311 put_bits(&s->pb, 8, 63); /* Se (not used) */ | |
312 put_bits(&s->pb, 8, 0); /* (not used) */ | |
313 } | |
314 | |
315 void mjpeg_picture_trailer(MpegEncContext *s) | |
316 { | |
317 jflush_put_bits(&s->pb); | |
318 put_marker(&s->pb, EOI); | |
319 } | |
320 | |
321 static inline void encode_dc(MpegEncContext *s, int val, | |
322 UINT8 *huff_size, UINT16 *huff_code) | |
323 { | |
324 int mant, nbits; | |
325 | |
326 if (val == 0) { | |
327 jput_bits(&s->pb, huff_size[0], huff_code[0]); | |
328 } else { | |
329 mant = val; | |
330 if (val < 0) { | |
331 val = -val; | |
332 mant--; | |
333 } | |
334 | |
335 /* compute the log (XXX: optimize) */ | |
336 nbits = 0; | |
337 while (val != 0) { | |
338 val = val >> 1; | |
339 nbits++; | |
340 } | |
341 | |
342 jput_bits(&s->pb, huff_size[nbits], huff_code[nbits]); | |
343 | |
344 jput_bits(&s->pb, nbits, mant & ((1 << nbits) - 1)); | |
345 } | |
346 } | |
347 | |
348 static void encode_block(MpegEncContext *s, DCTELEM *block, int n) | |
349 { | |
350 int mant, nbits, code, i, j; | |
351 int component, dc, run, last_index, val; | |
352 MJpegContext *m = s->mjpeg_ctx; | |
353 UINT8 *huff_size_ac; | |
354 UINT16 *huff_code_ac; | |
355 | |
356 /* DC coef */ | |
357 component = (n <= 3 ? 0 : n - 4 + 1); | |
358 dc = block[0]; /* overflow is impossible */ | |
359 val = dc - s->last_dc[component]; | |
360 if (n < 4) { | |
361 encode_dc(s, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance); | |
362 huff_size_ac = m->huff_size_ac_luminance; | |
363 huff_code_ac = m->huff_code_ac_luminance; | |
364 } else { | |
365 encode_dc(s, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance); | |
366 huff_size_ac = m->huff_size_ac_chrominance; | |
367 huff_code_ac = m->huff_code_ac_chrominance; | |
368 } | |
369 s->last_dc[component] = dc; | |
370 | |
371 /* AC coefs */ | |
372 | |
373 run = 0; | |
374 last_index = s->block_last_index[n]; | |
375 for(i=1;i<=last_index;i++) { | |
376 j = zigzag_direct[i]; | |
377 val = block[j]; | |
378 if (val == 0) { | |
379 run++; | |
380 } else { | |
381 while (run >= 16) { | |
382 jput_bits(&s->pb, huff_size_ac[0xf0], huff_code_ac[0xf0]); | |
383 run -= 16; | |
384 } | |
385 mant = val; | |
386 if (val < 0) { | |
387 val = -val; | |
388 mant--; | |
389 } | |
390 | |
391 /* compute the log (XXX: optimize) */ | |
392 nbits = 0; | |
393 while (val != 0) { | |
394 val = val >> 1; | |
395 nbits++; | |
396 } | |
397 code = (run << 4) | nbits; | |
398 | |
399 jput_bits(&s->pb, huff_size_ac[code], huff_code_ac[code]); | |
400 | |
401 jput_bits(&s->pb, nbits, mant & ((1 << nbits) - 1)); | |
402 run = 0; | |
403 } | |
404 } | |
405 | |
406 /* output EOB only if not already 64 values */ | |
407 if (last_index < 63 || run != 0) | |
408 jput_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]); | |
409 } | |
410 | |
411 void mjpeg_encode_mb(MpegEncContext *s, | |
412 DCTELEM block[6][64]) | |
413 { | |
414 int i; | |
415 for(i=0;i<6;i++) { | |
416 encode_block(s, block[i], i); | |
417 } | |
418 } | |
23 | 419 |
420 /******************************************/ | |
421 /* decoding */ | |
422 | |
423 /* compressed picture size */ | |
424 #define PICTURE_BUFFER_SIZE 100000 | |
425 | |
426 #define MAX_COMPONENTS 4 | |
427 | |
428 typedef struct MJpegDecodeContext { | |
429 GetBitContext gb; | |
430 UINT32 header_state; | |
431 int start_code; /* current start code */ | |
432 UINT8 *buf_ptr; | |
433 int buffer_size; | |
434 int mpeg_enc_ctx_allocated; /* true if decoding context allocated */ | |
435 INT16 quant_matrixes[4][64]; | |
436 VLC vlcs[2][4]; | |
53 | 437 |
438 int org_width, org_height; /* size given at codec init */ | |
439 int first_picture; /* true if decoding first picture */ | |
440 int interlaced; /* true if interlaced */ | |
441 int bottom_field; /* true if bottom field */ | |
442 | |
23 | 443 int width, height; |
26 | 444 int nb_components; |
445 int component_id[MAX_COMPONENTS]; | |
23 | 446 int h_count[MAX_COMPONENTS]; /* horizontal and vertical count for each component */ |
447 int v_count[MAX_COMPONENTS]; | |
448 int h_max, v_max; /* maximum h and v counts */ | |
449 int quant_index[4]; /* quant table index for each component */ | |
450 int last_dc[MAX_COMPONENTS]; /* last DEQUANTIZED dc (XXX: am I right to do that ?) */ | |
451 UINT8 *current_picture[MAX_COMPONENTS]; /* picture structure */ | |
452 int linesize[MAX_COMPONENTS]; | |
453 DCTELEM block[64] __align8; | |
454 UINT8 buffer[PICTURE_BUFFER_SIZE]; | |
455 } MJpegDecodeContext; | |
456 | |
29 | 457 static void build_vlc(VLC *vlc, const UINT8 *bits_table, const UINT8 *val_table, |
458 int nb_codes) | |
459 { | |
460 UINT8 huff_size[256]; | |
461 UINT16 huff_code[256]; | |
462 | |
463 memset(huff_size, 0, sizeof(huff_size)); | |
464 build_huffman_codes(huff_size, huff_code, bits_table, val_table); | |
465 | |
466 init_vlc(vlc, 9, nb_codes, huff_size, 1, 1, huff_code, 2, 2); | |
467 } | |
468 | |
23 | 469 static int mjpeg_decode_init(AVCodecContext *avctx) |
470 { | |
471 MJpegDecodeContext *s = avctx->priv_data; | |
472 | |
473 s->header_state = 0; | |
474 s->mpeg_enc_ctx_allocated = 0; | |
475 s->buffer_size = PICTURE_BUFFER_SIZE - 1; /* minus 1 to take into | |
476 account FF 00 case */ | |
477 s->start_code = -1; | |
478 s->buf_ptr = s->buffer; | |
53 | 479 s->first_picture = 1; |
480 s->org_width = avctx->width; | |
481 s->org_height = avctx->height; | |
29 | 482 |
483 build_vlc(&s->vlcs[0][0], bits_dc_luminance, val_dc_luminance, 12); | |
484 build_vlc(&s->vlcs[0][1], bits_dc_chrominance, val_dc_chrominance, 12); | |
485 build_vlc(&s->vlcs[1][0], bits_ac_luminance, val_ac_luminance, 251); | |
486 build_vlc(&s->vlcs[1][1], bits_ac_chrominance, val_ac_chrominance, 251); | |
23 | 487 return 0; |
488 } | |
489 | |
490 /* quantize tables */ | |
491 static int mjpeg_decode_dqt(MJpegDecodeContext *s, | |
492 UINT8 *buf, int buf_size) | |
493 { | |
37 | 494 int len, index, i, j; |
23 | 495 init_get_bits(&s->gb, buf, buf_size); |
496 | |
497 len = get_bits(&s->gb, 16); | |
498 len -= 2; | |
499 | |
500 while (len >= 65) { | |
501 /* only 8 bit precision handled */ | |
502 if (get_bits(&s->gb, 4) != 0) | |
503 return -1; | |
504 index = get_bits(&s->gb, 4); | |
505 if (index >= 4) | |
506 return -1; | |
507 dprintf("index=%d\n", index); | |
508 /* read quant table */ | |
37 | 509 for(i=0;i<64;i++) { |
510 j = zigzag_direct[i]; | |
511 s->quant_matrixes[index][j] = get_bits(&s->gb, 8); | |
512 } | |
23 | 513 len -= 65; |
514 } | |
515 return 0; | |
516 } | |
517 | |
518 /* decode huffman tables and build VLC decoders */ | |
519 static int mjpeg_decode_dht(MJpegDecodeContext *s, | |
520 UINT8 *buf, int buf_size) | |
521 { | |
522 int len, index, i, class, n, v, code_max; | |
523 UINT8 bits_table[17]; | |
524 UINT8 val_table[256]; | |
525 | |
526 init_get_bits(&s->gb, buf, buf_size); | |
527 | |
528 len = get_bits(&s->gb, 16); | |
529 len -= 2; | |
530 | |
531 while (len > 0) { | |
532 if (len < 17) | |
533 return -1; | |
534 class = get_bits(&s->gb, 4); | |
535 if (class >= 2) | |
536 return -1; | |
537 index = get_bits(&s->gb, 4); | |
538 if (index >= 4) | |
539 return -1; | |
540 n = 0; | |
541 for(i=1;i<=16;i++) { | |
542 bits_table[i] = get_bits(&s->gb, 8); | |
543 n += bits_table[i]; | |
544 } | |
545 len -= 17; | |
546 if (len < n || n > 256) | |
547 return -1; | |
548 | |
549 code_max = 0; | |
550 for(i=0;i<n;i++) { | |
551 v = get_bits(&s->gb, 8); | |
552 if (v > code_max) | |
553 code_max = v; | |
554 val_table[i] = v; | |
555 } | |
556 len -= n; | |
557 | |
558 /* build VLC and flush previous vlc if present */ | |
559 free_vlc(&s->vlcs[class][index]); | |
560 dprintf("class=%d index=%d nb_codes=%d\n", | |
561 class, index, code_max + 1); | |
29 | 562 build_vlc(&s->vlcs[class][index], bits_table, val_table, code_max + 1); |
23 | 563 } |
564 return 0; | |
565 } | |
566 | |
567 static int mjpeg_decode_sof0(MJpegDecodeContext *s, | |
568 UINT8 *buf, int buf_size) | |
569 { | |
26 | 570 int len, nb_components, i, width, height; |
23 | 571 |
572 init_get_bits(&s->gb, buf, buf_size); | |
573 | |
574 /* XXX: verify len field validity */ | |
575 len = get_bits(&s->gb, 16); | |
576 /* only 8 bits/component accepted */ | |
577 if (get_bits(&s->gb, 8) != 8) | |
578 return -1; | |
579 height = get_bits(&s->gb, 16); | |
580 width = get_bits(&s->gb, 16); | |
581 | |
582 nb_components = get_bits(&s->gb, 8); | |
583 if (nb_components <= 0 || | |
584 nb_components > MAX_COMPONENTS) | |
585 return -1; | |
26 | 586 s->nb_components = nb_components; |
23 | 587 s->h_max = 1; |
588 s->v_max = 1; | |
589 for(i=0;i<nb_components;i++) { | |
590 /* component id */ | |
26 | 591 s->component_id[i] = get_bits(&s->gb, 8) - 1; |
23 | 592 s->h_count[i] = get_bits(&s->gb, 4); |
593 s->v_count[i] = get_bits(&s->gb, 4); | |
594 /* compute hmax and vmax (only used in interleaved case) */ | |
595 if (s->h_count[i] > s->h_max) | |
596 s->h_max = s->h_count[i]; | |
597 if (s->v_count[i] > s->v_max) | |
598 s->v_max = s->v_count[i]; | |
599 s->quant_index[i] = get_bits(&s->gb, 8); | |
600 if (s->quant_index[i] >= 4) | |
601 return -1; | |
602 dprintf("component %d %d:%d\n", i, s->h_count[i], s->v_count[i]); | |
603 } | |
604 | |
605 /* if different size, realloc/alloc picture */ | |
606 /* XXX: also check h_count and v_count */ | |
607 if (width != s->width || height != s->height) { | |
608 for(i=0;i<MAX_COMPONENTS;i++) { | |
609 free(s->current_picture[i]); | |
610 s->current_picture[i] = NULL; | |
611 } | |
612 s->width = width; | |
613 s->height = height; | |
53 | 614 /* test interlaced mode */ |
615 if (s->first_picture && | |
616 s->org_height != 0 && | |
617 s->height < ((s->org_height * 3) / 4)) { | |
618 s->interlaced = 1; | |
619 s->bottom_field = 0; | |
620 } | |
621 | |
23 | 622 for(i=0;i<nb_components;i++) { |
226 | 623 int w, h; |
624 w = (s->width + 8 * s->h_max - 1) / (8 * s->h_max); | |
625 h = (s->height + 8 * s->v_max - 1) / (8 * s->v_max); | |
626 w = w * 8 * s->h_count[i]; | |
627 h = h * 8 * s->v_count[i]; | |
53 | 628 if (s->interlaced) |
629 w *= 2; | |
23 | 630 s->linesize[i] = w; |
631 /* memory test is done in mjpeg_decode_sos() */ | |
632 s->current_picture[i] = av_mallocz(w * h); | |
633 } | |
53 | 634 s->first_picture = 0; |
23 | 635 } |
53 | 636 |
23 | 637 return 0; |
638 } | |
639 | |
640 static inline int decode_dc(MJpegDecodeContext *s, int dc_index) | |
641 { | |
642 VLC *dc_vlc; | |
643 int code, diff; | |
644 | |
645 dc_vlc = &s->vlcs[0][dc_index]; | |
646 code = get_vlc(&s->gb, dc_vlc); | |
647 if (code < 0) | |
648 return 0xffff; | |
649 if (code == 0) { | |
650 diff = 0; | |
651 } else { | |
652 diff = get_bits(&s->gb, code); | |
653 if ((diff & (1 << (code - 1))) == 0) | |
654 diff = (-1 << code) | (diff + 1); | |
655 } | |
656 return diff; | |
657 } | |
658 | |
659 /* decode block and dequantize */ | |
660 static int decode_block(MJpegDecodeContext *s, DCTELEM *block, | |
661 int component, int dc_index, int ac_index, int quant_index) | |
662 { | |
663 int nbits, code, i, j, level; | |
664 int run, val; | |
665 VLC *ac_vlc; | |
666 INT16 *quant_matrix; | |
667 | |
668 quant_matrix = s->quant_matrixes[quant_index]; | |
669 /* DC coef */ | |
670 val = decode_dc(s, dc_index); | |
671 if (val == 0xffff) { | |
672 dprintf("error dc\n"); | |
673 return -1; | |
674 } | |
675 val = val * quant_matrix[0] + s->last_dc[component]; | |
676 s->last_dc[component] = val; | |
677 block[0] = val; | |
678 /* AC coefs */ | |
679 ac_vlc = &s->vlcs[1][ac_index]; | |
680 i = 1; | |
681 for(;;) { | |
682 code = get_vlc(&s->gb, ac_vlc); | |
683 if (code < 0) { | |
684 dprintf("error ac\n"); | |
685 return -1; | |
686 } | |
687 /* EOB */ | |
688 if (code == 0) | |
689 break; | |
690 if (code == 0xf0) { | |
691 i += 16; | |
692 } else { | |
693 run = code >> 4; | |
694 nbits = code & 0xf; | |
695 level = get_bits(&s->gb, nbits); | |
696 if ((level & (1 << (nbits - 1))) == 0) | |
697 level = (-1 << nbits) | (level + 1); | |
698 i += run; | |
699 if (i >= 64) { | |
700 dprintf("error count: %d\n", i); | |
701 return -1; | |
702 } | |
703 j = zigzag_direct[i]; | |
704 block[j] = level * quant_matrix[j]; | |
705 i++; | |
28
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
706 if (i >= 64) |
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
707 break; |
23 | 708 } |
709 } | |
710 return 0; | |
711 } | |
712 | |
713 static int mjpeg_decode_sos(MJpegDecodeContext *s, | |
714 UINT8 *buf, int buf_size) | |
715 { | |
47
bd0dd8d0b759
return dummy quality to avoid bug in -sameq case - forgot emms in error case
glantau
parents:
44
diff
changeset
|
716 int len, nb_components, i, j, n, h, v, ret; |
26 | 717 int mb_width, mb_height, mb_x, mb_y, vmax, hmax, index, id; |
23 | 718 int comp_index[4]; |
719 int dc_index[4]; | |
720 int ac_index[4]; | |
721 int nb_blocks[4]; | |
722 int h_count[4]; | |
723 int v_count[4]; | |
724 | |
725 init_get_bits(&s->gb, buf, buf_size); | |
726 /* XXX: verify len field validity */ | |
727 len = get_bits(&s->gb, 16); | |
728 nb_components = get_bits(&s->gb, 8); | |
729 /* XXX: only interleaved scan accepted */ | |
730 if (nb_components != 3) | |
731 return -1; | |
732 vmax = 0; | |
733 hmax = 0; | |
734 for(i=0;i<nb_components;i++) { | |
26 | 735 id = get_bits(&s->gb, 8) - 1; |
736 /* find component index */ | |
737 for(index=0;index<s->nb_components;index++) | |
738 if (id == s->component_id[index]) | |
739 break; | |
740 if (index == s->nb_components) | |
23 | 741 return -1; |
26 | 742 |
23 | 743 comp_index[i] = index; |
744 nb_blocks[i] = s->h_count[index] * s->v_count[index]; | |
745 h_count[i] = s->h_count[index]; | |
746 v_count[i] = s->v_count[index]; | |
28
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
747 |
23 | 748 dc_index[i] = get_bits(&s->gb, 4); |
749 if (dc_index[i] >= 4) | |
750 return -1; | |
751 ac_index[i] = get_bits(&s->gb, 4); | |
752 if (ac_index[i] >= 4) | |
753 return -1; | |
754 } | |
755 get_bits(&s->gb, 8); /* Ss */ | |
756 get_bits(&s->gb, 8); /* Se */ | |
757 get_bits(&s->gb, 8); /* not used */ | |
758 | |
759 for(i=0;i<nb_components;i++) | |
760 s->last_dc[i] = 1024; | |
761 | |
762 if (nb_components > 1) { | |
763 /* interleaved stream */ | |
764 mb_width = (s->width + s->h_max * 8 - 1) / (s->h_max * 8); | |
765 mb_height = (s->height + s->v_max * 8 - 1) / (s->v_max * 8); | |
766 } else { | |
767 h = s->h_max / s->h_count[comp_index[0]]; | |
768 v = s->v_max / s->v_count[comp_index[0]]; | |
769 mb_width = (s->width + h * 8 - 1) / (h * 8); | |
770 mb_height = (s->height + v * 8 - 1) / (v * 8); | |
771 nb_blocks[0] = 1; | |
772 h_count[0] = 1; | |
773 v_count[0] = 1; | |
774 } | |
775 | |
776 for(mb_y = 0; mb_y < mb_height; mb_y++) { | |
777 for(mb_x = 0; mb_x < mb_width; mb_x++) { | |
778 for(i=0;i<nb_components;i++) { | |
779 UINT8 *ptr; | |
780 int x, y, c; | |
781 n = nb_blocks[i]; | |
782 c = comp_index[i]; | |
783 h = h_count[i]; | |
784 v = v_count[i]; | |
785 x = 0; | |
786 y = 0; | |
787 for(j=0;j<n;j++) { | |
788 memset(s->block, 0, sizeof(s->block)); | |
789 if (decode_block(s, s->block, i, | |
790 dc_index[i], ac_index[i], | |
791 s->quant_index[c]) < 0) { | |
792 dprintf("error %d %d\n", mb_y, mb_x); | |
47
bd0dd8d0b759
return dummy quality to avoid bug in -sameq case - forgot emms in error case
glantau
parents:
44
diff
changeset
|
793 ret = -1; |
bd0dd8d0b759
return dummy quality to avoid bug in -sameq case - forgot emms in error case
glantau
parents:
44
diff
changeset
|
794 goto the_end; |
23 | 795 } |
796 ff_idct (s->block); | |
797 ptr = s->current_picture[c] + | |
798 (s->linesize[c] * (v * mb_y + y) * 8) + | |
799 (h * mb_x + x) * 8; | |
53 | 800 if (s->interlaced && s->bottom_field) |
801 ptr += s->linesize[c] >> 1; | |
23 | 802 put_pixels_clamped(s->block, ptr, s->linesize[c]); |
803 if (++x == h) { | |
804 x = 0; | |
805 y++; | |
806 } | |
807 } | |
808 } | |
809 } | |
810 } | |
47
bd0dd8d0b759
return dummy quality to avoid bug in -sameq case - forgot emms in error case
glantau
parents:
44
diff
changeset
|
811 ret = 0; |
bd0dd8d0b759
return dummy quality to avoid bug in -sameq case - forgot emms in error case
glantau
parents:
44
diff
changeset
|
812 the_end: |
44
92d51f683931
added forgotten emms() - fix various segmentation faults when using mjpeg
glantau
parents:
37
diff
changeset
|
813 emms_c(); |
47
bd0dd8d0b759
return dummy quality to avoid bug in -sameq case - forgot emms in error case
glantau
parents:
44
diff
changeset
|
814 return ret; |
23 | 815 } |
816 | |
817 /* return the 8 bit start code value and update the search | |
818 state. Return -1 if no start code found */ | |
819 static int find_marker(UINT8 **pbuf_ptr, UINT8 *buf_end, | |
820 UINT32 *header_state) | |
821 { | |
822 UINT8 *buf_ptr; | |
823 unsigned int state, v; | |
824 int val; | |
825 | |
826 state = *header_state; | |
827 buf_ptr = *pbuf_ptr; | |
828 if (state) { | |
829 /* get marker */ | |
830 found: | |
831 if (buf_ptr < buf_end) { | |
832 val = *buf_ptr++; | |
833 state = 0; | |
834 } else { | |
835 val = -1; | |
836 } | |
837 } else { | |
838 while (buf_ptr < buf_end) { | |
839 v = *buf_ptr++; | |
840 if (v == 0xff) { | |
841 state = 1; | |
842 goto found; | |
843 } | |
844 } | |
845 val = -1; | |
846 } | |
847 *pbuf_ptr = buf_ptr; | |
848 *header_state = state; | |
849 return val; | |
850 } | |
851 | |
852 static int mjpeg_decode_frame(AVCodecContext *avctx, | |
853 void *data, int *data_size, | |
854 UINT8 *buf, int buf_size) | |
855 { | |
856 MJpegDecodeContext *s = avctx->priv_data; | |
857 UINT8 *buf_end, *buf_ptr, *buf_start; | |
858 int len, code, start_code, input_size, i; | |
859 AVPicture *picture = data; | |
860 | |
68 | 861 *data_size = 0; |
862 | |
23 | 863 /* no supplementary picture */ |
68 | 864 if (buf_size == 0) |
23 | 865 return 0; |
866 | |
867 buf_ptr = buf; | |
868 buf_end = buf + buf_size; | |
869 while (buf_ptr < buf_end) { | |
870 buf_start = buf_ptr; | |
871 /* find start next marker */ | |
872 code = find_marker(&buf_ptr, buf_end, &s->header_state); | |
873 /* copy to buffer */ | |
874 len = buf_ptr - buf_start; | |
875 if (len + (s->buf_ptr - s->buffer) > s->buffer_size) { | |
876 /* data too big : flush */ | |
877 s->buf_ptr = s->buffer; | |
878 if (code > 0) | |
879 s->start_code = code; | |
880 } else { | |
881 memcpy(s->buf_ptr, buf_start, len); | |
882 s->buf_ptr += len; | |
883 /* if we got FF 00, we copy FF to the stream to unescape FF 00 */ | |
884 if (code == 0) { | |
885 s->buf_ptr--; | |
886 } else if (code > 0) { | |
887 /* prepare data for next start code */ | |
888 input_size = s->buf_ptr - s->buffer; | |
889 start_code = s->start_code; | |
890 s->buf_ptr = s->buffer; | |
891 s->start_code = code; | |
44
92d51f683931
added forgotten emms() - fix various segmentation faults when using mjpeg
glantau
parents:
37
diff
changeset
|
892 dprintf("marker=%x\n", start_code); |
23 | 893 switch(start_code) { |
894 case SOI: | |
895 /* nothing to do on SOI */ | |
896 break; | |
897 case DQT: | |
898 mjpeg_decode_dqt(s, s->buffer, input_size); | |
899 break; | |
900 case DHT: | |
901 mjpeg_decode_dht(s, s->buffer, input_size); | |
902 break; | |
903 case SOF0: | |
904 mjpeg_decode_sof0(s, s->buffer, input_size); | |
905 break; | |
906 case SOS: | |
907 mjpeg_decode_sos(s, s->buffer, input_size); | |
908 if (s->start_code == EOI) { | |
53 | 909 int l; |
910 if (s->interlaced) { | |
911 s->bottom_field ^= 1; | |
912 /* if not bottom field, do not output image yet */ | |
913 if (s->bottom_field) | |
914 goto the_end; | |
915 } | |
23 | 916 for(i=0;i<3;i++) { |
917 picture->data[i] = s->current_picture[i]; | |
53 | 918 l = s->linesize[i]; |
919 if (s->interlaced) | |
920 l >>= 1; | |
921 picture->linesize[i] = l; | |
23 | 922 } |
923 *data_size = sizeof(AVPicture); | |
924 avctx->height = s->height; | |
53 | 925 if (s->interlaced) |
926 avctx->height *= 2; | |
23 | 927 avctx->width = s->width; |
28
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
928 /* XXX: not complete test ! */ |
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
929 switch((s->h_count[0] << 4) | s->v_count[0]) { |
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
930 case 0x11: |
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
931 avctx->pix_fmt = PIX_FMT_YUV444P; |
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
932 break; |
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
933 case 0x21: |
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
934 avctx->pix_fmt = PIX_FMT_YUV422P; |
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
935 break; |
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
936 default: |
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
937 case 0x22: |
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
938 avctx->pix_fmt = PIX_FMT_YUV420P; |
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
939 break; |
b611fafddf9e
added 422P and 444P support - fixed block parsing error
glantau
parents:
26
diff
changeset
|
940 } |
47
bd0dd8d0b759
return dummy quality to avoid bug in -sameq case - forgot emms in error case
glantau
parents:
44
diff
changeset
|
941 /* dummy quality */ |
bd0dd8d0b759
return dummy quality to avoid bug in -sameq case - forgot emms in error case
glantau
parents:
44
diff
changeset
|
942 /* XXX: infer it with matrix */ |
bd0dd8d0b759
return dummy quality to avoid bug in -sameq case - forgot emms in error case
glantau
parents:
44
diff
changeset
|
943 avctx->quality = 3; |
23 | 944 goto the_end; |
945 } | |
946 break; | |
947 } | |
948 } | |
949 } | |
950 } | |
951 the_end: | |
952 return buf_ptr - buf; | |
953 } | |
954 | |
955 static int mjpeg_decode_end(AVCodecContext *avctx) | |
956 { | |
957 MJpegDecodeContext *s = avctx->priv_data; | |
958 int i, j; | |
959 | |
960 for(i=0;i<MAX_COMPONENTS;i++) | |
961 free(s->current_picture[i]); | |
962 for(i=0;i<2;i++) { | |
963 for(j=0;j<4;j++) | |
964 free_vlc(&s->vlcs[i][j]); | |
965 } | |
966 return 0; | |
967 } | |
968 | |
969 AVCodec mjpeg_decoder = { | |
970 "mjpeg", | |
971 CODEC_TYPE_VIDEO, | |
972 CODEC_ID_MJPEG, | |
973 sizeof(MJpegDecodeContext), | |
974 mjpeg_decode_init, | |
975 NULL, | |
976 mjpeg_decode_end, | |
977 mjpeg_decode_frame, | |
978 }; |