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 <stdlib.h> 28 29#include "libavutil/intreadwrite.h" 30#include "avcodec.h" 31#include "bytestream.h" 32#include "get_bits.h" 33#include "dsputil.h" 34#include "thread.h" 35 36enum { 37 PRED_NONE = 0, 38 PRED_LEFT, 39 PRED_GRADIENT, 40 PRED_MEDIAN, 41}; 42 43typedef struct UtvideoContext { 44 AVCodecContext *avctx; 45 AVFrame pic; 46 DSPContext dsp; 47 48 uint32_t frame_info_size, flags, frame_info; 49 int planes; 50 int slices; 51 int compression; 52 int interlaced; 53 int frame_pred; 54 55 uint8_t *slice_bits; 56 int slice_bits_size; 57} UtvideoContext; 58 59typedef struct HuffEntry { 60 uint8_t sym; 61 uint8_t len; 62} HuffEntry; 63 64static int huff_cmp(const void *a, const void *b) 65{ 66 const HuffEntry *aa = a, *bb = b; 67 return (aa->len - bb->len)*256 + aa->sym - bb->sym; 68} 69 70static int build_huff(const uint8_t *src, VLC *vlc, int *fsym) 71{ 72 int i; 73 HuffEntry he[256]; 74 int last; 75 uint32_t codes[256]; 76 uint8_t bits[256]; 77 uint8_t syms[256]; 78 uint32_t code; 79 80 *fsym = -1; 81 for (i = 0; i < 256; i++) { 82 he[i].sym = i; 83 he[i].len = *src++; 84 } 85 qsort(he, 256, sizeof(*he), huff_cmp); 86 87 if (!he[0].len) { 88 *fsym = he[0].sym; 89 return 0; 90 } 91 if (he[0].len > 32) 92 return -1; 93 94 last = 255; 95 while (he[last].len == 255 && last) 96 last--; 97 98 code = 1; 99 for (i = last; i >= 0; i--) { 100 codes[i] = code >> (32 - he[i].len); 101 bits[i] = he[i].len; 102 syms[i] = he[i].sym; 103 code += 0x80000000u >> (he[i].len - 1); 104 } 105 106 return ff_init_vlc_sparse(vlc, FFMIN(he[last].len, 9), last + 1, 107 bits, sizeof(*bits), sizeof(*bits), 108 codes, sizeof(*codes), sizeof(*codes), 109 syms, sizeof(*syms), sizeof(*syms), 0); 110} 111 112static int decode_plane(UtvideoContext *c, int plane_no, 113 uint8_t *dst, int step, int stride, 114 int width, int height, 115 const uint8_t *src, int src_size, int use_pred) 116{ 117 int i, j, slice, pix; 118 int sstart, send; 119 VLC vlc; 120 GetBitContext gb; 121 int prev, fsym; 122 const int cmask = ~(!plane_no && c->avctx->pix_fmt == PIX_FMT_YUV420P); 123 124 if (build_huff(src, &vlc, &fsym)) { 125 av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n"); 126 return AVERROR_INVALIDDATA; 127 } 128 if (fsym >= 0) { // build_huff reported a symbol to fill slices with 129 send = 0; 130 for (slice = 0; slice < c->slices; slice++) { 131 uint8_t *dest; 132 133 sstart = send; 134 send = (height * (slice + 1) / c->slices) & cmask; 135 dest = dst + sstart * stride; 136 137 prev = 0x80; 138 for (j = sstart; j < send; j++) { 139 for (i = 0; i < width * step; i += step) { 140 pix = fsym; 141 if (use_pred) { 142 prev += pix; 143 pix = prev; 144 } 145 dest[i] = pix; 146 } 147 dest += stride; 148 } 149 } 150 return 0; 151 } 152 153 src += 256; 154 src_size -= 256; 155 156 send = 0; 157 for (slice = 0; slice < c->slices; slice++) { 158 uint8_t *dest; 159 int slice_data_start, slice_data_end, slice_size; 160 161 sstart = send; 162 send = (height * (slice + 1) / c->slices) & cmask; 163 dest = dst + sstart * stride; 164 165 // slice offset and size validation was done earlier 166 slice_data_start = slice ? AV_RL32(src + slice * 4 - 4) : 0; 167 slice_data_end = AV_RL32(src + slice * 4); 168 slice_size = slice_data_end - slice_data_start; 169 170 if (!slice_size) { 171 for (j = sstart; j < send; j++) { 172 for (i = 0; i < width * step; i += step) 173 dest[i] = 0x80; 174 dest += stride; 175 } 176 continue; 177 } 178 179 memcpy(c->slice_bits, src + slice_data_start + c->slices * 4, slice_size); 180 memset(c->slice_bits + slice_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); 181 c->dsp.bswap_buf((uint32_t*)c->slice_bits, (uint32_t*)c->slice_bits, 182 (slice_data_end - slice_data_start + 3) >> 2); 183 init_get_bits(&gb, c->slice_bits, slice_size * 8); 184 185 prev = 0x80; 186 for (j = sstart; j < send; j++) { 187 for (i = 0; i < width * step; i += step) { 188 if (get_bits_left(&gb) <= 0) { 189 av_log(c->avctx, AV_LOG_ERROR, "Slice decoding ran out of bits\n"); 190 goto fail; 191 } 192 pix = get_vlc2(&gb, vlc.table, vlc.bits, 4); 193 if (pix < 0) { 194 av_log(c->avctx, AV_LOG_ERROR, "Decoding error\n"); 195 goto fail; 196 } 197 if (use_pred) { 198 prev += pix; 199 pix = prev; 200 } 201 dest[i] = pix; 202 } 203 dest += stride; 204 } 205 if (get_bits_left(&gb) > 32) 206 av_log(c->avctx, AV_LOG_WARNING, "%d bits left after decoding slice\n", 207 get_bits_left(&gb)); 208 } 209 210 ff_free_vlc(&vlc); 211 212 return 0; 213fail: 214 ff_free_vlc(&vlc); 215 return AVERROR_INVALIDDATA; 216} 217 218static const int rgb_order[4] = { 1, 2, 0, 3 }; 219 220static void restore_rgb_planes(uint8_t *src, int step, int stride, int width, int height) 221{ 222 int i, j; 223 uint8_t r, g, b; 224 225 for (j = 0; j < height; j++) { 226 for (i = 0; i < width * step; i += step) { 227 r = src[i]; 228 g = src[i + 1]; 229 b = src[i + 2]; 230 src[i] = r + g - 0x80; 231 src[i + 2] = b + g - 0x80; 232 } 233 src += stride; 234 } 235} 236 237static void restore_median(uint8_t *src, int step, int stride, 238 int width, int height, int slices, int rmode) 239{ 240 int i, j, slice; 241 int A, B, C; 242 uint8_t *bsrc; 243 int slice_start, slice_height; 244 const int cmask = ~rmode; 245 246 for (slice = 0; slice < slices; slice++) { 247 slice_start = ((slice * height) / slices) & cmask; 248 slice_height = ((((slice + 1) * height) / slices) & cmask) - slice_start; 249 250 bsrc = src + slice_start * stride; 251 252 // first line - left neighbour prediction 253 bsrc[0] += 0x80; 254 A = bsrc[0]; 255 for (i = step; i < width * step; i += step) { 256 bsrc[i] += A; 257 A = bsrc[i]; 258 } 259 bsrc += stride; 260 if (slice_height == 1) 261 continue; 262 // second line - first element has top predition, the rest uses median 263 C = bsrc[-stride]; 264 bsrc[0] += C; 265 A = bsrc[0]; 266 for (i = step; i < width * step; i += step) { 267 B = bsrc[i - stride]; 268 bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C)); 269 C = B; 270 A = bsrc[i]; 271 } 272 bsrc += stride; 273 // the rest of lines use continuous median prediction 274 for (j = 2; j < slice_height; j++) { 275 for (i = 0; i < width * step; i += step) { 276 B = bsrc[i - stride]; 277 bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C)); 278 C = B; 279 A = bsrc[i]; 280 } 281 bsrc += stride; 282 } 283 } 284} 285 286/* UtVideo interlaced mode treats every two lines as a single one, 287 * so restoring function should take care of possible padding between 288 * two parts of the same "line". 289 */ 290static void restore_median_il(uint8_t *src, int step, int stride, 291 int width, int height, int slices, int rmode) 292{ 293 int i, j, slice; 294 int A, B, C; 295 uint8_t *bsrc; 296 int slice_start, slice_height; 297 const int cmask = ~(rmode ? 3 : 1); 298 const int stride2 = stride << 1; 299 300 for (slice = 0; slice < slices; slice++) { 301 slice_start = ((slice * height) / slices) & cmask; 302 slice_height = ((((slice + 1) * height) / slices) & cmask) - slice_start; 303 slice_height >>= 1; 304 305 bsrc = src + slice_start * stride; 306 307 // first line - left neighbour prediction 308 bsrc[0] += 0x80; 309 A = bsrc[0]; 310 for (i = step; i < width * step; i += step) { 311 bsrc[i] += A; 312 A = bsrc[i]; 313 } 314 for (i = 0; i < width * step; i += step) { 315 bsrc[stride + i] += A; 316 A = bsrc[stride + i]; 317 } 318 bsrc += stride2; 319 if (slice_height == 1) 320 continue; 321 // second line - first element has top predition, the rest uses median 322 C = bsrc[-stride2]; 323 bsrc[0] += C; 324 A = bsrc[0]; 325 for (i = step; i < width * step; i += step) { 326 B = bsrc[i - stride2]; 327 bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C)); 328 C = B; 329 A = bsrc[i]; 330 } 331 for (i = 0; i < width * step; i += step) { 332 B = bsrc[i - stride]; 333 bsrc[stride + i] += mid_pred(A, B, (uint8_t)(A + B - C)); 334 C = B; 335 A = bsrc[stride + i]; 336 } 337 bsrc += stride2; 338 // the rest of lines use continuous median prediction 339 for (j = 2; j < slice_height; j++) { 340 for (i = 0; i < width * step; i += step) { 341 B = bsrc[i - stride2]; 342 bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C)); 343 C = B; 344 A = bsrc[i]; 345 } 346 for (i = 0; i < width * step; i += step) { 347 B = bsrc[i - stride]; 348 bsrc[i + stride] += mid_pred(A, B, (uint8_t)(A + B - C)); 349 C = B; 350 A = bsrc[i + stride]; 351 } 352 bsrc += stride2; 353 } 354 } 355} 356 357static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) 358{ 359 const uint8_t *buf = avpkt->data; 360 int buf_size = avpkt->size; 361 UtvideoContext *c = avctx->priv_data; 362 int i, j; 363 const uint8_t *plane_start[5]; 364 int plane_size, max_slice_size = 0, slice_start, slice_end, slice_size; 365 int ret; 366 GetByteContext gb; 367 368 if (c->pic.data[0]) 369 ff_thread_release_buffer(avctx, &c->pic); 370 371 c->pic.reference = 1; 372 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; 373 if ((ret = ff_thread_get_buffer(avctx, &c->pic)) < 0) { 374 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); 375 return ret; 376 } 377 378 ff_thread_finish_setup(avctx); 379 380 /* parse plane structure to retrieve frame flags and validate slice offsets */ 381 bytestream2_init(&gb, buf, buf_size); 382 for (i = 0; i < c->planes; i++) { 383 plane_start[i] = gb.buffer; 384 if (bytestream2_get_bytes_left(&gb) < 256 + 4 * c->slices) { 385 av_log(avctx, AV_LOG_ERROR, "Insufficient data for a plane\n"); 386 return AVERROR_INVALIDDATA; 387 } 388 bytestream2_skipu(&gb, 256); 389 slice_start = 0; 390 slice_end = 0; 391 for (j = 0; j < c->slices; j++) { 392 slice_end = bytestream2_get_le32u(&gb); 393 slice_size = slice_end - slice_start; 394 if (slice_end <= 0 || slice_size <= 0 || 395 bytestream2_get_bytes_left(&gb) < slice_end) { 396 av_log(avctx, AV_LOG_ERROR, "Incorrect slice size\n"); 397 return AVERROR_INVALIDDATA; 398 } 399 slice_start = slice_end; 400 max_slice_size = FFMAX(max_slice_size, slice_size); 401 } 402 plane_size = slice_end; 403 bytestream2_skipu(&gb, plane_size); 404 } 405 plane_start[c->planes] = gb.buffer; 406 if (bytestream2_get_bytes_left(&gb) < c->frame_info_size) { 407 av_log(avctx, AV_LOG_ERROR, "Not enough data for frame information\n"); 408 return AVERROR_INVALIDDATA; 409 } 410 c->frame_info = bytestream2_get_le32u(&gb); 411 av_log(avctx, AV_LOG_DEBUG, "frame information flags %X\n", c->frame_info); 412 413 c->frame_pred = (c->frame_info >> 8) & 3; 414 415 if (c->frame_pred == PRED_GRADIENT) { 416 av_log_ask_for_sample(avctx, "Frame uses gradient prediction\n"); 417 return AVERROR_PATCHWELCOME; 418 } 419 420 av_fast_malloc(&c->slice_bits, &c->slice_bits_size, 421 max_slice_size + FF_INPUT_BUFFER_PADDING_SIZE); 422 423 if (!c->slice_bits) { 424 av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n"); 425 return AVERROR(ENOMEM); 426 } 427 428 switch (c->avctx->pix_fmt) { 429 case PIX_FMT_RGB24: 430 case PIX_FMT_RGBA: 431 for (i = 0; i < c->planes; i++) { 432 ret = decode_plane(c, i, c->pic.data[0] + rgb_order[i], c->planes, 433 c->pic.linesize[0], avctx->width, avctx->height, 434 plane_start[i], plane_start[i + 1] - plane_start[i], 435 c->frame_pred == PRED_LEFT); 436 if (ret) 437 return ret; 438 if (c->frame_pred == PRED_MEDIAN) 439 restore_median(c->pic.data[0] + rgb_order[i], c->planes, 440 c->pic.linesize[0], avctx->width, avctx->height, 441 c->slices, 0); 442 } 443 restore_rgb_planes(c->pic.data[0], c->planes, c->pic.linesize[0], 444 avctx->width, avctx->height); 445 break; 446 case PIX_FMT_YUV420P: 447 for (i = 0; i < 3; i++) { 448 ret = decode_plane(c, i, c->pic.data[i], 1, 449 c->pic.linesize[i], avctx->width >> !!i, avctx->height >> !!i, 450 plane_start[i], plane_start[i + 1] - plane_start[i], 451 c->frame_pred == PRED_LEFT); 452 if (ret) 453 return ret; 454 if (c->frame_pred == PRED_MEDIAN) { 455 if (!c->interlaced) { 456 restore_median(c->pic.data[i], 1, c->pic.linesize[i], 457 avctx->width >> !!i, avctx->height >> !!i, 458 c->slices, !i); 459 } else { 460 restore_median_il(c->pic.data[i], 1, c->pic.linesize[i], 461 avctx->width >> !!i, 462 avctx->height >> !!i, 463 c->slices, !i); 464 } 465 } 466 } 467 break; 468 case PIX_FMT_YUV422P: 469 for (i = 0; i < 3; i++) { 470 ret = decode_plane(c, i, c->pic.data[i], 1, 471 c->pic.linesize[i], avctx->width >> !!i, avctx->height, 472 plane_start[i], plane_start[i + 1] - plane_start[i], 473 c->frame_pred == PRED_LEFT); 474 if (ret) 475 return ret; 476 if (c->frame_pred == PRED_MEDIAN) { 477 if (!c->interlaced) { 478 restore_median(c->pic.data[i], 1, c->pic.linesize[i], 479 avctx->width >> !!i, avctx->height, 480 c->slices, 0); 481 } else { 482 restore_median_il(c->pic.data[i], 1, c->pic.linesize[i], 483 avctx->width >> !!i, avctx->height, 484 c->slices, 0); 485 } 486 } 487 } 488 break; 489 } 490 491 *data_size = sizeof(AVFrame); 492 *(AVFrame*)data = c->pic; 493 494 /* always report that the buffer was completely consumed */ 495 return buf_size; 496} 497 498static av_cold int decode_init(AVCodecContext *avctx) 499{ 500 UtvideoContext * const c = avctx->priv_data; 501 502 c->avctx = avctx; 503 504 dsputil_init(&c->dsp, avctx); 505 506 if (avctx->extradata_size < 16) { 507 av_log(avctx, AV_LOG_ERROR, "Insufficient extradata size %d, should be at least 16\n", 508 avctx->extradata_size); 509 return AVERROR_INVALIDDATA; 510 } 511 512 av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d.%d.%d\n", 513 avctx->extradata[3], avctx->extradata[2], 514 avctx->extradata[1], avctx->extradata[0]); 515 av_log(avctx, AV_LOG_DEBUG, "Original format %X\n", AV_RB32(avctx->extradata + 4)); 516 c->frame_info_size = AV_RL32(avctx->extradata + 8); 517 c->flags = AV_RL32(avctx->extradata + 12); 518 519 if (c->frame_info_size != 4) 520 av_log_ask_for_sample(avctx, "Frame info is not 4 bytes\n"); 521 av_log(avctx, AV_LOG_DEBUG, "Encoding parameters %08X\n", c->flags); 522 c->slices = (c->flags >> 24) + 1; 523 c->compression = c->flags & 1; 524 c->interlaced = c->flags & 0x800; 525 526 c->slice_bits_size = 0; 527 528 switch (avctx->codec_tag) { 529 case MKTAG('U', 'L', 'R', 'G'): 530 c->planes = 3; 531 avctx->pix_fmt = PIX_FMT_RGB24; 532 break; 533 case MKTAG('U', 'L', 'R', 'A'): 534 c->planes = 4; 535 avctx->pix_fmt = PIX_FMT_RGBA; 536 break; 537 case MKTAG('U', 'L', 'Y', '0'): 538 c->planes = 3; 539 avctx->pix_fmt = PIX_FMT_YUV420P; 540 break; 541 case MKTAG('U', 'L', 'Y', '2'): 542 c->planes = 3; 543 avctx->pix_fmt = PIX_FMT_YUV422P; 544 break; 545 default: 546 av_log(avctx, AV_LOG_ERROR, "Unknown Ut Video FOURCC provided (%08X)\n", 547 avctx->codec_tag); 548 return AVERROR_INVALIDDATA; 549 } 550 551 return 0; 552} 553 554static av_cold int decode_end(AVCodecContext *avctx) 555{ 556 UtvideoContext * const c = avctx->priv_data; 557 558 if (c->pic.data[0]) 559 ff_thread_release_buffer(avctx, &c->pic); 560 561 av_freep(&c->slice_bits); 562 563 return 0; 564} 565 566AVCodec ff_utvideo_decoder = { 567 .name = "utvideo", 568 .type = AVMEDIA_TYPE_VIDEO, 569 .id = CODEC_ID_UTVIDEO, 570 .priv_data_size = sizeof(UtvideoContext), 571 .init = decode_init, 572 .close = decode_end, 573 .decode = decode_frame, 574 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, 575 .long_name = NULL_IF_CONFIG_SMALL("Ut Video"), 576}; 577 578