utvideodec: Support for gradient prediction
[libav.git] / libavcodec / utvideodec.c
1 /*
2 * Ut Video decoder
3 * Copyright (c) 2011 Konstantin Shishkov
4 *
5 * This file is part of Libav.
6 *
7 * Libav is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * Libav is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * Ut Video decoder
25 */
26
27 #include <inttypes.h>
28 #include <stdlib.h>
29
30 #include "libavutil/intreadwrite.h"
31
32 #include "avcodec.h"
33 #include "bitstream.h"
34 #include "bswapdsp.h"
35 #include "bytestream.h"
36 #include "internal.h"
37 #include "thread.h"
38 #include "utvideo.h"
39
40 static int build_huff10(const uint8_t *src, VLC *vlc, int *fsym)
41 {
42 int i;
43 HuffEntry he[1024];
44 int last;
45 uint32_t codes[1024];
46 uint8_t bits[1024];
47 uint16_t syms[1024];
48 uint32_t code;
49
50 *fsym = -1;
51 for (i = 0; i < 1024; i++) {
52 he[i].sym = i;
53 he[i].len = *src++;
54 }
55 qsort(he, 1024, sizeof(*he), ff_ut10_huff_cmp_len);
56
57 if (!he[0].len) {
58 *fsym = he[0].sym;
59 return 0;
60 }
61
62 last = 1023;
63 while (he[last].len == 255 && last)
64 last--;
65
66 if (he[last].len > 32) {
67 return -1;
68 }
69
70 code = 1;
71 for (i = last; i >= 0; i--) {
72 codes[i] = code >> (32 - he[i].len);
73 bits[i] = he[i].len;
74 syms[i] = he[i].sym;
75 code += 0x80000000u >> (he[i].len - 1);
76 }
77
78 return ff_init_vlc_sparse(vlc, FFMIN(he[last].len, 11), last + 1,
79 bits, sizeof(*bits), sizeof(*bits),
80 codes, sizeof(*codes), sizeof(*codes),
81 syms, sizeof(*syms), sizeof(*syms), 0);
82 }
83
84 static int build_huff(const uint8_t *src, VLC *vlc, int *fsym)
85 {
86 int i;
87 HuffEntry he[256];
88 int last;
89 uint32_t codes[256];
90 uint8_t bits[256];
91 uint8_t syms[256];
92 uint32_t code;
93
94 *fsym = -1;
95 for (i = 0; i < 256; i++) {
96 he[i].sym = i;
97 he[i].len = *src++;
98 }
99 qsort(he, 256, sizeof(*he), ff_ut_huff_cmp_len);
100
101 if (!he[0].len) {
102 *fsym = he[0].sym;
103 return 0;
104 }
105 if (he[0].len > 32)
106 return -1;
107
108 last = 255;
109 while (he[last].len == 255 && last)
110 last--;
111
112 code = 1;
113 for (i = last; i >= 0; i--) {
114 codes[i] = code >> (32 - he[i].len);
115 bits[i] = he[i].len;
116 syms[i] = he[i].sym;
117 code += 0x80000000u >> (he[i].len - 1);
118 }
119
120 return ff_init_vlc_sparse(vlc, FFMIN(he[last].len, 9), last + 1,
121 bits, sizeof(*bits), sizeof(*bits),
122 codes, sizeof(*codes), sizeof(*codes),
123 syms, sizeof(*syms), sizeof(*syms), 0);
124 }
125
126 static int decode_plane10(UtvideoContext *c, int plane_no,
127 uint16_t *dst, int step, int stride,
128 int width, int height,
129 const uint8_t *src, const uint8_t *huff,
130 int use_pred)
131 {
132 BitstreamContext bc;
133 int i, j, slice, pix, ret;
134 int sstart, send;
135 VLC vlc;
136 int prev, fsym;
137
138 if ((ret = build_huff10(huff, &vlc, &fsym)) < 0) {
139 av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
140 return ret;
141 }
142 if (fsym >= 0) { // build_huff reported a symbol to fill slices with
143 send = 0;
144 for (slice = 0; slice < c->slices; slice++) {
145 uint16_t *dest;
146
147 sstart = send;
148 send = (height * (slice + 1) / c->slices);
149 dest = dst + sstart * stride;
150
151 prev = 0x200;
152 for (j = sstart; j < send; j++) {
153 for (i = 0; i < width * step; i += step) {
154 pix = fsym;
155 if (use_pred) {
156 prev += pix;
157 prev &= 0x3FF;
158 pix = prev;
159 }
160 dest[i] = pix;
161 }
162 dest += stride;
163 }
164 }
165 return 0;
166 }
167
168 send = 0;
169 for (slice = 0; slice < c->slices; slice++) {
170 uint16_t *dest;
171 int slice_data_start, slice_data_end, slice_size;
172
173 sstart = send;
174 send = (height * (slice + 1) / c->slices);
175 dest = dst + sstart * stride;
176
177 // slice offset and size validation was done earlier
178 slice_data_start = slice ? AV_RL32(src + slice * 4 - 4) : 0;
179 slice_data_end = AV_RL32(src + slice * 4);
180 slice_size = slice_data_end - slice_data_start;
181
182 if (!slice_size) {
183 av_log(c->avctx, AV_LOG_ERROR, "Plane has more than one symbol "
184 "yet a slice has a length of zero.\n");
185 goto fail;
186 }
187
188 memcpy(c->slice_bits, src + slice_data_start + c->slices * 4,
189 slice_size);
190 memset(c->slice_bits + slice_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
191 c->bdsp.bswap_buf((uint32_t *) c->slice_bits,
192 (uint32_t *) c->slice_bits,
193 (slice_data_end - slice_data_start + 3) >> 2);
194 bitstream_init8(&bc, c->slice_bits, slice_size);
195
196 prev = 0x200;
197 for (j = sstart; j < send; j++) {
198 for (i = 0; i < width * step; i += step) {
199 if (bitstream_bits_left(&bc) <= 0) {
200 av_log(c->avctx, AV_LOG_ERROR,
201 "Slice decoding ran out of bits\n");
202 goto fail;
203 }
204 pix = bitstream_read_vlc(&bc, vlc.table, vlc.bits, 3);
205 if (pix < 0) {
206 av_log(c->avctx, AV_LOG_ERROR, "Decoding error\n");
207 goto fail;
208 }
209 if (use_pred) {
210 prev += pix;
211 prev &= 0x3FF;
212 pix = prev;
213 }
214 dest[i] = pix;
215 }
216 dest += stride;
217 }
218 if (bitstream_bits_left(&bc) > 32)
219 av_log(c->avctx, AV_LOG_WARNING,
220 "%d bits left after decoding slice\n", bitstream_bits_left(&bc));
221 }
222
223 ff_free_vlc(&vlc);
224
225 return 0;
226 fail:
227 ff_free_vlc(&vlc);
228 return AVERROR_INVALIDDATA;
229 }
230
231 static int decode_plane(UtvideoContext *c, int plane_no,
232 uint8_t *dst, int step, ptrdiff_t stride,
233 int width, int height,
234 const uint8_t *src, int use_pred)
235 {
236 int i, j, slice, pix;
237 int sstart, send;
238 VLC vlc;
239 BitstreamContext bc;
240 int prev, fsym;
241 const int cmask = ~(!plane_no && c->avctx->pix_fmt == AV_PIX_FMT_YUV420P);
242
243 if (build_huff(src, &vlc, &fsym)) {
244 av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
245 return AVERROR_INVALIDDATA;
246 }
247 if (fsym >= 0) { // build_huff reported a symbol to fill slices with
248 send = 0;
249 for (slice = 0; slice < c->slices; slice++) {
250 uint8_t *dest;
251
252 sstart = send;
253 send = (height * (slice + 1) / c->slices) & cmask;
254 dest = dst + sstart * stride;
255
256 prev = 0x80;
257 for (j = sstart; j < send; j++) {
258 for (i = 0; i < width * step; i += step) {
259 pix = fsym;
260 if (use_pred) {
261 prev += pix;
262 pix = prev;
263 }
264 dest[i] = pix;
265 }
266 dest += stride;
267 }
268 }
269 return 0;
270 }
271
272 src += 256;
273
274 send = 0;
275 for (slice = 0; slice < c->slices; slice++) {
276 uint8_t *dest;
277 int slice_data_start, slice_data_end, slice_size;
278
279 sstart = send;
280 send = (height * (slice + 1) / c->slices) & cmask;
281 dest = dst + sstart * stride;
282
283 // slice offset and size validation was done earlier
284 slice_data_start = slice ? AV_RL32(src + slice * 4 - 4) : 0;
285 slice_data_end = AV_RL32(src + slice * 4);
286 slice_size = slice_data_end - slice_data_start;
287
288 if (!slice_size) {
289 av_log(c->avctx, AV_LOG_ERROR, "Plane has more than one symbol "
290 "yet a slice has a length of zero.\n");
291 goto fail;
292 }
293
294 memcpy(c->slice_bits, src + slice_data_start + c->slices * 4,
295 slice_size);
296 memset(c->slice_bits + slice_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
297 c->bdsp.bswap_buf((uint32_t *) c->slice_bits,
298 (uint32_t *) c->slice_bits,
299 (slice_data_end - slice_data_start + 3) >> 2);
300 bitstream_init8(&bc, c->slice_bits, slice_size);
301
302 prev = 0x80;
303 for (j = sstart; j < send; j++) {
304 for (i = 0; i < width * step; i += step) {
305 if (bitstream_bits_left(&bc) <= 0) {
306 av_log(c->avctx, AV_LOG_ERROR,
307 "Slice decoding ran out of bits\n");
308 goto fail;
309 }
310 pix = bitstream_read_vlc(&bc, vlc.table, vlc.bits, 4);
311 if (pix < 0) {
312 av_log(c->avctx, AV_LOG_ERROR, "Decoding error\n");
313 goto fail;
314 }
315 if (use_pred) {
316 prev += pix;
317 pix = prev;
318 }
319 dest[i] = pix;
320 }
321 dest += stride;
322 }
323 if (bitstream_bits_left(&bc) > 32)
324 av_log(c->avctx, AV_LOG_WARNING,
325 "%d bits left after decoding slice\n", bitstream_bits_left(&bc));
326 }
327
328 ff_free_vlc(&vlc);
329
330 return 0;
331 fail:
332 ff_free_vlc(&vlc);
333 return AVERROR_INVALIDDATA;
334 }
335
336 static void restore_rgb_planes(uint8_t *src, int step, ptrdiff_t stride,
337 int width, int height)
338 {
339 int i, j;
340 uint8_t r, g, b;
341
342 for (j = 0; j < height; j++) {
343 for (i = 0; i < width * step; i += step) {
344 r = src[i];
345 g = src[i + 1];
346 b = src[i + 2];
347 src[i] = r + g - 0x80;
348 src[i + 2] = b + g - 0x80;
349 }
350 src += stride;
351 }
352 }
353
354 static void restore_rgb_planes10(AVFrame *frame, int width, int height)
355 {
356 uint16_t *src_r = (uint16_t *)frame->data[2];
357 uint16_t *src_g = (uint16_t *)frame->data[0];
358 uint16_t *src_b = (uint16_t *)frame->data[1];
359 int r, g, b;
360 int i, j;
361
362 for (j = 0; j < height; j++) {
363 for (i = 0; i < width; i++) {
364 r = src_r[i];
365 g = src_g[i];
366 b = src_b[i];
367 src_r[i] = (r + g - 0x200) & 0x3FF;
368 src_b[i] = (b + g - 0x200) & 0x3FF;
369 }
370 src_r += frame->linesize[2] / 2;
371 src_g += frame->linesize[0] / 2;
372 src_b += frame->linesize[1] / 2;
373 }
374 }
375
376 static void restore_median_planar(UtvideoContext *c, uint8_t *src,
377 ptrdiff_t stride, int width, int height,
378 int slices, int rmode)
379 {
380 int i, j, slice;
381 int A, B, C;
382 uint8_t *bsrc;
383 int slice_start, slice_height;
384 const int cmask = ~rmode;
385
386 for (slice = 0; slice < slices; slice++) {
387 slice_start = ((slice * height) / slices) & cmask;
388 slice_height = ((((slice + 1) * height) / slices) & cmask) -
389 slice_start;
390
391 if (!slice_height)
392 continue;
393 bsrc = src + slice_start * stride;
394
395 // first line - left neighbour prediction
396 bsrc[0] += 0x80;
397 c->hdspdec.add_hfyu_left_pred(bsrc, bsrc, width, 0);
398 bsrc += stride;
399 if (slice_height <= 1)
400 continue;
401 // second line - first element has top prediction, the rest uses median
402 C = bsrc[-stride];
403 bsrc[0] += C;
404 A = bsrc[0];
405 for (i = 1; i < width; i++) {
406 B = bsrc[i - stride];
407 bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
408 C = B;
409 A = bsrc[i];
410 }
411 bsrc += stride;
412 // the rest of lines use continuous median prediction
413 for (j = 2; j < slice_height; j++) {
414 c->hdspdec.add_hfyu_median_pred(bsrc, bsrc - stride,
415 bsrc, width, &A, &B);
416 bsrc += stride;
417 }
418 }
419 }
420
421 /* UtVideo interlaced mode treats every two lines as a single one,
422 * so restoring function should take care of possible padding between
423 * two parts of the same "line".
424 */
425 static void restore_median_planar_il(UtvideoContext *c, uint8_t *src,
426 ptrdiff_t stride, int width, int height,
427 int slices, int rmode)
428 {
429 int i, j, slice;
430 int A, B, C;
431 uint8_t *bsrc;
432 int slice_start, slice_height;
433 const int cmask = ~(rmode ? 3 : 1);
434 const int stride2 = stride << 1;
435
436 for (slice = 0; slice < slices; slice++) {
437 slice_start = ((slice * height) / slices) & cmask;
438 slice_height = ((((slice + 1) * height) / slices) & cmask) -
439 slice_start;
440 slice_height >>= 1;
441 if (!slice_height)
442 continue;
443
444 bsrc = src + slice_start * stride;
445
446 // first line - left neighbour prediction
447 bsrc[0] += 0x80;
448 A = c->hdspdec.add_hfyu_left_pred(bsrc, bsrc, width, 0);
449 c->hdspdec.add_hfyu_left_pred(bsrc + stride, bsrc + stride, width, A);
450 bsrc += stride2;
451 if (slice_height <= 1)
452 continue;
453 // second line - first element has top prediction, the rest uses median
454 C = bsrc[-stride2];
455 bsrc[0] += C;
456 A = bsrc[0];
457 for (i = 1; i < width; i++) {
458 B = bsrc[i - stride2];
459 bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
460 C = B;
461 A = bsrc[i];
462 }
463 c->hdspdec.add_hfyu_median_pred(bsrc + stride, bsrc - stride,
464 bsrc + stride, width, &A, &B);
465 bsrc += stride2;
466 // the rest of lines use continuous median prediction
467 for (j = 2; j < slice_height; j++) {
468 c->hdspdec.add_hfyu_median_pred(bsrc, bsrc - stride2,
469 bsrc, width, &A, &B);
470 c->hdspdec.add_hfyu_median_pred(bsrc + stride, bsrc - stride,
471 bsrc + stride, width, &A, &B);
472 bsrc += stride2;
473 }
474 }
475 }
476
477 static void restore_median_packed(uint8_t *src, int step, ptrdiff_t stride,
478 int width, int height,
479 int slices, int rmode)
480 {
481 int i, j, slice;
482 int A, B, C;
483 uint8_t *bsrc;
484 int slice_start, slice_height;
485 const int cmask = ~rmode;
486
487 for (slice = 0; slice < slices; slice++) {
488 slice_start = ((slice * height) / slices) & cmask;
489 slice_height = ((((slice + 1) * height) / slices) & cmask) -
490 slice_start;
491 if (!slice_height)
492 continue;
493
494 bsrc = src + slice_start * stride;
495
496 // first line - left neighbour prediction
497 bsrc[0] += 0x80;
498 A = bsrc[0];
499 for (i = step; i < width * step; i += step) {
500 bsrc[i] += A;
501 A = bsrc[i];
502 }
503 bsrc += stride;
504 if (slice_height == 1)
505 continue;
506 // second line - first element has top prediction, the rest uses median
507 C = bsrc[-stride];
508 bsrc[0] += C;
509 A = bsrc[0];
510 for (i = step; i < width * step; i += step) {
511 B = bsrc[i - stride];
512 bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
513 C = B;
514 A = bsrc[i];
515 }
516 bsrc += stride;
517 // the rest of lines use continuous median prediction
518 for (j = 2; j < slice_height; j++) {
519 for (i = 0; i < width * step; i += step) {
520 B = bsrc[i - stride];
521 bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
522 C = B;
523 A = bsrc[i];
524 }
525 bsrc += stride;
526 }
527 }
528 }
529
530 /* UtVideo interlaced mode treats every two lines as a single one,
531 * so restoring function should take care of possible padding between
532 * two parts of the same "line".
533 */
534 static void restore_median_packed_il(uint8_t *src, int step, ptrdiff_t stride,
535 int width, int height,
536 int slices, int rmode)
537 {
538 int i, j, slice;
539 int A, B, C;
540 uint8_t *bsrc;
541 int slice_start, slice_height;
542 const int cmask = ~(rmode ? 3 : 1);
543 const ptrdiff_t stride2 = stride << 1;
544
545 for (slice = 0; slice < slices; slice++) {
546 slice_start = ((slice * height) / slices) & cmask;
547 slice_height = ((((slice + 1) * height) / slices) & cmask) -
548 slice_start;
549 slice_height >>= 1;
550 if (!slice_height)
551 continue;
552
553 bsrc = src + slice_start * stride;
554
555 // first line - left neighbour prediction
556 bsrc[0] += 0x80;
557 A = bsrc[0];
558 for (i = step; i < width * step; i += step) {
559 bsrc[i] += A;
560 A = bsrc[i];
561 }
562 for (i = 0; i < width * step; i += step) {
563 bsrc[stride + i] += A;
564 A = bsrc[stride + i];
565 }
566 bsrc += stride2;
567 if (slice_height == 1)
568 continue;
569 // second line - first element has top prediction, the rest uses median
570 C = bsrc[-stride2];
571 bsrc[0] += C;
572 A = bsrc[0];
573 for (i = step; i < width * step; i += step) {
574 B = bsrc[i - stride2];
575 bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
576 C = B;
577 A = bsrc[i];
578 }
579 for (i = 0; i < width * step; i += step) {
580 B = bsrc[i - stride];
581 bsrc[stride + i] += mid_pred(A, B, (uint8_t)(A + B - C));
582 C = B;
583 A = bsrc[stride + i];
584 }
585 bsrc += stride2;
586 // the rest of lines use continuous median prediction
587 for (j = 2; j < slice_height; j++) {
588 for (i = 0; i < width * step; i += step) {
589 B = bsrc[i - stride2];
590 bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
591 C = B;
592 A = bsrc[i];
593 }
594 for (i = 0; i < width * step; i += step) {
595 B = bsrc[i - stride];
596 bsrc[i + stride] += mid_pred(A, B, (uint8_t)(A + B - C));
597 C = B;
598 A = bsrc[i + stride];
599 }
600 bsrc += stride2;
601 }
602 }
603 }
604
605 static void restore_gradient_planar(UtvideoContext *c, uint8_t *src, ptrdiff_t stride,
606 int width, int height, int slices, int rmode)
607 {
608 int i, j, slice;
609 int A, B, C;
610 uint8_t *bsrc;
611 int slice_start, slice_height;
612 const int cmask = ~rmode;
613
614 for (slice = 0; slice < slices; slice++) {
615 slice_start = ((slice * height) / slices) & cmask;
616 slice_height = ((((slice + 1) * height) / slices) & cmask) -
617 slice_start;
618
619 if (!slice_height)
620 continue;
621 bsrc = src + slice_start * stride;
622
623 // first line - left neighbour prediction
624 bsrc[0] += 0x80;
625 c->hdspdec.add_hfyu_left_pred(bsrc, bsrc, width, 0);
626 bsrc += stride;
627 if (slice_height <= 1)
628 continue;
629 for (j = 1; j < slice_height; j++) {
630 // second line - first element has top prediction, the rest uses gradient
631 bsrc[0] = (bsrc[0] + bsrc[-stride]) & 0xFF;
632 for (i = 1; i < width; i++) {
633 A = bsrc[i - stride];
634 B = bsrc[i - (stride + 1)];
635 C = bsrc[i - 1];
636 bsrc[i] = (A - B + C + bsrc[i]) & 0xFF;
637 }
638 bsrc += stride;
639 }
640 }
641 }
642
643 static void restore_gradient_planar_il(UtvideoContext *c, uint8_t *src, ptrdiff_t stride,
644 int width, int height, int slices, int rmode)
645 {
646 int i, j, slice;
647 int A, B, C;
648 uint8_t *bsrc;
649 int slice_start, slice_height;
650 const int cmask = ~(rmode ? 3 : 1);
651 const ptrdiff_t stride2 = stride << 1;
652
653 for (slice = 0; slice < slices; slice++) {
654 slice_start = ((slice * height) / slices) & cmask;
655 slice_height = ((((slice + 1) * height) / slices) & cmask) -
656 slice_start;
657 slice_height >>= 1;
658 if (!slice_height)
659 continue;
660
661 bsrc = src + slice_start * stride;
662
663 // first line - left neighbour prediction
664 bsrc[0] += 0x80;
665 A = c->hdspdec.add_hfyu_left_pred(bsrc, bsrc, width, 0);
666 c->hdspdec.add_hfyu_left_pred(bsrc + stride, bsrc + stride, width, A);
667 bsrc += stride2;
668 if (slice_height <= 1)
669 continue;
670 for (j = 1; j < slice_height; j++) {
671 // second line - first element has top prediction, the rest uses gradient
672 bsrc[0] = (bsrc[0] + bsrc[-stride2]) & 0xFF;
673 for (i = 1; i < width; i++) {
674 A = bsrc[i - stride2];
675 B = bsrc[i - (stride2 + 1)];
676 C = bsrc[i - 1];
677 bsrc[i] = (A - B + C + bsrc[i]) & 0xFF;
678 }
679 for (i = 0; i < width; i++) {
680 A = bsrc[i - stride];
681 B = bsrc[i - (1 + stride)];
682 C = bsrc[i - 1 + stride];
683 bsrc[i + stride] = (A - B + C + bsrc[i + stride]) & 0xFF;
684 }
685 bsrc += stride2;
686 }
687 }
688 }
689
690 static void restore_gradient_packed(uint8_t *src, int step, ptrdiff_t stride,
691 int width, int height, int slices, int rmode)
692 {
693 int i, j, slice;
694 int A, B, C;
695 uint8_t *bsrc;
696 int slice_start, slice_height;
697 const int cmask = ~rmode;
698
699 for (slice = 0; slice < slices; slice++) {
700 slice_start = ((slice * height) / slices) & cmask;
701 slice_height = ((((slice + 1) * height) / slices) & cmask) -
702 slice_start;
703
704 if (!slice_height)
705 continue;
706 bsrc = src + slice_start * stride;
707
708 // first line - left neighbour prediction
709 bsrc[0] += 0x80;
710 A = bsrc[0];
711 for (i = step; i < width * step; i += step) {
712 bsrc[i] += A;
713 A = bsrc[i];
714 }
715 bsrc += stride;
716 if (slice_height <= 1)
717 continue;
718 for (j = 1; j < slice_height; j++) {
719 // second line - first element has top prediction, the rest uses gradient
720 C = bsrc[-stride];
721 bsrc[0] += C;
722 for (i = step; i < width * step; i += step) {
723 A = bsrc[i - stride];
724 B = bsrc[i - (stride + step)];
725 C = bsrc[i - step];
726 bsrc[i] = (A - B + C + bsrc[i]) & 0xFF;
727 }
728 bsrc += stride;
729 }
730 }
731 }
732
733 static void restore_gradient_packed_il(uint8_t *src, int step, ptrdiff_t stride,
734 int width, int height, int slices, int rmode)
735 {
736 int i, j, slice;
737 int A, B, C;
738 uint8_t *bsrc;
739 int slice_start, slice_height;
740 const int cmask = ~(rmode ? 3 : 1);
741 const ptrdiff_t stride2 = stride << 1;
742
743 for (slice = 0; slice < slices; slice++) {
744 slice_start = ((slice * height) / slices) & cmask;
745 slice_height = ((((slice + 1) * height) / slices) & cmask) -
746 slice_start;
747 slice_height >>= 1;
748 if (!slice_height)
749 continue;
750
751 bsrc = src + slice_start * stride;
752
753 // first line - left neighbour prediction
754 bsrc[0] += 0x80;
755 A = bsrc[0];
756 for (i = step; i < width * step; i += step) {
757 bsrc[i] += A;
758 A = bsrc[i];
759 }
760 for (i = 0; i < width * step; i += step) {
761 bsrc[stride + i] += A;
762 A = bsrc[stride + i];
763 }
764 bsrc += stride2;
765 if (slice_height <= 1)
766 continue;
767 for (j = 1; j < slice_height; j++) {
768 // second line - first element has top prediction, the rest uses gradient
769 C = bsrc[-stride2];
770 bsrc[0] += C;
771 for (i = step; i < width * step; i += step) {
772 A = bsrc[i - stride2];
773 B = bsrc[i - (stride2 + step)];
774 C = bsrc[i - step];
775 bsrc[i] = (A - B + C + bsrc[i]) & 0xFF;
776 }
777 for (i = 0; i < width * step; i += step) {
778 A = bsrc[i - stride];
779 B = bsrc[i - (step + stride)];
780 C = bsrc[i - step + stride];
781 bsrc[i + stride] = (A - B + C + bsrc[i + stride]) & 0xFF;
782 }
783 bsrc += stride2;
784 }
785 }
786 }
787
788 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
789 AVPacket *avpkt)
790 {
791 const uint8_t *buf = avpkt->data;
792 int buf_size = avpkt->size;
793 UtvideoContext *c = avctx->priv_data;
794 int i, j;
795 const uint8_t *plane_start[5];
796 int plane_size, max_slice_size = 0, slice_start, slice_end, slice_size;
797 int ret;
798 GetByteContext gb;
799 ThreadFrame frame = { .f = data };
800
801 if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) {
802 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
803 return ret;
804 }
805
806 ff_thread_finish_setup(avctx);
807
808 /* parse plane structure to get frame flags and validate slice offsets */
809 bytestream2_init(&gb, buf, buf_size);
810 if (c->pro) {
811 if (bytestream2_get_bytes_left(&gb) < c->frame_info_size) {
812 av_log(avctx, AV_LOG_ERROR, "Not enough data for frame information\n");
813 return AVERROR_INVALIDDATA;
814 }
815 c->frame_info = bytestream2_get_le32u(&gb);
816 c->slices = ((c->frame_info >> 16) & 0xff) + 1;
817 for (i = 0; i < c->planes; i++) {
818 plane_start[i] = gb.buffer;
819 if (bytestream2_get_bytes_left(&gb) < 1024 + 4 * c->slices) {
820 av_log(avctx, AV_LOG_ERROR, "Insufficient data for a plane\n");
821 return AVERROR_INVALIDDATA;
822 }
823 slice_start = 0;
824 slice_end = 0;
825 for (j = 0; j < c->slices; j++) {
826 slice_end = bytestream2_get_le32u(&gb);
827 if (slice_end < 0 || slice_end < slice_start ||
828 bytestream2_get_bytes_left(&gb) < slice_end) {
829 av_log(avctx, AV_LOG_ERROR, "Incorrect slice size\n");
830 return AVERROR_INVALIDDATA;
831 }
832 slice_size = slice_end - slice_start;
833 slice_start = slice_end;
834 max_slice_size = FFMAX(max_slice_size, slice_size);
835 }
836 plane_size = slice_end;
837 bytestream2_skipu(&gb, plane_size);
838 bytestream2_skipu(&gb, 1024);
839 }
840 plane_start[c->planes] = gb.buffer;
841 } else {
842 for (i = 0; i < c->planes; i++) {
843 plane_start[i] = gb.buffer;
844 if (bytestream2_get_bytes_left(&gb) < 256 + 4 * c->slices) {
845 av_log(avctx, AV_LOG_ERROR, "Insufficient data for a plane\n");
846 return AVERROR_INVALIDDATA;
847 }
848 bytestream2_skipu(&gb, 256);
849 slice_start = 0;
850 slice_end = 0;
851 for (j = 0; j < c->slices; j++) {
852 slice_end = bytestream2_get_le32u(&gb);
853 if (slice_end < 0 || slice_end < slice_start ||
854 bytestream2_get_bytes_left(&gb) < slice_end) {
855 av_log(avctx, AV_LOG_ERROR, "Incorrect slice size\n");
856 return AVERROR_INVALIDDATA;
857 }
858 slice_size = slice_end - slice_start;
859 slice_start = slice_end;
860 max_slice_size = FFMAX(max_slice_size, slice_size);
861 }
862 plane_size = slice_end;
863 bytestream2_skipu(&gb, plane_size);
864 }
865 plane_start[c->planes] = gb.buffer;
866 if (bytestream2_get_bytes_left(&gb) < c->frame_info_size) {
867 av_log(avctx, AV_LOG_ERROR, "Not enough data for frame information\n");
868 return AVERROR_INVALIDDATA;
869 }
870 c->frame_info = bytestream2_get_le32u(&gb);
871 }
872 av_log(avctx, AV_LOG_DEBUG, "frame information flags %"PRIX32"\n",
873 c->frame_info);
874
875 c->frame_pred = (c->frame_info >> 8) & 3;
876
877 av_fast_malloc(&c->slice_bits, &c->slice_bits_size,
878 max_slice_size + AV_INPUT_BUFFER_PADDING_SIZE);
879
880 if (!c->slice_bits) {
881 av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
882 return AVERROR(ENOMEM);
883 }
884
885 switch (c->avctx->pix_fmt) {
886 case AV_PIX_FMT_RGB24:
887 case AV_PIX_FMT_RGBA:
888 for (i = 0; i < c->planes; i++) {
889 ret = decode_plane(c, i, frame.f->data[0] + ff_ut_rgb_order[i],
890 c->planes, frame.f->linesize[0], avctx->width,
891 avctx->height, plane_start[i],
892 c->frame_pred == PRED_LEFT);
893 if (ret)
894 return ret;
895 if (c->frame_pred == PRED_MEDIAN) {
896 if (!c->interlaced) {
897 restore_median_packed(frame.f->data[0] + ff_ut_rgb_order[i],
898 c->planes, frame.f->linesize[0], avctx->width,
899 avctx->height, c->slices, 0);
900 } else {
901 restore_median_packed_il(frame.f->data[0] + ff_ut_rgb_order[i],
902 c->planes, frame.f->linesize[0],
903 avctx->width, avctx->height, c->slices,
904 0);
905 }
906 } else if (c->frame_pred == PRED_GRADIENT) {
907 if (!c->interlaced) {
908 restore_gradient_packed(frame.f->data[0] + ff_ut_rgb_order[i],
909 c->planes, frame.f->linesize[0],
910 avctx->width, avctx->height,
911 c->slices, 0);
912 } else {
913 restore_gradient_packed_il(frame.f->data[0] + ff_ut_rgb_order[i],
914 c->planes, frame.f->linesize[0],
915 avctx->width, avctx->height,
916 c->slices, 0);
917 }
918 }
919 }
920 restore_rgb_planes(frame.f->data[0], c->planes, frame.f->linesize[0],
921 avctx->width, avctx->height);
922 break;
923 case AV_PIX_FMT_GBRAP10:
924 case AV_PIX_FMT_GBRP10:
925 for (i = 0; i < c->planes; i++) {
926 ret = decode_plane10(c, i, (uint16_t *)frame.f->data[i], 1,
927 frame.f->linesize[i] / 2, avctx->width,
928 avctx->height, plane_start[i],
929 plane_start[i + 1] - 1024,
930 c->frame_pred == PRED_LEFT);
931 if (ret)
932 return ret;
933 }
934 restore_rgb_planes10(frame.f, avctx->width, avctx->height);
935 break;
936 case AV_PIX_FMT_YUV420P:
937 for (i = 0; i < 3; i++) {
938 ret = decode_plane(c, i, frame.f->data[i], 1, frame.f->linesize[i],
939 avctx->width >> !!i, avctx->height >> !!i,
940 plane_start[i], c->frame_pred == PRED_LEFT);
941 if (ret)
942 return ret;
943 if (c->frame_pred == PRED_MEDIAN) {
944 if (!c->interlaced) {
945 restore_median_planar(c, frame.f->data[i], frame.f->linesize[i],
946 avctx->width >> !!i, avctx->height >> !!i,
947 c->slices, !i);
948 } else {
949 restore_median_planar_il(c, frame.f->data[i], frame.f->linesize[i],
950 avctx->width >> !!i,
951 avctx->height >> !!i,
952 c->slices, !i);
953 }
954 } else if (c->frame_pred == PRED_GRADIENT) {
955 if (!c->interlaced) {
956 restore_gradient_planar(c, frame.f->data[i], frame.f->linesize[i],
957 avctx->width >> !!i,
958 avctx->height >> !!i,
959 c->slices, !i);
960 } else {
961 restore_gradient_planar_il(c, frame.f->data[i], frame.f->linesize[i],
962 avctx->width >> !!i,
963 avctx->height >> !!i,
964 c->slices, !i);
965 }
966 }
967 }
968 break;
969 case AV_PIX_FMT_YUV422P:
970 for (i = 0; i < 3; i++) {
971 ret = decode_plane(c, i, frame.f->data[i], 1, frame.f->linesize[i],
972 avctx->width >> !!i, avctx->height,
973 plane_start[i], c->frame_pred == PRED_LEFT);
974 if (ret)
975 return ret;
976 if (c->frame_pred == PRED_MEDIAN) {
977 if (!c->interlaced) {
978 restore_median_planar(c, frame.f->data[i], frame.f->linesize[i],
979 avctx->width >> !!i, avctx->height,
980 c->slices, 0);
981 } else {
982 restore_median_planar_il(c, frame.f->data[i], frame.f->linesize[i],
983 avctx->width >> !!i, avctx->height,
984 c->slices, 0);
985 }
986 } else if (c->frame_pred == PRED_GRADIENT) {
987 if (!c->interlaced) {
988 restore_gradient_planar(c, frame.f->data[i], frame.f->linesize[i],
989 avctx->width >> !!i, avctx->height,
990 c->slices, 0);
991 } else {
992 restore_gradient_planar_il(c, frame.f->data[i], frame.f->linesize[i],
993 avctx->width >> !!i, avctx->height,
994 c->slices, 0);
995 }
996 }
997 }
998 break;
999 case AV_PIX_FMT_YUV444P:
1000 for (i = 0; i < 3; i++) {
1001 ret = decode_plane(c, i, frame.f->data[i], 1, frame.f->linesize[i],
1002 avctx->width, avctx->height,
1003 plane_start[i], c->frame_pred == PRED_LEFT);
1004 if (ret)
1005 return ret;
1006 if (c->frame_pred == PRED_MEDIAN) {
1007 if (!c->interlaced) {
1008 restore_median_planar(c, frame.f->data[i], frame.f->linesize[i],
1009 avctx->width, avctx->height,
1010 c->slices, 0);
1011 } else {
1012 restore_median_planar_il(c, frame.f->data[i], frame.f->linesize[i],
1013 avctx->width, avctx->height,
1014 c->slices, 0);
1015 }
1016 } else if (c->frame_pred == PRED_GRADIENT) {
1017 if (!c->interlaced) {
1018 restore_gradient_planar(c, frame.f->data[i], frame.f->linesize[i],
1019 avctx->width, avctx->height,
1020 c->slices, 0);
1021 } else {
1022 restore_gradient_planar_il(c, frame.f->data[i], frame.f->linesize[i],
1023 avctx->width, avctx->height,
1024 c->slices, 0);
1025 }
1026 }
1027 }
1028 break;
1029 case AV_PIX_FMT_YUV422P10:
1030 for (i = 0; i < 3; i++) {
1031 ret = decode_plane10(c, i, (uint16_t *)frame.f->data[i], 1, frame.f->linesize[i] / 2,
1032 avctx->width >> !!i, avctx->height,
1033 plane_start[i], plane_start[i + 1] - 1024, c->frame_pred == PRED_LEFT);
1034 if (ret)
1035 return ret;
1036 }
1037 break;
1038 }
1039
1040 frame.f->key_frame = 1;
1041 frame.f->pict_type = AV_PICTURE_TYPE_I;
1042 frame.f->interlaced_frame = !!c->interlaced;
1043
1044 *got_frame = 1;
1045
1046 /* always report that the buffer was completely consumed */
1047 return buf_size;
1048 }
1049
1050 static av_cold int decode_init(AVCodecContext *avctx)
1051 {
1052 UtvideoContext * const c = avctx->priv_data;
1053
1054 c->avctx = avctx;
1055
1056 ff_bswapdsp_init(&c->bdsp);
1057 ff_huffyuvdsp_init(&c->hdspdec);
1058
1059 if (avctx->extradata_size >= 16) {
1060 av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d.%d.%d\n",
1061 avctx->extradata[3], avctx->extradata[2],
1062 avctx->extradata[1], avctx->extradata[0]);
1063 av_log(avctx, AV_LOG_DEBUG, "Original format %"PRIX32"\n",
1064 AV_RB32(avctx->extradata + 4));
1065 c->frame_info_size = AV_RL32(avctx->extradata + 8);
1066 c->flags = AV_RL32(avctx->extradata + 12);
1067
1068 if (c->frame_info_size != 4)
1069 avpriv_request_sample(avctx, "Frame info not 4 bytes");
1070 av_log(avctx, AV_LOG_DEBUG, "Encoding parameters %08"PRIX32"\n", c->flags);
1071 c->slices = (c->flags >> 24) + 1;
1072 c->compression = c->flags & 1;
1073 c->interlaced = c->flags & 0x800;
1074 } else if (avctx->extradata_size == 8) {
1075 av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d.%d.%d\n",
1076 avctx->extradata[3], avctx->extradata[2],
1077 avctx->extradata[1], avctx->extradata[0]);
1078 av_log(avctx, AV_LOG_DEBUG, "Original format %"PRIX32"\n",
1079 AV_RB32(avctx->extradata + 4));
1080 c->interlaced = 0;
1081 c->pro = 1;
1082 c->frame_info_size = 4;
1083 } else {
1084 av_log(avctx, AV_LOG_ERROR,
1085 "Insufficient extradata size %d, should be at least 16\n",
1086 avctx->extradata_size);
1087 return AVERROR_INVALIDDATA;
1088 }
1089
1090 c->slice_bits_size = 0;
1091
1092 switch (avctx->codec_tag) {
1093 case MKTAG('U', 'L', 'R', 'G'):
1094 c->planes = 3;
1095 avctx->pix_fmt = AV_PIX_FMT_RGB24;
1096 break;
1097 case MKTAG('U', 'L', 'R', 'A'):
1098 c->planes = 4;
1099 avctx->pix_fmt = AV_PIX_FMT_RGBA;
1100 break;
1101 case MKTAG('U', 'L', 'Y', '0'):
1102 c->planes = 3;
1103 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
1104 avctx->colorspace = AVCOL_SPC_BT470BG;
1105 break;
1106 case MKTAG('U', 'L', 'Y', '2'):
1107 c->planes = 3;
1108 avctx->pix_fmt = AV_PIX_FMT_YUV422P;
1109 avctx->colorspace = AVCOL_SPC_BT470BG;
1110 break;
1111 case MKTAG('U', 'L', 'Y', '4'):
1112 c->planes = 3;
1113 avctx->pix_fmt = AV_PIX_FMT_YUV444P;
1114 avctx->colorspace = AVCOL_SPC_BT470BG;
1115 break;
1116 case MKTAG('U', 'Q', 'Y', '2'):
1117 c->planes = 3;
1118 avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
1119 break;
1120 case MKTAG('U', 'Q', 'R', 'G'):
1121 c->planes = 3;
1122 avctx->pix_fmt = AV_PIX_FMT_GBRP10;
1123 break;
1124 case MKTAG('U', 'Q', 'R', 'A'):
1125 c->planes = 4;
1126 avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
1127 break;
1128 case MKTAG('U', 'L', 'H', '0'):
1129 c->planes = 3;
1130 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
1131 avctx->colorspace = AVCOL_SPC_BT709;
1132 break;
1133 case MKTAG('U', 'L', 'H', '2'):
1134 c->planes = 3;
1135 avctx->pix_fmt = AV_PIX_FMT_YUV422P;
1136 avctx->colorspace = AVCOL_SPC_BT709;
1137 break;
1138 case MKTAG('U', 'L', 'H', '4'):
1139 c->planes = 3;
1140 avctx->pix_fmt = AV_PIX_FMT_YUV444P;
1141 avctx->colorspace = AVCOL_SPC_BT709;
1142 break;
1143 default:
1144 av_log(avctx, AV_LOG_ERROR, "Unknown Ut Video FOURCC provided (%08X)\n",
1145 avctx->codec_tag);
1146 return AVERROR_INVALIDDATA;
1147 }
1148
1149 return 0;
1150 }
1151
1152 static av_cold int decode_end(AVCodecContext *avctx)
1153 {
1154 UtvideoContext * const c = avctx->priv_data;
1155
1156 av_freep(&c->slice_bits);
1157
1158 return 0;
1159 }
1160
1161 AVCodec ff_utvideo_decoder = {
1162 .name = "utvideo",
1163 .long_name = NULL_IF_CONFIG_SMALL("Ut Video"),
1164 .type = AVMEDIA_TYPE_VIDEO,
1165 .id = AV_CODEC_ID_UTVIDEO,
1166 .priv_data_size = sizeof(UtvideoContext),
1167 .init = decode_init,
1168 .close = decode_end,
1169 .decode = decode_frame,
1170 .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
1171 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
1172 };