LCOV - code coverage report
Current view: top level - libavcodec - asvenc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 193 207 93.2 %
Date: 2017-12-18 20:14:19 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2003 Michael Niedermayer
       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             : /**
      22             :  * @file
      23             :  * ASUS V1/V2 encoder.
      24             :  */
      25             : 
      26             : #include "libavutil/attributes.h"
      27             : #include "libavutil/mem.h"
      28             : 
      29             : #include "aandcttab.h"
      30             : #include "asv.h"
      31             : #include "avcodec.h"
      32             : #include "dct.h"
      33             : #include "fdctdsp.h"
      34             : #include "internal.h"
      35             : #include "mathops.h"
      36             : #include "mpeg12data.h"
      37             : 
      38      718813 : static inline void asv2_put_bits(PutBitContext *pb, int n, int v)
      39             : {
      40      718813 :     put_bits(pb, n, ff_reverse[v << (8 - n)]);
      41      718813 : }
      42             : 
      43     2972884 : static inline void asv1_put_level(PutBitContext *pb, int level)
      44             : {
      45     2972884 :     unsigned int index = level + 3;
      46             : 
      47     2972884 :     if (index <= 6) {
      48     2543172 :         put_bits(pb, ff_asv_level_tab[index][1], ff_asv_level_tab[index][0]);
      49             :     } else {
      50      429712 :         put_bits(pb, ff_asv_level_tab[3][1], ff_asv_level_tab[3][0]);
      51      429712 :         put_sbits(pb, 8, level);
      52             :     }
      53     2972884 : }
      54             : 
      55     3660409 : static inline void asv2_put_level(ASV1Context *a, PutBitContext *pb, int level)
      56             : {
      57     3660409 :     unsigned int index = level + 31;
      58             : 
      59     3660409 :     if (index <= 62) {
      60     3659796 :         put_bits(pb, ff_asv2_level_tab[index][1], ff_asv2_level_tab[index][0]);
      61             :     } else {
      62         613 :         put_bits(pb, ff_asv2_level_tab[31][1], ff_asv2_level_tab[31][0]);
      63         613 :         if (level < -128 || level > 127) {
      64           0 :             av_log(a->avctx, AV_LOG_WARNING, "Clipping level %d, increase qscale\n", level);
      65           0 :             level = av_clip_int8(level);
      66             :         }
      67         613 :         asv2_put_bits(pb, 8, level & 0xFF);
      68             :     }
      69     3660409 : }
      70             : 
      71      359100 : static inline void asv1_encode_block(ASV1Context *a, int16_t block[64])
      72             : {
      73             :     int i;
      74      359100 :     int nc_count = 0;
      75             : 
      76      359100 :     put_bits(&a->pb, 8, (block[0] + 32) >> 6);
      77      359100 :     block[0] = 0;
      78             : 
      79     3950100 :     for (i = 0; i < 10; i++) {
      80     3591000 :         const int index = ff_asv_scantab[4 * i];
      81     3591000 :         int ccp         = 0;
      82             : 
      83    10773000 :         if ((block[index + 0] = (block[index + 0] *
      84     7182000 :                                  a->q_intra_matrix[index + 0] + (1 << 15)) >> 16))
      85      759471 :             ccp |= 8;
      86    10773000 :         if ((block[index + 8] = (block[index + 8] *
      87     7182000 :                                  a->q_intra_matrix[index + 8] + (1 << 15)) >> 16))
      88      828513 :             ccp |= 4;
      89    10773000 :         if ((block[index + 1] = (block[index + 1] *
      90     7182000 :                                  a->q_intra_matrix[index + 1] + (1 << 15)) >> 16))
      91      781213 :             ccp |= 2;
      92    10773000 :         if ((block[index + 9] = (block[index + 9] *
      93     7182000 :                                  a->q_intra_matrix[index + 9] + (1 << 15)) >> 16))
      94      603687 :             ccp |= 1;
      95             : 
      96     3591000 :         if (ccp) {
      97     1769652 :             for (; nc_count; nc_count--)
      98      405258 :                 put_bits(&a->pb, ff_asv_ccp_tab[0][1], ff_asv_ccp_tab[0][0]);
      99             : 
     100     1364394 :             put_bits(&a->pb, ff_asv_ccp_tab[ccp][1], ff_asv_ccp_tab[ccp][0]);
     101             : 
     102     1364394 :             if (ccp & 8)
     103      759471 :                 asv1_put_level(&a->pb, block[index + 0]);
     104     1364394 :             if (ccp & 4)
     105      828513 :                 asv1_put_level(&a->pb, block[index + 8]);
     106     1364394 :             if (ccp & 2)
     107      781213 :                 asv1_put_level(&a->pb, block[index + 1]);
     108     1364394 :             if (ccp & 1)
     109      603687 :                 asv1_put_level(&a->pb, block[index + 9]);
     110             :         } else {
     111     2226606 :             nc_count++;
     112             :         }
     113             :     }
     114      359100 :     put_bits(&a->pb, ff_asv_ccp_tab[16][1], ff_asv_ccp_tab[16][0]);
     115      359100 : }
     116             : 
     117      359100 : static inline void asv2_encode_block(ASV1Context *a, int16_t block[64])
     118             : {
     119             :     int i;
     120      359100 :     int count = 0;
     121             : 
     122    14496453 :     for (count = 63; count > 3; count--) {
     123    14433466 :         const int index = ff_asv_scantab[count];
     124    14433466 :         if ((block[index] * a->q_intra_matrix[index] + (1 << 15)) >> 16)
     125      296113 :             break;
     126             :     }
     127             : 
     128      359100 :     count >>= 2;
     129             : 
     130      359100 :     asv2_put_bits(&a->pb, 4, count);
     131      359100 :     asv2_put_bits(&a->pb, 8, (block[0] + 32) >> 6);
     132      359100 :     block[0] = 0;
     133             : 
     134     2709128 :     for (i = 0; i <= count; i++) {
     135     2350028 :         const int index = ff_asv_scantab[4 * i];
     136     2350028 :         int ccp         = 0;
     137             : 
     138     7050084 :         if ((block[index + 0] = (block[index + 0] *
     139     4700056 :                                  a->q_intra_matrix[index + 0] + (1 << 15)) >> 16))
     140      968959 :             ccp |= 8;
     141     7050084 :         if ((block[index + 8] = (block[index + 8] *
     142     4700056 :                                  a->q_intra_matrix[index + 8] + (1 << 15)) >> 16))
     143     1014552 :             ccp |= 4;
     144     7050084 :         if ((block[index + 1] = (block[index + 1] *
     145     4700056 :                                  a->q_intra_matrix[index + 1] + (1 << 15)) >> 16))
     146      951514 :             ccp |= 2;
     147     7050084 :         if ((block[index + 9] = (block[index + 9] *
     148     4700056 :                                  a->q_intra_matrix[index + 9] + (1 << 15)) >> 16))
     149      725384 :             ccp |= 1;
     150             : 
     151             :         av_assert2(i || ccp < 8);
     152     2350028 :         if (i)
     153     1990928 :             put_bits(&a->pb, ff_asv_ac_ccp_tab[ccp][1], ff_asv_ac_ccp_tab[ccp][0]);
     154             :         else
     155      359100 :             put_bits(&a->pb, ff_asv_dc_ccp_tab[ccp][1], ff_asv_dc_ccp_tab[ccp][0]);
     156             : 
     157     2350028 :         if (ccp) {
     158     1697818 :             if (ccp & 8)
     159      968959 :                 asv2_put_level(a, &a->pb, block[index + 0]);
     160     1697818 :             if (ccp & 4)
     161     1014552 :                 asv2_put_level(a, &a->pb, block[index + 8]);
     162     1697818 :             if (ccp & 2)
     163      951514 :                 asv2_put_level(a, &a->pb, block[index + 1]);
     164     1697818 :             if (ccp & 1)
     165      725384 :                 asv2_put_level(a, &a->pb, block[index + 9]);
     166             :         }
     167             :     }
     168      359100 : }
     169             : 
     170             : #define MAX_MB_SIZE (30 * 16 * 16 * 3 / 2 / 8)
     171             : 
     172      119700 : static inline int encode_mb(ASV1Context *a, int16_t block[6][64])
     173             : {
     174             :     int i;
     175             : 
     176      119700 :     if (a->pb.buf_end - a->pb.buf - (put_bits_count(&a->pb) >> 3) < MAX_MB_SIZE) {
     177           0 :         av_log(a->avctx, AV_LOG_ERROR, "encoded frame too large\n");
     178           0 :         return -1;
     179             :     }
     180             : 
     181      119700 :     if (a->avctx->codec_id == AV_CODEC_ID_ASV1) {
     182      418950 :         for (i = 0; i < 6; i++)
     183      359100 :             asv1_encode_block(a, block[i]);
     184             :     } else {
     185      418950 :         for (i = 0; i < 6; i++) {
     186      359100 :             asv2_encode_block(a, block[i]);
     187             :         }
     188             :     }
     189      119700 :     return 0;
     190             : }
     191             : 
     192      119700 : static inline void dct_get(ASV1Context *a, const AVFrame *frame,
     193             :                            int mb_x, int mb_y)
     194             : {
     195      119700 :     int16_t (*block)[64] = a->block;
     196      119700 :     int linesize = frame->linesize[0];
     197             :     int i;
     198             : 
     199      119700 :     uint8_t *ptr_y  = frame->data[0] + (mb_y * 16 * linesize)           + mb_x * 16;
     200      119700 :     uint8_t *ptr_cb = frame->data[1] + (mb_y *  8 * frame->linesize[1]) + mb_x *  8;
     201      119700 :     uint8_t *ptr_cr = frame->data[2] + (mb_y *  8 * frame->linesize[2]) + mb_x *  8;
     202             : 
     203      119700 :     a->pdsp.get_pixels(block[0], ptr_y,                    linesize);
     204      119700 :     a->pdsp.get_pixels(block[1], ptr_y + 8,                linesize);
     205      119700 :     a->pdsp.get_pixels(block[2], ptr_y + 8 * linesize,     linesize);
     206      119700 :     a->pdsp.get_pixels(block[3], ptr_y + 8 * linesize + 8, linesize);
     207      598500 :     for (i = 0; i < 4; i++)
     208      478800 :         a->fdsp.fdct(block[i]);
     209             : 
     210      119700 :     if (!(a->avctx->flags & AV_CODEC_FLAG_GRAY)) {
     211      119700 :         a->pdsp.get_pixels(block[4], ptr_cb, frame->linesize[1]);
     212      119700 :         a->pdsp.get_pixels(block[5], ptr_cr, frame->linesize[2]);
     213      359100 :         for (i = 4; i < 6; i++)
     214      239400 :             a->fdsp.fdct(block[i]);
     215             :     }
     216      119700 : }
     217             : 
     218         500 : static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     219             :                         const AVFrame *pict, int *got_packet)
     220             : {
     221         500 :     ASV1Context *const a = avctx->priv_data;
     222             :     int size, ret;
     223             :     int mb_x, mb_y;
     224             : 
     225         500 :     if (pict->width % 16 || pict->height % 16) {
     226         100 :         AVFrame *clone = av_frame_alloc();
     227             :         int i;
     228             : 
     229         100 :         if (!clone)
     230           0 :             return AVERROR(ENOMEM);
     231         100 :         clone->format = pict->format;
     232         100 :         clone->width  = FFALIGN(pict->width, 16);
     233         100 :         clone->height = FFALIGN(pict->height, 16);
     234         100 :         ret = av_frame_get_buffer(clone, 32);
     235         100 :         if (ret < 0) {
     236           0 :             av_frame_free(&clone);
     237           0 :             return ret;
     238             :         }
     239             : 
     240         100 :         ret = av_frame_copy(clone, pict);
     241         100 :         if (ret < 0) {
     242           0 :             av_frame_free(&clone);
     243           0 :             return ret;
     244             :         }
     245             : 
     246         400 :         for (i = 0; i<3; i++) {
     247             :             int x, y;
     248         300 :             int w  = AV_CEIL_RSHIFT(pict->width, !!i);
     249         300 :             int h  = AV_CEIL_RSHIFT(pict->height, !!i);
     250         300 :             int w2 = AV_CEIL_RSHIFT(clone->width, !!i);
     251         300 :             int h2 = AV_CEIL_RSHIFT(clone->height, !!i);
     252        7100 :             for (y=0; y<h; y++)
     253       78200 :                 for (x=w; x<w2; x++)
     254      142800 :                     clone->data[i][x + y*clone->linesize[i]] =
     255      142800 :                         clone->data[i][w - 1 + y*clone->linesize[i]];
     256        3100 :             for (y=h; y<h2; y++)
     257      103600 :                 for (x=0; x<w2; x++)
     258      201600 :                     clone->data[i][x + y*clone->linesize[i]] =
     259      201600 :                         clone->data[i][x + (h-1)*clone->linesize[i]];
     260             :         }
     261         100 :         ret = encode_frame(avctx, pkt, clone, got_packet);
     262             : 
     263         100 :         av_frame_free(&clone);
     264         100 :         return ret;
     265             :     }
     266             : 
     267         400 :     if ((ret = ff_alloc_packet2(avctx, pkt, a->mb_height * a->mb_width * MAX_MB_SIZE +
     268             :                                 AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
     269           0 :         return ret;
     270             : 
     271         400 :     init_put_bits(&a->pb, pkt->data, pkt->size);
     272             : 
     273        6000 :     for (mb_y = 0; mb_y < a->mb_height2; mb_y++) {
     274      124800 :         for (mb_x = 0; mb_x < a->mb_width2; mb_x++) {
     275      119200 :             dct_get(a, pict, mb_x, mb_y);
     276      119200 :             encode_mb(a, a->block);
     277             :         }
     278             :     }
     279             : 
     280         400 :     if (a->mb_width2 != a->mb_width) {
     281         100 :         mb_x = a->mb_width2;
     282         300 :         for (mb_y = 0; mb_y < a->mb_height2; mb_y++) {
     283         200 :             dct_get(a, pict, mb_x, mb_y);
     284         200 :             encode_mb(a, a->block);
     285             :         }
     286             :     }
     287             : 
     288         400 :     if (a->mb_height2 != a->mb_height) {
     289         100 :         mb_y = a->mb_height2;
     290         400 :         for (mb_x = 0; mb_x < a->mb_width; mb_x++) {
     291         300 :             dct_get(a, pict, mb_x, mb_y);
     292         300 :             encode_mb(a, a->block);
     293             :         }
     294             :     }
     295         400 :     emms_c();
     296             : 
     297         400 :     avpriv_align_put_bits(&a->pb);
     298        1403 :     while (put_bits_count(&a->pb) & 31)
     299         603 :         put_bits(&a->pb, 8, 0);
     300             : 
     301         400 :     size = put_bits_count(&a->pb) / 32;
     302             : 
     303         400 :     if (avctx->codec_id == AV_CODEC_ID_ASV1) {
     304         400 :         a->bbdsp.bswap_buf((uint32_t *) pkt->data,
     305         200 :                            (uint32_t *) pkt->data, size);
     306             :     } else {
     307             :         int i;
     308     2941200 :         for (i = 0; i < 4 * size; i++)
     309     2941000 :             pkt->data[i] = ff_reverse[pkt->data[i]];
     310             :     }
     311             : 
     312         400 :     pkt->size   = size * 4;
     313         400 :     pkt->flags |= AV_PKT_FLAG_KEY;
     314         400 :     *got_packet = 1;
     315             : 
     316         400 :     return 0;
     317             : }
     318             : 
     319           8 : static av_cold int encode_init(AVCodecContext *avctx)
     320             : {
     321           8 :     ASV1Context *const a = avctx->priv_data;
     322             :     int i;
     323           8 :     const int scale = avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2;
     324             : 
     325           8 :     ff_asv_common_init(avctx);
     326           8 :     ff_fdctdsp_init(&a->fdsp, avctx);
     327           8 :     ff_pixblockdsp_init(&a->pdsp, avctx);
     328             : 
     329           8 :     if (avctx->global_quality <= 0)
     330           0 :         avctx->global_quality = 4 * FF_QUALITY_SCALE;
     331             : 
     332          24 :     a->inv_qscale = (32 * scale * FF_QUALITY_SCALE +
     333          16 :                      avctx->global_quality / 2) / avctx->global_quality;
     334             : 
     335           8 :     avctx->extradata                   = av_mallocz(8);
     336           8 :     if (!avctx->extradata)
     337           0 :         return AVERROR(ENOMEM);
     338           8 :     avctx->extradata_size              = 8;
     339           8 :     ((uint32_t *) avctx->extradata)[0] = av_le2ne32(a->inv_qscale);
     340           8 :     ((uint32_t *) avctx->extradata)[1] = av_le2ne32(AV_RL32("ASUS"));
     341             : 
     342         520 :     for (i = 0; i < 64; i++) {
     343         512 :         if (a->fdsp.fdct == ff_fdct_ifast) {
     344         512 :             int q = 32LL * scale * ff_mpeg1_default_intra_matrix[i] * ff_aanscales[i];
     345         512 :             a->q_intra_matrix[i] = (((int64_t)a->inv_qscale << 30) + q / 2) / q;
     346             :         } else {
     347           0 :             int q = 32 * scale * ff_mpeg1_default_intra_matrix[i];
     348           0 :             a->q_intra_matrix[i] = ((a->inv_qscale << 16) + q / 2) / q;
     349             :         }
     350             :     }
     351             : 
     352           8 :     return 0;
     353             : }
     354             : 
     355             : #if CONFIG_ASV1_ENCODER
     356             : AVCodec ff_asv1_encoder = {
     357             :     .name           = "asv1",
     358             :     .long_name      = NULL_IF_CONFIG_SMALL("ASUS V1"),
     359             :     .type           = AVMEDIA_TYPE_VIDEO,
     360             :     .id             = AV_CODEC_ID_ASV1,
     361             :     .priv_data_size = sizeof(ASV1Context),
     362             :     .init           = encode_init,
     363             :     .encode2        = encode_frame,
     364             :     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
     365             :                                                      AV_PIX_FMT_NONE },
     366             :     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     367             : };
     368             : #endif
     369             : 
     370             : #if CONFIG_ASV2_ENCODER
     371             : AVCodec ff_asv2_encoder = {
     372             :     .name           = "asv2",
     373             :     .long_name      = NULL_IF_CONFIG_SMALL("ASUS V2"),
     374             :     .type           = AVMEDIA_TYPE_VIDEO,
     375             :     .id             = AV_CODEC_ID_ASV2,
     376             :     .priv_data_size = sizeof(ASV1Context),
     377             :     .init           = encode_init,
     378             :     .encode2        = encode_frame,
     379             :     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
     380             :                                                      AV_PIX_FMT_NONE },
     381             :     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
     382             : };
     383             : #endif

Generated by: LCOV version 1.13