LCOV - code coverage report
Current view: top level - libavcodec - utvideodec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 360 553 65.1 %
Date: 2017-12-13 10:57:33 Functions: 10 12 83.3 %

          Line data    Source code
       1             : /*
       2             :  * Ut Video decoder
       3             :  * Copyright (c) 2011 Konstantin Shishkov
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg 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             :  * FFmpeg 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 FFmpeg; 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             : #define UNCHECKED_BITSTREAM_READER 1
      31             : 
      32             : #include "libavutil/intreadwrite.h"
      33             : #include "avcodec.h"
      34             : #include "bswapdsp.h"
      35             : #include "bytestream.h"
      36             : #include "get_bits.h"
      37             : #include "internal.h"
      38             : #include "thread.h"
      39             : #include "utvideo.h"
      40             : 
      41           0 : static int build_huff10(const uint8_t *src, VLC *vlc, int *fsym)
      42             : {
      43             :     int i;
      44             :     HuffEntry he[1024];
      45             :     int last;
      46             :     uint32_t codes[1024];
      47             :     uint8_t bits[1024];
      48             :     uint16_t syms[1024];
      49             :     uint32_t code;
      50             : 
      51           0 :     *fsym = -1;
      52           0 :     for (i = 0; i < 1024; i++) {
      53           0 :         he[i].sym = i;
      54           0 :         he[i].len = *src++;
      55             :     }
      56           0 :     qsort(he, 1024, sizeof(*he), ff_ut10_huff_cmp_len);
      57             : 
      58           0 :     if (!he[0].len) {
      59           0 :         *fsym = he[0].sym;
      60           0 :         return 0;
      61             :     }
      62             : 
      63           0 :     last = 1023;
      64           0 :     while (he[last].len == 255 && last)
      65           0 :         last--;
      66             : 
      67           0 :     if (he[last].len > 32) {
      68           0 :         return -1;
      69             :     }
      70             : 
      71           0 :     code = 1;
      72           0 :     for (i = last; i >= 0; i--) {
      73           0 :         codes[i] = code >> (32 - he[i].len);
      74           0 :         bits[i]  = he[i].len;
      75           0 :         syms[i]  = he[i].sym;
      76           0 :         code += 0x80000000u >> (he[i].len - 1);
      77             :     }
      78             : #define VLC_BITS 11
      79           0 :     return ff_init_vlc_sparse(vlc, VLC_BITS, last + 1,
      80             :                               bits,  sizeof(*bits),  sizeof(*bits),
      81             :                               codes, sizeof(*codes), sizeof(*codes),
      82             :                               syms,  sizeof(*syms),  sizeof(*syms), 0);
      83             : }
      84             : 
      85         183 : static int build_huff(const uint8_t *src, VLC *vlc, int *fsym)
      86             : {
      87             :     int i;
      88             :     HuffEntry he[256];
      89             :     int last;
      90             :     uint32_t codes[256];
      91             :     uint8_t bits[256];
      92             :     uint8_t syms[256];
      93             :     uint32_t code;
      94             : 
      95         183 :     *fsym = -1;
      96       47031 :     for (i = 0; i < 256; i++) {
      97       46848 :         he[i].sym = i;
      98       46848 :         he[i].len = *src++;
      99             :     }
     100         183 :     qsort(he, 256, sizeof(*he), ff_ut_huff_cmp_len);
     101             : 
     102         183 :     if (!he[0].len) {
     103           4 :         *fsym = he[0].sym;
     104           4 :         return 0;
     105             :     }
     106             : 
     107         179 :     last = 255;
     108       18429 :     while (he[last].len == 255 && last)
     109       18071 :         last--;
     110             : 
     111         179 :     if (he[last].len > 32)
     112           0 :         return -1;
     113             : 
     114         179 :     code = 1;
     115       27932 :     for (i = last; i >= 0; i--) {
     116       27753 :         codes[i] = code >> (32 - he[i].len);
     117       27753 :         bits[i]  = he[i].len;
     118       27753 :         syms[i]  = he[i].sym;
     119       27753 :         code += 0x80000000u >> (he[i].len - 1);
     120             :     }
     121             : 
     122         179 :     return ff_init_vlc_sparse(vlc, VLC_BITS, last + 1,
     123             :                               bits,  sizeof(*bits),  sizeof(*bits),
     124             :                               codes, sizeof(*codes), sizeof(*codes),
     125             :                               syms,  sizeof(*syms),  sizeof(*syms), 0);
     126             : }
     127             : 
     128           0 : static int decode_plane10(UtvideoContext *c, int plane_no,
     129             :                           uint16_t *dst, ptrdiff_t stride,
     130             :                           int width, int height,
     131             :                           const uint8_t *src, const uint8_t *huff,
     132             :                           int use_pred)
     133             : {
     134             :     int i, j, slice, pix, ret;
     135             :     int sstart, send;
     136             :     VLC vlc;
     137             :     GetBitContext gb;
     138             :     int prev, fsym;
     139             : 
     140           0 :     if ((ret = build_huff10(huff, &vlc, &fsym)) < 0) {
     141           0 :         av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
     142           0 :         return ret;
     143             :     }
     144           0 :     if (fsym >= 0) { // build_huff reported a symbol to fill slices with
     145           0 :         send = 0;
     146           0 :         for (slice = 0; slice < c->slices; slice++) {
     147             :             uint16_t *dest;
     148             : 
     149           0 :             sstart = send;
     150           0 :             send   = (height * (slice + 1) / c->slices);
     151           0 :             dest   = dst + sstart * stride;
     152             : 
     153           0 :             prev = 0x200;
     154           0 :             for (j = sstart; j < send; j++) {
     155           0 :                 for (i = 0; i < width; i++) {
     156           0 :                     pix = fsym;
     157           0 :                     if (use_pred) {
     158           0 :                         prev += pix;
     159           0 :                         prev &= 0x3FF;
     160           0 :                         pix   = prev;
     161             :                     }
     162           0 :                     dest[i] = pix;
     163             :                 }
     164           0 :                 dest += stride;
     165             :             }
     166             :         }
     167           0 :         return 0;
     168             :     }
     169             : 
     170           0 :     send = 0;
     171           0 :     for (slice = 0; slice < c->slices; slice++) {
     172             :         uint16_t *dest;
     173             :         int slice_data_start, slice_data_end, slice_size;
     174             : 
     175           0 :         sstart = send;
     176           0 :         send   = (height * (slice + 1) / c->slices);
     177           0 :         dest   = dst + sstart * stride;
     178             : 
     179             :         // slice offset and size validation was done earlier
     180           0 :         slice_data_start = slice ? AV_RL32(src + slice * 4 - 4) : 0;
     181           0 :         slice_data_end   = AV_RL32(src + slice * 4);
     182           0 :         slice_size       = slice_data_end - slice_data_start;
     183             : 
     184           0 :         if (!slice_size) {
     185           0 :             av_log(c->avctx, AV_LOG_ERROR, "Plane has more than one symbol "
     186             :                    "yet a slice has a length of zero.\n");
     187           0 :             goto fail;
     188             :         }
     189             : 
     190           0 :         memset(c->slice_bits + slice_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
     191           0 :         c->bdsp.bswap_buf((uint32_t *) c->slice_bits,
     192           0 :                           (uint32_t *)(src + slice_data_start + c->slices * 4),
     193           0 :                           (slice_data_end - slice_data_start + 3) >> 2);
     194           0 :         init_get_bits(&gb, c->slice_bits, slice_size * 8);
     195             : 
     196           0 :         prev = 0x200;
     197           0 :         for (j = sstart; j < send; j++) {
     198           0 :             for (i = 0; i < width; i++) {
     199           0 :                 pix = get_vlc2(&gb, vlc.table, VLC_BITS, 3);
     200           0 :                 if (pix < 0) {
     201           0 :                     av_log(c->avctx, AV_LOG_ERROR, "Decoding error\n");
     202           0 :                     goto fail;
     203             :                 }
     204           0 :                 if (use_pred) {
     205           0 :                     prev += pix;
     206           0 :                     prev &= 0x3FF;
     207           0 :                     pix   = prev;
     208             :                 }
     209           0 :                 dest[i] = pix;
     210             :             }
     211           0 :             dest += stride;
     212           0 :             if (get_bits_left(&gb) < 0) {
     213           0 :                 av_log(c->avctx, AV_LOG_ERROR,
     214             :                         "Slice decoding ran out of bits\n");
     215           0 :                 goto fail;
     216             :             }
     217             :         }
     218           0 :         if (get_bits_left(&gb) > 32)
     219           0 :             av_log(c->avctx, AV_LOG_WARNING,
     220             :                    "%d bits left after decoding slice\n", get_bits_left(&gb));
     221             :     }
     222             : 
     223           0 :     ff_free_vlc(&vlc);
     224             : 
     225           0 :     return 0;
     226           0 : fail:
     227           0 :     ff_free_vlc(&vlc);
     228           0 :     return AVERROR_INVALIDDATA;
     229             : }
     230             : 
     231         183 : static int compute_cmask(int plane_no, int interlaced, enum AVPixelFormat pix_fmt)
     232             : {
     233         183 :     const int is_luma = (pix_fmt == AV_PIX_FMT_YUV420P) && !plane_no;
     234             : 
     235         183 :     if (interlaced)
     236          24 :         return ~(1 + 2 * is_luma);
     237             : 
     238         159 :     return ~is_luma;
     239             : }
     240             : 
     241         183 : static int decode_plane(UtvideoContext *c, int plane_no,
     242             :                         uint8_t *dst, ptrdiff_t stride,
     243             :                         int width, int height,
     244             :                         const uint8_t *src, int use_pred)
     245             : {
     246             :     int i, j, slice, pix;
     247             :     int sstart, send;
     248             :     VLC vlc;
     249             :     GetBitContext gb;
     250             :     int prev, fsym;
     251         183 :     const int cmask = compute_cmask(plane_no, c->interlaced, c->avctx->pix_fmt);
     252             : 
     253         183 :     if (build_huff(src, &vlc, &fsym)) {
     254           0 :         av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
     255           0 :         return AVERROR_INVALIDDATA;
     256             :     }
     257         183 :     if (fsym >= 0) { // build_huff reported a symbol to fill slices with
     258           4 :         send = 0;
     259          20 :         for (slice = 0; slice < c->slices; slice++) {
     260             :             uint8_t *dest;
     261             : 
     262          16 :             sstart = send;
     263          16 :             send   = (height * (slice + 1) / c->slices) & cmask;
     264          16 :             dest   = dst + sstart * stride;
     265             : 
     266          16 :             prev = 0x80;
     267        3088 :             for (j = sstart; j < send; j++) {
     268     3148800 :                 for (i = 0; i < width; i++) {
     269     3145728 :                     pix = fsym;
     270     3145728 :                     if (use_pred) {
     271           0 :                         prev += pix;
     272           0 :                         pix   = prev;
     273             :                     }
     274     3145728 :                     dest[i] = pix;
     275             :                 }
     276        3072 :                 dest += stride;
     277             :             }
     278             :         }
     279           4 :         return 0;
     280             :     }
     281             : 
     282         179 :     src      += 256;
     283             : 
     284         179 :     send = 0;
     285         895 :     for (slice = 0; slice < c->slices; slice++) {
     286             :         uint8_t *dest;
     287             :         int slice_data_start, slice_data_end, slice_size;
     288             : 
     289         716 :         sstart = send;
     290         716 :         send   = (height * (slice + 1) / c->slices) & cmask;
     291         716 :         dest   = dst + sstart * stride;
     292             : 
     293             :         // slice offset and size validation was done earlier
     294         716 :         slice_data_start = slice ? AV_RL32(src + slice * 4 - 4) : 0;
     295         716 :         slice_data_end   = AV_RL32(src + slice * 4);
     296         716 :         slice_size       = slice_data_end - slice_data_start;
     297             : 
     298         716 :         if (!slice_size) {
     299           0 :             av_log(c->avctx, AV_LOG_ERROR, "Plane has more than one symbol "
     300             :                    "yet a slice has a length of zero.\n");
     301           0 :             goto fail;
     302             :         }
     303             : 
     304         716 :         memset(c->slice_bits + slice_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
     305        2148 :         c->bdsp.bswap_buf((uint32_t *) c->slice_bits,
     306         716 :                           (uint32_t *)(src + slice_data_start + c->slices * 4),
     307         716 :                           (slice_data_end - slice_data_start + 3) >> 2);
     308         716 :         init_get_bits(&gb, c->slice_bits, slice_size * 8);
     309             : 
     310         716 :         prev = 0x80;
     311       63858 :         for (j = sstart; j < send; j++) {
     312    35325686 :             for (i = 0; i < width; i++) {
     313    35262544 :                 pix = get_vlc2(&gb, vlc.table, VLC_BITS, 3);
     314    35262544 :                 if (pix < 0) {
     315           0 :                     av_log(c->avctx, AV_LOG_ERROR, "Decoding error\n");
     316           0 :                     goto fail;
     317             :                 }
     318    35262544 :                 if (use_pred) {
     319    15513600 :                     prev += pix;
     320    15513600 :                     pix   = prev;
     321             :                 }
     322    35262544 :                 dest[i] = pix;
     323             :             }
     324       63142 :             if (get_bits_left(&gb) < 0) {
     325           0 :                 av_log(c->avctx, AV_LOG_ERROR,
     326             :                         "Slice decoding ran out of bits\n");
     327           0 :                 goto fail;
     328             :             }
     329       63142 :             dest += stride;
     330             :         }
     331         716 :         if (get_bits_left(&gb) > 32)
     332           0 :             av_log(c->avctx, AV_LOG_WARNING,
     333             :                    "%d bits left after decoding slice\n", get_bits_left(&gb));
     334             :     }
     335             : 
     336         179 :     ff_free_vlc(&vlc);
     337             : 
     338         179 :     return 0;
     339           0 : fail:
     340           0 :     ff_free_vlc(&vlc);
     341           0 :     return AVERROR_INVALIDDATA;
     342             : }
     343             : 
     344             : #undef A
     345             : #undef B
     346             : #undef C
     347             : 
     348          77 : static void restore_median_planar(UtvideoContext *c, uint8_t *src, ptrdiff_t stride,
     349             :                                   int width, int height, int slices, int rmode)
     350             : {
     351             :     int i, j, slice;
     352             :     int A, B, C;
     353             :     uint8_t *bsrc;
     354             :     int slice_start, slice_height;
     355          77 :     const int cmask = ~rmode;
     356             : 
     357         385 :     for (slice = 0; slice < slices; slice++) {
     358         308 :         slice_start  = ((slice * height) / slices) & cmask;
     359         308 :         slice_height = ((((slice + 1) * height) / slices) & cmask) -
     360             :                        slice_start;
     361             : 
     362         308 :         if (!slice_height)
     363           0 :             continue;
     364         308 :         bsrc = src + slice_start * stride;
     365             : 
     366             :         // first line - left neighbour prediction
     367         308 :         bsrc[0] += 0x80;
     368         308 :         c->llviddsp.add_left_pred(bsrc, bsrc, width, 0);
     369         308 :         bsrc += stride;
     370         308 :         if (slice_height <= 1)
     371           0 :             continue;
     372             :         // second line - first element has top prediction, the rest uses median
     373         308 :         C        = bsrc[-stride];
     374         308 :         bsrc[0] += C;
     375         308 :         A        = bsrc[0];
     376        4928 :         for (i = 1; i < FFMIN(width, 16); i++) { /* scalar loop (DSP need align 16) */
     377        4620 :             B        = bsrc[i - stride];
     378        4620 :             bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
     379        4620 :             C        = B;
     380        4620 :             A        = bsrc[i];
     381             :         }
     382         308 :         if (width > 16)
     383         924 :             c->llviddsp.add_median_pred(bsrc + 16, bsrc - stride + 16,
     384         616 :                                         bsrc + 16, width - 16, &A, &B);
     385             : 
     386         308 :         bsrc += stride;
     387             :         // the rest of lines use continuous median prediction
     388       33436 :         for (j = 2; j < slice_height; j++) {
     389       33128 :             c->llviddsp.add_median_pred(bsrc, bsrc - stride,
     390             :                                             bsrc, width, &A, &B);
     391       33128 :             bsrc += stride;
     392             :         }
     393             :     }
     394          77 : }
     395             : 
     396             : /* UtVideo interlaced mode treats every two lines as a single one,
     397             :  * so restoring function should take care of possible padding between
     398             :  * two parts of the same "line".
     399             :  */
     400          12 : static void restore_median_planar_il(UtvideoContext *c, uint8_t *src, ptrdiff_t stride,
     401             :                                      int width, int height, int slices, int rmode)
     402             : {
     403             :     int i, j, slice;
     404             :     int A, B, C;
     405             :     uint8_t *bsrc;
     406             :     int slice_start, slice_height;
     407          12 :     const int cmask   = ~(rmode ? 3 : 1);
     408          12 :     const ptrdiff_t stride2 = stride << 1;
     409             : 
     410          60 :     for (slice = 0; slice < slices; slice++) {
     411          48 :         slice_start    = ((slice * height) / slices) & cmask;
     412          48 :         slice_height   = ((((slice + 1) * height) / slices) & cmask) -
     413             :                          slice_start;
     414          48 :         slice_height >>= 1;
     415          48 :         if (!slice_height)
     416           0 :             continue;
     417             : 
     418          48 :         bsrc = src + slice_start * stride;
     419             : 
     420             :         // first line - left neighbour prediction
     421          48 :         bsrc[0] += 0x80;
     422          48 :         A = c->llviddsp.add_left_pred(bsrc, bsrc, width, 0);
     423          48 :         c->llviddsp.add_left_pred(bsrc + stride, bsrc + stride, width, A);
     424          48 :         bsrc += stride2;
     425          48 :         if (slice_height <= 1)
     426           0 :             continue;
     427             :         // second line - first element has top prediction, the rest uses median
     428          48 :         C        = bsrc[-stride2];
     429          48 :         bsrc[0] += C;
     430          48 :         A        = bsrc[0];
     431         768 :         for (i = 1; i < FFMIN(width, 16); i++) { /* scalar loop (DSP need align 16) */
     432         720 :             B        = bsrc[i - stride2];
     433         720 :             bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
     434         720 :             C        = B;
     435         720 :             A        = bsrc[i];
     436             :         }
     437          48 :         if (width > 16)
     438         144 :             c->llviddsp.add_median_pred(bsrc + 16, bsrc - stride2 + 16,
     439          96 :                                         bsrc + 16, width - 16, &A, &B);
     440             : 
     441          96 :         c->llviddsp.add_median_pred(bsrc + stride, bsrc - stride,
     442          48 :                                         bsrc + stride, width, &A, &B);
     443          48 :         bsrc += stride2;
     444             :         // the rest of lines use continuous median prediction
     445         216 :         for (j = 2; j < slice_height; j++) {
     446         168 :             c->llviddsp.add_median_pred(bsrc, bsrc - stride2,
     447             :                                             bsrc, width, &A, &B);
     448         336 :             c->llviddsp.add_median_pred(bsrc + stride, bsrc - stride,
     449         168 :                                             bsrc + stride, width, &A, &B);
     450         168 :             bsrc += stride2;
     451             :         }
     452             :     }
     453          12 : }
     454             : 
     455          13 : static void restore_gradient_planar(UtvideoContext *c, uint8_t *src, ptrdiff_t stride,
     456             :                                     int width, int height, int slices, int rmode)
     457             : {
     458             :     int i, j, slice;
     459             :     int A, B, C;
     460             :     uint8_t *bsrc;
     461             :     int slice_start, slice_height;
     462          13 :     const int cmask = ~rmode;
     463          13 :     int min_width = FFMIN(width, 32);
     464             : 
     465          65 :     for (slice = 0; slice < slices; slice++) {
     466          52 :         slice_start  = ((slice * height) / slices) & cmask;
     467          52 :         slice_height = ((((slice + 1) * height) / slices) & cmask) -
     468             :                        slice_start;
     469             : 
     470          52 :         if (!slice_height)
     471           0 :             continue;
     472          52 :         bsrc = src + slice_start * stride;
     473             : 
     474             :         // first line - left neighbour prediction
     475          52 :         bsrc[0] += 0x80;
     476          52 :         c->llviddsp.add_left_pred(bsrc, bsrc, width, 0);
     477          52 :         bsrc += stride;
     478          52 :         if (slice_height <= 1)
     479           0 :             continue;
     480         502 :         for (j = 1; j < slice_height; j++) {
     481             :             // second line - first element has top prediction, the rest uses gradient
     482         450 :             bsrc[0] = (bsrc[0] + bsrc[-stride]) & 0xFF;
     483       14400 :             for (i = 1; i < min_width; i++) { /* dsp need align 32 */
     484       13950 :                 A = bsrc[i - stride];
     485       13950 :                 B = bsrc[i - (stride + 1)];
     486       13950 :                 C = bsrc[i - 1];
     487       13950 :                 bsrc[i] = (A - B + C + bsrc[i]) & 0xFF;
     488             :             }
     489         450 :             if (width > 32)
     490         322 :                 c->llviddsp.add_gradient_pred(bsrc + 32, stride, width - 32);
     491         450 :             bsrc += stride;
     492             :         }
     493             :     }
     494          13 : }
     495             : 
     496          12 : static void restore_gradient_planar_il(UtvideoContext *c, uint8_t *src, ptrdiff_t stride,
     497             :                                       int width, int height, int slices, int rmode)
     498             : {
     499             :     int i, j, slice;
     500             :     int A, B, C;
     501             :     uint8_t *bsrc;
     502             :     int slice_start, slice_height;
     503          12 :     const int cmask   = ~(rmode ? 3 : 1);
     504          12 :     const ptrdiff_t stride2 = stride << 1;
     505             : 
     506          60 :     for (slice = 0; slice < slices; slice++) {
     507          48 :         slice_start    = ((slice * height) / slices) & cmask;
     508          48 :         slice_height   = ((((slice + 1) * height) / slices) & cmask) -
     509             :                          slice_start;
     510          48 :         slice_height >>= 1;
     511          48 :         if (!slice_height)
     512           0 :             continue;
     513             : 
     514          48 :         bsrc = src + slice_start * stride;
     515             : 
     516             :         // first line - left neighbour prediction
     517          48 :         bsrc[0] += 0x80;
     518          48 :         A = c->llviddsp.add_left_pred(bsrc, bsrc, width, 0);
     519          48 :         c->llviddsp.add_left_pred(bsrc + stride, bsrc + stride, width, A);
     520          48 :         bsrc += stride2;
     521          48 :         if (slice_height <= 1)
     522           0 :             continue;
     523         264 :         for (j = 1; j < slice_height; j++) {
     524             :             // second line - first element has top prediction, the rest uses gradient
     525         216 :             bsrc[0] = (bsrc[0] + bsrc[-stride2]) & 0xFF;
     526       12032 :             for (i = 1; i < width; i++) {
     527       11816 :                 A = bsrc[i - stride2];
     528       11816 :                 B = bsrc[i - (stride2 + 1)];
     529       11816 :                 C = bsrc[i - 1];
     530       11816 :                 bsrc[i] = (A - B + C + bsrc[i]) & 0xFF;
     531             :             }
     532         216 :             A = bsrc[-stride];
     533         216 :             B = bsrc[-(1 + stride + stride - width)];
     534         216 :             C = bsrc[width - 1];
     535         216 :             bsrc[stride] = (A - B + C + bsrc[stride]) & 0xFF;
     536       12032 :             for (i = 1; i < width; i++) {
     537       11816 :                 A = bsrc[i - stride];
     538       11816 :                 B = bsrc[i - (1 + stride)];
     539       11816 :                 C = bsrc[i - 1 + stride];
     540       11816 :                 bsrc[i + stride] = (A - B + C + bsrc[i + stride]) & 0xFF;
     541             :             }
     542         216 :             bsrc += stride2;
     543             :         }
     544             :     }
     545          12 : }
     546             : 
     547          57 : static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     548             :                         AVPacket *avpkt)
     549             : {
     550          57 :     const uint8_t *buf = avpkt->data;
     551          57 :     int buf_size = avpkt->size;
     552          57 :     UtvideoContext *c = avctx->priv_data;
     553             :     int i, j;
     554             :     const uint8_t *plane_start[5];
     555          57 :     int plane_size, max_slice_size = 0, slice_start, slice_end, slice_size;
     556             :     int ret;
     557             :     GetByteContext gb;
     558          57 :     ThreadFrame frame = { .f = data };
     559             : 
     560          57 :     if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
     561           0 :         return ret;
     562             : 
     563             :     /* parse plane structure to get frame flags and validate slice offsets */
     564          57 :     bytestream2_init(&gb, buf, buf_size);
     565          57 :     if (c->pro) {
     566           0 :         if (bytestream2_get_bytes_left(&gb) < c->frame_info_size) {
     567           0 :             av_log(avctx, AV_LOG_ERROR, "Not enough data for frame information\n");
     568           0 :             return AVERROR_INVALIDDATA;
     569             :         }
     570           0 :         c->frame_info = bytestream2_get_le32u(&gb);
     571           0 :         c->slices = ((c->frame_info >> 16) & 0xff) + 1;
     572           0 :         for (i = 0; i < c->planes; i++) {
     573           0 :             plane_start[i] = gb.buffer;
     574           0 :             if (bytestream2_get_bytes_left(&gb) < 1024 + 4 * c->slices) {
     575           0 :                 av_log(avctx, AV_LOG_ERROR, "Insufficient data for a plane\n");
     576           0 :                 return AVERROR_INVALIDDATA;
     577             :             }
     578           0 :             slice_start = 0;
     579           0 :             slice_end   = 0;
     580           0 :             for (j = 0; j < c->slices; j++) {
     581           0 :                 slice_end   = bytestream2_get_le32u(&gb);
     582           0 :                 if (slice_end < 0 || slice_end < slice_start ||
     583           0 :                     bytestream2_get_bytes_left(&gb) < slice_end) {
     584           0 :                     av_log(avctx, AV_LOG_ERROR, "Incorrect slice size\n");
     585           0 :                     return AVERROR_INVALIDDATA;
     586             :                 }
     587           0 :                 slice_size  = slice_end - slice_start;
     588           0 :                 slice_start = slice_end;
     589           0 :                 max_slice_size = FFMAX(max_slice_size, slice_size);
     590             :             }
     591           0 :             plane_size = slice_end;
     592           0 :             bytestream2_skipu(&gb, plane_size);
     593           0 :             bytestream2_skipu(&gb, 1024);
     594             :         }
     595           0 :         plane_start[c->planes] = gb.buffer;
     596             :     } else {
     597         240 :         for (i = 0; i < c->planes; i++) {
     598         183 :             plane_start[i] = gb.buffer;
     599         183 :             if (bytestream2_get_bytes_left(&gb) < 256 + 4 * c->slices) {
     600           0 :                 av_log(avctx, AV_LOG_ERROR, "Insufficient data for a plane\n");
     601           0 :                 return AVERROR_INVALIDDATA;
     602             :             }
     603         183 :             bytestream2_skipu(&gb, 256);
     604         183 :             slice_start = 0;
     605         183 :             slice_end   = 0;
     606         915 :             for (j = 0; j < c->slices; j++) {
     607         732 :                 slice_end   = bytestream2_get_le32u(&gb);
     608        1464 :                 if (slice_end < 0 || slice_end < slice_start ||
     609         732 :                     bytestream2_get_bytes_left(&gb) < slice_end) {
     610           0 :                     av_log(avctx, AV_LOG_ERROR, "Incorrect slice size\n");
     611           0 :                     return AVERROR_INVALIDDATA;
     612             :                 }
     613         732 :                 slice_size  = slice_end - slice_start;
     614         732 :                 slice_start = slice_end;
     615         732 :                 max_slice_size = FFMAX(max_slice_size, slice_size);
     616             :             }
     617         183 :             plane_size = slice_end;
     618         183 :             bytestream2_skipu(&gb, plane_size);
     619             :         }
     620          57 :         plane_start[c->planes] = gb.buffer;
     621          57 :         if (bytestream2_get_bytes_left(&gb) < c->frame_info_size) {
     622           0 :             av_log(avctx, AV_LOG_ERROR, "Not enough data for frame information\n");
     623           0 :             return AVERROR_INVALIDDATA;
     624             :         }
     625          57 :         c->frame_info = bytestream2_get_le32u(&gb);
     626             :     }
     627          57 :     av_log(avctx, AV_LOG_DEBUG, "frame information flags %"PRIX32"\n",
     628             :            c->frame_info);
     629             : 
     630          57 :     c->frame_pred = (c->frame_info >> 8) & 3;
     631             : 
     632          57 :     max_slice_size += 4*avctx->width;
     633             : 
     634          57 :     av_fast_malloc(&c->slice_bits, &c->slice_bits_size,
     635          57 :                    max_slice_size + AV_INPUT_BUFFER_PADDING_SIZE);
     636             : 
     637          57 :     if (!c->slice_bits) {
     638           0 :         av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
     639           0 :         return AVERROR(ENOMEM);
     640             :     }
     641             : 
     642          57 :     switch (c->avctx->pix_fmt) {
     643          28 :     case AV_PIX_FMT_GBRP:
     644             :     case AV_PIX_FMT_GBRAP:
     645         124 :         for (i = 0; i < c->planes; i++) {
     646         192 :             ret = decode_plane(c, i, frame.f->data[i],
     647          96 :                                frame.f->linesize[i], avctx->width,
     648             :                                avctx->height, plane_start[i],
     649          96 :                                c->frame_pred == PRED_LEFT);
     650          96 :             if (ret)
     651           0 :                 return ret;
     652          96 :             if (c->frame_pred == PRED_MEDIAN) {
     653          53 :                 if (!c->interlaced) {
     654         100 :                     restore_median_planar(c, frame.f->data[i],
     655          50 :                                           frame.f->linesize[i], avctx->width,
     656             :                                           avctx->height, c->slices, 0);
     657             :                 } else {
     658           6 :                     restore_median_planar_il(c, frame.f->data[i],
     659           3 :                                              frame.f->linesize[i],
     660             :                                              avctx->width, avctx->height, c->slices,
     661             :                                              0);
     662             :                 }
     663          43 :             } else if (c->frame_pred == PRED_GRADIENT) {
     664           7 :                 if (!c->interlaced) {
     665           8 :                     restore_gradient_planar(c, frame.f->data[i],
     666           4 :                                             frame.f->linesize[i], avctx->width,
     667             :                                             avctx->height, c->slices, 0);
     668             :                 } else {
     669           6 :                     restore_gradient_planar_il(c, frame.f->data[i],
     670           3 :                                                frame.f->linesize[i],
     671             :                                                avctx->width, avctx->height, c->slices,
     672             :                                                0);
     673             :                 }
     674             :             }
     675             :         }
     676         112 :         c->utdsp.restore_rgb_planes(frame.f->data[2], frame.f->data[0], frame.f->data[1],
     677          84 :                                     frame.f->linesize[2], frame.f->linesize[0], frame.f->linesize[1],
     678             :                                     avctx->width, avctx->height);
     679          28 :         break;
     680           0 :     case AV_PIX_FMT_GBRAP10:
     681             :     case AV_PIX_FMT_GBRP10:
     682           0 :         for (i = 0; i < c->planes; i++) {
     683           0 :             ret = decode_plane10(c, i, (uint16_t *)frame.f->data[i],
     684           0 :                                  frame.f->linesize[i] / 2, avctx->width,
     685             :                                  avctx->height, plane_start[i],
     686           0 :                                  plane_start[i + 1] - 1024,
     687           0 :                                  c->frame_pred == PRED_LEFT);
     688           0 :             if (ret)
     689           0 :                 return ret;
     690             :         }
     691           0 :         c->utdsp.restore_rgb_planes10((uint16_t *)frame.f->data[2], (uint16_t *)frame.f->data[0], (uint16_t *)frame.f->data[1],
     692           0 :                                       frame.f->linesize[2] / 2, frame.f->linesize[0] / 2, frame.f->linesize[1] / 2,
     693             :                                       avctx->width, avctx->height);
     694           0 :         break;
     695          14 :     case AV_PIX_FMT_YUV420P:
     696          56 :         for (i = 0; i < 3; i++) {
     697         126 :             ret = decode_plane(c, i, frame.f->data[i], frame.f->linesize[i],
     698          84 :                                avctx->width >> !!i, avctx->height >> !!i,
     699          42 :                                plane_start[i], c->frame_pred == PRED_LEFT);
     700          42 :             if (ret)
     701           0 :                 return ret;
     702          42 :             if (c->frame_pred == PRED_MEDIAN) {
     703          15 :                 if (!c->interlaced) {
     704          36 :                     restore_median_planar(c, frame.f->data[i], frame.f->linesize[i],
     705          24 :                                           avctx->width >> !!i, avctx->height >> !!i,
     706             :                                           c->slices, !i);
     707             :                 } else {
     708           9 :                     restore_median_planar_il(c, frame.f->data[i], frame.f->linesize[i],
     709           3 :                                              avctx->width  >> !!i,
     710           3 :                                              avctx->height >> !!i,
     711             :                                              c->slices, !i);
     712             :                 }
     713          27 :             } else if (c->frame_pred == PRED_GRADIENT) {
     714           6 :                 if (!c->interlaced) {
     715           9 :                     restore_gradient_planar(c, frame.f->data[i], frame.f->linesize[i],
     716           6 :                                             avctx->width >> !!i, avctx->height >> !!i,
     717             :                                             c->slices, !i);
     718             :                 } else {
     719           9 :                     restore_gradient_planar_il(c, frame.f->data[i], frame.f->linesize[i],
     720           3 :                                                avctx->width  >> !!i,
     721           3 :                                                avctx->height >> !!i,
     722             :                                                c->slices, !i);
     723             :                 }
     724             :             }
     725             :         }
     726          14 :         break;
     727          11 :     case AV_PIX_FMT_YUV422P:
     728          44 :         for (i = 0; i < 3; i++) {
     729          66 :             ret = decode_plane(c, i, frame.f->data[i], frame.f->linesize[i],
     730          33 :                                avctx->width >> !!i, avctx->height,
     731          33 :                                plane_start[i], c->frame_pred == PRED_LEFT);
     732          33 :             if (ret)
     733           0 :                 return ret;
     734          33 :             if (c->frame_pred == PRED_MEDIAN) {
     735          15 :                 if (!c->interlaced) {
     736          24 :                     restore_median_planar(c, frame.f->data[i], frame.f->linesize[i],
     737          12 :                                           avctx->width >> !!i, avctx->height,
     738             :                                           c->slices, 0);
     739             :                 } else {
     740           6 :                     restore_median_planar_il(c, frame.f->data[i], frame.f->linesize[i],
     741           3 :                                              avctx->width >> !!i, avctx->height,
     742             :                                              c->slices, 0);
     743             :                 }
     744          18 :             } else if (c->frame_pred == PRED_GRADIENT) {
     745           6 :                 if (!c->interlaced) {
     746           6 :                     restore_gradient_planar(c, frame.f->data[i], frame.f->linesize[i],
     747           3 :                                             avctx->width >> !!i, avctx->height,
     748             :                                             c->slices, 0);
     749             :                 } else {
     750           6 :                     restore_gradient_planar_il(c, frame.f->data[i], frame.f->linesize[i],
     751           3 :                                                avctx->width  >> !!i, avctx->height,
     752             :                                                c->slices, 0);
     753             :                 }
     754             :             }
     755             :         }
     756          11 :         break;
     757           4 :     case AV_PIX_FMT_YUV444P:
     758          16 :         for (i = 0; i < 3; i++) {
     759          12 :             ret = decode_plane(c, i, frame.f->data[i], frame.f->linesize[i],
     760             :                                avctx->width, avctx->height,
     761          12 :                                plane_start[i], c->frame_pred == PRED_LEFT);
     762          12 :             if (ret)
     763           0 :                 return ret;
     764          12 :             if (c->frame_pred == PRED_MEDIAN) {
     765           6 :                 if (!c->interlaced) {
     766           3 :                     restore_median_planar(c, frame.f->data[i], frame.f->linesize[i],
     767             :                                           avctx->width, avctx->height,
     768             :                                           c->slices, 0);
     769             :                 } else {
     770           3 :                     restore_median_planar_il(c, frame.f->data[i], frame.f->linesize[i],
     771             :                                              avctx->width, avctx->height,
     772             :                                              c->slices, 0);
     773             :                 }
     774           6 :             } else if (c->frame_pred == PRED_GRADIENT) {
     775           6 :                 if (!c->interlaced) {
     776           3 :                     restore_gradient_planar(c, frame.f->data[i], frame.f->linesize[i],
     777             :                                             avctx->width, avctx->height,
     778             :                                             c->slices, 0);
     779             :                 } else {
     780           3 :                     restore_gradient_planar_il(c, frame.f->data[i], frame.f->linesize[i],
     781             :                                                avctx->width, avctx->height,
     782             :                                                c->slices, 0);
     783             :                 }
     784             :             }
     785             :         }
     786           4 :         break;
     787           0 :     case AV_PIX_FMT_YUV422P10:
     788           0 :         for (i = 0; i < 3; i++) {
     789           0 :             ret = decode_plane10(c, i, (uint16_t *)frame.f->data[i], frame.f->linesize[i] / 2,
     790           0 :                                  avctx->width >> !!i, avctx->height,
     791           0 :                                  plane_start[i], plane_start[i + 1] - 1024, c->frame_pred == PRED_LEFT);
     792           0 :             if (ret)
     793           0 :                 return ret;
     794             :         }
     795           0 :         break;
     796             :     }
     797             : 
     798          57 :     frame.f->key_frame = 1;
     799          57 :     frame.f->pict_type = AV_PICTURE_TYPE_I;
     800          57 :     frame.f->interlaced_frame = !!c->interlaced;
     801             : 
     802          57 :     *got_frame = 1;
     803             : 
     804             :     /* always report that the buffer was completely consumed */
     805          57 :     return buf_size;
     806             : }
     807             : 
     808          46 : static av_cold int decode_init(AVCodecContext *avctx)
     809             : {
     810          46 :     UtvideoContext * const c = avctx->priv_data;
     811             : 
     812          46 :     c->avctx = avctx;
     813             : 
     814          46 :     ff_utvideodsp_init(&c->utdsp);
     815          46 :     ff_bswapdsp_init(&c->bdsp);
     816          46 :     ff_llviddsp_init(&c->llviddsp);
     817             : 
     818          46 :     if (avctx->extradata_size >= 16) {
     819         184 :         av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d.%d.%d\n",
     820          92 :                avctx->extradata[3], avctx->extradata[2],
     821          92 :                avctx->extradata[1], avctx->extradata[0]);
     822          46 :         av_log(avctx, AV_LOG_DEBUG, "Original format %"PRIX32"\n",
     823          46 :                AV_RB32(avctx->extradata + 4));
     824          46 :         c->frame_info_size = AV_RL32(avctx->extradata + 8);
     825          46 :         c->flags           = AV_RL32(avctx->extradata + 12);
     826             : 
     827          46 :         if (c->frame_info_size != 4)
     828           0 :             avpriv_request_sample(avctx, "Frame info not 4 bytes");
     829          46 :         av_log(avctx, AV_LOG_DEBUG, "Encoding parameters %08"PRIX32"\n", c->flags);
     830          46 :         c->slices      = (c->flags >> 24) + 1;
     831          46 :         c->compression = c->flags & 1;
     832          46 :         c->interlaced  = c->flags & 0x800;
     833           0 :     } else if (avctx->extradata_size == 8) {
     834           0 :         av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d.%d.%d\n",
     835           0 :                avctx->extradata[3], avctx->extradata[2],
     836           0 :                avctx->extradata[1], avctx->extradata[0]);
     837           0 :         av_log(avctx, AV_LOG_DEBUG, "Original format %"PRIX32"\n",
     838           0 :                AV_RB32(avctx->extradata + 4));
     839           0 :         c->interlaced  = 0;
     840           0 :         c->pro         = 1;
     841           0 :         c->frame_info_size = 4;
     842             :     } else {
     843           0 :         av_log(avctx, AV_LOG_ERROR,
     844             :                "Insufficient extradata size %d, should be at least 16\n",
     845             :                avctx->extradata_size);
     846           0 :         return AVERROR_INVALIDDATA;
     847             :     }
     848             : 
     849          46 :     c->slice_bits_size = 0;
     850             : 
     851          46 :     switch (avctx->codec_tag) {
     852          10 :     case MKTAG('U', 'L', 'R', 'G'):
     853          10 :         c->planes      = 3;
     854          10 :         avctx->pix_fmt = AV_PIX_FMT_GBRP;
     855          10 :         break;
     856           8 :     case MKTAG('U', 'L', 'R', 'A'):
     857           8 :         c->planes      = 4;
     858           8 :         avctx->pix_fmt = AV_PIX_FMT_GBRAP;
     859           8 :         break;
     860           4 :     case MKTAG('U', 'L', 'Y', '0'):
     861           4 :         c->planes      = 3;
     862           4 :         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     863           4 :         avctx->colorspace = AVCOL_SPC_BT470BG;
     864           4 :         break;
     865           4 :     case MKTAG('U', 'L', 'Y', '2'):
     866           4 :         c->planes      = 3;
     867           4 :         avctx->pix_fmt = AV_PIX_FMT_YUV422P;
     868           4 :         avctx->colorspace = AVCOL_SPC_BT470BG;
     869           4 :         break;
     870           0 :     case MKTAG('U', 'L', 'Y', '4'):
     871           0 :         c->planes      = 3;
     872           0 :         avctx->pix_fmt = AV_PIX_FMT_YUV444P;
     873           0 :         avctx->colorspace = AVCOL_SPC_BT470BG;
     874           0 :         break;
     875           0 :     case MKTAG('U', 'Q', 'Y', '2'):
     876           0 :         c->planes      = 3;
     877           0 :         avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
     878           0 :         break;
     879           0 :     case MKTAG('U', 'Q', 'R', 'G'):
     880           0 :         c->planes      = 3;
     881           0 :         avctx->pix_fmt = AV_PIX_FMT_GBRP10;
     882           0 :         break;
     883           0 :     case MKTAG('U', 'Q', 'R', 'A'):
     884           0 :         c->planes      = 4;
     885           0 :         avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
     886           0 :         break;
     887           6 :     case MKTAG('U', 'L', 'H', '0'):
     888           6 :         c->planes      = 3;
     889           6 :         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     890           6 :         avctx->colorspace = AVCOL_SPC_BT709;
     891           6 :         break;
     892           6 :     case MKTAG('U', 'L', 'H', '2'):
     893           6 :         c->planes      = 3;
     894           6 :         avctx->pix_fmt = AV_PIX_FMT_YUV422P;
     895           6 :         avctx->colorspace = AVCOL_SPC_BT709;
     896           6 :         break;
     897           8 :     case MKTAG('U', 'L', 'H', '4'):
     898           8 :         c->planes      = 3;
     899           8 :         avctx->pix_fmt = AV_PIX_FMT_YUV444P;
     900           8 :         avctx->colorspace = AVCOL_SPC_BT709;
     901           8 :         break;
     902           0 :     default:
     903           0 :         av_log(avctx, AV_LOG_ERROR, "Unknown Ut Video FOURCC provided (%08X)\n",
     904             :                avctx->codec_tag);
     905           0 :         return AVERROR_INVALIDDATA;
     906             :     }
     907             : 
     908          46 :     return 0;
     909             : }
     910             : 
     911          46 : static av_cold int decode_end(AVCodecContext *avctx)
     912             : {
     913          46 :     UtvideoContext * const c = avctx->priv_data;
     914             : 
     915          46 :     av_freep(&c->slice_bits);
     916             : 
     917          46 :     return 0;
     918             : }
     919             : 
     920             : AVCodec ff_utvideo_decoder = {
     921             :     .name           = "utvideo",
     922             :     .long_name      = NULL_IF_CONFIG_SMALL("Ut Video"),
     923             :     .type           = AVMEDIA_TYPE_VIDEO,
     924             :     .id             = AV_CODEC_ID_UTVIDEO,
     925             :     .priv_data_size = sizeof(UtvideoContext),
     926             :     .init           = decode_init,
     927             :     .close          = decode_end,
     928             :     .decode         = decode_frame,
     929             :     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
     930             :     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     931             : };

Generated by: LCOV version 1.13