The RLTable API in rl.c is not well designed for codecs with an explicit end-of-block code. ff_h261_rl_tcoeff's vlc has the EOB code as first element (presumably so that the decoder can check for it via "if (level == 0)") and this implies that the indices returned by get_rl_index() are off by one for run == 0 which is therefore explicitly checked. This commit changes this by adding a simple LUT for the values not requiring escaping. It is easy to directly include the sign bit into this, so this has also been done.
Unified · Split
| @@ -36,6 +36,14 @@ · 35 unmodified lines | ||
| 36 | 36 | #include "h261enc.h" |
| 37 | 37 | #include "mpegvideoenc.h" |
| 38 | 38 | |
| 39 | +#define H261_MAX_RUN 26 | |
| 40 | +#define H261_MAX_LEVEL 15 | |
| 41 | + | |
| 42 | +static struct VLCLUT { | |
| 43 | + uint8_t len; | |
| 44 | + uint16_t code; | |
| 45 | +} vlc_lut[H261_MAX_RUN + 1][32 /* 0..2 * H261_MAX_LEN are used */]; | |
| 46 | + | |
| 39 | 47 | static uint8_t uni_h261_rl_len [64*64*2*2]; |
| 40 | 48 | #define UNI_ENC_INDEX(last,run,level) ((last)*128*64 + (run)*128 + (level)) |
| 41 | 49 | |
| @@ -165,10 +173,8 @@ static inline int get_cbp(MpegEncContext *s, int16_t block[6][64]) · 123 unmodified lines | ||
| 165 | 173 | static void h261_encode_block(H261EncContext *h, int16_t *block, int n) |
| 166 | 174 | { |
| 167 | 175 | MpegEncContext *const s = &h->s; |
| 168 | − int level, run, i, j, last_index, last_non_zero, sign, slevel, code; | |
| 169 | − const RLTable *rl; | |
| 176 | + int level, run, i, j, last_index, last_non_zero; | |
| 170 | 177 | |
| 171 | − rl = &ff_h261_rl_tcoeff; | |
| 172 | 178 | if (s->mb_intra) { |
| 173 | 179 | /* DC coef */ |
| 174 | 180 | level = block[0]; |
| @@ -204,24 +210,18 @@ static void h261_encode_block(H261EncContext *h, int16_t *block, int n) · 29 unmodified lines | ||
| 204 | 210 | level = block[j]; |
| 205 | 211 | if (level) { |
| 206 | 212 | run = i - last_non_zero - 1; |
| 207 | − sign = 0; | |
| 208 | − slevel = level; | |
| 209 | − if (level < 0) { | |
| 210 | − sign = 1; | |
| 211 | − level = -level; | |
| 212 | − } | |
| 213 | − code = get_rl_index(rl, 0 /*no last in H.261, EOB is used*/, | |
| 214 | − run, level); | |
| 215 | − if (run == 0 && level < 16) | |
| 216 | − code += 1; | |
| 217 | − put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); | |
| 218 | − if (code == rl->n) { | |
| 219 | − put_bits(&s->pb, 6, run); | |
| 220 | − av_assert1(slevel != 0); | |
| 221 | − av_assert1(level <= 127); | |
| 222 | − put_sbits(&s->pb, 8, slevel); | |
| 213 | + | |
| 214 | + if (run <= H261_MAX_RUN && | |
| 215 | + (unsigned)(level + H261_MAX_LEVEL) <= 2 * H261_MAX_LEVEL && | |
| 216 | + vlc_lut[run][level + H261_MAX_LEVEL].len) { | |
| 217 | + put_bits(&s->pb, vlc_lut[run][level + H261_MAX_LEVEL].len, | |
| 218 | + vlc_lut[run][level + H261_MAX_LEVEL].code); | |
| 223 | 219 | } else { |
| 224 | − put_bits(&s->pb, 1, sign); | |
| 220 | + /* Escape */ | |
| 221 | + put_bits(&s->pb, 6 + 6, (1 << 6) | run); | |
| 222 | + av_assert1(level != 0); | |
| 223 | + av_assert1(FFABS(level) <= 127); | |
| 224 | + put_sbits(&s->pb, 8, level); | |
| 225 | 225 | } |
| 226 | 226 | last_non_zero = i; |
| 227 | 227 | } |
| @@ -365,6 +365,17 @@ static av_cold void h261_encode_init_static(void) · 137 unmodified lines | ||
| 365 | 365 | |
| 366 | 366 | ff_rl_init(&ff_h261_rl_tcoeff, h261_rl_table_store); |
| 367 | 367 | init_uni_h261_rl_tab(&ff_h261_rl_tcoeff, uni_h261_rl_len); |
| 368 | + | |
| 369 | + // The following loop is over the ordinary elements, not EOB or escape. | |
| 370 | + for (size_t i = 1; i < FF_ARRAY_ELEMS(ff_h261_tcoeff_vlc) - 1; i++) { | |
| 371 | + unsigned run = ff_h261_tcoeff_run[i]; | |
| 372 | + unsigned level = ff_h261_tcoeff_level[i]; | |
| 373 | + unsigned len = ff_h261_tcoeff_vlc[i][1] + 1 /* sign */; | |
| 374 | + unsigned code = ff_h261_tcoeff_vlc[i][0]; | |
| 375 | + | |
| 376 | + vlc_lut[run][H261_MAX_LEVEL + level] = (struct VLCLUT){ len, code << 1 }; | |
| 377 | + vlc_lut[run][H261_MAX_LEVEL - level] = (struct VLCLUT){ len, (code << 1) | 1 }; | |
| 378 | + } | |
| 368 | 379 | } |
| 369 | 380 | |
| 370 | 381 | av_cold int ff_h261_encode_init(MpegEncContext *s) |