| Line | Branch | Exec | Source | 
|---|---|---|---|
| 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 "config_components.h" | ||
| 27 | |||
| 28 | #include "libavutil/attributes.h" | ||
| 29 | #include "libavutil/intreadwrite.h" | ||
| 30 | #include "libavutil/mem.h" | ||
| 31 | #include "libavutil/mem_internal.h" | ||
| 32 | |||
| 33 | #include "aandcttab.h" | ||
| 34 | #include "asv.h" | ||
| 35 | #include "avcodec.h" | ||
| 36 | #include "codec_internal.h" | ||
| 37 | #include "encode.h" | ||
| 38 | #include "fdctdsp.h" | ||
| 39 | #include "mpeg12data.h" | ||
| 40 | #include "pixblockdsp.h" | ||
| 41 | #include "put_bits.h" | ||
| 42 | |||
| 43 | typedef struct ASVEncContext { | ||
| 44 | ASVCommonContext c; | ||
| 45 | |||
| 46 | PutBitContext pb; | ||
| 47 | |||
| 48 | void (*get_pixels)(int16_t *restrict block, | ||
| 49 | const uint8_t *pixels, | ||
| 50 | ptrdiff_t stride); | ||
| 51 | |||
| 52 | PixblockDSPContext pdsp; | ||
| 53 | FDCTDSPContext fdsp; | ||
| 54 | DECLARE_ALIGNED(32, int16_t, block)[6][64]; | ||
| 55 | int q_intra_matrix[64]; | ||
| 56 | } ASVEncContext; | ||
| 57 | |||
| 58 | enum { | ||
| 59 | ASV1_MAX_BLOCK_SIZE = 8 + 10 * FFMAX(2 /* skip */, 5 /* ccp */ + 4 * 11 /* level */) + 5, | ||
| 60 | ASV1_MAX_MB_SIZE = 6 * ASV1_MAX_BLOCK_SIZE, | ||
| 61 | ASV2_MAX_BLOCK_SIZE = 4 + 8 + 16 * (6 /* ccp */ + 4 * 13 /* level */), | ||
| 62 | ASV2_MAX_MB_SIZE = 6 * ASV2_MAX_BLOCK_SIZE, | ||
| 63 | MAX_MB_SIZE = (FFMAX(ASV1_MAX_MB_SIZE, ASV2_MAX_MB_SIZE) + 7) / 8 | ||
| 64 | }; | ||
| 65 | |||
| 66 | 2970458 | static inline void asv1_put_level(PutBitContext *pb, int level) | |
| 67 | { | ||
| 68 | 2970458 | unsigned int index = level + 3; | |
| 69 | unsigned n, code; | ||
| 70 | |||
| 71 | 
        2/2✓ Branch 0 taken 2541647 times. 
          ✓ Branch 1 taken 428811 times. 
         | 
      2970458 | if (index <= 6) { | 
| 72 | 2541647 | n = ff_asv_level_tab[index][1]; | |
| 73 | 2541647 | code = ff_asv_level_tab[index][0]; | |
| 74 | } else { | ||
| 75 | 428811 | n = 3 + 8; | |
| 76 | 428811 | code = (0 /* Escape code */ << 8) | (level & 0xFF); | |
| 77 | } | ||
| 78 | 2970458 | put_bits(pb, n, code); | |
| 79 | 2970458 | } | |
| 80 | |||
| 81 | 3657862 | static inline void asv2_put_level(ASVEncContext *a, PutBitContext *pb, int level) | |
| 82 | { | ||
| 83 | 3657862 | unsigned int index = level + 31; | |
| 84 | unsigned n, code; | ||
| 85 | |||
| 86 | 
        2/2✓ Branch 0 taken 3657249 times. 
          ✓ Branch 1 taken 613 times. 
         | 
      3657862 | if (index <= 62) { | 
| 87 | 3657249 | n = ff_asv2_level_tab[index][1]; | |
| 88 | 3657249 | code = ff_asv2_level_tab[index][0]; | |
| 89 | } else { | ||
| 90 | 
        2/4✓ Branch 0 taken 613 times. 
          ✗ Branch 1 not taken. 
          ✗ Branch 2 not taken. 
          ✓ Branch 3 taken 613 times. 
         | 
      613 | if (level < -128 || level > 127) { | 
| 91 | ✗ | av_log(a->c.avctx, AV_LOG_WARNING, "Clipping level %d, increase qscale\n", level); | |
| 92 | ✗ | level = av_clip_int8(level); | |
| 93 | } | ||
| 94 | 613 | n = 5 + 8; | |
| 95 | 613 | code = (level & 0xFF) << 5 | /* Escape code */ 0; | |
| 96 | } | ||
| 97 | 3657862 | put_bits_le(pb, n, code); | |
| 98 | 3657862 | } | |
| 99 | |||
| 100 | 359100 | static inline void asv1_encode_block(ASVEncContext *a, int16_t block[64]) | |
| 101 | { | ||
| 102 | 359100 | put_bits(&a->pb, 8, (block[0] + 32) >> 6); | |
| 103 | 359100 | block[0] = 0; | |
| 104 | |||
| 105 | 
        2/2✓ Branch 0 taken 3591000 times. 
          ✓ Branch 1 taken 359100 times. 
         | 
      3950100 | for (unsigned i = 0, nc_bits = 0, nc_val = 0; i < 10; i++) { | 
| 106 | 3591000 | const int index = ff_asv_scantab[4 * i]; | |
| 107 | 3591000 | int ccp = 0; | |
| 108 | |||
| 109 | 3591000 | if ((block[index + 0] = (block[index + 0] * | |
| 110 | 
        2/2✓ Branch 0 taken 758490 times. 
          ✓ Branch 1 taken 2832510 times. 
         | 
      3591000 | a->q_intra_matrix[index + 0] + (1 << 15)) >> 16)) | 
| 111 | 758490 | ccp |= 8; | |
| 112 | 3591000 | if ((block[index + 8] = (block[index + 8] * | |
| 113 | 
        2/2✓ Branch 0 taken 827835 times. 
          ✓ Branch 1 taken 2763165 times. 
         | 
      3591000 | a->q_intra_matrix[index + 8] + (1 << 15)) >> 16)) | 
| 114 | 827835 | ccp |= 4; | |
| 115 | 3591000 | if ((block[index + 1] = (block[index + 1] * | |
| 116 | 
        2/2✓ Branch 0 taken 780446 times. 
          ✓ Branch 1 taken 2810554 times. 
         | 
      3591000 | a->q_intra_matrix[index + 1] + (1 << 15)) >> 16)) | 
| 117 | 780446 | ccp |= 2; | |
| 118 | 3591000 | if ((block[index + 9] = (block[index + 9] * | |
| 119 | 
        2/2✓ Branch 0 taken 603687 times. 
          ✓ Branch 1 taken 2987313 times. 
         | 
      3591000 | a->q_intra_matrix[index + 9] + (1 << 15)) >> 16)) | 
| 120 | 603687 | ccp |= 1; | |
| 121 | |||
| 122 | 
        2/2✓ Branch 0 taken 1362801 times. 
          ✓ Branch 1 taken 2228199 times. 
         | 
      3591000 | if (ccp) { | 
| 123 | 1362801 | put_bits(&a->pb, nc_bits + ff_asv_ccp_tab[ccp][1], | |
| 124 | 1362801 | nc_val << ff_asv_ccp_tab[ccp][1] /* Skip */ | | |
| 125 | 1362801 | ff_asv_ccp_tab[ccp][0]); | |
| 126 | 1362801 | nc_bits = 0; | |
| 127 | 1362801 | nc_val = 0; | |
| 128 | |||
| 129 | 
        2/2✓ Branch 0 taken 758490 times. 
          ✓ Branch 1 taken 604311 times. 
         | 
      1362801 | if (ccp & 8) | 
| 130 | 758490 | asv1_put_level(&a->pb, block[index + 0]); | |
| 131 | 
        2/2✓ Branch 0 taken 827835 times. 
          ✓ Branch 1 taken 534966 times. 
         | 
      1362801 | if (ccp & 4) | 
| 132 | 827835 | asv1_put_level(&a->pb, block[index + 8]); | |
| 133 | 
        2/2✓ Branch 0 taken 780446 times. 
          ✓ Branch 1 taken 582355 times. 
         | 
      1362801 | if (ccp & 2) | 
| 134 | 780446 | asv1_put_level(&a->pb, block[index + 1]); | |
| 135 | 
        2/2✓ Branch 0 taken 603687 times. 
          ✓ Branch 1 taken 759114 times. 
         | 
      1362801 | if (ccp & 1) | 
| 136 | 603687 | asv1_put_level(&a->pb, block[index + 9]); | |
| 137 | } else { | ||
| 138 | 2228199 | nc_bits += 2; | |
| 139 | 2228199 | nc_val = (nc_val << 2) | 2; | |
| 140 | } | ||
| 141 | } | ||
| 142 | 359100 | put_bits(&a->pb, 5, 0xF); /* End of block */ | |
| 143 | 359100 | } | |
| 144 | |||
| 145 | 359100 | static inline void asv2_encode_block(ASVEncContext *a, int16_t block[64]) | |
| 146 | { | ||
| 147 | int i; | ||
| 148 | 359100 | int count = 0; | |
| 149 | |||
| 150 | 
        2/2✓ Branch 0 taken 14443629 times. 
          ✓ Branch 1 taken 63439 times. 
         | 
      14507068 | for (count = 63; count > 3; count--) { | 
| 151 | 14443629 | const int index = ff_asv_scantab[count]; | |
| 152 | 
        2/2✓ Branch 0 taken 295661 times. 
          ✓ Branch 1 taken 14147968 times. 
         | 
      14443629 | if ((block[index] * a->q_intra_matrix[index] + (1 << 15)) >> 16) | 
| 153 | 295661 | break; | |
| 154 | } | ||
| 155 | |||
| 156 | 359100 | count >>= 2; | |
| 157 | |||
| 158 | 359100 | put_bits_le(&a->pb, 4 + 8, count /* 4 bits */ | | |
| 159 | 359100 | (/* DC */(block[0] + 32) >> 6) << 4); | |
| 160 | 359100 | block[0] = 0; | |
| 161 | |||
| 162 | 
        2/2✓ Branch 0 taken 2347174 times. 
          ✓ Branch 1 taken 359100 times. 
         | 
      2706274 | for (i = 0; i <= count; i++) { | 
| 163 | 2347174 | const int index = ff_asv_scantab[4 * i]; | |
| 164 | 2347174 | int ccp = 0; | |
| 165 | |||
| 166 | 2347174 | if ((block[index + 0] = (block[index + 0] * | |
| 167 | 
        2/2✓ Branch 0 taken 967939 times. 
          ✓ Branch 1 taken 1379235 times. 
         | 
      2347174 | a->q_intra_matrix[index + 0] + (1 << 15)) >> 16)) | 
| 168 | 967939 | ccp |= 8; | |
| 169 | 2347174 | if ((block[index + 8] = (block[index + 8] * | |
| 170 | 
        2/2✓ Branch 0 taken 1013819 times. 
          ✓ Branch 1 taken 1333355 times. 
         | 
      2347174 | a->q_intra_matrix[index + 8] + (1 << 15)) >> 16)) | 
| 171 | 1013819 | ccp |= 4; | |
| 172 | 2347174 | if ((block[index + 1] = (block[index + 1] * | |
| 173 | 
        2/2✓ Branch 0 taken 950720 times. 
          ✓ Branch 1 taken 1396454 times. 
         | 
      2347174 | a->q_intra_matrix[index + 1] + (1 << 15)) >> 16)) | 
| 174 | 950720 | ccp |= 2; | |
| 175 | 2347174 | if ((block[index + 9] = (block[index + 9] * | |
| 176 | 
        2/2✓ Branch 0 taken 725384 times. 
          ✓ Branch 1 taken 1621790 times. 
         | 
      2347174 | a->q_intra_matrix[index + 9] + (1 << 15)) >> 16)) | 
| 177 | 725384 | ccp |= 1; | |
| 178 | |||
| 179 | av_assert2(i || ccp < 8); | ||
| 180 | 
        2/2✓ Branch 0 taken 1988074 times. 
          ✓ Branch 1 taken 359100 times. 
         | 
      2347174 | if (i) | 
| 181 | 1988074 | put_bits_le(&a->pb, ff_asv_ac_ccp_tab[ccp][1], ff_asv_ac_ccp_tab[ccp][0]); | |
| 182 | else | ||
| 183 | 359100 | put_bits_le(&a->pb, ff_asv_dc_ccp_tab[ccp][1], ff_asv_dc_ccp_tab[ccp][0]); | |
| 184 | |||
| 185 | 
        2/2✓ Branch 0 taken 1696154 times. 
          ✓ Branch 1 taken 651020 times. 
         | 
      2347174 | if (ccp) { | 
| 186 | 
        2/2✓ Branch 0 taken 967939 times. 
          ✓ Branch 1 taken 728215 times. 
         | 
      1696154 | if (ccp & 8) | 
| 187 | 967939 | asv2_put_level(a, &a->pb, block[index + 0]); | |
| 188 | 
        2/2✓ Branch 0 taken 1013819 times. 
          ✓ Branch 1 taken 682335 times. 
         | 
      1696154 | if (ccp & 4) | 
| 189 | 1013819 | asv2_put_level(a, &a->pb, block[index + 8]); | |
| 190 | 
        2/2✓ Branch 0 taken 950720 times. 
          ✓ Branch 1 taken 745434 times. 
         | 
      1696154 | if (ccp & 2) | 
| 191 | 950720 | asv2_put_level(a, &a->pb, block[index + 1]); | |
| 192 | 
        2/2✓ Branch 0 taken 725384 times. 
          ✓ Branch 1 taken 970770 times. 
         | 
      1696154 | if (ccp & 1) | 
| 193 | 725384 | asv2_put_level(a, &a->pb, block[index + 9]); | |
| 194 | } | ||
| 195 | } | ||
| 196 | 359100 | } | |
| 197 | |||
| 198 | 119700 | static inline int encode_mb(ASVEncContext *a, int16_t block[6][64]) | |
| 199 | { | ||
| 200 | int i; | ||
| 201 | |||
| 202 | 
        1/2✗ Branch 1 not taken. 
          ✓ Branch 2 taken 119700 times. 
         | 
      119700 | av_assert0(put_bytes_left(&a->pb, 0) >= MAX_MB_SIZE); | 
| 203 | |||
| 204 | 
        2/2✓ Branch 0 taken 59850 times. 
          ✓ Branch 1 taken 59850 times. 
         | 
      119700 | if (a->c.avctx->codec_id == AV_CODEC_ID_ASV1) { | 
| 205 | 
        2/2✓ Branch 0 taken 359100 times. 
          ✓ Branch 1 taken 59850 times. 
         | 
      418950 | for (i = 0; i < 6; i++) | 
| 206 | 359100 | asv1_encode_block(a, block[i]); | |
| 207 | } else { | ||
| 208 | 
        2/2✓ Branch 0 taken 359100 times. 
          ✓ Branch 1 taken 59850 times. 
         | 
      418950 | for (i = 0; i < 6; i++) { | 
| 209 | 359100 | asv2_encode_block(a, block[i]); | |
| 210 | } | ||
| 211 | } | ||
| 212 | 119700 | return 0; | |
| 213 | } | ||
| 214 | |||
| 215 | 119200 | static inline void dct_get(ASVEncContext *a, const AVFrame *frame, | |
| 216 | int mb_x, int mb_y) | ||
| 217 | { | ||
| 218 | 119200 | int16_t (*block)[64] = a->block; | |
| 219 | 119200 | int linesize = frame->linesize[0]; | |
| 220 | int i; | ||
| 221 | |||
| 222 | 119200 | const uint8_t *ptr_y = frame->data[0] + (mb_y * 16 * linesize) + mb_x * 16; | |
| 223 | 119200 | const uint8_t *ptr_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8; | |
| 224 | 119200 | const uint8_t *ptr_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8; | |
| 225 | |||
| 226 | 119200 | a->get_pixels(block[0], ptr_y, linesize); | |
| 227 | 119200 | a->get_pixels(block[1], ptr_y + 8, linesize); | |
| 228 | 119200 | a->get_pixels(block[2], ptr_y + 8 * linesize, linesize); | |
| 229 | 119200 | a->get_pixels(block[3], ptr_y + 8 * linesize + 8, linesize); | |
| 230 | 
        2/2✓ Branch 0 taken 476800 times. 
          ✓ Branch 1 taken 119200 times. 
         | 
      596000 | for (i = 0; i < 4; i++) | 
| 231 | 476800 | a->fdsp.fdct(block[i]); | |
| 232 | |||
| 233 | 
        1/2✓ Branch 0 taken 119200 times. 
          ✗ Branch 1 not taken. 
         | 
      119200 | if (!(a->c.avctx->flags & AV_CODEC_FLAG_GRAY)) { | 
| 234 | 119200 | a->get_pixels(block[4], ptr_cb, frame->linesize[1]); | |
| 235 | 119200 | a->get_pixels(block[5], ptr_cr, frame->linesize[2]); | |
| 236 | 
        2/2✓ Branch 0 taken 238400 times. 
          ✓ Branch 1 taken 119200 times. 
         | 
      357600 | for (i = 4; i < 6; i++) | 
| 237 | 238400 | a->fdsp.fdct(block[i]); | |
| 238 | } | ||
| 239 | 119200 | } | |
| 240 | |||
| 241 | 500 | static void handle_partial_mb(ASVEncContext *a, const uint8_t *const data[3], | |
| 242 | const int linesizes[3], | ||
| 243 | int valid_width, int valid_height) | ||
| 244 | { | ||
| 245 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 500 times. 
         | 
      500 | const int nb_blocks = a->c.avctx->flags & AV_CODEC_FLAG_GRAY ? 4 : 6; | 
| 246 | static const struct Descriptor { | ||
| 247 | uint8_t x_offset, y_offset; | ||
| 248 | uint8_t component, subsampling; | ||
| 249 | } block_descriptor[] = { | ||
| 250 | { 0, 0, 0, 0 }, { 8, 0, 0, 0 }, { 0, 8, 0, 0 }, { 8, 8, 0, 0 }, | ||
| 251 | { 0, 0, 1, 1 }, { 0, 0, 2, 1 }, | ||
| 252 | }; | ||
| 253 | |||
| 254 | 
        2/2✓ Branch 0 taken 3000 times. 
          ✓ Branch 1 taken 500 times. 
         | 
      3500 | for (int i = 0; i < nb_blocks; ++i) { | 
| 255 | 3000 | const struct Descriptor *const desc = block_descriptor + i; | |
| 256 | 3000 | int width_avail = AV_CEIL_RSHIFT(valid_width, desc->subsampling) - desc->x_offset; | |
| 257 | 3000 | int height_avail = AV_CEIL_RSHIFT(valid_height, desc->subsampling) - desc->y_offset; | |
| 258 | |||
| 259 | 
        4/4✓ Branch 0 taken 2400 times. 
          ✓ Branch 1 taken 600 times. 
          ✓ Branch 2 taken 500 times. 
          ✓ Branch 3 taken 1900 times. 
         | 
      3000 | if (width_avail <= 0 || height_avail <= 0) { | 
| 260 | // This block is outside of the visible part; don't replicate pixels, | ||
| 261 | // just zero the block, so that only the dc value will be coded. | ||
| 262 | 1100 | memset(a->block[i], 0, sizeof(a->block[i])); | |
| 263 | 1100 | continue; | |
| 264 | } | ||
| 265 | 1900 | width_avail = FFMIN(width_avail, 8); | |
| 266 | 1900 | height_avail = FFMIN(height_avail, 8); | |
| 267 | |||
| 268 | 1900 | ptrdiff_t linesize = linesizes[desc->component]; | |
| 269 | 1900 | const uint8_t *src = data[desc->component] + desc->y_offset * linesize + desc->x_offset; | |
| 270 | 1900 | int16_t *block = a->block[i]; | |
| 271 | |||
| 272 | 8000 | for (int h = 0;; block += 8, src += linesize) { | |
| 273 | int16_t last; | ||
| 274 | 
        2/2✓ Branch 0 taken 19800 times. 
          ✓ Branch 1 taken 8000 times. 
         | 
      27800 | for (int w = 0; w < width_avail; ++w) | 
| 275 | 19800 | last = block[w] = src[w]; | |
| 276 | 
        2/2✓ Branch 0 taken 44200 times. 
          ✓ Branch 1 taken 8000 times. 
         | 
      52200 | for (int w = width_avail; w < 8; ++w) | 
| 277 | 44200 | block[w] = last; | |
| 278 | 
        2/2✓ Branch 0 taken 1900 times. 
          ✓ Branch 1 taken 6100 times. 
         | 
      8000 | if (++h == height_avail) | 
| 279 | 1900 | break; | |
| 280 | } | ||
| 281 | 1900 | const int16_t *const last_row = block; | |
| 282 | 
        2/2✓ Branch 0 taken 7200 times. 
          ✓ Branch 1 taken 1900 times. 
         | 
      9100 | for (int h = height_avail; h < 8; ++h) { | 
| 283 | 7200 | block += 8; | |
| 284 | 7200 | AV_COPY128(block, last_row); | |
| 285 | } | ||
| 286 | |||
| 287 | 1900 | a->fdsp.fdct(a->block[i]); | |
| 288 | } | ||
| 289 | |||
| 290 | 500 | encode_mb(a, a->block); | |
| 291 | 500 | } | |
| 292 | |||
| 293 | 400 | static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, | |
| 294 | const AVFrame *pict, int *got_packet) | ||
| 295 | { | ||
| 296 | 400 | ASVEncContext *const a = avctx->priv_data; | |
| 297 | 400 | const ASVCommonContext *const c = &a->c; | |
| 298 | int size, ret; | ||
| 299 | |||
| 300 | 400 | ret = ff_alloc_packet(avctx, pkt, c->mb_height * c->mb_width * MAX_MB_SIZE + 3); | |
| 301 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 400 times. 
         | 
      400 | if (ret < 0) | 
| 302 | ✗ | return ret; | |
| 303 | |||
| 304 | if (!PIXBLOCKDSP_8BPP_GET_PIXELS_SUPPORTS_UNALIGNED && | ||
| 305 | ((uintptr_t)pict->data[0] & 7 || pict->linesize[0] & 7 || | ||
| 306 | (uintptr_t)pict->data[1] & 7 || pict->linesize[1] & 7 || | ||
| 307 | (uintptr_t)pict->data[2] & 7 || pict->linesize[2] & 7)) | ||
| 308 | a->get_pixels = a->pdsp.get_pixels_unaligned; | ||
| 309 | else | ||
| 310 | 400 | a->get_pixels = a->pdsp.get_pixels; | |
| 311 | |||
| 312 | 400 | init_put_bits(&a->pb, pkt->data, pkt->size); | |
| 313 | |||
| 314 | 
        2/2✓ Branch 0 taken 5600 times. 
          ✓ Branch 1 taken 400 times. 
         | 
      6000 | for (int mb_y = 0; mb_y < c->mb_height2; mb_y++) { | 
| 315 | 
        2/2✓ Branch 0 taken 119200 times. 
          ✓ Branch 1 taken 5600 times. 
         | 
      124800 | for (int mb_x = 0; mb_x < c->mb_width2; mb_x++) { | 
| 316 | 119200 | dct_get(a, pict, mb_x, mb_y); | |
| 317 | 119200 | encode_mb(a, a->block); | |
| 318 | } | ||
| 319 | } | ||
| 320 | |||
| 321 | 
        2/2✓ Branch 0 taken 100 times. 
          ✓ Branch 1 taken 300 times. 
         | 
      400 | if (avctx->width & 15) { | 
| 322 | 100 | const uint8_t *src[3] = { | |
| 323 | 100 | pict->data[0] + c->mb_width2 * 16, | |
| 324 | 100 | pict->data[1] + c->mb_width2 * 8, | |
| 325 | 100 | pict->data[2] + c->mb_width2 * 8, | |
| 326 | }; | ||
| 327 | 100 | int available_width = avctx->width & 15; | |
| 328 | |||
| 329 | 
        2/2✓ Branch 0 taken 200 times. 
          ✓ Branch 1 taken 100 times. 
         | 
      300 | for (int mb_y = 0; mb_y < c->mb_height2; mb_y++) { | 
| 330 | 200 | handle_partial_mb(a, src, pict->linesize, available_width, 16); | |
| 331 | 200 | src[0] += 16 * pict->linesize[0]; | |
| 332 | 200 | src[1] += 8 * pict->linesize[1]; | |
| 333 | 200 | src[2] += 8 * pict->linesize[2]; | |
| 334 | } | ||
| 335 | } | ||
| 336 | |||
| 337 | 
        2/2✓ Branch 0 taken 100 times. 
          ✓ Branch 1 taken 300 times. 
         | 
      400 | if (avctx->height & 15) { | 
| 338 | 100 | const uint8_t *src[3] = { | |
| 339 | 100 | pict->data[0] + c->mb_height2 * 16 * pict->linesize[0], | |
| 340 | 100 | pict->data[1] + c->mb_height2 * 8 * pict->linesize[1], | |
| 341 | 100 | pict->data[2] + c->mb_height2 * 8 * pict->linesize[2], | |
| 342 | }; | ||
| 343 | 100 | int available_height = avctx->height & 15; | |
| 344 | |||
| 345 | 100 | for (int remaining = avctx->width;; remaining -= 16) { | |
| 346 | 300 | handle_partial_mb(a, src, pict->linesize, remaining, available_height); | |
| 347 | 
        2/2✓ Branch 0 taken 100 times. 
          ✓ Branch 1 taken 200 times. 
         | 
      300 | if (remaining <= 16) | 
| 348 | 100 | break; | |
| 349 | 200 | src[0] += 16; | |
| 350 | 200 | src[1] += 8; | |
| 351 | 200 | src[2] += 8; | |
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 355 | 
        2/2✓ Branch 0 taken 200 times. 
          ✓ Branch 1 taken 200 times. 
         | 
      400 | if (avctx->codec_id == AV_CODEC_ID_ASV1) | 
| 356 | 200 | flush_put_bits(&a->pb); | |
| 357 | else | ||
| 358 | 200 | flush_put_bits_le(&a->pb); | |
| 359 | 400 | AV_WN32(put_bits_ptr(&a->pb), 0); | |
| 360 | 400 | size = (put_bytes_output(&a->pb) + 3) / 4; | |
| 361 | |||
| 362 | 
        2/2✓ Branch 0 taken 200 times. 
          ✓ Branch 1 taken 200 times. 
         | 
      400 | if (avctx->codec_id == AV_CODEC_ID_ASV1) { | 
| 363 | 200 | c->bbdsp.bswap_buf((uint32_t *) pkt->data, | |
| 364 | 200 | (uint32_t *) pkt->data, size); | |
| 365 | } | ||
| 366 | |||
| 367 | 400 | pkt->size = size * 4; | |
| 368 | 400 | *got_packet = 1; | |
| 369 | |||
| 370 | 400 | return 0; | |
| 371 | } | ||
| 372 | |||
| 373 | 8 | static av_cold int encode_init(AVCodecContext *avctx) | |
| 374 | { | ||
| 375 | 8 | ASVEncContext *const a = avctx->priv_data; | |
| 376 | int i; | ||
| 377 | 
        2/2✓ Branch 0 taken 4 times. 
          ✓ Branch 1 taken 4 times. 
         | 
      8 | const int scale = avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2; | 
| 378 | int inv_qscale; | ||
| 379 | |||
| 380 | 8 | ff_asv_common_init(avctx); | |
| 381 | 8 | ff_fdctdsp_init(&a->fdsp, avctx); | |
| 382 | 8 | ff_pixblockdsp_init(&a->pdsp, 8); | |
| 383 | |||
| 384 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 8 times. 
         | 
      8 | if (avctx->global_quality <= 0) | 
| 385 | ✗ | avctx->global_quality = 4 * FF_QUALITY_SCALE; | |
| 386 | |||
| 387 | 8 | inv_qscale = (32 * scale * FF_QUALITY_SCALE + | |
| 388 | 8 | avctx->global_quality / 2) / avctx->global_quality; | |
| 389 | |||
| 390 | 8 | avctx->extradata = av_mallocz(8); | |
| 391 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 8 times. 
         | 
      8 | if (!avctx->extradata) | 
| 392 | ✗ | return AVERROR(ENOMEM); | |
| 393 | 8 | avctx->extradata_size = 8; | |
| 394 | 8 | AV_WL32A(avctx->extradata, inv_qscale); | |
| 395 | 8 | AV_WL32A(avctx->extradata + 4, MKTAG('A', 'S', 'U', 'S')); | |
| 396 | |||
| 397 | 
        2/2✓ Branch 0 taken 512 times. 
          ✓ Branch 1 taken 8 times. 
         | 
      520 | for (i = 0; i < 64; i++) { | 
| 398 | 
        1/2✓ Branch 0 taken 512 times. 
          ✗ Branch 1 not taken. 
         | 
      512 | if (a->fdsp.fdct == ff_fdct_ifast) { | 
| 399 | 512 | int q = 32LL * scale * ff_mpeg1_default_intra_matrix[i] * ff_aanscales[i]; | |
| 400 | 512 | a->q_intra_matrix[i] = (((int64_t)inv_qscale << 30) + q / 2) / q; | |
| 401 | } else { | ||
| 402 | ✗ | int q = 32 * scale * ff_mpeg1_default_intra_matrix[i]; | |
| 403 | ✗ | a->q_intra_matrix[i] = ((inv_qscale << 16) + q / 2) / q; | |
| 404 | } | ||
| 405 | } | ||
| 406 | |||
| 407 | 8 | return 0; | |
| 408 | } | ||
| 409 | |||
| 410 | #if CONFIG_ASV1_ENCODER | ||
| 411 | const FFCodec ff_asv1_encoder = { | ||
| 412 | .p.name = "asv1", | ||
| 413 | CODEC_LONG_NAME("ASUS V1"), | ||
| 414 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
| 415 | .p.id = AV_CODEC_ID_ASV1, | ||
| 416 | .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, | ||
| 417 | .priv_data_size = sizeof(ASVEncContext), | ||
| 418 | .init = encode_init, | ||
| 419 | FF_CODEC_ENCODE_CB(encode_frame), | ||
| 420 | CODEC_PIXFMTS(AV_PIX_FMT_YUV420P), | ||
| 421 | .color_ranges = AVCOL_RANGE_MPEG, | ||
| 422 | }; | ||
| 423 | #endif | ||
| 424 | |||
| 425 | #if CONFIG_ASV2_ENCODER | ||
| 426 | const FFCodec ff_asv2_encoder = { | ||
| 427 | .p.name = "asv2", | ||
| 428 | CODEC_LONG_NAME("ASUS V2"), | ||
| 429 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
| 430 | .p.id = AV_CODEC_ID_ASV2, | ||
| 431 | .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, | ||
| 432 | .priv_data_size = sizeof(ASVEncContext), | ||
| 433 | .init = encode_init, | ||
| 434 | FF_CODEC_ENCODE_CB(encode_frame), | ||
| 435 | CODEC_PIXFMTS(AV_PIX_FMT_YUV420P), | ||
| 436 | .color_ranges = AVCOL_RANGE_MPEG, | ||
| 437 | }; | ||
| 438 | #endif | ||
| 439 |