| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of FFmpeg. | ||
| 3 | * | ||
| 4 | * FFmpeg is free software; you can redistribute it and/or | ||
| 5 | * modify it under the terms of the GNU Lesser General Public | ||
| 6 | * License as published by the Free Software Foundation; either | ||
| 7 | * version 2.1 of the License, or (at your option) any later version. | ||
| 8 | * | ||
| 9 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * Lesser General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU Lesser General Public | ||
| 15 | * License along with FFmpeg; if not, write to the Free Software | ||
| 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | |||
| 19 | /** | ||
| 20 | * @file | ||
| 21 | * @brief IntraX8 (J-Frame) subdecoder, used by WMV2 and VC-1 | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include "libavutil/avassert.h" | ||
| 25 | #include "libavutil/mem.h" | ||
| 26 | #include "libavutil/thread.h" | ||
| 27 | #include "avcodec.h" | ||
| 28 | #include "get_bits.h" | ||
| 29 | #include "idctdsp.h" | ||
| 30 | #include "msmpeg4_vc1_data.h" | ||
| 31 | #include "intrax8huf.h" | ||
| 32 | #include "intrax8.h" | ||
| 33 | #include "intrax8dsp.h" | ||
| 34 | #include "mpegutils.h" | ||
| 35 | |||
| 36 | #define VLC_BUFFER_SIZE 28150 | ||
| 37 | |||
| 38 | #define MAX_TABLE_DEPTH(table_bits, max_bits) \ | ||
| 39 | ((max_bits + table_bits - 1) / table_bits) | ||
| 40 | |||
| 41 | #define DC_VLC_BITS 9 | ||
| 42 | #define AC_VLC_BITS 9 | ||
| 43 | #define OR_VLC_BITS 7 | ||
| 44 | |||
| 45 | #define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS) | ||
| 46 | #define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS) | ||
| 47 | #define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS) | ||
| 48 | |||
| 49 | static const VLCElem *j_ac_vlc[2][2][8]; // [quant < 13], [intra / inter], [select] | ||
| 50 | static const VLCElem *j_dc_vlc[2][8]; // [quant], [select] | ||
| 51 | static const VLCElem *j_orient_vlc[2][4]; // [quant], [select] | ||
| 52 | |||
| 53 | 1350 | static av_cold const VLCElem *x8_init_vlc(VLCInitState *state, int nb_bits, | |
| 54 | int nb_codes, const uint8_t table[][2]) | ||
| 55 | { | ||
| 56 | 2700 | return ff_vlc_init_tables_from_lengths(state, nb_bits, nb_codes, &table[0][1], 2, | |
| 57 | 1350 | &table[0][0], 2, 1, 0, 0); | |
| 58 | } | ||
| 59 | |||
| 60 | 25 | static av_cold void x8_vlc_init(void) | |
| 61 | { | ||
| 62 | static VLCElem vlc_buf[VLC_BUFFER_SIZE]; | ||
| 63 | 25 | VLCInitState state = VLC_INIT_STATE(vlc_buf); | |
| 64 | int i; | ||
| 65 | |||
| 66 | // set ac tables | ||
| 67 |
2/2✓ Branch 0 taken 50 times.
✓ Branch 1 taken 25 times.
|
75 | for (int i = 0; i < 2; i++) |
| 68 |
2/2✓ Branch 0 taken 100 times.
✓ Branch 1 taken 50 times.
|
150 | for (int j = 0; j < 2; j++) |
| 69 |
2/2✓ Branch 0 taken 800 times.
✓ Branch 1 taken 100 times.
|
900 | for (int k = 0; k < 8; k++) |
| 70 | 800 | j_ac_vlc[i][j][k] = x8_init_vlc(&state, AC_VLC_BITS, 77, | |
| 71 | 800 | x8_ac_quant_table[i][j][k]); | |
| 72 | |||
| 73 | // set dc tables | ||
| 74 |
2/2✓ Branch 0 taken 50 times.
✓ Branch 1 taken 25 times.
|
75 | for (int i = 0; i < 2; i++) |
| 75 |
2/2✓ Branch 0 taken 400 times.
✓ Branch 1 taken 50 times.
|
450 | for (int j = 0; j < 8; j++) |
| 76 | 400 | j_dc_vlc[i][j] = x8_init_vlc(&state, DC_VLC_BITS, 34, | |
| 77 | 400 | x8_dc_quant_table[i][j]); | |
| 78 | |||
| 79 | // set orient tables | ||
| 80 |
2/2✓ Branch 0 taken 50 times.
✓ Branch 1 taken 25 times.
|
75 | for (i = 0; i < 2; i++) |
| 81 | 50 | j_orient_vlc[0][i] = x8_init_vlc(&state, OR_VLC_BITS, 12, | |
| 82 | 50 | x8_orient_highquant_table[i]); | |
| 83 |
2/2✓ Branch 0 taken 100 times.
✓ Branch 1 taken 25 times.
|
125 | for (i = 0; i < 4; i++) |
| 84 | 100 | j_orient_vlc[1][i] = x8_init_vlc(&state, OR_VLC_BITS, 12, | |
| 85 | 100 | x8_orient_lowquant_table[i]); | |
| 86 | 25 | } | |
| 87 | |||
| 88 | 3 | static void x8_reset_vlc_tables(IntraX8Context *w) | |
| 89 | { | ||
| 90 | 3 | memset(w->j_dc_vlc_table, 0, sizeof(w->j_dc_vlc_table)); | |
| 91 | 3 | memset(w->j_ac_vlc_table, 0, sizeof(w->j_ac_vlc_table)); | |
| 92 | 3 | w->j_orient_vlc_table = NULL; | |
| 93 | 3 | } | |
| 94 | |||
| 95 | 3909 | static inline void x8_select_ac_table(IntraX8Context *const w, int mode) | |
| 96 | { | ||
| 97 | int table_index; | ||
| 98 | |||
| 99 | av_assert2(mode < 4); | ||
| 100 | |||
| 101 |
2/2✓ Branch 0 taken 3897 times.
✓ Branch 1 taken 12 times.
|
3909 | if (w->j_ac_vlc_table[mode]) |
| 102 | 3897 | return; | |
| 103 | |||
| 104 | 12 | table_index = get_bits(w->gb, 3); | |
| 105 | // 2 modes use same tables | ||
| 106 | 12 | w->j_ac_vlc_table[mode] = j_ac_vlc[w->quant < 13][mode >> 1][table_index]; | |
| 107 | av_assert2(w->j_ac_vlc_table[mode]); | ||
| 108 | } | ||
| 109 | |||
| 110 | 1304 | static inline int x8_get_orient_vlc(IntraX8Context *w) | |
| 111 | { | ||
| 112 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1301 times.
|
1304 | if (!w->j_orient_vlc_table) { |
| 113 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | int table_index = get_bits(w->gb, 1 + (w->quant < 13)); |
| 114 | 3 | w->j_orient_vlc_table = j_orient_vlc[w->quant < 13][table_index]; | |
| 115 | } | ||
| 116 | |||
| 117 | 1304 | return get_vlc2(w->gb, w->j_orient_vlc_table, OR_VLC_BITS, OR_VLC_MTD); | |
| 118 | } | ||
| 119 | |||
| 120 | #define extra_bits(eb) (eb) // 3 bits | ||
| 121 | #define extra_run (0xFF << 8) // 1 bit | ||
| 122 | #define extra_level (0x00 << 8) // 1 bit | ||
| 123 | #define run_offset(r) ((r) << 16) // 6 bits | ||
| 124 | #define level_offset(l) ((l) << 24) // 5 bits | ||
| 125 | static const uint32_t ac_decode_table[] = { | ||
| 126 | /* 46 */ extra_bits(3) | extra_run | run_offset(16) | level_offset(0), | ||
| 127 | /* 47 */ extra_bits(3) | extra_run | run_offset(24) | level_offset(0), | ||
| 128 | /* 48 */ extra_bits(2) | extra_run | run_offset(4) | level_offset(1), | ||
| 129 | /* 49 */ extra_bits(3) | extra_run | run_offset(8) | level_offset(1), | ||
| 130 | |||
| 131 | /* 50 */ extra_bits(5) | extra_run | run_offset(32) | level_offset(0), | ||
| 132 | /* 51 */ extra_bits(4) | extra_run | run_offset(16) | level_offset(1), | ||
| 133 | |||
| 134 | /* 52 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(4), | ||
| 135 | /* 53 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(8), | ||
| 136 | /* 54 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(12), | ||
| 137 | /* 55 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(16), | ||
| 138 | /* 56 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(24), | ||
| 139 | |||
| 140 | /* 57 */ extra_bits(2) | extra_level | run_offset(1) | level_offset(3), | ||
| 141 | /* 58 */ extra_bits(3) | extra_level | run_offset(1) | level_offset(7), | ||
| 142 | |||
| 143 | /* 59 */ extra_bits(2) | extra_run | run_offset(16) | level_offset(0), | ||
| 144 | /* 60 */ extra_bits(2) | extra_run | run_offset(20) | level_offset(0), | ||
| 145 | /* 61 */ extra_bits(2) | extra_run | run_offset(24) | level_offset(0), | ||
| 146 | /* 62 */ extra_bits(2) | extra_run | run_offset(28) | level_offset(0), | ||
| 147 | /* 63 */ extra_bits(4) | extra_run | run_offset(32) | level_offset(0), | ||
| 148 | /* 64 */ extra_bits(4) | extra_run | run_offset(48) | level_offset(0), | ||
| 149 | |||
| 150 | /* 65 */ extra_bits(2) | extra_run | run_offset(4) | level_offset(1), | ||
| 151 | /* 66 */ extra_bits(3) | extra_run | run_offset(8) | level_offset(1), | ||
| 152 | /* 67 */ extra_bits(4) | extra_run | run_offset(16) | level_offset(1), | ||
| 153 | |||
| 154 | /* 68 */ extra_bits(2) | extra_level | run_offset(0) | level_offset(4), | ||
| 155 | /* 69 */ extra_bits(3) | extra_level | run_offset(0) | level_offset(8), | ||
| 156 | /* 70 */ extra_bits(4) | extra_level | run_offset(0) | level_offset(16), | ||
| 157 | |||
| 158 | /* 71 */ extra_bits(2) | extra_level | run_offset(1) | level_offset(3), | ||
| 159 | /* 72 */ extra_bits(3) | extra_level | run_offset(1) | level_offset(7), | ||
| 160 | }; | ||
| 161 | #undef extra_bits | ||
| 162 | #undef extra_run | ||
| 163 | #undef extra_level | ||
| 164 | #undef run_offset | ||
| 165 | #undef level_offset | ||
| 166 | |||
| 167 | 8932 | static void x8_get_ac_rlf(IntraX8Context *const w, const int mode, | |
| 168 | int *const run, int *const level, int *const final) | ||
| 169 | { | ||
| 170 | int i, e; | ||
| 171 | |||
| 172 | // x8_select_ac_table(w, mode); | ||
| 173 | 8932 | i = get_vlc2(w->gb, w->j_ac_vlc_table[mode], AC_VLC_BITS, AC_VLC_MTD); | |
| 174 | |||
| 175 |
2/2✓ Branch 0 taken 7635 times.
✓ Branch 1 taken 1297 times.
|
8932 | if (i < 46) { // [0-45] |
| 176 | int t, l; | ||
| 177 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7635 times.
|
7635 | if (i < 0) { |
| 178 | ✗ | *level = | |
| 179 | ✗ | *final = // prevent 'may be used uninitialized' | |
| 180 | ✗ | *run = 64; // this would cause error exit in the ac loop | |
| 181 | ✗ | return; | |
| 182 | } | ||
| 183 | |||
| 184 | /* | ||
| 185 | * i == 0-15 r = 0-15 l = 0; r = i & %01111 | ||
| 186 | * i == 16-19 r = 0-3 l = 1; r = i & %00011 | ||
| 187 | * i == 20-21 r = 0-1 l = 2; r = i & %00001 | ||
| 188 | * i == 22 r = 0 l = 3; r = i & %00000 | ||
| 189 | */ | ||
| 190 | |||
| 191 | 7635 | *final = | |
| 192 | 7635 | t = i > 22; | |
| 193 | 7635 | i -= 23 * t; | |
| 194 | |||
| 195 | /* l = lut_l[i / 2] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3 }[i >> 1]; | ||
| 196 | * 11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000 */ | ||
| 197 | 7635 | l = (0xE50000 >> (i & 0x1E)) & 3; // 0x1E or ~1 or (i >> 1 << 1) | |
| 198 | |||
| 199 | /* t = lut_mask[l] = { 0x0f, 0x03, 0x01, 0x00 }[l]; | ||
| 200 | * as i < 256 the higher bits do not matter */ | ||
| 201 | 7635 | t = 0x01030F >> (l << 3); | |
| 202 | |||
| 203 | 7635 | *run = i & t; | |
| 204 | 7635 | *level = l; | |
| 205 |
2/2✓ Branch 0 taken 1057 times.
✓ Branch 1 taken 240 times.
|
1297 | } else if (i < 73) { // [46-72] |
| 206 | uint32_t sm; | ||
| 207 | uint32_t mask; | ||
| 208 | |||
| 209 | 1057 | i -= 46; | |
| 210 | 1057 | sm = ac_decode_table[i]; | |
| 211 | |||
| 212 | 1057 | e = get_bits(w->gb, sm & 0xF); | |
| 213 | 1057 | sm >>= 8; // 3 bits | |
| 214 | 1057 | mask = sm & 0xff; | |
| 215 | 1057 | sm >>= 8; // 1 bit | |
| 216 | |||
| 217 | 1057 | *run = (sm & 0xff) + (e & mask); // 6 bits | |
| 218 | 1057 | *level = (sm >> 8) + (e & ~mask); // 5 bits | |
| 219 | 1057 | *final = i > (58 - 46); | |
| 220 |
2/2✓ Branch 0 taken 234 times.
✓ Branch 1 taken 6 times.
|
240 | } else if (i < 75) { // [73-74] |
| 221 | static const uint8_t crazy_mix_runlevel[32] = { | ||
| 222 | 0x22, 0x32, 0x33, 0x53, 0x23, 0x42, 0x43, 0x63, | ||
| 223 | 0x24, 0x52, 0x34, 0x73, 0x25, 0x62, 0x44, 0x83, | ||
| 224 | 0x26, 0x72, 0x35, 0x54, 0x27, 0x82, 0x45, 0x64, | ||
| 225 | 0x28, 0x92, 0x36, 0x74, 0x29, 0xa2, 0x46, 0x84, | ||
| 226 | }; | ||
| 227 | |||
| 228 | 234 | *final = !(i & 1); | |
| 229 | 234 | e = get_bits(w->gb, 5); // get the extra bits | |
| 230 | 234 | *run = crazy_mix_runlevel[e] >> 4; | |
| 231 | 234 | *level = crazy_mix_runlevel[e] & 0x0F; | |
| 232 | } else { | ||
| 233 | 6 | *level = get_bits(w->gb, 7 - 3 * (i & 1)); | |
| 234 | 6 | *run = get_bits(w->gb, 6); | |
| 235 | 6 | *final = get_bits1(w->gb); | |
| 236 | } | ||
| 237 | 8932 | return; | |
| 238 | } | ||
| 239 | |||
| 240 | /* static const uint8_t dc_extra_sbits[] = { | ||
| 241 | * 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, | ||
| 242 | * }; */ | ||
| 243 | static const uint8_t dc_index_offset[] = { | ||
| 244 | 0, 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, | ||
| 245 | }; | ||
| 246 | |||
| 247 | 5400 | static int x8_get_dc_rlf(IntraX8Context *const w, const int mode, | |
| 248 | int *const level, int *const final) | ||
| 249 | { | ||
| 250 | int i, e, c; | ||
| 251 | |||
| 252 | av_assert2(mode < 3); | ||
| 253 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 5391 times.
|
5400 | if (!w->j_dc_vlc_table[mode]) { |
| 254 | 9 | int table_index = get_bits(w->gb, 3); | |
| 255 | // 4 modes, same table | ||
| 256 | 9 | w->j_dc_vlc_table[mode] = j_dc_vlc[w->quant < 13][table_index]; | |
| 257 | } | ||
| 258 | |||
| 259 | 5400 | i = get_vlc2(w->gb, w->j_dc_vlc_table[mode], DC_VLC_BITS, DC_VLC_MTD); | |
| 260 | |||
| 261 | /* (i >= 17) { i -= 17; final =1; } */ | ||
| 262 | 5400 | c = i > 16; | |
| 263 | 5400 | *final = c; | |
| 264 | 5400 | i -= 17 * c; | |
| 265 | |||
| 266 |
2/2✓ Branch 0 taken 1320 times.
✓ Branch 1 taken 4080 times.
|
5400 | if (i <= 0) { |
| 267 | 1320 | *level = 0; | |
| 268 | 1320 | return -i; | |
| 269 | } | ||
| 270 | 4080 | c = (i + 1) >> 1; // hackish way to calculate dc_extra_sbits[] | |
| 271 | 4080 | c -= c > 1; | |
| 272 | |||
| 273 | 4080 | e = get_bits(w->gb, c); // get the extra bits | |
| 274 | 4080 | i = dc_index_offset[i] + (e >> 1); | |
| 275 | |||
| 276 | 4080 | e = -(e & 1); // 0, 0xffffff | |
| 277 | 4080 | *level = (i ^ e) - e; // (i ^ 0) - 0, (i ^ 0xff) - (-1) | |
| 278 | 4080 | return 0; | |
| 279 | } | ||
| 280 | |||
| 281 | // end of huffman | ||
| 282 | |||
| 283 | 5400 | static int x8_setup_spatial_predictor(IntraX8Context *const w, const int chroma) | |
| 284 | { | ||
| 285 | int range; | ||
| 286 | int sum; | ||
| 287 | int quant; | ||
| 288 | |||
| 289 | 5400 | w->dsp.setup_spatial_compensation(w->dest[chroma], w->scratchpad, | |
| 290 | 5400 | w->frame->linesize[chroma > 0], | |
| 291 | &range, &sum, w->edges); | ||
| 292 |
2/2✓ Branch 0 taken 1800 times.
✓ Branch 1 taken 3600 times.
|
5400 | if (chroma) { |
| 293 | 1800 | w->orient = w->chroma_orient; | |
| 294 | 1800 | quant = w->quant_dc_chroma; | |
| 295 | } else { | ||
| 296 | 3600 | quant = w->quant; | |
| 297 | } | ||
| 298 | |||
| 299 | 5400 | w->flat_dc = 0; | |
| 300 |
3/4✓ Branch 0 taken 2014 times.
✓ Branch 1 taken 3386 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2014 times.
|
5400 | if (range < quant || range < 3) { |
| 301 | 3386 | w->orient = 0; | |
| 302 | |||
| 303 | // yep you read right, a +-1 idct error may break decoding! | ||
| 304 |
2/2✓ Branch 0 taken 1365 times.
✓ Branch 1 taken 2021 times.
|
3386 | if (range < 3) { |
| 305 | 1365 | w->flat_dc = 1; | |
| 306 | 1365 | sum += 9; | |
| 307 | // ((1 << 17) + 9) / (8 + 8 + 1 + 2) = 6899 | ||
| 308 | 1365 | w->predicted_dc = sum * 6899 >> 17; | |
| 309 | } | ||
| 310 | } | ||
| 311 |
2/2✓ Branch 0 taken 1800 times.
✓ Branch 1 taken 3600 times.
|
5400 | if (chroma) |
| 312 | 1800 | return 0; | |
| 313 | |||
| 314 | av_assert2(w->orient < 3); | ||
| 315 |
2/2✓ Branch 0 taken 2296 times.
✓ Branch 1 taken 1304 times.
|
3600 | if (range < 2 * w->quant) { |
| 316 |
2/2✓ Branch 0 taken 2102 times.
✓ Branch 1 taken 194 times.
|
2296 | if ((w->edges & 3) == 0) { |
| 317 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2096 times.
|
2102 | if (w->orient == 1) |
| 318 | 6 | w->orient = 11; | |
| 319 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2086 times.
|
2102 | if (w->orient == 2) |
| 320 | 16 | w->orient = 10; | |
| 321 | } else { | ||
| 322 | 194 | w->orient = 0; | |
| 323 | } | ||
| 324 | 2296 | w->raw_orient = 0; | |
| 325 | } else { | ||
| 326 | static const uint8_t prediction_table[3][12] = { | ||
| 327 | { 0, 8, 4, 10, 11, 2, 6, 9, 1, 3, 5, 7 }, | ||
| 328 | { 4, 0, 8, 11, 10, 3, 5, 2, 6, 9, 1, 7 }, | ||
| 329 | { 8, 0, 4, 10, 11, 1, 7, 2, 6, 9, 3, 5 }, | ||
| 330 | }; | ||
| 331 | 1304 | w->raw_orient = x8_get_orient_vlc(w); | |
| 332 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1304 times.
|
1304 | if (w->raw_orient < 0) |
| 333 | ✗ | return -1; | |
| 334 | av_assert2(w->raw_orient < 12); | ||
| 335 | av_assert2(w->orient < 3); | ||
| 336 | 1304 | w->orient=prediction_table[w->orient][w->raw_orient]; | |
| 337 | } | ||
| 338 | 3600 | return 0; | |
| 339 | } | ||
| 340 | |||
| 341 | 3600 | static void x8_update_predictions(IntraX8Context *const w, const int orient, | |
| 342 | const int est_run) | ||
| 343 | { | ||
| 344 |
2/2✓ Branch 0 taken 469 times.
✓ Branch 1 taken 3131 times.
|
3600 | w->prediction_table[w->mb_x * 2 + (w->mb_y & 1)] = (est_run << 2) + 1 * (orient == 4) + 2 * (orient == 8); |
| 345 | /* | ||
| 346 | * y = 2n + 0 -> // 0 2 4 | ||
| 347 | * y = 2n + 1 -> // 1 3 5 | ||
| 348 | */ | ||
| 349 | 3600 | } | |
| 350 | |||
| 351 | 900 | static void x8_get_prediction_chroma(IntraX8Context *const w) | |
| 352 | { | ||
| 353 | 900 | w->edges = 1 * !(w->mb_x >> 1); | |
| 354 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 840 times.
|
900 | w->edges |= 2 * !(w->mb_y >> 1); |
| 355 |
2/2✓ Branch 0 taken 45 times.
✓ Branch 1 taken 855 times.
|
900 | w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1)); // mb_x for chroma would always be odd |
| 356 | |||
| 357 | 900 | w->raw_orient = 0; | |
| 358 | // lut_co[8] = {inv,4,8,8, inv,4,8,8} <- => {1,1,0,0;1,1,0,0} => 0xCC | ||
| 359 |
2/2✓ Branch 0 taken 102 times.
✓ Branch 1 taken 798 times.
|
900 | if (w->edges & 3) { |
| 360 | 102 | w->chroma_orient = 4 << ((0xCC >> w->edges) & 1); | |
| 361 | 102 | return; | |
| 362 | } | ||
| 363 | // block[x - 1][y | 1 - 1)] | ||
| 364 | 798 | w->chroma_orient = (w->prediction_table[2 * w->mb_x - 2] & 0x03) << 2; | |
| 365 | } | ||
| 366 | |||
| 367 | 3600 | static void x8_get_prediction(IntraX8Context *const w) | |
| 368 | { | ||
| 369 | int a, b, c, i; | ||
| 370 | |||
| 371 | 3600 | w->edges = 1 * !w->mb_x; | |
| 372 |
2/2✓ Branch 0 taken 120 times.
✓ Branch 1 taken 3480 times.
|
3600 | w->edges |= 2 * !w->mb_y; |
| 373 |
2/2✓ Branch 0 taken 90 times.
✓ Branch 1 taken 3510 times.
|
3600 | w->edges |= 4 * (w->mb_x >= (2 * w->mb_width - 1)); |
| 374 | |||
| 375 |
4/5✓ Branch 0 taken 3393 times.
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 117 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
|
3600 | switch (w->edges & 3) { |
| 376 | 3393 | case 0: | |
| 377 | 3393 | break; | |
| 378 | 87 | case 1: | |
| 379 | // take the one from the above block[0][y - 1] | ||
| 380 | 87 | w->est_run = w->prediction_table[!(w->mb_y & 1)] >> 2; | |
| 381 | 87 | w->orient = 1; | |
| 382 | 87 | return; | |
| 383 | 117 | case 2: | |
| 384 | // take the one from the previous block[x - 1][0] | ||
| 385 | 117 | w->est_run = w->prediction_table[2 * w->mb_x - 2] >> 2; | |
| 386 | 117 | w->orient = 2; | |
| 387 | 117 | return; | |
| 388 | 3 | case 3: | |
| 389 | 3 | w->est_run = 16; | |
| 390 | 3 | w->orient = 0; | |
| 391 | 3 | return; | |
| 392 | } | ||
| 393 | // no edge cases | ||
| 394 | 3393 | b = w->prediction_table[2 * w->mb_x + !(w->mb_y & 1)]; // block[x ][y - 1] | |
| 395 | 3393 | a = w->prediction_table[2 * w->mb_x - 2 + (w->mb_y & 1)]; // block[x - 1][y ] | |
| 396 | 3393 | c = w->prediction_table[2 * w->mb_x - 2 + !(w->mb_y & 1)]; // block[x - 1][y - 1] | |
| 397 | |||
| 398 | 3393 | w->est_run = FFMIN(b, a); | |
| 399 | /* This condition has nothing to do with w->edges, even if it looks | ||
| 400 | * similar it would trigger if e.g. x = 3; y = 2; | ||
| 401 | * I guess somebody wrote something wrong and it became standard. */ | ||
| 402 |
2/2✓ Branch 0 taken 2565 times.
✓ Branch 1 taken 828 times.
|
3393 | if ((w->mb_x & w->mb_y) != 0) |
| 403 | 2565 | w->est_run = FFMIN(c, w->est_run); | |
| 404 | 3393 | w->est_run >>= 2; | |
| 405 | |||
| 406 | 3393 | a &= 3; | |
| 407 | 3393 | b &= 3; | |
| 408 | 3393 | c &= 3; | |
| 409 | |||
| 410 | 3393 | i = (0xFFEAF4C4 >> (2 * b + 8 * a)) & 3; | |
| 411 |
2/2✓ Branch 0 taken 3373 times.
✓ Branch 1 taken 20 times.
|
3393 | if (i != 3) |
| 412 | 3373 | w->orient = i; | |
| 413 | else | ||
| 414 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 16 times.
|
20 | w->orient = (0xFFEAD8 >> (2 * c + 8 * (w->quant > 12))) & 3; |
| 415 | /* | ||
| 416 | * lut1[b][a] = { | ||
| 417 | * ->{ 0, 1, 0, pad }, | ||
| 418 | * { 0, 1, X, pad }, | ||
| 419 | * { 2, 2, 2, pad } | ||
| 420 | * } | ||
| 421 | * pad 2 2 2; | ||
| 422 | * pad X 1 0; | ||
| 423 | * pad 0 1 0 <- | ||
| 424 | * -> 11 10 '10 10 '11 11'01 00 '11 00'01 00 => 0xEAF4C4 | ||
| 425 | * | ||
| 426 | * lut2[q>12][c] = { | ||
| 427 | * ->{ 0, 2, 1, pad}, | ||
| 428 | * { 2, 2, 2, pad} | ||
| 429 | * } | ||
| 430 | * pad 2 2 2; | ||
| 431 | * pad 1 2 0 <- | ||
| 432 | * -> 11 10'10 10 '11 01'10 00 => 0xEAD8 | ||
| 433 | */ | ||
| 434 | } | ||
| 435 | |||
| 436 | 2761 | static void x8_ac_compensation(IntraX8Context *const w, const int direction, | |
| 437 | const int dc_level) | ||
| 438 | { | ||
| 439 | int t; | ||
| 440 | #define B(x,y) w->block[w->idct_permutation[(x) + (y) * 8]] | ||
| 441 | #define T(x) ((x) * dc_level + 0x8000) >> 16; | ||
| 442 |
3/4✓ Branch 0 taken 1946 times.
✓ Branch 1 taken 312 times.
✓ Branch 2 taken 503 times.
✗ Branch 3 not taken.
|
2761 | switch (direction) { |
| 443 | 1946 | case 0: | |
| 444 | 1946 | t = T(3811); // h | |
| 445 | 1946 | B(1, 0) -= t; | |
| 446 | 1946 | B(0, 1) -= t; | |
| 447 | |||
| 448 | 1946 | t = T(487); // e | |
| 449 | 1946 | B(2, 0) -= t; | |
| 450 | 1946 | B(0, 2) -= t; | |
| 451 | |||
| 452 | 1946 | t = T(506); // f | |
| 453 | 1946 | B(3, 0) -= t; | |
| 454 | 1946 | B(0, 3) -= t; | |
| 455 | |||
| 456 | 1946 | t = T(135); // c | |
| 457 | 1946 | B(4, 0) -= t; | |
| 458 | 1946 | B(0, 4) -= t; | |
| 459 | 1946 | B(2, 1) += t; | |
| 460 | 1946 | B(1, 2) += t; | |
| 461 | 1946 | B(3, 1) += t; | |
| 462 | 1946 | B(1, 3) += t; | |
| 463 | |||
| 464 | 1946 | t = T(173); // d | |
| 465 | 1946 | B(5, 0) -= t; | |
| 466 | 1946 | B(0, 5) -= t; | |
| 467 | |||
| 468 | 1946 | t = T(61); // b | |
| 469 | 1946 | B(6, 0) -= t; | |
| 470 | 1946 | B(0, 6) -= t; | |
| 471 | 1946 | B(5, 1) += t; | |
| 472 | 1946 | B(1, 5) += t; | |
| 473 | |||
| 474 | 1946 | t = T(42); // a | |
| 475 | 1946 | B(7, 0) -= t; | |
| 476 | 1946 | B(0, 7) -= t; | |
| 477 | 1946 | B(4, 1) += t; | |
| 478 | 1946 | B(1, 4) += t; | |
| 479 | 1946 | B(4, 4) += t; | |
| 480 | |||
| 481 | 1946 | t = T(1084); // g | |
| 482 | 1946 | B(1, 1) += t; | |
| 483 | 1946 | break; | |
| 484 | 312 | case 1: | |
| 485 | 312 | B(0, 1) -= T(6269); | |
| 486 | 312 | B(0, 3) -= T(708); | |
| 487 | 312 | B(0, 5) -= T(172); | |
| 488 | 312 | B(0, 7) -= T(73); | |
| 489 | 312 | break; | |
| 490 | 503 | case 2: | |
| 491 | 503 | B(1, 0) -= T(6269); | |
| 492 | 503 | B(3, 0) -= T(708); | |
| 493 | 503 | B(5, 0) -= T(172); | |
| 494 | 503 | B(7, 0) -= T(73); | |
| 495 | 503 | break; | |
| 496 | } | ||
| 497 | #undef B | ||
| 498 | #undef T | ||
| 499 | 2761 | } | |
| 500 | |||
| 501 | 1365 | static void dsp_x8_put_solidcolor(const uint8_t pix, uint8_t *dst, | |
| 502 | const ptrdiff_t linesize) | ||
| 503 | { | ||
| 504 | int k; | ||
| 505 |
2/2✓ Branch 0 taken 10920 times.
✓ Branch 1 taken 1365 times.
|
12285 | for (k = 0; k < 8; k++) { |
| 506 | 10920 | memset(dst, pix, 8); | |
| 507 | 10920 | dst += linesize; | |
| 508 | } | ||
| 509 | 1365 | } | |
| 510 | |||
| 511 | static const int16_t quant_table[64] = { | ||
| 512 | 256, 256, 256, 256, 256, 256, 259, 262, | ||
| 513 | 265, 269, 272, 275, 278, 282, 285, 288, | ||
| 514 | 292, 295, 299, 303, 306, 310, 314, 317, | ||
| 515 | 321, 325, 329, 333, 337, 341, 345, 349, | ||
| 516 | 353, 358, 362, 366, 371, 375, 379, 384, | ||
| 517 | 389, 393, 398, 403, 408, 413, 417, 422, | ||
| 518 | 428, 433, 438, 443, 448, 454, 459, 465, | ||
| 519 | 470, 476, 482, 488, 493, 499, 505, 511, | ||
| 520 | }; | ||
| 521 | |||
| 522 | 5400 | static int x8_decode_intra_mb(IntraX8Context *const w, const int chroma) | |
| 523 | { | ||
| 524 | uint8_t *scantable; | ||
| 525 | int final, run, level; | ||
| 526 | int ac_mode, dc_mode, est_run, dc_level; | ||
| 527 | int pos, n; | ||
| 528 | int zeros_only; | ||
| 529 | int use_quant_matrix; | ||
| 530 | int sign; | ||
| 531 | |||
| 532 | av_assert2(w->orient < 12); | ||
| 533 | 5400 | w->bdsp.clear_block(w->block); | |
| 534 | |||
| 535 |
2/2✓ Branch 0 taken 1800 times.
✓ Branch 1 taken 3600 times.
|
5400 | if (chroma) |
| 536 | 1800 | dc_mode = 2; | |
| 537 | else | ||
| 538 | 3600 | dc_mode = !!w->est_run; // 0, 1 | |
| 539 | |||
| 540 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5400 times.
|
5400 | if (x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) |
| 541 | ✗ | return -1; | |
| 542 | 5400 | n = 0; | |
| 543 | 5400 | zeros_only = 0; | |
| 544 |
2/2✓ Branch 0 taken 1693 times.
✓ Branch 1 taken 3707 times.
|
5400 | if (!final) { // decode ac |
| 545 | 1693 | use_quant_matrix = w->use_quant_matrix; | |
| 546 |
2/2✓ Branch 0 taken 368 times.
✓ Branch 1 taken 1325 times.
|
1693 | if (chroma) { |
| 547 | 368 | ac_mode = 1; | |
| 548 | 368 | est_run = 64; // not used | |
| 549 | } else { | ||
| 550 |
2/2✓ Branch 0 taken 905 times.
✓ Branch 1 taken 420 times.
|
1325 | if (w->raw_orient < 3) |
| 551 | 905 | use_quant_matrix = 0; | |
| 552 | |||
| 553 |
2/2✓ Branch 0 taken 124 times.
✓ Branch 1 taken 1201 times.
|
1325 | if (w->raw_orient > 4) { |
| 554 | 124 | ac_mode = 0; | |
| 555 | 124 | est_run = 64; | |
| 556 | } else { | ||
| 557 |
2/2✓ Branch 0 taken 540 times.
✓ Branch 1 taken 661 times.
|
1201 | if (w->est_run > 1) { |
| 558 | 540 | ac_mode = 2; | |
| 559 | 540 | est_run = w->est_run; | |
| 560 | } else { | ||
| 561 | 661 | ac_mode = 3; | |
| 562 | 661 | est_run = 64; | |
| 563 | } | ||
| 564 | } | ||
| 565 | } | ||
| 566 | 1693 | x8_select_ac_table(w, ac_mode); | |
| 567 | /* scantable_selector[12] = { 0, 2, 0, 1, 1, 1, 0, 2, 2, 0, 1, 2 }; <- | ||
| 568 | * -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 => 0x928548 */ | ||
| 569 | 1693 | scantable = w->permutated_scantable[(0x928548 >> (2 * w->orient)) & 3]; | |
| 570 | 1693 | pos = 0; | |
| 571 | do { | ||
| 572 | 8932 | n++; | |
| 573 |
2/2✓ Branch 0 taken 2216 times.
✓ Branch 1 taken 6716 times.
|
8932 | if (n >= est_run) { |
| 574 | 2216 | ac_mode = 3; | |
| 575 | 2216 | x8_select_ac_table(w, 3); | |
| 576 | } | ||
| 577 | |||
| 578 | 8932 | x8_get_ac_rlf(w, ac_mode, &run, &level, &final); | |
| 579 | |||
| 580 | 8932 | pos += run + 1; | |
| 581 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8932 times.
|
8932 | if (pos > 63) { |
| 582 | // this also handles vlc error in x8_get_ac_rlf | ||
| 583 | ✗ | return -1; | |
| 584 | } | ||
| 585 | 8932 | level = (level + 1) * w->dquant; | |
| 586 | 8932 | level += w->qsum; | |
| 587 | |||
| 588 | 8932 | sign = -get_bits1(w->gb); | |
| 589 | 8932 | level = (level ^ sign) - sign; | |
| 590 | |||
| 591 |
2/2✓ Branch 0 taken 4784 times.
✓ Branch 1 taken 4148 times.
|
8932 | if (use_quant_matrix) |
| 592 | 4784 | level = (level * quant_table[pos]) >> 8; | |
| 593 | |||
| 594 | 8932 | w->block[scantable[pos]] = level; | |
| 595 |
2/2✓ Branch 0 taken 7239 times.
✓ Branch 1 taken 1693 times.
|
8932 | } while (!final); |
| 596 | } else { // DC only | ||
| 597 |
4/4✓ Branch 0 taken 1321 times.
✓ Branch 1 taken 2386 times.
✓ Branch 2 taken 1189 times.
✓ Branch 3 taken 132 times.
|
3707 | if (w->flat_dc && ((unsigned) (dc_level + 1)) < 3) { // [-1; 1] |
| 598 | 1189 | int32_t divide_quant = !chroma ? w->divide_quant_dc_luma | |
| 599 |
2/2✓ Branch 0 taken 529 times.
✓ Branch 1 taken 660 times.
|
1189 | : w->divide_quant_dc_chroma; |
| 600 | 1189 | int32_t dc_quant = !chroma ? w->quant | |
| 601 |
2/2✓ Branch 0 taken 529 times.
✓ Branch 1 taken 660 times.
|
1189 | : w->quant_dc_chroma; |
| 602 | |||
| 603 | // original intent dc_level += predicted_dc/quant; | ||
| 604 | // but it got lost somewhere in the rounding | ||
| 605 | 1189 | dc_level += (w->predicted_dc * divide_quant + (1 << 12)) >> 13; | |
| 606 | |||
| 607 | 1189 | dsp_x8_put_solidcolor(av_clip_uint8((dc_level * dc_quant + 4) >> 3), | |
| 608 | w->dest[chroma], | ||
| 609 | 1189 | w->frame->linesize[!!chroma]); | |
| 610 | |||
| 611 | 1189 | goto block_placed; | |
| 612 | } | ||
| 613 | 2518 | zeros_only = dc_level == 0; | |
| 614 | } | ||
| 615 |
2/2✓ Branch 0 taken 3071 times.
✓ Branch 1 taken 1140 times.
|
4211 | if (!chroma) |
| 616 | 3071 | w->block[0] = dc_level * w->quant; | |
| 617 | else | ||
| 618 | 1140 | w->block[0] = dc_level * w->quant_dc_chroma; | |
| 619 | |||
| 620 | // there is !zero_only check in the original, but dc_level check is enough | ||
| 621 |
4/4✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 1428 times.
✓ Branch 2 taken 2780 times.
✓ Branch 3 taken 3 times.
|
4211 | if ((unsigned int) (dc_level + 1) >= 3 && (w->edges & 3) != 3) { |
| 622 | int direction; | ||
| 623 | /* ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 }; <- | ||
| 624 | * -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 => 0x6A017C */ | ||
| 625 | 2780 | direction = (0x6A017C >> (w->orient * 2)) & 3; | |
| 626 |
2/2✓ Branch 0 taken 2761 times.
✓ Branch 1 taken 19 times.
|
2780 | if (direction != 3) { |
| 627 | 2761 | x8_ac_compensation(w, direction, w->block[0]); | |
| 628 | } | ||
| 629 | } | ||
| 630 | |||
| 631 |
2/2✓ Branch 0 taken 176 times.
✓ Branch 1 taken 4035 times.
|
4211 | if (w->flat_dc) { |
| 632 | 176 | dsp_x8_put_solidcolor(w->predicted_dc, w->dest[chroma], | |
| 633 | 176 | w->frame->linesize[!!chroma]); | |
| 634 | } else { | ||
| 635 | 4035 | w->dsp.spatial_compensation[w->orient](w->scratchpad, | |
| 636 | w->dest[chroma], | ||
| 637 | 4035 | w->frame->linesize[!!chroma]); | |
| 638 | } | ||
| 639 |
2/2✓ Branch 0 taken 386 times.
✓ Branch 1 taken 3825 times.
|
4211 | if (!zeros_only) |
| 640 | 3825 | w->wdsp.idct_add(w->dest[chroma], | |
| 641 | 3825 | w->frame->linesize[!!chroma], | |
| 642 | w->block); | ||
| 643 | |||
| 644 | 386 | block_placed: | |
| 645 |
2/2✓ Branch 0 taken 3600 times.
✓ Branch 1 taken 1800 times.
|
5400 | if (!chroma) |
| 646 | 3600 | x8_update_predictions(w, w->orient, n); | |
| 647 | |||
| 648 |
1/2✓ Branch 0 taken 5400 times.
✗ Branch 1 not taken.
|
5400 | if (w->loopfilter) { |
| 649 | 5400 | uint8_t *ptr = w->dest[chroma]; | |
| 650 | 5400 | ptrdiff_t linesize = w->frame->linesize[!!chroma]; | |
| 651 | |||
| 652 |
6/6✓ Branch 0 taken 5160 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 386 times.
✓ Branch 3 taken 4774 times.
✓ Branch 4 taken 62 times.
✓ Branch 5 taken 324 times.
|
5400 | if (!((w->edges & 2) || (zeros_only && (w->orient | 4) == 4))) |
| 653 | 4836 | w->dsp.h_loop_filter(ptr, linesize, w->quant); | |
| 654 | |||
| 655 |
6/6✓ Branch 0 taken 5220 times.
✓ Branch 1 taken 180 times.
✓ Branch 2 taken 383 times.
✓ Branch 3 taken 4837 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 371 times.
|
5400 | if (!((w->edges & 1) || (zeros_only && (w->orient | 8) == 8))) |
| 656 | 4849 | w->dsp.v_loop_filter(ptr, linesize, w->quant); | |
| 657 | } | ||
| 658 | 5400 | return 0; | |
| 659 | } | ||
| 660 | |||
| 661 | // FIXME maybe merge with ff_* | ||
| 662 | 90 | static void x8_init_block_index(IntraX8Context *w, AVFrame *frame) | |
| 663 | { | ||
| 664 | // not parent codec linesize as this would be wrong for field pics | ||
| 665 | // not that IntraX8 has interlacing support ;) | ||
| 666 | 90 | const ptrdiff_t linesize = frame->linesize[0]; | |
| 667 | 90 | const ptrdiff_t uvlinesize = frame->linesize[1]; | |
| 668 | |||
| 669 | 90 | w->dest[0] = frame->data[0]; | |
| 670 | 90 | w->dest[1] = frame->data[1]; | |
| 671 | 90 | w->dest[2] = frame->data[2]; | |
| 672 | |||
| 673 | 90 | w->dest[0] += w->mb_y * linesize << 3; | |
| 674 | // chroma blocks are on add rows | ||
| 675 | 90 | w->dest[1] += (w->mb_y & ~1) * uvlinesize << 2; | |
| 676 | 90 | w->dest[2] += (w->mb_y & ~1) * uvlinesize << 2; | |
| 677 | 90 | } | |
| 678 | |||
| 679 | 46 | av_cold int ff_intrax8_common_init(AVCodecContext *avctx, | |
| 680 | IntraX8Context *w, | ||
| 681 | int16_t block[64], | ||
| 682 | int mb_width, int mb_height) | ||
| 683 | { | ||
| 684 | static AVOnce init_static_once = AV_ONCE_INIT; | ||
| 685 | |||
| 686 | 46 | w->avctx = avctx; | |
| 687 | 46 | w->mb_width = mb_width; | |
| 688 | 46 | w->mb_height = mb_height; | |
| 689 | 46 | w->block = block; | |
| 690 | |||
| 691 | // two rows, 2 blocks per cannon mb | ||
| 692 | 46 | w->prediction_table = av_mallocz(w->mb_width * 2 * 2); | |
| 693 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
|
46 | if (!w->prediction_table) |
| 694 | ✗ | return AVERROR(ENOMEM); | |
| 695 | |||
| 696 | 46 | ff_wmv2dsp_init(&w->wdsp); | |
| 697 | |||
| 698 | 46 | ff_init_scantable_permutation(w->idct_permutation, | |
| 699 | 46 | w->wdsp.idct_perm); | |
| 700 | |||
| 701 | 46 | ff_permute_scantable(w->permutated_scantable[0], ff_wmv1_scantable[0], | |
| 702 | 46 | w->idct_permutation); | |
| 703 | 46 | ff_permute_scantable(w->permutated_scantable[1], ff_wmv1_scantable[2], | |
| 704 | 46 | w->idct_permutation); | |
| 705 | 46 | ff_permute_scantable(w->permutated_scantable[2], ff_wmv1_scantable[3], | |
| 706 | 46 | w->idct_permutation); | |
| 707 | |||
| 708 | 46 | ff_intrax8dsp_init(&w->dsp); | |
| 709 | 46 | ff_blockdsp_init(&w->bdsp); | |
| 710 | |||
| 711 | 46 | ff_thread_once(&init_static_once, x8_vlc_init); | |
| 712 | |||
| 713 | 46 | return 0; | |
| 714 | } | ||
| 715 | |||
| 716 | 46 | av_cold void ff_intrax8_common_end(IntraX8Context *w) | |
| 717 | { | ||
| 718 | 46 | av_freep(&w->prediction_table); | |
| 719 | 46 | } | |
| 720 | |||
| 721 | 3 | int ff_intrax8_decode_picture(IntraX8Context *w, MPVPicture *pict, | |
| 722 | GetBitContext *gb, int *mb_x, int *mb_y, | ||
| 723 | int dquant, int quant_offset, | ||
| 724 | int loopfilter, int lowdelay) | ||
| 725 | { | ||
| 726 | int mb_xy; | ||
| 727 | |||
| 728 | 3 | w->gb = gb; | |
| 729 | 3 | w->dquant = dquant; | |
| 730 | 3 | w->quant = dquant >> 1; | |
| 731 | 3 | w->qsum = quant_offset; | |
| 732 | 3 | w->frame = pict->f; | |
| 733 | 3 | w->loopfilter = loopfilter; | |
| 734 | 3 | w->use_quant_matrix = get_bits1(w->gb); | |
| 735 | |||
| 736 | 3 | w->mb_x = *mb_x; | |
| 737 | 3 | w->mb_y = *mb_y; | |
| 738 | |||
| 739 | 3 | w->divide_quant_dc_luma = ((1 << 16) + (w->quant >> 1)) / w->quant; | |
| 740 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | if (w->quant < 5) { |
| 741 | ✗ | w->quant_dc_chroma = w->quant; | |
| 742 | ✗ | w->divide_quant_dc_chroma = w->divide_quant_dc_luma; | |
| 743 | } else { | ||
| 744 | 3 | w->quant_dc_chroma = w->quant + ((w->quant + 3) >> 3); | |
| 745 | 3 | w->divide_quant_dc_chroma = ((1 << 16) + (w->quant_dc_chroma >> 1)) / w->quant_dc_chroma; | |
| 746 | } | ||
| 747 | 3 | x8_reset_vlc_tables(w); | |
| 748 | |||
| 749 |
2/2✓ Branch 0 taken 90 times.
✓ Branch 1 taken 3 times.
|
93 | for (w->mb_y = 0; w->mb_y < w->mb_height * 2; w->mb_y++) { |
| 750 | 90 | x8_init_block_index(w, w->frame); | |
| 751 | 90 | mb_xy = (w->mb_y >> 1) * (w->mb_width + 1); | |
| 752 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 90 times.
|
90 | if (get_bits_left(gb) < 1) |
| 753 | ✗ | goto error; | |
| 754 |
2/2✓ Branch 0 taken 3600 times.
✓ Branch 1 taken 90 times.
|
3690 | for (w->mb_x = 0; w->mb_x < w->mb_width * 2; w->mb_x++) { |
| 755 | 3600 | x8_get_prediction(w); | |
| 756 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3600 times.
|
3600 | if (x8_setup_spatial_predictor(w, 0)) |
| 757 | ✗ | goto error; | |
| 758 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3600 times.
|
3600 | if (x8_decode_intra_mb(w, 0)) |
| 759 | ✗ | goto error; | |
| 760 | |||
| 761 |
2/2✓ Branch 0 taken 900 times.
✓ Branch 1 taken 2700 times.
|
3600 | if (w->mb_x & w->mb_y & 1) { |
| 762 | 900 | x8_get_prediction_chroma(w); | |
| 763 | |||
| 764 | /* when setting up chroma, no vlc is read, | ||
| 765 | * so no error condition can be reached */ | ||
| 766 | 900 | x8_setup_spatial_predictor(w, 1); | |
| 767 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 900 times.
|
900 | if (x8_decode_intra_mb(w, 1)) |
| 768 | ✗ | goto error; | |
| 769 | |||
| 770 | 900 | x8_setup_spatial_predictor(w, 2); | |
| 771 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 900 times.
|
900 | if (x8_decode_intra_mb(w, 2)) |
| 772 | ✗ | goto error; | |
| 773 | |||
| 774 | 900 | w->dest[1] += 8; | |
| 775 | 900 | w->dest[2] += 8; | |
| 776 | |||
| 777 | 900 | pict->qscale_table[mb_xy] = w->quant; | |
| 778 | 900 | mb_xy++; | |
| 779 | } | ||
| 780 | 3600 | w->dest[0] += 8; | |
| 781 | } | ||
| 782 |
2/2✓ Branch 0 taken 45 times.
✓ Branch 1 taken 45 times.
|
90 | if (w->mb_y & 1) |
| 783 | 45 | ff_draw_horiz_band(w->avctx, w->frame, w->frame, | |
| 784 | 45 | (w->mb_y - 1) * 8, 16, | |
| 785 | PICT_FRAME, 0, lowdelay); | ||
| 786 | } | ||
| 787 | |||
| 788 | 3 | error: | |
| 789 | 3 | *mb_x = w->mb_x; | |
| 790 | 3 | *mb_y = w->mb_y; | |
| 791 | |||
| 792 | 3 | return 0; | |
| 793 | } | ||
| 794 |