LCOV - code coverage report
Current view: top level - libavcodec - hq_hqa.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 159 187 85.0 %
Date: 2017-12-18 13:19:42 Functions: 10 10 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Canopus HQ/HQA decoder
       3             :  *
       4             :  * This file is part of FFmpeg.
       5             :  *
       6             :  * FFmpeg is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU Lesser General Public
       8             :  * License as published by the Free Software Foundation; either
       9             :  * version 2.1 of the License, or (at your option) any later version.
      10             :  *
      11             :  * FFmpeg is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with FFmpeg; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <stdint.h>
      22             : 
      23             : #include "libavutil/attributes.h"
      24             : #include "libavutil/intreadwrite.h"
      25             : 
      26             : #include "avcodec.h"
      27             : #include "canopus.h"
      28             : #include "get_bits.h"
      29             : #include "internal.h"
      30             : 
      31             : #include "hq_hqa.h"
      32             : #include "hq_hqadsp.h"
      33             : 
      34             : /* HQ/HQA slices are a set of macroblocks belonging to a frame, and
      35             :  * they usually form a pseudorandom pattern (probably because it is
      36             :  * nicer to display on partial decode).
      37             :  *
      38             :  * For HQA it just happens that each slice is on every 8th macroblock,
      39             :  * but they can be on any frame width like
      40             :  *   X.......X.
      41             :  *   ......X...
      42             :  *   ....X.....
      43             :  *   ..X.......
      44             :  * etc.
      45             :  *
      46             :  * The original decoder has special handling for edge macroblocks,
      47             :  * while lavc simply aligns coded_width and coded_height.
      48             :  */
      49             : 
      50      221520 : static inline void put_blocks(HQContext *c, AVFrame *pic,
      51             :                               int plane, int x, int y, int ilace,
      52             :                               int16_t *block0, int16_t *block1)
      53             : {
      54      221520 :     uint8_t *p = pic->data[plane] + x;
      55             : 
      56      443040 :     c->hqhqadsp.idct_put(p + y * pic->linesize[plane],
      57      221520 :                          pic->linesize[plane] << ilace, block0);
      58      443040 :     c->hqhqadsp.idct_put(p + (y + (ilace ? 1 : 8)) * pic->linesize[plane],
      59      221520 :                          pic->linesize[plane] << ilace, block1);
      60      221520 : }
      61             : 
      62      365300 : static int hq_decode_block(HQContext *c, GetBitContext *gb, int16_t block[64],
      63             :                            int qsel, int is_chroma, int is_hqa)
      64             : {
      65             :     const int32_t *q;
      66      365300 :     int val, pos = 1;
      67             : 
      68      365300 :     memset(block, 0, 64 * sizeof(*block));
      69             : 
      70      365300 :     if (!is_hqa) {
      71      247200 :         block[0] = get_sbits(gb, 9) * 64;
      72      247200 :         q = ff_hq_quants[qsel][is_chroma][get_bits(gb, 2)];
      73             :     } else {
      74      118100 :         q = ff_hq_quants[qsel][is_chroma][get_bits(gb, 2)];
      75      118100 :         block[0] = get_sbits(gb, 9) * 64;
      76             :     }
      77             : 
      78             :     for (;;) {
      79    11317448 :         val = get_vlc2(gb, c->hq_ac_vlc.table, 9, 2);
      80     5841374 :         if (val < 0)
      81           0 :             return AVERROR_INVALIDDATA;
      82             : 
      83     5841374 :         pos += ff_hq_ac_skips[val];
      84     5841374 :         if (pos >= 64)
      85      365300 :             break;
      86     5476074 :         block[ff_zigzag_direct[pos]] = (int)(ff_hq_ac_syms[val] * (unsigned)q[pos]) >> 12;
      87     5476074 :         pos++;
      88             :     }
      89             : 
      90      365300 :     return 0;
      91             : }
      92             : 
      93       30900 : static int hq_decode_mb(HQContext *c, AVFrame *pic,
      94             :                         GetBitContext *gb, int x, int y)
      95             : {
      96             :     int qgroup, flag;
      97             :     int i, ret;
      98             : 
      99       30900 :     qgroup = get_bits(gb, 4);
     100       30900 :     flag = get_bits1(gb);
     101             : 
     102      278100 :     for (i = 0; i < 8; i++) {
     103      247200 :         ret = hq_decode_block(c, gb, c->block[i], qgroup, i >= 4, 0);
     104      247200 :         if (ret < 0)
     105           0 :             return ret;
     106             :     }
     107             : 
     108       30900 :     put_blocks(c, pic, 0, x,      y, flag, c->block[0], c->block[2]);
     109       30900 :     put_blocks(c, pic, 0, x + 8,  y, flag, c->block[1], c->block[3]);
     110       30900 :     put_blocks(c, pic, 2, x >> 1, y, flag, c->block[4], c->block[5]);
     111       30900 :     put_blocks(c, pic, 1, x >> 1, y, flag, c->block[6], c->block[7]);
     112             : 
     113       30900 :     return 0;
     114             : }
     115             : 
     116          11 : static int hq_decode_frame(HQContext *ctx, AVFrame *pic,
     117             :                            int prof_num, size_t data_size)
     118             : {
     119             :     const HQProfile *profile;
     120             :     GetBitContext gb;
     121          11 :     const uint8_t *perm, *src = ctx->gbc.buffer;
     122             :     uint32_t slice_off[21];
     123             :     int slice, start_off, next_off, i, ret;
     124             : 
     125          11 :     if ((unsigned)prof_num >= NUM_HQ_PROFILES) {
     126           0 :         profile = &ff_hq_profile[0];
     127           0 :         avpriv_request_sample(ctx->avctx, "HQ Profile %d", prof_num);
     128             :     } else {
     129          11 :         profile = &ff_hq_profile[prof_num];
     130          11 :         av_log(ctx->avctx, AV_LOG_VERBOSE, "HQ Profile %d\n", prof_num);
     131             :     }
     132             : 
     133          11 :     ctx->avctx->coded_width         = FFALIGN(profile->width,  16);
     134          11 :     ctx->avctx->coded_height        = FFALIGN(profile->height, 16);
     135          11 :     ctx->avctx->width               = profile->width;
     136          11 :     ctx->avctx->height              = profile->height;
     137          11 :     ctx->avctx->bits_per_raw_sample = 8;
     138          11 :     ctx->avctx->pix_fmt             = AV_PIX_FMT_YUV422P;
     139             : 
     140          11 :     ret = ff_get_buffer(ctx->avctx, pic, 0);
     141          11 :     if (ret < 0)
     142           0 :         return ret;
     143             : 
     144             :     /* Offsets are stored from CUV position, so adjust them accordingly. */
     145         134 :     for (i = 0; i < profile->num_slices + 1; i++)
     146         123 :         slice_off[i] = bytestream2_get_be24(&ctx->gbc) - 4;
     147             : 
     148          11 :     next_off = 0;
     149         123 :     for (slice = 0; slice < profile->num_slices; slice++) {
     150         112 :         start_off = next_off;
     151         112 :         next_off  = profile->tab_h * (slice + 1) / profile->num_slices;
     152         112 :         perm = profile->perm_tab + start_off * profile->tab_w * 2;
     153             : 
     154         224 :         if (slice_off[slice] < (profile->num_slices + 1) * 3 ||
     155         224 :             slice_off[slice] >= slice_off[slice + 1] ||
     156         112 :             slice_off[slice + 1] > data_size) {
     157           0 :             av_log(ctx->avctx, AV_LOG_ERROR,
     158             :                    "Invalid slice size %"SIZE_SPECIFIER".\n", data_size);
     159           0 :             break;
     160             :         }
     161         112 :         init_get_bits(&gb, src + slice_off[slice],
     162         112 :                       (slice_off[slice + 1] - slice_off[slice]) * 8);
     163             : 
     164       31012 :         for (i = 0; i < (next_off - start_off) * profile->tab_w; i++) {
     165       30900 :             ret = hq_decode_mb(ctx, pic, &gb, perm[0] * 16, perm[1] * 16);
     166       30900 :             if (ret < 0) {
     167           0 :                 av_log(ctx->avctx, AV_LOG_ERROR,
     168             :                        "Error decoding macroblock %d at slice %d.\n", i, slice);
     169           0 :                 return ret;
     170             :             }
     171       30900 :             perm += 2;
     172             :         }
     173             :     }
     174             : 
     175          11 :     return 0;
     176             : }
     177             : 
     178       16320 : static int hqa_decode_mb(HQContext *c, AVFrame *pic, int qgroup,
     179             :                          GetBitContext *gb, int x, int y)
     180             : {
     181       16320 :     int flag = 0;
     182             :     int i, ret, cbp;
     183             : 
     184       16320 :     cbp = get_vlc2(gb, c->hqa_cbp_vlc.table, 5, 1);
     185             : 
     186      212160 :     for (i = 0; i < 12; i++)
     187      195840 :         memset(c->block[i], 0, sizeof(*c->block));
     188      212160 :     for (i = 0; i < 12; i++)
     189      195840 :         c->block[i][0] = -128 * (1 << 6);
     190             : 
     191       16320 :     if (cbp) {
     192        9978 :         flag = get_bits1(gb);
     193             : 
     194        9978 :         cbp |= cbp << 4;
     195        9978 :         if (cbp & 0x3)
     196        9890 :             cbp |= 0x500;
     197        9978 :         if (cbp & 0xC)
     198        9874 :             cbp |= 0xA00;
     199      129714 :         for (i = 0; i < 12; i++) {
     200      119736 :             if (!(cbp & (1 << i)))
     201        1636 :                 continue;
     202      118100 :             ret = hq_decode_block(c, gb, c->block[i], qgroup, i >= 8, 1);
     203      118100 :             if (ret < 0)
     204           0 :                 return ret;
     205             :         }
     206             :     }
     207             : 
     208       16320 :     put_blocks(c, pic, 3, x,      y, flag, c->block[ 0], c->block[ 2]);
     209       16320 :     put_blocks(c, pic, 3, x + 8,  y, flag, c->block[ 1], c->block[ 3]);
     210       16320 :     put_blocks(c, pic, 0, x,      y, flag, c->block[ 4], c->block[ 6]);
     211       16320 :     put_blocks(c, pic, 0, x + 8,  y, flag, c->block[ 5], c->block[ 7]);
     212       16320 :     put_blocks(c, pic, 2, x >> 1, y, flag, c->block[ 8], c->block[ 9]);
     213       16320 :     put_blocks(c, pic, 1, x >> 1, y, flag, c->block[10], c->block[11]);
     214             : 
     215       16320 :     return 0;
     216             : }
     217             : 
     218          16 : static int hqa_decode_slice(HQContext *ctx, AVFrame *pic, GetBitContext *gb,
     219             :                             int quant, int slice_no, int w, int h)
     220             : {
     221             :     int i, j, off;
     222             :     int ret;
     223             : 
     224        1104 :     for (i = 0; i < h; i += 16) {
     225        1088 :         off = (slice_no * 16 + i * 3) & 0x70;
     226       17408 :         for (j = off; j < w; j += 128) {
     227       16320 :             ret = hqa_decode_mb(ctx, pic, quant, gb, j, i);
     228       16320 :             if (ret < 0) {
     229           0 :                 av_log(ctx->avctx, AV_LOG_ERROR,
     230             :                        "Error decoding macroblock at %dx%d.\n", i, j);
     231           0 :                 return ret;
     232             :             }
     233             :         }
     234             :     }
     235             : 
     236          16 :     return 0;
     237             : }
     238             : 
     239           2 : static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, size_t data_size)
     240             : {
     241             :     GetBitContext gb;
     242           2 :     const int num_slices = 8;
     243             :     uint32_t slice_off[9];
     244             :     int i, slice, ret;
     245             :     int width, height, quant;
     246           2 :     const uint8_t *src = ctx->gbc.buffer;
     247             : 
     248           2 :     width  = bytestream2_get_be16(&ctx->gbc);
     249           2 :     height = bytestream2_get_be16(&ctx->gbc);
     250             : 
     251           2 :     ctx->avctx->coded_width         = FFALIGN(width,  16);
     252           2 :     ctx->avctx->coded_height        = FFALIGN(height, 16);
     253           2 :     ctx->avctx->width               = width;
     254           2 :     ctx->avctx->height              = height;
     255           2 :     ctx->avctx->bits_per_raw_sample = 8;
     256           2 :     ctx->avctx->pix_fmt             = AV_PIX_FMT_YUVA422P;
     257             : 
     258           2 :     av_log(ctx->avctx, AV_LOG_VERBOSE, "HQA Profile\n");
     259             : 
     260           2 :     quant = bytestream2_get_byte(&ctx->gbc);
     261           2 :     bytestream2_skip(&ctx->gbc, 3);
     262           2 :     if (quant >= NUM_HQ_QUANTS) {
     263           0 :         av_log(ctx->avctx, AV_LOG_ERROR,
     264             :                "Invalid quantization matrix %d.\n", quant);
     265           0 :         return AVERROR_INVALIDDATA;
     266             :     }
     267             : 
     268           2 :     ret = ff_get_buffer(ctx->avctx, pic, 0);
     269           2 :     if (ret < 0)
     270           0 :         return ret;
     271             : 
     272             :     /* Offsets are stored from HQA1 position, so adjust them accordingly. */
     273          20 :     for (i = 0; i < num_slices + 1; i++)
     274          18 :         slice_off[i] = bytestream2_get_be32(&ctx->gbc) - 4;
     275             : 
     276          18 :     for (slice = 0; slice < num_slices; slice++) {
     277          32 :         if (slice_off[slice] < (num_slices + 1) * 3 ||
     278          32 :             slice_off[slice] >= slice_off[slice + 1] ||
     279          16 :             slice_off[slice + 1] > data_size) {
     280           0 :             av_log(ctx->avctx, AV_LOG_ERROR,
     281             :                    "Invalid slice size %"SIZE_SPECIFIER".\n", data_size);
     282           0 :             break;
     283             :         }
     284          16 :         init_get_bits(&gb, src + slice_off[slice],
     285          16 :                       (slice_off[slice + 1] - slice_off[slice]) * 8);
     286             : 
     287          16 :         ret = hqa_decode_slice(ctx, pic, &gb, quant, slice, width, height);
     288          16 :         if (ret < 0)
     289           0 :             return ret;
     290             :     }
     291             : 
     292           2 :     return 0;
     293             : }
     294             : 
     295          13 : static int hq_hqa_decode_frame(AVCodecContext *avctx, void *data,
     296             :                                int *got_frame, AVPacket *avpkt)
     297             : {
     298          13 :     HQContext *ctx = avctx->priv_data;
     299          13 :     AVFrame *pic = data;
     300             :     uint32_t info_tag;
     301             :     unsigned int data_size;
     302             :     int ret;
     303             :     unsigned tag;
     304             : 
     305          13 :     bytestream2_init(&ctx->gbc, avpkt->data, avpkt->size);
     306          13 :     if (bytestream2_get_bytes_left(&ctx->gbc) < 4 + 4) {
     307           0 :         av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", avpkt->size);
     308           0 :         return AVERROR_INVALIDDATA;
     309             :     }
     310             : 
     311          13 :     info_tag = bytestream2_peek_le32(&ctx->gbc);
     312          13 :     if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
     313             :         int info_size;
     314          13 :         bytestream2_skip(&ctx->gbc, 4);
     315          13 :         info_size = bytestream2_get_le32(&ctx->gbc);
     316          13 :         if (bytestream2_get_bytes_left(&ctx->gbc) < info_size) {
     317           0 :             av_log(avctx, AV_LOG_ERROR, "Invalid INFO size (%d).\n", info_size);
     318           0 :             return AVERROR_INVALIDDATA;
     319             :         }
     320          13 :         ff_canopus_parse_info_tag(avctx, ctx->gbc.buffer, info_size);
     321             : 
     322          13 :         bytestream2_skip(&ctx->gbc, info_size);
     323             :     }
     324             : 
     325          13 :     data_size = bytestream2_get_bytes_left(&ctx->gbc);
     326          13 :     if (data_size < 4) {
     327           0 :         av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", data_size);
     328           0 :         return AVERROR_INVALIDDATA;
     329             :     }
     330             : 
     331             :     /* HQ defines dimensions and number of slices, and thus slice traversal
     332             :      * order. HQA has no size constraint and a fixed number of slices, so it
     333             :      * needs a separate scheme for it. */
     334          13 :     tag = bytestream2_get_le32(&ctx->gbc);
     335          13 :     if ((tag & 0x00FFFFFF) == (MKTAG('U', 'V', 'C', ' ') & 0x00FFFFFF)) {
     336          11 :         ret = hq_decode_frame(ctx, pic, tag >> 24, data_size);
     337           2 :     } else if (tag == MKTAG('H', 'Q', 'A', '1')) {
     338           2 :         ret = hqa_decode_frame(ctx, pic, data_size);
     339             :     } else {
     340           0 :         av_log(avctx, AV_LOG_ERROR, "Not a HQ/HQA frame.\n");
     341           0 :         return AVERROR_INVALIDDATA;
     342             :     }
     343          13 :     if (ret < 0) {
     344           0 :         av_log(avctx, AV_LOG_ERROR, "Error decoding frame.\n");
     345           0 :         return ret;
     346             :     }
     347             : 
     348          13 :     pic->key_frame = 1;
     349          13 :     pic->pict_type = AV_PICTURE_TYPE_I;
     350             : 
     351          13 :     *got_frame = 1;
     352             : 
     353          13 :     return avpkt->size;
     354             : }
     355             : 
     356           6 : static av_cold int hq_hqa_decode_init(AVCodecContext *avctx)
     357             : {
     358           6 :     HQContext *ctx = avctx->priv_data;
     359           6 :     ctx->avctx = avctx;
     360             : 
     361           6 :     ff_hqdsp_init(&ctx->hqhqadsp);
     362             : 
     363           6 :     return ff_hq_init_vlcs(ctx);
     364             : }
     365             : 
     366           6 : static av_cold int hq_hqa_decode_close(AVCodecContext *avctx)
     367             : {
     368           6 :     HQContext *ctx = avctx->priv_data;
     369             : 
     370           6 :     ff_free_vlc(&ctx->hq_ac_vlc);
     371           6 :     ff_free_vlc(&ctx->hqa_cbp_vlc);
     372             : 
     373           6 :     return 0;
     374             : }
     375             : 
     376             : AVCodec ff_hq_hqa_decoder = {
     377             :     .name           = "hq_hqa",
     378             :     .long_name      = NULL_IF_CONFIG_SMALL("Canopus HQ/HQA"),
     379             :     .type           = AVMEDIA_TYPE_VIDEO,
     380             :     .id             = AV_CODEC_ID_HQ_HQA,
     381             :     .priv_data_size = sizeof(HQContext),
     382             :     .init           = hq_hqa_decode_init,
     383             :     .decode         = hq_hqa_decode_frame,
     384             :     .close          = hq_hqa_decode_close,
     385             :     .capabilities   = AV_CODEC_CAP_DR1,
     386             :     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
     387             :                       FF_CODEC_CAP_INIT_CLEANUP,
     388             : };

Generated by: LCOV version 1.13