LCOV - code coverage report
Current view: top level - libavcodec - escape130.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 146 161 90.7 %
Date: 2017-12-16 01:21:47 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Escape 130 video decoder
       3             :  * Copyright (C) 2008 Eli Friedman (eli.friedman <at> gmail.com)
       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             : #include "libavutil/attributes.h"
      23             : #include "libavutil/mem.h"
      24             : 
      25             : #define BITSTREAM_READER_LE
      26             : #include "avcodec.h"
      27             : #include "get_bits.h"
      28             : #include "internal.h"
      29             : 
      30             : typedef struct Escape130Context {
      31             :     uint8_t *old_y_avg;
      32             : 
      33             :     uint8_t *new_y, *old_y;
      34             :     uint8_t *new_u, *old_u;
      35             :     uint8_t *new_v, *old_v;
      36             : 
      37             :     uint8_t *buf1, *buf2;
      38             :     int     linesize[3];
      39             : } Escape130Context;
      40             : 
      41             : static const uint8_t offset_table[] = { 2, 4, 10, 20 };
      42             : static const int8_t sign_table[64][4] = {
      43             :     {  0,  0,  0,  0 },
      44             :     { -1,  1,  0,  0 },
      45             :     {  1, -1,  0,  0 },
      46             :     { -1,  0,  1,  0 },
      47             :     { -1,  1,  1,  0 },
      48             :     {  0, -1,  1,  0 },
      49             :     {  1, -1,  1,  0 },
      50             :     { -1, -1,  1,  0 },
      51             :     {  1,  0, -1,  0 },
      52             :     {  0,  1, -1,  0 },
      53             :     {  1,  1, -1,  0 },
      54             :     { -1,  1, -1,  0 },
      55             :     {  1, -1, -1,  0 },
      56             :     { -1,  0,  0,  1 },
      57             :     { -1,  1,  0,  1 },
      58             :     {  0, -1,  0,  1 },
      59             : 
      60             :     {  0,  0,  0,  0 },
      61             :     {  1, -1,  0,  1 },
      62             :     { -1, -1,  0,  1 },
      63             :     { -1,  0,  1,  1 },
      64             :     { -1,  1,  1,  1 },
      65             :     {  0, -1,  1,  1 },
      66             :     {  1, -1,  1,  1 },
      67             :     { -1, -1,  1,  1 },
      68             :     {  0,  0, -1,  1 },
      69             :     {  1,  0, -1,  1 },
      70             :     { -1,  0, -1,  1 },
      71             :     {  0,  1, -1,  1 },
      72             :     {  1,  1, -1,  1 },
      73             :     { -1,  1, -1,  1 },
      74             :     {  0, -1, -1,  1 },
      75             :     {  1, -1, -1,  1 },
      76             : 
      77             :     {  0,  0,  0,  0 },
      78             :     { -1, -1, -1,  1 },
      79             :     {  1,  0,  0, -1 },
      80             :     {  0,  1,  0, -1 },
      81             :     {  1,  1,  0, -1 },
      82             :     { -1,  1,  0, -1 },
      83             :     {  1, -1,  0, -1 },
      84             :     {  0,  0,  1, -1 },
      85             :     {  1,  0,  1, -1 },
      86             :     { -1,  0,  1, -1 },
      87             :     {  0,  1,  1, -1 },
      88             :     {  1,  1,  1, -1 },
      89             :     { -1,  1,  1, -1 },
      90             :     {  0, -1,  1, -1 },
      91             :     {  1, -1,  1, -1 },
      92             :     { -1, -1,  1, -1 },
      93             : 
      94             :     {  0,  0,  0,  0 },
      95             :     {  1,  0, -1, -1 },
      96             :     {  0,  1, -1, -1 },
      97             :     {  1,  1, -1, -1 },
      98             :     { -1,  1, -1, -1 },
      99             :     {  1, -1, -1, -1 }
     100             : };
     101             : 
     102             : static const int8_t luma_adjust[] = { -4, -3, -2, -1, 1, 2, 3, 4 };
     103             : 
     104             : static const int8_t chroma_adjust[2][8] = {
     105             :     { 1, 1, 0, -1, -1, -1,  0,  1 },
     106             :     { 0, 1, 1,  1,  0, -1, -1, -1 }
     107             : };
     108             : 
     109             : static const uint8_t chroma_vals[] = {
     110             :      20,  28,  36,  44,  52,  60,  68,  76,
     111             :      84,  92, 100, 106, 112, 116, 120, 124,
     112             :     128, 132, 136, 140, 144, 150, 156, 164,
     113             :     172, 180, 188, 196, 204, 212, 220, 228
     114             : };
     115             : 
     116           2 : static av_cold int escape130_decode_init(AVCodecContext *avctx)
     117             : {
     118           2 :     Escape130Context *s = avctx->priv_data;
     119           2 :     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     120             : 
     121           2 :     if ((avctx->width & 1) || (avctx->height & 1)) {
     122           0 :         av_log(avctx, AV_LOG_ERROR,
     123             :                "Dimensions should be a multiple of two.\n");
     124           0 :         return AVERROR_INVALIDDATA;
     125             :     }
     126             : 
     127           2 :     s->old_y_avg = av_malloc(avctx->width * avctx->height / 4);
     128           2 :     s->buf1      = av_malloc(avctx->width * avctx->height * 3 / 2);
     129           2 :     s->buf2      = av_malloc(avctx->width * avctx->height * 3 / 2);
     130           2 :     if (!s->old_y_avg || !s->buf1 || !s->buf2) {
     131           0 :         av_freep(&s->old_y_avg);
     132           0 :         av_freep(&s->buf1);
     133           0 :         av_freep(&s->buf2);
     134           0 :         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
     135           0 :         return AVERROR(ENOMEM);
     136             :     }
     137             : 
     138           2 :     s->linesize[0] = avctx->width;
     139           2 :     s->linesize[1] =
     140           2 :     s->linesize[2] = avctx->width / 2;
     141             : 
     142           2 :     s->new_y = s->buf1;
     143           2 :     s->new_u = s->new_y + avctx->width * avctx->height;
     144           2 :     s->new_v = s->new_u + avctx->width * avctx->height / 4;
     145           2 :     s->old_y = s->buf2;
     146           2 :     s->old_u = s->old_y + avctx->width * avctx->height;
     147           2 :     s->old_v = s->old_u + avctx->width * avctx->height / 4;
     148           2 :     memset(s->old_y, 0,    avctx->width * avctx->height);
     149           2 :     memset(s->old_u, 0x10, avctx->width * avctx->height / 4);
     150           2 :     memset(s->old_v, 0x10, avctx->width * avctx->height / 4);
     151             : 
     152           2 :     return 0;
     153             : }
     154             : 
     155           2 : static av_cold int escape130_decode_close(AVCodecContext *avctx)
     156             : {
     157           2 :     Escape130Context *s = avctx->priv_data;
     158             : 
     159           2 :     av_freep(&s->old_y_avg);
     160           2 :     av_freep(&s->buf1);
     161           2 :     av_freep(&s->buf2);
     162             : 
     163           2 :     return 0;
     164             : }
     165             : 
     166     1642909 : static int decode_skip_count(GetBitContext* gb)
     167             : {
     168             :     int value;
     169             : 
     170     1642909 :     if (get_bits_left(gb) < 1+3)
     171           0 :         return -1;
     172             : 
     173     1642909 :     value = get_bits1(gb);
     174     1642909 :     if (value)
     175     1274799 :         return 0;
     176             : 
     177      368110 :     value = get_bits(gb, 3);
     178      368110 :     if (value)
     179      296591 :         return value;
     180             : 
     181       71519 :     value = get_bits(gb, 8);
     182       71519 :     if (value)
     183       70932 :         return value + 7;
     184             : 
     185         587 :     value = get_bits(gb, 15);
     186         587 :     if (value)
     187         587 :         return value + 262;
     188             : 
     189           0 :     return -1;
     190             : }
     191             : 
     192         359 : static int escape130_decode_frame(AVCodecContext *avctx, void *data,
     193             :                                   int *got_frame, AVPacket *avpkt)
     194             : {
     195         359 :     int buf_size        = avpkt->size;
     196         359 :     Escape130Context *s = avctx->priv_data;
     197         359 :     AVFrame *pic        = data;
     198             :     GetBitContext gb;
     199             :     int ret;
     200             : 
     201             :     uint8_t *old_y, *old_cb, *old_cr,
     202             :             *new_y, *new_cb, *new_cr;
     203             :     uint8_t *dstY, *dstU, *dstV;
     204             :     unsigned old_y_stride, old_cb_stride, old_cr_stride,
     205             :              new_y_stride, new_cb_stride, new_cr_stride;
     206         359 :     unsigned total_blocks = avctx->width * avctx->height / 4,
     207         359 :              block_index, block_x = 0;
     208         359 :     unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10;
     209         359 :     int skip = -1, y_avg = 0, i, j;
     210         359 :     uint8_t *ya = s->old_y_avg;
     211             : 
     212             :     // first 16 bytes are header; no useful information in here
     213         359 :     if (buf_size <= 16) {
     214           0 :         av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n");
     215           0 :         return AVERROR_INVALIDDATA;
     216             :     }
     217             : 
     218         359 :     if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
     219           0 :         return ret;
     220             : 
     221         359 :     if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
     222           0 :         return ret;
     223         359 :     skip_bits_long(&gb, 16 * 8);
     224             : 
     225         359 :     new_y  = s->new_y;
     226         359 :     new_cb = s->new_u;
     227         359 :     new_cr = s->new_v;
     228         359 :     new_y_stride  = s->linesize[0];
     229         359 :     new_cb_stride = s->linesize[1];
     230         359 :     new_cr_stride = s->linesize[2];
     231         359 :     old_y  = s->old_y;
     232         359 :     old_cb = s->old_u;
     233         359 :     old_cr = s->old_v;
     234         359 :     old_y_stride  = s->linesize[0];
     235         359 :     old_cb_stride = s->linesize[1];
     236         359 :     old_cr_stride = s->linesize[2];
     237             : 
     238     4595559 :     for (block_index = 0; block_index < total_blocks; block_index++) {
     239             :         // Note that this call will make us skip the rest of the blocks
     240             :         // if the frame ends prematurely.
     241     4595200 :         if (skip == -1)
     242     1642909 :             skip = decode_skip_count(&gb);
     243     4595200 :         if (skip == -1) {
     244           0 :             av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n");
     245           0 :             return AVERROR_INVALIDDATA;
     246             :         }
     247             : 
     248     4595200 :         if (skip) {
     249     2952495 :             y[0] = old_y[0];
     250     2952495 :             y[1] = old_y[1];
     251     2952495 :             y[2] = old_y[old_y_stride];
     252     2952495 :             y[3] = old_y[old_y_stride + 1];
     253     2952495 :             y_avg = ya[0];
     254     2952495 :             cb = old_cb[0];
     255     2952495 :             cr = old_cr[0];
     256             :         } else {
     257     1642705 :             if (get_bits1(&gb)) {
     258      506697 :                 unsigned sign_selector       = get_bits(&gb, 6);
     259      506697 :                 unsigned difference_selector = get_bits(&gb, 2);
     260      506697 :                 y_avg = 2 * get_bits(&gb, 5);
     261     2533485 :                 for (i = 0; i < 4; i++) {
     262     4053576 :                     y[i] = av_clip(y_avg + offset_table[difference_selector] *
     263     2026788 :                                    sign_table[sign_selector][i], 0, 63);
     264             :                 }
     265     1136008 :             } else if (get_bits1(&gb)) {
     266      686938 :                 if (get_bits1(&gb)) {
     267       35948 :                     y_avg = get_bits(&gb, 6);
     268             :                 } else {
     269      650990 :                     unsigned adjust_index = get_bits(&gb, 3);
     270      650990 :                     y_avg = (y_avg + luma_adjust[adjust_index]) & 63;
     271             :                 }
     272     3434690 :                 for (i = 0; i < 4; i++)
     273     2747752 :                     y[i] = y_avg;
     274             :             }
     275             : 
     276     1642705 :             if (get_bits1(&gb)) {
     277      340030 :                 if (get_bits1(&gb)) {
     278        9871 :                     cb = get_bits(&gb, 5);
     279        9871 :                     cr = get_bits(&gb, 5);
     280             :                 } else {
     281      330159 :                     unsigned adjust_index = get_bits(&gb, 3);
     282      330159 :                     cb = (cb + chroma_adjust[0][adjust_index]) & 31;
     283      330159 :                     cr = (cr + chroma_adjust[1][adjust_index]) & 31;
     284             :                 }
     285             :             }
     286             :         }
     287     4595200 :         *ya++ = y_avg;
     288             : 
     289     4595200 :         new_y[0]                = y[0];
     290     4595200 :         new_y[1]                = y[1];
     291     4595200 :         new_y[new_y_stride]     = y[2];
     292     4595200 :         new_y[new_y_stride + 1] = y[3];
     293     4595200 :         *new_cb = cb;
     294     4595200 :         *new_cr = cr;
     295             : 
     296     4595200 :         old_y += 2;
     297     4595200 :         old_cb++;
     298     4595200 :         old_cr++;
     299     4595200 :         new_y += 2;
     300     4595200 :         new_cb++;
     301     4595200 :         new_cr++;
     302     4595200 :         block_x++;
     303     4595200 :         if (block_x * 2 == avctx->width) {
     304       28720 :             block_x = 0;
     305       28720 :             old_y  += old_y_stride * 2  - avctx->width;
     306       28720 :             old_cb += old_cb_stride     - avctx->width / 2;
     307       28720 :             old_cr += old_cr_stride     - avctx->width / 2;
     308       28720 :             new_y  += new_y_stride * 2  - avctx->width;
     309       28720 :             new_cb += new_cb_stride     - avctx->width / 2;
     310       28720 :             new_cr += new_cr_stride     - avctx->width / 2;
     311             :         }
     312             : 
     313     4595200 :         skip--;
     314             :     }
     315             : 
     316         359 :     new_y  = s->new_y;
     317         359 :     new_cb = s->new_u;
     318         359 :     new_cr = s->new_v;
     319         359 :     dstY   = pic->data[0];
     320         359 :     dstU   = pic->data[1];
     321         359 :     dstV   = pic->data[2];
     322       57799 :     for (j = 0; j < avctx->height; j++) {
     323    18438240 :         for (i = 0; i < avctx->width; i++)
     324    18380800 :             dstY[i] = new_y[i] << 2;
     325       57440 :         dstY  += pic->linesize[0];
     326       57440 :         new_y += new_y_stride;
     327             :     }
     328       29079 :     for (j = 0; j < avctx->height / 2; j++) {
     329     4623920 :         for (i = 0; i < avctx->width / 2; i++) {
     330     4595200 :             dstU[i] = chroma_vals[new_cb[i]];
     331     4595200 :             dstV[i] = chroma_vals[new_cr[i]];
     332             :         }
     333       28720 :         dstU   += pic->linesize[1];
     334       28720 :         dstV   += pic->linesize[2];
     335       28720 :         new_cb += new_cb_stride;
     336       28720 :         new_cr += new_cr_stride;
     337             :     }
     338             : 
     339             :     ff_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n",
     340             :             buf_size, get_bits_count(&gb) >> 3);
     341             : 
     342         359 :     FFSWAP(uint8_t*, s->old_y, s->new_y);
     343         359 :     FFSWAP(uint8_t*, s->old_u, s->new_u);
     344         359 :     FFSWAP(uint8_t*, s->old_v, s->new_v);
     345             : 
     346         359 :     *got_frame = 1;
     347             : 
     348         359 :     return buf_size;
     349             : }
     350             : 
     351             : AVCodec ff_escape130_decoder = {
     352             :     .name           = "escape130",
     353             :     .long_name      = NULL_IF_CONFIG_SMALL("Escape 130"),
     354             :     .type           = AVMEDIA_TYPE_VIDEO,
     355             :     .id             = AV_CODEC_ID_ESCAPE130,
     356             :     .priv_data_size = sizeof(Escape130Context),
     357             :     .init           = escape130_decode_init,
     358             :     .close          = escape130_decode_close,
     359             :     .decode         = escape130_decode_frame,
     360             :     .capabilities   = AV_CODEC_CAP_DR1,
     361             : };

Generated by: LCOV version 1.13