Commit | Line | Data |
---|---|---|
11f18faf MN |
1 | /* |
2 | * huffyuv codec for libavcodec | |
3 | * | |
aaa1e4cd | 4 | * Copyright (c) 2002-2003 Michael Niedermayer <michaelni@gmx.at> |
11f18faf | 5 | * |
7b94177e DB |
6 | * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of |
7 | * the algorithm used | |
8 | * | |
b78e7197 DB |
9 | * This file is part of FFmpeg. |
10 | * | |
11 | * FFmpeg is free software; you can redistribute it and/or | |
11f18faf MN |
12 | * modify it under the terms of the GNU Lesser General Public |
13 | * License as published by the Free Software Foundation; either | |
b78e7197 | 14 | * version 2.1 of the License, or (at your option) any later version. |
11f18faf | 15 | * |
b78e7197 | 16 | * FFmpeg is distributed in the hope that it will be useful, |
11f18faf MN |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
19 | * Lesser General Public License for more details. | |
20 | * | |
21 | * You should have received a copy of the GNU Lesser General Public | |
b78e7197 | 22 | * License along with FFmpeg; if not, write to the Free Software |
5509bffa | 23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
11f18faf | 24 | */ |
115329f1 | 25 | |
983e3246 | 26 | /** |
bad5537e | 27 | * @file libavcodec/huffyuv.c |
983e3246 MN |
28 | * huffyuv codec for libavcodec. |
29 | */ | |
11f18faf | 30 | |
11f18faf | 31 | #include "avcodec.h" |
9106a698 | 32 | #include "get_bits.h" |
b2755007 | 33 | #include "put_bits.h" |
11f18faf MN |
34 | #include "dsputil.h" |
35 | ||
11f18faf | 36 | #define VLC_BITS 11 |
1e491e29 | 37 | |
63613fe6 | 38 | #if HAVE_BIGENDIAN |
3ad7dd8c MN |
39 | #define B 3 |
40 | #define G 2 | |
41 | #define R 1 | |
f267d3ac | 42 | #define A 0 |
3ad7dd8c MN |
43 | #else |
44 | #define B 0 | |
45 | #define G 1 | |
46 | #define R 2 | |
f267d3ac | 47 | #define A 3 |
3ad7dd8c MN |
48 | #endif |
49 | ||
11f18faf MN |
50 | typedef enum Predictor{ |
51 | LEFT= 0, | |
52 | PLANE, | |
53 | MEDIAN, | |
54 | } Predictor; | |
115329f1 | 55 | |
11f18faf MN |
56 | typedef struct HYuvContext{ |
57 | AVCodecContext *avctx; | |
58 | Predictor predictor; | |
59 | GetBitContext gb; | |
60 | PutBitContext pb; | |
61 | int interlaced; | |
62 | int decorrelate; | |
63 | int bitstream_bpp; | |
64 | int version; | |
65 | int yuy2; //use yuy2 instead of 422P | |
66 | int bgr32; //use bgr32 instead of bgr24 | |
67 | int width, height; | |
68 | int flags; | |
11087086 | 69 | int context; |
11f18faf | 70 | int picture_number; |
7c5ab7b8 | 71 | int last_slice_end; |
0ecca7a4 | 72 | uint8_t *temp[3]; |
11f18faf MN |
73 | uint64_t stats[3][256]; |
74 | uint8_t len[3][256]; | |
75 | uint32_t bits[3][256]; | |
8be6dac8 | 76 | uint32_t pix_bgr_map[1<<VLC_BITS]; |
19716d64 | 77 | VLC vlc[6]; //Y,U,V,YY,YU,YV |
492cd3a9 | 78 | AVFrame picture; |
0ecca7a4 | 79 | uint8_t *bitstream_buffer; |
f038fe8b | 80 | unsigned int bitstream_buffer_size; |
115329f1 | 81 | DSPContext dsp; |
11f18faf MN |
82 | }HYuvContext; |
83 | ||
24def10e | 84 | static const unsigned char classic_shift_luma[] = { |
676b385c MN |
85 | 34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8, |
86 | 16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70, | |
87 | 69,68, 0 | |
88 | }; | |
89 | ||
24def10e | 90 | static const unsigned char classic_shift_chroma[] = { |
676b385c MN |
91 | 66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183, |
92 | 56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119, | |
93 | 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0 | |
94 | }; | |
95 | ||
24def10e | 96 | static const unsigned char classic_add_luma[256] = { |
676b385c MN |
97 | 3, 9, 5, 12, 10, 35, 32, 29, 27, 50, 48, 45, 44, 41, 39, 37, |
98 | 73, 70, 68, 65, 64, 61, 58, 56, 53, 50, 49, 46, 44, 41, 38, 36, | |
99 | 68, 65, 63, 61, 58, 55, 53, 51, 48, 46, 45, 43, 41, 39, 38, 36, | |
100 | 35, 33, 32, 30, 29, 27, 26, 25, 48, 47, 46, 44, 43, 41, 40, 39, | |
101 | 37, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 22, 20, 19, 37, | |
102 | 35, 34, 33, 31, 30, 29, 27, 26, 24, 23, 21, 20, 18, 17, 15, 29, | |
103 | 27, 26, 24, 22, 21, 19, 17, 16, 14, 26, 25, 23, 21, 19, 18, 16, | |
104 | 15, 27, 25, 23, 21, 19, 17, 16, 14, 26, 25, 23, 21, 18, 17, 14, | |
105 | 12, 17, 19, 13, 4, 9, 2, 11, 1, 7, 8, 0, 16, 3, 14, 6, | |
106 | 12, 10, 5, 15, 18, 11, 10, 13, 15, 16, 19, 20, 22, 24, 27, 15, | |
107 | 18, 20, 22, 24, 26, 14, 17, 20, 22, 24, 27, 15, 18, 20, 23, 25, | |
108 | 28, 16, 19, 22, 25, 28, 32, 36, 21, 25, 29, 33, 38, 42, 45, 49, | |
109 | 28, 31, 34, 37, 40, 42, 44, 47, 49, 50, 52, 54, 56, 57, 59, 60, | |
110 | 62, 64, 66, 67, 69, 35, 37, 39, 40, 42, 43, 45, 47, 48, 51, 52, | |
111 | 54, 55, 57, 59, 60, 62, 63, 66, 67, 69, 71, 72, 38, 40, 42, 43, | |
112 | 46, 47, 49, 51, 26, 28, 30, 31, 33, 34, 18, 19, 11, 13, 7, 8, | |
113 | }; | |
114 | ||
24def10e | 115 | static const unsigned char classic_add_chroma[256] = { |
676b385c MN |
116 | 3, 1, 2, 2, 2, 2, 3, 3, 7, 5, 7, 5, 8, 6, 11, 9, |
117 | 7, 13, 11, 10, 9, 8, 7, 5, 9, 7, 6, 4, 7, 5, 8, 7, | |
118 | 11, 8, 13, 11, 19, 15, 22, 23, 20, 33, 32, 28, 27, 29, 51, 77, | |
119 | 43, 45, 76, 81, 46, 82, 75, 55, 56,144, 58, 80, 60, 74,147, 63, | |
120 | 143, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, | |
121 | 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 27, 30, 21, 22, | |
122 | 17, 14, 5, 6,100, 54, 47, 50, 51, 53,106,107,108,109,110,111, | |
123 | 112,113,114,115, 4,117,118, 92, 94,121,122, 3,124,103, 2, 1, | |
124 | 0,129,130,131,120,119,126,125,136,137,138,139,140,141,142,134, | |
125 | 135,132,133,104, 64,101, 62, 57,102, 95, 93, 59, 61, 28, 97, 96, | |
126 | 52, 49, 48, 29, 32, 25, 24, 46, 23, 98, 45, 44, 43, 20, 42, 41, | |
127 | 19, 18, 99, 40, 15, 39, 38, 16, 13, 12, 11, 37, 10, 9, 8, 36, | |
128 | 7,128,127,105,123,116, 35, 34, 33,145, 31, 79, 42,146, 78, 26, | |
129 | 83, 48, 49, 50, 44, 47, 26, 31, 30, 18, 17, 19, 21, 24, 25, 13, | |
130 | 14, 16, 17, 18, 20, 21, 12, 14, 15, 9, 10, 6, 9, 6, 5, 8, | |
131 | 6, 12, 8, 10, 7, 9, 6, 4, 6, 2, 2, 3, 3, 3, 3, 2, | |
132 | }; | |
133 | ||
7c5ab7b8 | 134 | static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int left){ |
11f18faf | 135 | int i; |
7c5ab7b8 MN |
136 | if(w<32){ |
137 | for(i=0; i<w; i++){ | |
138 | const int temp= src[i]; | |
139 | dst[i]= temp - left; | |
140 | left= temp; | |
141 | } | |
142 | return left; | |
143 | }else{ | |
144 | for(i=0; i<16; i++){ | |
145 | const int temp= src[i]; | |
146 | dst[i]= temp - left; | |
147 | left= temp; | |
148 | } | |
149 | s->dsp.diff_bytes(dst+16, src+16, src+15, w-16); | |
150 | return src[w-1]; | |
11f18faf | 151 | } |
11f18faf | 152 | } |
2a250222 | 153 | |
d2bfaf8a LM |
154 | static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){ |
155 | int i; | |
156 | int r,g,b; | |
157 | r= *red; | |
158 | g= *green; | |
159 | b= *blue; | |
160 | for(i=0; i<FFMIN(w,4); i++){ | |
161 | const int rt= src[i*4+R]; | |
162 | const int gt= src[i*4+G]; | |
163 | const int bt= src[i*4+B]; | |
164 | dst[i*4+R]= rt - r; | |
165 | dst[i*4+G]= gt - g; | |
166 | dst[i*4+B]= bt - b; | |
167 | r = rt; | |
168 | g = gt; | |
169 | b = bt; | |
170 | } | |
171 | s->dsp.diff_bytes(dst+16, src+16, src+12, w*4-16); | |
172 | *red= src[(w-1)*4+R]; | |
173 | *green= src[(w-1)*4+G]; | |
174 | *blue= src[(w-1)*4+B]; | |
175 | } | |
176 | ||
e30004fa | 177 | static int read_len_table(uint8_t *dst, GetBitContext *gb){ |
11f18faf | 178 | int i, val, repeat; |
115329f1 | 179 | |
11f18faf MN |
180 | for(i=0; i<256;){ |
181 | repeat= get_bits(gb, 3); | |
182 | val = get_bits(gb, 5); | |
183 | if(repeat==0) | |
184 | repeat= get_bits(gb, 8); | |
185 | //printf("%d %d\n", val, repeat); | |
e30004fa LM |
186 | if(i+repeat > 256) { |
187 | av_log(NULL, AV_LOG_ERROR, "Error reading huffman table\n"); | |
188 | return -1; | |
189 | } | |
11f18faf MN |
190 | while (repeat--) |
191 | dst[i++] = val; | |
192 | } | |
e30004fa | 193 | return 0; |
11f18faf MN |
194 | } |
195 | ||
196 | static int generate_bits_table(uint32_t *dst, uint8_t *len_table){ | |
197 | int len, index; | |
198 | uint32_t bits=0; | |
199 | ||
200 | for(len=32; len>0; len--){ | |
11f18faf | 201 | for(index=0; index<256; index++){ |
14b74d38 MN |
202 | if(len_table[index]==len) |
203 | dst[index]= bits++; | |
11f18faf | 204 | } |
14b74d38 | 205 | if(bits & 1){ |
9b879566 | 206 | av_log(NULL, AV_LOG_ERROR, "Error generating huffman table\n"); |
14b74d38 MN |
207 | return -1; |
208 | } | |
209 | bits >>= 1; | |
11f18faf MN |
210 | } |
211 | return 0; | |
212 | } | |
213 | ||
b250f9c6 | 214 | #if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER |
98ef8c32 LM |
215 | typedef struct { |
216 | uint64_t val; | |
217 | int name; | |
fe5c7e58 | 218 | } HeapElem; |
98ef8c32 | 219 | |
fe5c7e58 | 220 | static void heap_sift(HeapElem *h, int root, int size) |
98ef8c32 LM |
221 | { |
222 | while(root*2+1 < size) { | |
223 | int child = root*2+1; | |
224 | if(child < size-1 && h[child].val > h[child+1].val) | |
225 | child++; | |
226 | if(h[root].val > h[child].val) { | |
fe5c7e58 | 227 | FFSWAP(HeapElem, h[root], h[child]); |
98ef8c32 LM |
228 | root = child; |
229 | } else | |
230 | break; | |
231 | } | |
232 | } | |
233 | ||
11f18faf | 234 | static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){ |
fe5c7e58 | 235 | HeapElem h[size]; |
11f18faf | 236 | int up[2*size]; |
98ef8c32 | 237 | int len[2*size]; |
11f18faf | 238 | int offset, i, next; |
115329f1 | 239 | |
11f18faf MN |
240 | for(offset=1; ; offset<<=1){ |
241 | for(i=0; i<size; i++){ | |
98ef8c32 LM |
242 | h[i].name = i; |
243 | h[i].val = (stats[i] << 8) + offset; | |
11f18faf | 244 | } |
98ef8c32 LM |
245 | for(i=size/2-1; i>=0; i--) |
246 | heap_sift(h, i, size); | |
247 | ||
248 | for(next=size; next<size*2-1; next++){ | |
249 | // merge the two smallest entries, and put it back in the heap | |
250 | uint64_t min1v = h[0].val; | |
251 | up[h[0].name] = next; | |
252 | h[0].val = INT64_MAX; | |
253 | heap_sift(h, 0, size); | |
254 | up[h[0].name] = next; | |
255 | h[0].name = next; | |
256 | h[0].val += min1v; | |
257 | heap_sift(h, 0, size); | |
11f18faf | 258 | } |
115329f1 | 259 | |
98ef8c32 LM |
260 | len[2*size-2] = 0; |
261 | for(i=2*size-3; i>=size; i--) | |
262 | len[i] = len[up[i]] + 1; | |
263 | for(i=0; i<size; i++) { | |
264 | dst[i] = len[up[i]] + 1; | |
2bf4aa2e | 265 | if(dst[i] >= 32) break; |
11f18faf MN |
266 | } |
267 | if(i==size) break; | |
268 | } | |
269 | } | |
b250f9c6 | 270 | #endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */ |
11f18faf | 271 | |
19716d64 | 272 | static void generate_joint_tables(HYuvContext *s){ |
8be6dac8 LM |
273 | uint16_t symbols[1<<VLC_BITS]; |
274 | uint16_t bits[1<<VLC_BITS]; | |
275 | uint8_t len[1<<VLC_BITS]; | |
19716d64 | 276 | if(s->bitstream_bpp < 24){ |
19716d64 LM |
277 | int p, i, y, u; |
278 | for(p=0; p<3; p++){ | |
279 | for(i=y=0; y<256; y++){ | |
280 | int len0 = s->len[0][y]; | |
281 | int limit = VLC_BITS - len0; | |
f45fcba3 LM |
282 | if(limit <= 0) |
283 | continue; | |
284 | for(u=0; u<256; u++){ | |
285 | int len1 = s->len[p][u]; | |
286 | if(len1 > limit) | |
287 | continue; | |
288 | len[i] = len0 + len1; | |
289 | bits[i] = (s->bits[0][y] << len1) + s->bits[p][u]; | |
290 | symbols[i] = (y<<8) + u; | |
291 | if(symbols[i] != 0xffff) // reserved to mean "invalid" | |
292 | i++; | |
19716d64 LM |
293 | } |
294 | } | |
295 | free_vlc(&s->vlc[3+p]); | |
acc0e0c8 | 296 | init_vlc_sparse(&s->vlc[3+p], VLC_BITS, i, len, 1, 1, bits, 2, 2, symbols, 2, 2, 0); |
19716d64 | 297 | } |
8be6dac8 LM |
298 | }else{ |
299 | uint8_t (*map)[4] = (uint8_t(*)[4])s->pix_bgr_map; | |
300 | int i, b, g, r, code; | |
301 | int p0 = s->decorrelate; | |
302 | int p1 = !s->decorrelate; | |
303 | // restrict the range to +/-16 becaues that's pretty much guaranteed to | |
304 | // cover all the combinations that fit in 11 bits total, and it doesn't | |
305 | // matter if we miss a few rare codes. | |
306 | for(i=0, g=-16; g<16; g++){ | |
307 | int len0 = s->len[p0][g&255]; | |
308 | int limit0 = VLC_BITS - len0; | |
309 | if(limit0 < 2) | |
310 | continue; | |
311 | for(b=-16; b<16; b++){ | |
312 | int len1 = s->len[p1][b&255]; | |
313 | int limit1 = limit0 - len1; | |
314 | if(limit1 < 1) | |
315 | continue; | |
316 | code = (s->bits[p0][g&255] << len1) + s->bits[p1][b&255]; | |
317 | for(r=-16; r<16; r++){ | |
318 | int len2 = s->len[2][r&255]; | |
319 | if(len2 > limit1) | |
320 | continue; | |
321 | len[i] = len0 + len1 + len2; | |
322 | bits[i] = (code << len2) + s->bits[2][r&255]; | |
323 | if(s->decorrelate){ | |
324 | map[i][G] = g; | |
325 | map[i][B] = g+b; | |
326 | map[i][R] = g+r; | |
327 | }else{ | |
328 | map[i][B] = g; | |
329 | map[i][G] = b; | |
330 | map[i][R] = r; | |
331 | } | |
332 | i++; | |
333 | } | |
334 | } | |
335 | } | |
336 | free_vlc(&s->vlc[3]); | |
337 | init_vlc(&s->vlc[3], VLC_BITS, i, len, 1, 1, bits, 2, 2, 0); | |
19716d64 LM |
338 | } |
339 | } | |
340 | ||
11f18faf MN |
341 | static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){ |
342 | GetBitContext gb; | |
343 | int i; | |
115329f1 | 344 | |
68f593b4 | 345 | init_get_bits(&gb, src, length*8); |
115329f1 | 346 | |
11f18faf | 347 | for(i=0; i<3; i++){ |
e30004fa LM |
348 | if(read_len_table(s->len[i], &gb)<0) |
349 | return -1; | |
11f18faf MN |
350 | if(generate_bits_table(s->bits[i], s->len[i])<0){ |
351 | return -1; | |
352 | } | |
353 | #if 0 | |
354 | for(j=0; j<256; j++){ | |
355 | printf("%6X, %2d, %3d\n", s->bits[i][j], s->len[i][j], j); | |
356 | } | |
357 | #endif | |
11087086 | 358 | free_vlc(&s->vlc[i]); |
073c2593 | 359 | init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0); |
11f18faf | 360 | } |
115329f1 | 361 | |
19716d64 LM |
362 | generate_joint_tables(s); |
363 | ||
11087086 | 364 | return (get_bits_count(&gb)+7)/8; |
11f18faf MN |
365 | } |
366 | ||
367 | static int read_old_huffman_tables(HYuvContext *s){ | |
676b385c | 368 | #if 1 |
11f18faf MN |
369 | GetBitContext gb; |
370 | int i; | |
371 | ||
68f593b4 | 372 | init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8); |
e30004fa LM |
373 | if(read_len_table(s->len[0], &gb)<0) |
374 | return -1; | |
68f593b4 | 375 | init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8); |
e30004fa LM |
376 | if(read_len_table(s->len[1], &gb)<0) |
377 | return -1; | |
115329f1 | 378 | |
11f18faf MN |
379 | for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma [i]; |
380 | for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i]; | |
381 | ||
382 | if(s->bitstream_bpp >= 24){ | |
383 | memcpy(s->bits[1], s->bits[0], 256*sizeof(uint32_t)); | |
384 | memcpy(s->len[1] , s->len [0], 256*sizeof(uint8_t)); | |
385 | } | |
386 | memcpy(s->bits[2], s->bits[1], 256*sizeof(uint32_t)); | |
387 | memcpy(s->len[2] , s->len [1], 256*sizeof(uint8_t)); | |
115329f1 | 388 | |
11087086 LM |
389 | for(i=0; i<3; i++){ |
390 | free_vlc(&s->vlc[i]); | |
073c2593 | 391 | init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0); |
11087086 | 392 | } |
115329f1 | 393 | |
19716d64 LM |
394 | generate_joint_tables(s); |
395 | ||
11f18faf MN |
396 | return 0; |
397 | #else | |
267f7edc | 398 | av_log(s->avctx, AV_LOG_DEBUG, "v1 huffyuv is not supported \n"); |
11f18faf MN |
399 | return -1; |
400 | #endif | |
401 | } | |
402 | ||
5ef251e5 | 403 | static av_cold void alloc_temp(HYuvContext *s){ |
ae2f1d46 | 404 | int i; |
115329f1 | 405 | |
ae2f1d46 MN |
406 | if(s->bitstream_bpp<24){ |
407 | for(i=0; i<3; i++){ | |
408 | s->temp[i]= av_malloc(s->width + 16); | |
409 | } | |
410 | }else{ | |
f267d3ac | 411 | s->temp[0]= av_mallocz(4*s->width + 16); |
ae2f1d46 MN |
412 | } |
413 | } | |
414 | ||
5ef251e5 | 415 | static av_cold int common_init(AVCodecContext *avctx){ |
11f18faf | 416 | HYuvContext *s = avctx->priv_data; |
11f18faf MN |
417 | |
418 | s->avctx= avctx; | |
419 | s->flags= avctx->flags; | |
115329f1 | 420 | |
1d98dca3 | 421 | dsputil_init(&s->dsp, avctx); |
115329f1 | 422 | |
0ecca7a4 MN |
423 | s->width= avctx->width; |
424 | s->height= avctx->height; | |
425 | assert(s->width>0 && s->height>0); | |
115329f1 | 426 | |
0ecca7a4 MN |
427 | return 0; |
428 | } | |
429 | ||
b250f9c6 | 430 | #if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER |
98a6fff9 | 431 | static av_cold int decode_init(AVCodecContext *avctx) |
0ecca7a4 MN |
432 | { |
433 | HYuvContext *s = avctx->priv_data; | |
434 | ||
435 | common_init(avctx); | |
11087086 | 436 | memset(s->vlc, 0, 3*sizeof(VLC)); |
115329f1 | 437 | |
492cd3a9 | 438 | avctx->coded_frame= &s->picture; |
0ecca7a4 | 439 | s->interlaced= s->height > 288; |
1e491e29 | 440 | |
11f18faf | 441 | s->bgr32=1; |
11f18faf MN |
442 | //if(avctx->extradata) |
443 | // printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size); | |
444 | if(avctx->extradata_size){ | |
dd1c8f3e | 445 | if((avctx->bits_per_coded_sample&7) && avctx->bits_per_coded_sample != 12) |
11f18faf MN |
446 | s->version=1; // do such files exist at all? |
447 | else | |
448 | s->version=2; | |
449 | }else | |
450 | s->version=0; | |
115329f1 | 451 | |
11f18faf | 452 | if(s->version==2){ |
42dd22c4 | 453 | int method, interlace; |
11f18faf | 454 | |
2818bdf2 MK |
455 | if (avctx->extradata_size < 4) |
456 | return -1; | |
457 | ||
11f18faf MN |
458 | method= ((uint8_t*)avctx->extradata)[0]; |
459 | s->decorrelate= method&64 ? 1 : 0; | |
460 | s->predictor= method&63; | |
461 | s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1]; | |
115329f1 | 462 | if(s->bitstream_bpp==0) |
dd1c8f3e | 463 | s->bitstream_bpp= avctx->bits_per_coded_sample&~7; |
42dd22c4 LM |
464 | interlace= (((uint8_t*)avctx->extradata)[2] & 0x30) >> 4; |
465 | s->interlaced= (interlace==1) ? 1 : (interlace==2) ? 0 : s->interlaced; | |
11087086 | 466 | s->context= ((uint8_t*)avctx->extradata)[2] & 0x40 ? 1 : 0; |
115329f1 | 467 | |
2818bdf2 | 468 | if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size-4) < 0) |
11f18faf MN |
469 | return -1; |
470 | }else{ | |
dd1c8f3e | 471 | switch(avctx->bits_per_coded_sample&7){ |
11f18faf MN |
472 | case 1: |
473 | s->predictor= LEFT; | |
474 | s->decorrelate= 0; | |
475 | break; | |
476 | case 2: | |
477 | s->predictor= LEFT; | |
478 | s->decorrelate= 1; | |
479 | break; | |
480 | case 3: | |
481 | s->predictor= PLANE; | |
dd1c8f3e | 482 | s->decorrelate= avctx->bits_per_coded_sample >= 24; |
11f18faf MN |
483 | break; |
484 | case 4: | |
485 | s->predictor= MEDIAN; | |
486 | s->decorrelate= 0; | |
487 | break; | |
488 | default: | |
489 | s->predictor= LEFT; //OLD | |
490 | s->decorrelate= 0; | |
491 | break; | |
492 | } | |
dd1c8f3e | 493 | s->bitstream_bpp= avctx->bits_per_coded_sample & ~7; |
11087086 | 494 | s->context= 0; |
115329f1 | 495 | |
11f18faf MN |
496 | if(read_old_huffman_tables(s) < 0) |
497 | return -1; | |
498 | } | |
115329f1 | 499 | |
11f18faf MN |
500 | switch(s->bitstream_bpp){ |
501 | case 12: | |
502 | avctx->pix_fmt = PIX_FMT_YUV420P; | |
11f18faf MN |
503 | break; |
504 | case 16: | |
505 | if(s->yuy2){ | |
71e445fc | 506 | avctx->pix_fmt = PIX_FMT_YUYV422; |
11f18faf MN |
507 | }else{ |
508 | avctx->pix_fmt = PIX_FMT_YUV422P; | |
11f18faf MN |
509 | } |
510 | break; | |
511 | case 24: | |
512 | case 32: | |
513 | if(s->bgr32){ | |
71e445fc | 514 | avctx->pix_fmt = PIX_FMT_RGB32; |
11f18faf MN |
515 | }else{ |
516 | avctx->pix_fmt = PIX_FMT_BGR24; | |
11f18faf MN |
517 | } |
518 | break; | |
519 | default: | |
520 | assert(0); | |
11f18faf | 521 | } |
115329f1 | 522 | |
ae2f1d46 | 523 | alloc_temp(s); |
115329f1 | 524 | |
dd1c8f3e | 525 | // av_log(NULL, AV_LOG_DEBUG, "pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_coded_sample, s->interlaced); |
07140e39 | 526 | |
11f18faf MN |
527 | return 0; |
528 | } | |
b250f9c6 | 529 | #endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */ |
11f18faf | 530 | |
b250f9c6 | 531 | #if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER |
11087086 | 532 | static int store_table(HYuvContext *s, uint8_t *len, uint8_t *buf){ |
11f18faf | 533 | int i; |
11087086 | 534 | int index= 0; |
11f18faf MN |
535 | |
536 | for(i=0; i<256;){ | |
11f18faf | 537 | int val= len[i]; |
a003ee9a | 538 | int repeat=0; |
115329f1 | 539 | |
a003ee9a MN |
540 | for(; i<256 && len[i]==val && repeat<255; i++) |
541 | repeat++; | |
115329f1 | 542 | |
a003ee9a | 543 | assert(val < 32 && val >0 && repeat<256 && repeat>0); |
11f18faf | 544 | if(repeat>7){ |
11087086 LM |
545 | buf[index++]= val; |
546 | buf[index++]= repeat; | |
11f18faf | 547 | }else{ |
11087086 | 548 | buf[index++]= val | (repeat<<5); |
11f18faf MN |
549 | } |
550 | } | |
115329f1 | 551 | |
11087086 | 552 | return index; |
11f18faf MN |
553 | } |
554 | ||
98a6fff9 | 555 | static av_cold int encode_init(AVCodecContext *avctx) |
11f18faf MN |
556 | { |
557 | HYuvContext *s = avctx->priv_data; | |
0ecca7a4 | 558 | int i, j; |
11f18faf | 559 | |
0ecca7a4 | 560 | common_init(avctx); |
115329f1 | 561 | |
0ecca7a4 MN |
562 | avctx->extradata= av_mallocz(1024*30); // 256*3+4 == 772 |
563 | avctx->stats_out= av_mallocz(1024*30); // 21*256*3(%llu ) + 3(\n) + 1(0) = 16132 | |
11f18faf | 564 | s->version=2; |
115329f1 | 565 | |
492cd3a9 | 566 | avctx->coded_frame= &s->picture; |
115329f1 | 567 | |
11f18faf | 568 | switch(avctx->pix_fmt){ |
152ba68c | 569 | case PIX_FMT_YUV420P: |
152ba68c MN |
570 | s->bitstream_bpp= 12; |
571 | break; | |
11f18faf MN |
572 | case PIX_FMT_YUV422P: |
573 | s->bitstream_bpp= 16; | |
574 | break; | |
d2bfaf8a LM |
575 | case PIX_FMT_RGB32: |
576 | s->bitstream_bpp= 24; | |
577 | break; | |
11f18faf | 578 | default: |
9b879566 | 579 | av_log(avctx, AV_LOG_ERROR, "format not supported\n"); |
11f18faf MN |
580 | return -1; |
581 | } | |
dd1c8f3e | 582 | avctx->bits_per_coded_sample= s->bitstream_bpp; |
11f18faf MN |
583 | s->decorrelate= s->bitstream_bpp >= 24; |
584 | s->predictor= avctx->prediction_method; | |
ee598f7b | 585 | s->interlaced= avctx->flags&CODEC_FLAG_INTERLACED_ME ? 1 : 0; |
11087086 LM |
586 | if(avctx->context_model==1){ |
587 | s->context= avctx->context_model; | |
11087086 LM |
588 | if(s->flags & (CODEC_FLAG_PASS1|CODEC_FLAG_PASS2)){ |
589 | av_log(avctx, AV_LOG_ERROR, "context=1 is not compatible with 2 pass huffyuv encoding\n"); | |
590 | return -1; | |
591 | } | |
11087086 | 592 | }else s->context= 0; |
115329f1 | 593 | |
f37b9768 LM |
594 | if(avctx->codec->id==CODEC_ID_HUFFYUV){ |
595 | if(avctx->pix_fmt==PIX_FMT_YUV420P){ | |
596 | av_log(avctx, AV_LOG_ERROR, "Error: YV12 is not supported by huffyuv; use vcodec=ffvhuff or format=422p\n"); | |
597 | return -1; | |
598 | } | |
599 | if(avctx->context_model){ | |
600 | av_log(avctx, AV_LOG_ERROR, "Error: per-frame huffman tables are not supported by huffyuv; use vcodec=ffvhuff\n"); | |
601 | return -1; | |
602 | } | |
0ecca7a4 | 603 | if(s->interlaced != ( s->height > 288 )) |
f37b9768 | 604 | av_log(avctx, AV_LOG_INFO, "using huffyuv 2.2.0 or newer interlacing flag\n"); |
f37b9768 | 605 | } |
115329f1 | 606 | |
d2bfaf8a LM |
607 | if(s->bitstream_bpp>=24 && s->predictor==MEDIAN){ |
608 | av_log(avctx, AV_LOG_ERROR, "Error: RGB is incompatible with median predictor\n"); | |
609 | return -1; | |
610 | } | |
611 | ||
612 | ((uint8_t*)avctx->extradata)[0]= s->predictor | (s->decorrelate << 6); | |
11f18faf | 613 | ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp; |
42dd22c4 | 614 | ((uint8_t*)avctx->extradata)[2]= s->interlaced ? 0x10 : 0x20; |
11087086 LM |
615 | if(s->context) |
616 | ((uint8_t*)avctx->extradata)[2]|= 0x40; | |
11f18faf MN |
617 | ((uint8_t*)avctx->extradata)[3]= 0; |
618 | s->avctx->extradata_size= 4; | |
115329f1 | 619 | |
11f18faf MN |
620 | if(avctx->stats_in){ |
621 | char *p= avctx->stats_in; | |
115329f1 | 622 | |
11f18faf MN |
623 | for(i=0; i<3; i++) |
624 | for(j=0; j<256; j++) | |
625 | s->stats[i][j]= 1; | |
626 | ||
627 | for(;;){ | |
628 | for(i=0; i<3; i++){ | |
629 | char *next; | |
630 | ||
631 | for(j=0; j<256; j++){ | |
632 | s->stats[i][j]+= strtol(p, &next, 0); | |
633 | if(next==p) return -1; | |
634 | p=next; | |
115329f1 | 635 | } |
11f18faf MN |
636 | } |
637 | if(p[0]==0 || p[1]==0 || p[2]==0) break; | |
638 | } | |
639 | }else{ | |
640 | for(i=0; i<3; i++) | |
641 | for(j=0; j<256; j++){ | |
642 | int d= FFMIN(j, 256-j); | |
115329f1 | 643 | |
11f18faf MN |
644 | s->stats[i][j]= 100000000/(d+1); |
645 | } | |
646 | } | |
115329f1 | 647 | |
11f18faf MN |
648 | for(i=0; i<3; i++){ |
649 | generate_len_table(s->len[i], s->stats[i], 256); | |
650 | ||
651 | if(generate_bits_table(s->bits[i], s->len[i])<0){ | |
652 | return -1; | |
653 | } | |
115329f1 | 654 | |
11087086 LM |
655 | s->avctx->extradata_size+= |
656 | store_table(s, s->len[i], &((uint8_t*)s->avctx->extradata)[s->avctx->extradata_size]); | |
11f18faf MN |
657 | } |
658 | ||
11087086 LM |
659 | if(s->context){ |
660 | for(i=0; i<3; i++){ | |
0ecca7a4 | 661 | int pels = s->width*s->height / (i?40:10); |
11087086 LM |
662 | for(j=0; j<256; j++){ |
663 | int d= FFMIN(j, 256-j); | |
664 | s->stats[i][j]= pels/(d+1); | |
665 | } | |
666 | } | |
667 | }else{ | |
668 | for(i=0; i<3; i++) | |
669 | for(j=0; j<256; j++) | |
670 | s->stats[i][j]= 0; | |
671 | } | |
115329f1 | 672 | |
dd1c8f3e | 673 | // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_coded_sample, s->interlaced); |
5fd74135 | 674 | |
ae2f1d46 MN |
675 | alloc_temp(s); |
676 | ||
11f18faf | 677 | s->picture_number=0; |
5fd74135 | 678 | |
11f18faf MN |
679 | return 0; |
680 | } | |
b250f9c6 | 681 | #endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */ |
11f18faf | 682 | |
19716d64 LM |
683 | /* TODO instead of restarting the read when the code isn't in the first level |
684 | * of the joint table, jump into the 2nd level of the individual table. */ | |
685 | #define READ_2PIX(dst0, dst1, plane1){\ | |
acc0e0c8 LM |
686 | uint16_t code = get_vlc2(&s->gb, s->vlc[3+plane1].table, VLC_BITS, 1);\ |
687 | if(code != 0xffff){\ | |
688 | dst0 = code>>8;\ | |
689 | dst1 = code;\ | |
19716d64 LM |
690 | }else{\ |
691 | dst0 = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);\ | |
692 | dst1 = get_vlc2(&s->gb, s->vlc[plane1].table, VLC_BITS, 3);\ | |
693 | }\ | |
694 | } | |
695 | ||
11f18faf MN |
696 | static void decode_422_bitstream(HYuvContext *s, int count){ |
697 | int i; | |
5fd74135 | 698 | |
11f18faf | 699 | count/=2; |
115329f1 | 700 | |
6e44ba15 | 701 | if(count >= (get_bits_left(&s->gb))/(31*4)){ |
37458d7e MN |
702 | for(i=0; i<count && get_bits_count(&s->gb) < s->gb.size_in_bits; i++){ |
703 | READ_2PIX(s->temp[0][2*i ], s->temp[1][i], 1); | |
704 | READ_2PIX(s->temp[0][2*i+1], s->temp[2][i], 2); | |
705 | } | |
706 | }else{ | |
fb6ecd72 MN |
707 | for(i=0; i<count; i++){ |
708 | READ_2PIX(s->temp[0][2*i ], s->temp[1][i], 1); | |
709 | READ_2PIX(s->temp[0][2*i+1], s->temp[2][i], 2); | |
710 | } | |
37458d7e | 711 | } |
11f18faf MN |
712 | } |
713 | ||
152ba68c MN |
714 | static void decode_gray_bitstream(HYuvContext *s, int count){ |
715 | int i; | |
115329f1 | 716 | |
152ba68c | 717 | count/=2; |
115329f1 | 718 | |
6e44ba15 | 719 | if(count >= (get_bits_left(&s->gb))/(31*2)){ |
37458d7e MN |
720 | for(i=0; i<count && get_bits_count(&s->gb) < s->gb.size_in_bits; i++){ |
721 | READ_2PIX(s->temp[0][2*i ], s->temp[0][2*i+1], 0); | |
722 | } | |
723 | }else{ | |
fb6ecd72 MN |
724 | for(i=0; i<count; i++){ |
725 | READ_2PIX(s->temp[0][2*i ], s->temp[0][2*i+1], 0); | |
726 | } | |
37458d7e | 727 | } |
152ba68c MN |
728 | } |
729 | ||
b250f9c6 | 730 | #if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER |
aa5cfdfb | 731 | static int encode_422_bitstream(HYuvContext *s, int offset, int count){ |
11f18faf | 732 | int i; |
aa5cfdfb JD |
733 | const uint8_t *y = s->temp[0] + offset; |
734 | const uint8_t *u = s->temp[1] + offset/2; | |
735 | const uint8_t *v = s->temp[2] + offset/2; | |
115329f1 | 736 | |
0ecca7a4 MN |
737 | if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 2*4*count){ |
738 | av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); | |
739 | return -1; | |
740 | } | |
115329f1 | 741 | |
bf1a5a46 | 742 | #define LOAD4\ |
aa5cfdfb JD |
743 | int y0 = y[2*i];\ |
744 | int y1 = y[2*i+1];\ | |
745 | int u0 = u[i];\ | |
746 | int v0 = v[i]; | |
bf1a5a46 | 747 | |
11f18faf MN |
748 | count/=2; |
749 | if(s->flags&CODEC_FLAG_PASS1){ | |
750 | for(i=0; i<count; i++){ | |
bf1a5a46 LM |
751 | LOAD4; |
752 | s->stats[0][y0]++; | |
753 | s->stats[1][u0]++; | |
754 | s->stats[0][y1]++; | |
755 | s->stats[2][v0]++; | |
11f18faf | 756 | } |
09b0499f MN |
757 | } |
758 | if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT) | |
759 | return 0; | |
760 | if(s->context){ | |
11087086 | 761 | for(i=0; i<count; i++){ |
bf1a5a46 LM |
762 | LOAD4; |
763 | s->stats[0][y0]++; | |
764 | put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]); | |
765 | s->stats[1][u0]++; | |
766 | put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]); | |
767 | s->stats[0][y1]++; | |
768 | put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]); | |
769 | s->stats[2][v0]++; | |
770 | put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]); | |
11087086 | 771 | } |
11f18faf MN |
772 | }else{ |
773 | for(i=0; i<count; i++){ | |
bf1a5a46 LM |
774 | LOAD4; |
775 | put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]); | |
776 | put_bits(&s->pb, s->len[1][u0], s->bits[1][u0]); | |
777 | put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]); | |
778 | put_bits(&s->pb, s->len[2][v0], s->bits[2][v0]); | |
11f18faf MN |
779 | } |
780 | } | |
0ecca7a4 | 781 | return 0; |
11f18faf MN |
782 | } |
783 | ||
0ecca7a4 | 784 | static int encode_gray_bitstream(HYuvContext *s, int count){ |
152ba68c | 785 | int i; |
115329f1 | 786 | |
0ecca7a4 MN |
787 | if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 4*count){ |
788 | av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); | |
789 | return -1; | |
790 | } | |
791 | ||
bf1a5a46 LM |
792 | #define LOAD2\ |
793 | int y0 = s->temp[0][2*i];\ | |
794 | int y1 = s->temp[0][2*i+1]; | |
795 | #define STAT2\ | |
796 | s->stats[0][y0]++;\ | |
797 | s->stats[0][y1]++; | |
798 | #define WRITE2\ | |
799 | put_bits(&s->pb, s->len[0][y0], s->bits[0][y0]);\ | |
800 | put_bits(&s->pb, s->len[0][y1], s->bits[0][y1]); | |
801 | ||
152ba68c MN |
802 | count/=2; |
803 | if(s->flags&CODEC_FLAG_PASS1){ | |
804 | for(i=0; i<count; i++){ | |
bf1a5a46 LM |
805 | LOAD2; |
806 | STAT2; | |
152ba68c | 807 | } |
09b0499f MN |
808 | } |
809 | if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT) | |
810 | return 0; | |
115329f1 | 811 | |
09b0499f | 812 | if(s->context){ |
11087086 | 813 | for(i=0; i<count; i++){ |
bf1a5a46 LM |
814 | LOAD2; |
815 | STAT2; | |
816 | WRITE2; | |
11087086 | 817 | } |
152ba68c MN |
818 | }else{ |
819 | for(i=0; i<count; i++){ | |
bf1a5a46 LM |
820 | LOAD2; |
821 | WRITE2; | |
152ba68c MN |
822 | } |
823 | } | |
0ecca7a4 | 824 | return 0; |
152ba68c | 825 | } |
b250f9c6 | 826 | #endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */ |
152ba68c | 827 | |
8be6dac8 | 828 | static av_always_inline void decode_bgr_1(HYuvContext *s, int count, int decorrelate, int alpha){ |
11f18faf | 829 | int i; |
8be6dac8 LM |
830 | for(i=0; i<count; i++){ |
831 | int code = get_vlc2(&s->gb, s->vlc[3].table, VLC_BITS, 1); | |
832 | if(code != -1){ | |
833 | *(uint32_t*)&s->temp[0][4*i] = s->pix_bgr_map[code]; | |
834 | }else if(decorrelate){ | |
835 | s->temp[0][4*i+G] = get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); | |
836 | s->temp[0][4*i+B] = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+G]; | |
837 | s->temp[0][4*i+R] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+G]; | |
11f18faf | 838 | }else{ |
8be6dac8 LM |
839 | s->temp[0][4*i+B] = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); |
840 | s->temp[0][4*i+G] = get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); | |
841 | s->temp[0][4*i+R] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); | |
11f18faf | 842 | } |
8be6dac8 | 843 | if(alpha) |
f267d3ac | 844 | s->temp[0][4*i+A] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); |
8be6dac8 LM |
845 | } |
846 | } | |
847 | ||
848 | static void decode_bgr_bitstream(HYuvContext *s, int count){ | |
849 | if(s->decorrelate){ | |
850 | if(s->bitstream_bpp==24) | |
851 | decode_bgr_1(s, count, 1, 0); | |
852 | else | |
853 | decode_bgr_1(s, count, 1, 1); | |
11f18faf | 854 | }else{ |
8be6dac8 LM |
855 | if(s->bitstream_bpp==24) |
856 | decode_bgr_1(s, count, 0, 0); | |
857 | else | |
858 | decode_bgr_1(s, count, 0, 1); | |
11f18faf MN |
859 | } |
860 | } | |
861 | ||
d2bfaf8a LM |
862 | static int encode_bgr_bitstream(HYuvContext *s, int count){ |
863 | int i; | |
864 | ||
865 | if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 3*4*count){ | |
866 | av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); | |
867 | return -1; | |
868 | } | |
869 | ||
bf1a5a46 LM |
870 | #define LOAD3\ |
871 | int g= s->temp[0][4*i+G];\ | |
872 | int b= (s->temp[0][4*i+B] - g) & 0xff;\ | |
d2bfaf8a | 873 | int r= (s->temp[0][4*i+R] - g) & 0xff; |
bf1a5a46 LM |
874 | #define STAT3\ |
875 | s->stats[0][b]++;\ | |
876 | s->stats[1][g]++;\ | |
d2bfaf8a | 877 | s->stats[2][r]++; |
bf1a5a46 LM |
878 | #define WRITE3\ |
879 | put_bits(&s->pb, s->len[1][g], s->bits[1][g]);\ | |
880 | put_bits(&s->pb, s->len[0][b], s->bits[0][b]);\ | |
881 | put_bits(&s->pb, s->len[2][r], s->bits[2][r]); | |
882 | ||
883 | if((s->flags&CODEC_FLAG_PASS1) && (s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT)){ | |
884 | for(i=0; i<count; i++){ | |
885 | LOAD3; | |
886 | STAT3; | |
d2bfaf8a LM |
887 | } |
888 | }else if(s->context || (s->flags&CODEC_FLAG_PASS1)){ | |
889 | for(i=0; i<count; i++){ | |
bf1a5a46 LM |
890 | LOAD3; |
891 | STAT3; | |
892 | WRITE3; | |
d2bfaf8a LM |
893 | } |
894 | }else{ | |
895 | for(i=0; i<count; i++){ | |
bf1a5a46 LM |
896 | LOAD3; |
897 | WRITE3; | |
d2bfaf8a LM |
898 | } |
899 | } | |
900 | return 0; | |
901 | } | |
902 | ||
b250f9c6 | 903 | #if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER |
7c5ab7b8 MN |
904 | static void draw_slice(HYuvContext *s, int y){ |
905 | int h, cy; | |
7a06ff14 | 906 | int offset[4]; |
115329f1 DB |
907 | |
908 | if(s->avctx->draw_horiz_band==NULL) | |
7c5ab7b8 | 909 | return; |
115329f1 | 910 | |
7c5ab7b8 MN |
911 | h= y - s->last_slice_end; |
912 | y -= h; | |
115329f1 | 913 | |
7c5ab7b8 MN |
914 | if(s->bitstream_bpp==12){ |
915 | cy= y>>1; | |
916 | }else{ | |
917 | cy= y; | |
918 | } | |
7a06ff14 MN |
919 | |
920 | offset[0] = s->picture.linesize[0]*y; | |
921 | offset[1] = s->picture.linesize[1]*cy; | |
922 | offset[2] = s->picture.linesize[2]*cy; | |
923 | offset[3] = 0; | |
7c5ab7b8 MN |
924 | emms_c(); |
925 | ||
3bb07d61 | 926 | s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h); |
115329f1 | 927 | |
7c5ab7b8 MN |
928 | s->last_slice_end= y + h; |
929 | } | |
930 | ||
7a00bbad TB |
931 | static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt){ |
932 | const uint8_t *buf = avpkt->data; | |
933 | int buf_size = avpkt->size; | |
11f18faf MN |
934 | HYuvContext *s = avctx->priv_data; |
935 | const int width= s->width; | |
936 | const int width2= s->width>>1; | |
937 | const int height= s->height; | |
22f3e8be | 938 | int fake_ystride, fake_ustride, fake_vstride; |
492cd3a9 | 939 | AVFrame * const p= &s->picture; |
11087086 | 940 | int table_size= 0; |
11f18faf | 941 | |
492cd3a9 | 942 | AVFrame *picture = data; |
11f18faf | 943 | |
238ef6da RD |
944 | av_fast_malloc(&s->bitstream_buffer, &s->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); |
945 | if (!s->bitstream_buffer) | |
946 | return AVERROR(ENOMEM); | |
11f18faf | 947 | |
6ec8eadd | 948 | memset(s->bitstream_buffer + buf_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); |
fb2cf1bc | 949 | s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (const uint32_t*)buf, buf_size/4); |
115329f1 | 950 | |
e20c4069 MN |
951 | if(p->data[0]) |
952 | avctx->release_buffer(avctx, p); | |
953 | ||
1e491e29 MN |
954 | p->reference= 0; |
955 | if(avctx->get_buffer(avctx, p) < 0){ | |
9b879566 | 956 | av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
1e491e29 | 957 | return -1; |
22f3e8be | 958 | } |
115329f1 | 959 | |
11087086 LM |
960 | if(s->context){ |
961 | table_size = read_huffman_tables(s, s->bitstream_buffer, buf_size); | |
962 | if(table_size < 0) | |
963 | return -1; | |
964 | } | |
965 | ||
e70e7a4b MN |
966 | if((unsigned)(buf_size-table_size) >= INT_MAX/8) |
967 | return -1; | |
968 | ||
11087086 | 969 | init_get_bits(&s->gb, s->bitstream_buffer+table_size, (buf_size-table_size)*8); |
1e491e29 MN |
970 | |
971 | fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0]; | |
972 | fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1]; | |
973 | fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2]; | |
115329f1 | 974 | |
7c5ab7b8 | 975 | s->last_slice_end= 0; |
115329f1 | 976 | |
11f18faf | 977 | if(s->bitstream_bpp<24){ |
152ba68c | 978 | int y, cy; |
11f18faf MN |
979 | int lefty, leftu, leftv; |
980 | int lefttopy, lefttopu, lefttopv; | |
115329f1 | 981 | |
11f18faf | 982 | if(s->yuy2){ |
1e491e29 MN |
983 | p->data[0][3]= get_bits(&s->gb, 8); |
984 | p->data[0][2]= get_bits(&s->gb, 8); | |
985 | p->data[0][1]= get_bits(&s->gb, 8); | |
986 | p->data[0][0]= get_bits(&s->gb, 8); | |
115329f1 | 987 | |
160d679c | 988 | av_log(avctx, AV_LOG_ERROR, "YUY2 output is not implemented yet\n"); |
11f18faf MN |
989 | return -1; |
990 | }else{ | |
115329f1 | 991 | |
1e491e29 MN |
992 | leftv= p->data[2][0]= get_bits(&s->gb, 8); |
993 | lefty= p->data[0][1]= get_bits(&s->gb, 8); | |
994 | leftu= p->data[1][0]= get_bits(&s->gb, 8); | |
995 | p->data[0][0]= get_bits(&s->gb, 8); | |
115329f1 | 996 | |
11f18faf MN |
997 | switch(s->predictor){ |
998 | case LEFT: | |
999 | case PLANE: | |
1000 | decode_422_bitstream(s, width-2); | |
73c6f598 | 1001 | lefty= s->dsp.add_hfyu_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty); |
11f18faf | 1002 | if(!(s->flags&CODEC_FLAG_GRAY)){ |
73c6f598 NC |
1003 | leftu= s->dsp.add_hfyu_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu); |
1004 | leftv= s->dsp.add_hfyu_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv); | |
11f18faf MN |
1005 | } |
1006 | ||
152ba68c | 1007 | for(cy=y=1; y<s->height; y++,cy++){ |
11f18faf | 1008 | uint8_t *ydst, *udst, *vdst; |
115329f1 | 1009 | |
152ba68c MN |
1010 | if(s->bitstream_bpp==12){ |
1011 | decode_gray_bitstream(s, width); | |
115329f1 | 1012 | |
1e491e29 | 1013 | ydst= p->data[0] + p->linesize[0]*y; |
152ba68c | 1014 | |
73c6f598 | 1015 | lefty= s->dsp.add_hfyu_left_prediction(ydst, s->temp[0], width, lefty); |
152ba68c MN |
1016 | if(s->predictor == PLANE){ |
1017 | if(y>s->interlaced) | |
1018 | s->dsp.add_bytes(ydst, ydst - fake_ystride, width); | |
1019 | } | |
1020 | y++; | |
1021 | if(y>=s->height) break; | |
1022 | } | |
115329f1 | 1023 | |
7c5ab7b8 | 1024 | draw_slice(s, y); |
115329f1 | 1025 | |
1e491e29 MN |
1026 | ydst= p->data[0] + p->linesize[0]*y; |
1027 | udst= p->data[1] + p->linesize[1]*cy; | |
1028 | vdst= p->data[2] + p->linesize[2]*cy; | |
115329f1 | 1029 | |
152ba68c | 1030 | decode_422_bitstream(s, width); |
73c6f598 | 1031 | lefty= s->dsp.add_hfyu_left_prediction(ydst, s->temp[0], width, lefty); |
11f18faf | 1032 | if(!(s->flags&CODEC_FLAG_GRAY)){ |
73c6f598 NC |
1033 | leftu= s->dsp.add_hfyu_left_prediction(udst, s->temp[1], width2, leftu); |
1034 | leftv= s->dsp.add_hfyu_left_prediction(vdst, s->temp[2], width2, leftv); | |
11f18faf MN |
1035 | } |
1036 | if(s->predictor == PLANE){ | |
152ba68c | 1037 | if(cy>s->interlaced){ |
11f18faf MN |
1038 | s->dsp.add_bytes(ydst, ydst - fake_ystride, width); |
1039 | if(!(s->flags&CODEC_FLAG_GRAY)){ | |
1040 | s->dsp.add_bytes(udst, udst - fake_ustride, width2); | |
1041 | s->dsp.add_bytes(vdst, vdst - fake_vstride, width2); | |
1042 | } | |
1043 | } | |
1044 | } | |
1045 | } | |
7c5ab7b8 | 1046 | draw_slice(s, height); |
115329f1 | 1047 | |
11f18faf MN |
1048 | break; |
1049 | case MEDIAN: | |
1050 | /* first line except first 2 pixels is left predicted */ | |
1051 | decode_422_bitstream(s, width-2); | |
73c6f598 | 1052 | lefty= s->dsp.add_hfyu_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty); |
11f18faf | 1053 | if(!(s->flags&CODEC_FLAG_GRAY)){ |
73c6f598 NC |
1054 | leftu= s->dsp.add_hfyu_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu); |
1055 | leftv= s->dsp.add_hfyu_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv); | |
11f18faf | 1056 | } |
115329f1 | 1057 | |
152ba68c | 1058 | cy=y=1; |
115329f1 | 1059 | |
11f18faf MN |
1060 | /* second line is left predicted for interlaced case */ |
1061 | if(s->interlaced){ | |
1062 | decode_422_bitstream(s, width); | |
73c6f598 | 1063 | lefty= s->dsp.add_hfyu_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty); |
11f18faf | 1064 | if(!(s->flags&CODEC_FLAG_GRAY)){ |
73c6f598 NC |
1065 | leftu= s->dsp.add_hfyu_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu); |
1066 | leftv= s->dsp.add_hfyu_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv); | |
11f18faf | 1067 | } |
152ba68c | 1068 | y++; cy++; |
11f18faf MN |
1069 | } |
1070 | ||
1071 | /* next 4 pixels are left predicted too */ | |
1072 | decode_422_bitstream(s, 4); | |
73c6f598 | 1073 | lefty= s->dsp.add_hfyu_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty); |
11f18faf | 1074 | if(!(s->flags&CODEC_FLAG_GRAY)){ |
73c6f598 NC |
1075 | leftu= s->dsp.add_hfyu_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu); |
1076 | leftv= s->dsp.add_hfyu_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv); | |
11f18faf MN |
1077 | } |
1078 | ||
1079 | /* next line except the first 4 pixels is median predicted */ | |
1e491e29 | 1080 | lefttopy= p->data[0][3]; |
11f18faf | 1081 | decode_422_bitstream(s, width-4); |
3daa434a | 1082 | s->dsp.add_hfyu_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy); |
11f18faf | 1083 | if(!(s->flags&CODEC_FLAG_GRAY)){ |
1e491e29 MN |
1084 | lefttopu= p->data[1][1]; |
1085 | lefttopv= p->data[2][1]; | |
3daa434a LM |
1086 | s->dsp.add_hfyu_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu); |
1087 | s->dsp.add_hfyu_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv); | |
11f18faf | 1088 | } |
152ba68c | 1089 | y++; cy++; |
115329f1 | 1090 | |
152ba68c | 1091 | for(; y<height; y++,cy++){ |
11f18faf | 1092 | uint8_t *ydst, *udst, *vdst; |
152ba68c MN |
1093 | |
1094 | if(s->bitstream_bpp==12){ | |
1095 | while(2*cy > y){ | |
1096 | decode_gray_bitstream(s, width); | |
1e491e29 | 1097 | ydst= p->data[0] + p->linesize[0]*y; |
3daa434a | 1098 | s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); |
152ba68c MN |
1099 | y++; |
1100 | } | |
1101 | if(y>=height) break; | |
1102 | } | |
7c5ab7b8 | 1103 | draw_slice(s, y); |
152ba68c | 1104 | |
11f18faf | 1105 | decode_422_bitstream(s, width); |
152ba68c | 1106 | |
1e491e29 MN |
1107 | ydst= p->data[0] + p->linesize[0]*y; |
1108 | udst= p->data[1] + p->linesize[1]*cy; | |
1109 | vdst= p->data[2] + p->linesize[2]*cy; | |
11f18faf | 1110 | |
3daa434a | 1111 | s->dsp.add_hfyu_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); |
11f18faf | 1112 | if(!(s->flags&CODEC_FLAG_GRAY)){ |
3daa434a LM |
1113 | s->dsp.add_hfyu_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu); |
1114 | s->dsp.add_hfyu_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv); | |
11f18faf MN |
1115 | } |
1116 | } | |
7c5ab7b8 MN |
1117 | |
1118 | draw_slice(s, height); | |
11f18faf MN |
1119 | break; |
1120 | } | |
1121 | } | |
1122 | }else{ | |
1123 | int y; | |
f267d3ac | 1124 | int leftr, leftg, leftb, lefta; |
1e491e29 | 1125 | const int last_line= (height-1)*p->linesize[0]; |
115329f1 | 1126 | |
11f18faf | 1127 | if(s->bitstream_bpp==32){ |
f267d3ac | 1128 | lefta= p->data[0][last_line+A]= get_bits(&s->gb, 8); |
0722ccdb MN |
1129 | leftr= p->data[0][last_line+R]= get_bits(&s->gb, 8); |
1130 | leftg= p->data[0][last_line+G]= get_bits(&s->gb, 8); | |
1131 | leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8); | |
11f18faf | 1132 | }else{ |
0722ccdb MN |
1133 | leftr= p->data[0][last_line+R]= get_bits(&s->gb, 8); |
1134 | leftg= p->data[0][last_line+G]= get_bits(&s->gb, 8); | |
1135 | leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8); | |
f267d3ac | 1136 | lefta= p->data[0][last_line+A]= 255; |
11f18faf MN |
1137 | skip_bits(&s->gb, 8); |
1138 | } | |
115329f1 | 1139 | |
11f18faf MN |
1140 | if(s->bgr32){ |
1141 | switch(s->predictor){ | |
1142 | case LEFT: | |
1143 | case PLANE: | |
1144 | decode_bgr_bitstream(s, width-1); | |
f267d3ac | 1145 | s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb, &lefta); |
11f18faf | 1146 | |
90b5b51e | 1147 | for(y=s->height-2; y>=0; y--){ //Yes it is stored upside down. |
11f18faf | 1148 | decode_bgr_bitstream(s, width); |
115329f1 | 1149 | |
f267d3ac | 1150 | s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb, &lefta); |
11f18faf | 1151 | if(s->predictor == PLANE){ |
f267d3ac | 1152 | if(s->bitstream_bpp!=32) lefta=0; |
fc0be57f | 1153 | if((y&s->interlaced)==0 && y<s->height-1-s->interlaced){ |
115329f1 | 1154 | s->dsp.add_bytes(p->data[0] + p->linesize[0]*y, |
1e491e29 | 1155 | p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride); |
11f18faf MN |
1156 | } |
1157 | } | |
1158 | } | |
160d679c | 1159 | draw_slice(s, height); // just 1 large slice as this is not possible in reverse order |
11f18faf MN |
1160 | break; |
1161 | default: | |
9b879566 | 1162 | av_log(avctx, AV_LOG_ERROR, "prediction type not supported!\n"); |
11f18faf MN |
1163 | } |
1164 | }else{ | |
1165 | ||
160d679c | 1166 | av_log(avctx, AV_LOG_ERROR, "BGR24 output is not implemented yet\n"); |
11f18faf MN |
1167 | return -1; |
1168 | } | |
1169 | } | |
1170 | emms_c(); | |
115329f1 | 1171 | |
1e491e29 | 1172 | *picture= *p; |
492cd3a9 | 1173 | *data_size = sizeof(AVFrame); |
115329f1 | 1174 | |
1adc29ee | 1175 | return (get_bits_count(&s->gb)+31)/32*4 + table_size; |
11f18faf | 1176 | } |
b250f9c6 | 1177 | #endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */ |
11f18faf | 1178 | |
0ecca7a4 MN |
1179 | static int common_end(HYuvContext *s){ |
1180 | int i; | |
115329f1 | 1181 | |
0ecca7a4 MN |
1182 | for(i=0; i<3; i++){ |
1183 | av_freep(&s->temp[i]); | |
1184 | } | |
1185 | return 0; | |
1186 | } | |
1187 | ||
b250f9c6 | 1188 | #if CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER |
98a6fff9 | 1189 | static av_cold int decode_end(AVCodecContext *avctx) |
11f18faf MN |
1190 | { |
1191 | HYuvContext *s = avctx->priv_data; | |
1192 | int i; | |
115329f1 | 1193 | |
0b7f39c9 CEH |
1194 | if (s->picture.data[0]) |
1195 | avctx->release_buffer(avctx, &s->picture); | |
1196 | ||
0ecca7a4 MN |
1197 | common_end(s); |
1198 | av_freep(&s->bitstream_buffer); | |
115329f1 | 1199 | |
7b62bb2b | 1200 | for(i=0; i<6; i++){ |
11f18faf MN |
1201 | free_vlc(&s->vlc[i]); |
1202 | } | |
1e491e29 | 1203 | |
11f18faf MN |
1204 | return 0; |
1205 | } | |
b250f9c6 | 1206 | #endif /* CONFIG_HUFFYUV_DECODER || CONFIG_FFVHUFF_DECODER */ |
11f18faf | 1207 | |
b250f9c6 | 1208 | #if CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER |
11f18faf MN |
1209 | static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ |
1210 | HYuvContext *s = avctx->priv_data; | |
492cd3a9 | 1211 | AVFrame *pict = data; |
11f18faf MN |
1212 | const int width= s->width; |
1213 | const int width2= s->width>>1; | |
1214 | const int height= s->height; | |
1215 | const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0]; | |
1216 | const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1]; | |
1217 | const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2]; | |
492cd3a9 | 1218 | AVFrame * const p= &s->picture; |
11087086 | 1219 | int i, j, size=0; |
11f18faf | 1220 | |
1e491e29 | 1221 | *p = *pict; |
aaa1e4cd MN |
1222 | p->pict_type= FF_I_TYPE; |
1223 | p->key_frame= 1; | |
115329f1 | 1224 | |
11087086 LM |
1225 | if(s->context){ |
1226 | for(i=0; i<3; i++){ | |
1227 | generate_len_table(s->len[i], s->stats[i], 256); | |
1228 | if(generate_bits_table(s->bits[i], s->len[i])<0) | |
1229 | return -1; | |
1230 | size+= store_table(s, s->len[i], &buf[size]); | |
1231 | } | |
1232 | ||
1233 | for(i=0; i<3; i++) | |
1234 | for(j=0; j<256; j++) | |
1235 | s->stats[i][j] >>= 1; | |
1236 | } | |
1237 | ||
1238 | init_put_bits(&s->pb, buf+size, buf_size-size); | |
1239 | ||
152ba68c MN |
1240 | if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){ |
1241 | int lefty, leftu, leftv, y, cy; | |
11f18faf | 1242 | |
1e491e29 MN |
1243 | put_bits(&s->pb, 8, leftv= p->data[2][0]); |
1244 | put_bits(&s->pb, 8, lefty= p->data[0][1]); | |
1245 | put_bits(&s->pb, 8, leftu= p->data[1][0]); | |
1246 | put_bits(&s->pb, 8, p->data[0][0]); | |
115329f1 | 1247 | |
fdb699de JD |
1248 | lefty= sub_left_prediction(s, s->temp[0], p->data[0], width , 0); |
1249 | leftu= sub_left_prediction(s, s->temp[1], p->data[1], width2, 0); | |
1250 | leftv= sub_left_prediction(s, s->temp[2], p->data[2], width2, 0); | |
115329f1 | 1251 | |
fdb699de | 1252 | encode_422_bitstream(s, 2, width-2); |
115329f1 | 1253 | |
11f18faf MN |
1254 | if(s->predictor==MEDIAN){ |
1255 | int lefttopy, lefttopu, lefttopv; | |
152ba68c | 1256 | cy=y=1; |
11f18faf | 1257 | if(s->interlaced){ |
1e491e29 MN |
1258 | lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty); |
1259 | leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu); | |
1260 | leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv); | |
115329f1 | 1261 | |
aa5cfdfb | 1262 | encode_422_bitstream(s, 0, width); |
152ba68c | 1263 | y++; cy++; |
11f18faf | 1264 | } |
115329f1 | 1265 | |
1e491e29 | 1266 | lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty); |
07140e39 MN |
1267 | leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ustride, 2, leftu); |
1268 | leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_vstride, 2, leftv); | |
115329f1 | 1269 | |
aa5cfdfb | 1270 | encode_422_bitstream(s, 0, 4); |
152ba68c | 1271 | |
1e491e29 MN |
1272 | lefttopy= p->data[0][3]; |
1273 | lefttopu= p->data[1][1]; | |
1274 | lefttopv= p->data[2][1]; | |
84705403 MN |
1275 | s->dsp.sub_hfyu_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy); |
1276 | s->dsp.sub_hfyu_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu); | |
1277 | s->dsp.sub_hfyu_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv); | |
aa5cfdfb | 1278 | encode_422_bitstream(s, 0, width-4); |
152ba68c | 1279 | y++; cy++; |
11f18faf | 1280 | |
152ba68c | 1281 | for(; y<height; y++,cy++){ |
11f18faf | 1282 | uint8_t *ydst, *udst, *vdst; |
115329f1 | 1283 | |
152ba68c MN |
1284 | if(s->bitstream_bpp==12){ |
1285 | while(2*cy > y){ | |
1e491e29 | 1286 | ydst= p->data[0] + p->linesize[0]*y; |
84705403 | 1287 | s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy); |
152ba68c MN |
1288 | encode_gray_bitstream(s, width); |
1289 | y++; | |
1290 | } | |
1291 | if(y>=height) break; | |
1292 | } | |
1e491e29 MN |
1293 | ydst= p->data[0] + p->linesize[0]*y; |
1294 | udst= p->data[1] + p->linesize[1]*cy; | |
1295 | vdst= p->data[2] + p->linesize[2]*cy; | |
11f18faf | 1296 | |
84705403 MN |
1297 | s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy); |
1298 | s->dsp.sub_hfyu_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu); | |
1299 | s->dsp.sub_hfyu_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv); | |
11f18faf | 1300 | |
aa5cfdfb | 1301 | encode_422_bitstream(s, 0, width); |
11f18faf MN |
1302 | } |
1303 | }else{ | |
152ba68c | 1304 | for(cy=y=1; y<height; y++,cy++){ |
11f18faf | 1305 | uint8_t *ydst, *udst, *vdst; |
115329f1 | 1306 | |
152ba68c MN |
1307 | /* encode a luma only line & y++ */ |
1308 | if(s->bitstream_bpp==12){ | |
1e491e29 | 1309 | ydst= p->data[0] + p->linesize[0]*y; |
152ba68c MN |
1310 | |
1311 | if(s->predictor == PLANE && s->interlaced < y){ | |
7c5ab7b8 | 1312 | s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width); |
152ba68c | 1313 | |
7c5ab7b8 | 1314 | lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty); |
152ba68c | 1315 | }else{ |
7c5ab7b8 | 1316 | lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty); |
152ba68c MN |
1317 | } |
1318 | encode_gray_bitstream(s, width); | |
1319 | y++; | |
1320 | if(y>=height) break; | |
1321 | } | |
115329f1 | 1322 | |
1e491e29 MN |
1323 | ydst= p->data[0] + p->linesize[0]*y; |
1324 | udst= p->data[1] + p->linesize[1]*cy; | |
1325 | vdst= p->data[2] + p->linesize[2]*cy; | |
11f18faf | 1326 | |
152ba68c | 1327 | if(s->predictor == PLANE && s->interlaced < cy){ |
7c5ab7b8 MN |
1328 | s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width); |
1329 | s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2); | |
ae2f1d46 | 1330 | s->dsp.diff_bytes(s->temp[2] + width2, vdst, vdst - fake_vstride, width2); |
11f18faf | 1331 | |
7c5ab7b8 MN |
1332 | lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty); |
1333 | leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu); | |
ae2f1d46 | 1334 | leftv= sub_left_prediction(s, s->temp[2], s->temp[2] + width2, width2, leftv); |
11f18faf | 1335 | }else{ |
7c5ab7b8 MN |
1336 | lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty); |
1337 | leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu); | |
1338 | leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv); | |
11f18faf MN |
1339 | } |
1340 | ||
aa5cfdfb | 1341 | encode_422_bitstream(s, 0, width); |
11f18faf | 1342 | } |
115329f1 | 1343 | } |
d2bfaf8a LM |
1344 | }else if(avctx->pix_fmt == PIX_FMT_RGB32){ |
1345 | uint8_t *data = p->data[0] + (height-1)*p->linesize[0]; | |
1346 | const int stride = -p->linesize[0]; | |
1347 | const int fake_stride = -fake_ystride; | |
1348 | int y; | |
1349 | int leftr, leftg, leftb; | |
1350 | ||
1351 | put_bits(&s->pb, 8, leftr= data[R]); | |
1352 | put_bits(&s->pb, 8, leftg= data[G]); | |
1353 | put_bits(&s->pb, 8, leftb= data[B]); | |
1354 | put_bits(&s->pb, 8, 0); | |
1355 | ||
1356 | sub_left_prediction_bgr32(s, s->temp[0], data+4, width-1, &leftr, &leftg, &leftb); | |
1357 | encode_bgr_bitstream(s, width-1); | |
1358 | ||
1359 | for(y=1; y<s->height; y++){ | |
1360 | uint8_t *dst = data + y*stride; | |
1361 | if(s->predictor == PLANE && s->interlaced < y){ | |
1362 | s->dsp.diff_bytes(s->temp[1], dst, dst - fake_stride, width*4); | |
1363 | sub_left_prediction_bgr32(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb); | |
1364 | }else{ | |
1365 | sub_left_prediction_bgr32(s, s->temp[0], dst, width, &leftr, &leftg, &leftb); | |
1366 | } | |
1367 | encode_bgr_bitstream(s, width); | |
1368 | } | |
11f18faf | 1369 | }else{ |
9b879566 | 1370 | av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); |
11f18faf MN |
1371 | } |
1372 | emms_c(); | |
115329f1 | 1373 | |
11087086 | 1374 | size+= (put_bits_count(&s->pb)+31)/8; |
300a3d0d MN |
1375 | put_bits(&s->pb, 16, 0); |
1376 | put_bits(&s->pb, 15, 0); | |
11087086 | 1377 | size/= 4; |
115329f1 | 1378 | |
11f18faf MN |
1379 | if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){ |
1380 | int j; | |
1381 | char *p= avctx->stats_out; | |
2fc8ea24 | 1382 | char *end= p + 1024*30; |
11f18faf MN |
1383 | for(i=0; i<3; i++){ |
1384 | for(j=0; j<256; j++){ | |
4733abcb | 1385 | snprintf(p, end-p, "%"PRIu64" ", s->stats[i][j]); |
11f18faf MN |
1386 | p+= strlen(p); |
1387 | s->stats[i][j]= 0; | |
1388 | } | |
2fc8ea24 | 1389 | snprintf(p, end-p, "\n"); |
11f18faf MN |
1390 | p++; |
1391 | } | |
390f9f31 LM |
1392 | } else |
1393 | avctx->stats_out[0] = '\0'; | |
09b0499f | 1394 | if(!(s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)){ |
152ba68c | 1395 | flush_put_bits(&s->pb); |
3d2e8cce | 1396 | s->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size); |
11f18faf | 1397 | } |
115329f1 | 1398 | |
11f18faf | 1399 | s->picture_number++; |
1e491e29 | 1400 | |
11f18faf MN |
1401 | return size*4; |
1402 | } | |
1403 | ||
98a6fff9 | 1404 | static av_cold int encode_end(AVCodecContext *avctx) |
11f18faf | 1405 | { |
0ecca7a4 | 1406 | HYuvContext *s = avctx->priv_data; |
115329f1 | 1407 | |
0ecca7a4 | 1408 | common_end(s); |
11f18faf MN |
1409 | |
1410 | av_freep(&avctx->extradata); | |
1411 | av_freep(&avctx->stats_out); | |
115329f1 | 1412 | |
11f18faf MN |
1413 | return 0; |
1414 | } | |
b250f9c6 | 1415 | #endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */ |
11f18faf | 1416 | |
b250f9c6 | 1417 | #if CONFIG_HUFFYUV_DECODER |
11f18faf MN |
1418 | AVCodec huffyuv_decoder = { |
1419 | "huffyuv", | |
72415b2a | 1420 | AVMEDIA_TYPE_VIDEO, |
11f18faf MN |
1421 | CODEC_ID_HUFFYUV, |
1422 | sizeof(HYuvContext), | |
1423 | decode_init, | |
1424 | NULL, | |
1425 | decode_end, | |
1426 | decode_frame, | |
7c5ab7b8 | 1427 | CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND, |
bcdb2378 | 1428 | NULL, |
fe4bf374 | 1429 | .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), |
11f18faf | 1430 | }; |
2a43a093 | 1431 | #endif |
11f18faf | 1432 | |
b250f9c6 | 1433 | #if CONFIG_FFVHUFF_DECODER |
f37b9768 LM |
1434 | AVCodec ffvhuff_decoder = { |
1435 | "ffvhuff", | |
72415b2a | 1436 | AVMEDIA_TYPE_VIDEO, |
f37b9768 LM |
1437 | CODEC_ID_FFVHUFF, |
1438 | sizeof(HYuvContext), | |
1439 | decode_init, | |
1440 | NULL, | |
1441 | decode_end, | |
1442 | decode_frame, | |
1443 | CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND, | |
bcdb2378 | 1444 | NULL, |
fe4bf374 | 1445 | .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"), |
f37b9768 | 1446 | }; |
62bb489b | 1447 | #endif |
f37b9768 | 1448 | |
b250f9c6 | 1449 | #if CONFIG_HUFFYUV_ENCODER |
11f18faf MN |
1450 | AVCodec huffyuv_encoder = { |
1451 | "huffyuv", | |
72415b2a | 1452 | AVMEDIA_TYPE_VIDEO, |
11f18faf MN |
1453 | CODEC_ID_HUFFYUV, |
1454 | sizeof(HYuvContext), | |
1455 | encode_init, | |
1456 | encode_frame, | |
1457 | encode_end, | |
2ba83017 | 1458 | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_RGB32, PIX_FMT_NONE}, |
fe4bf374 | 1459 | .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"), |
11f18faf | 1460 | }; |
f544a5fc | 1461 | #endif |
5fd74135 | 1462 | |
b250f9c6 | 1463 | #if CONFIG_FFVHUFF_ENCODER |
f37b9768 LM |
1464 | AVCodec ffvhuff_encoder = { |
1465 | "ffvhuff", | |
72415b2a | 1466 | AVMEDIA_TYPE_VIDEO, |
f37b9768 LM |
1467 | CODEC_ID_FFVHUFF, |
1468 | sizeof(HYuvContext), | |
1469 | encode_init, | |
1470 | encode_frame, | |
1471 | encode_end, | |
2ba83017 | 1472 | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_RGB32, PIX_FMT_NONE}, |
fe4bf374 | 1473 | .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"), |
f37b9768 | 1474 | }; |
f544a5fc | 1475 | #endif |