You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-04 22:03:09 +02:00
avcodec/mpeg4videoenc: Simplify creating LUT
There four cases for the LUT entry: An ordinary entry or one of three escaping methods. Three of these methods are only rarely possible --they correspond to the 102 codes of the underlying VLC and so only 102 of 16384 entries are possible. The earlier code would nevertheless try them all for every LUT entry and use the best one; the new code meanwhile only uses one method (the fallback one (i.e. the worst)) for them all and only processes the 102 valid entries afterwards. The implementation used also means that index_run, max_level and max_run of the RLTable are no longer needed; the earlier code would initialize said static tables although they are only used for a short time to initialize something else. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
@ -1184,95 +1184,78 @@ static av_cold void init_uni_dc_tab(void)
|
||||
static av_cold void init_uni_mpeg4_rl_tab(RLTable *rl, uint32_t *bits_tab,
|
||||
uint8_t *len_tab)
|
||||
{
|
||||
int slevel, run, last;
|
||||
// Type 3 escape method. The escape code is the same for both VLCs
|
||||
// (0x3, seven bits), so it is hardcoded.
|
||||
memset(len_tab, 30, 2 * 2 * 64 * 64);
|
||||
len_tab += 64;
|
||||
bits_tab += 64;
|
||||
for (int run = 0; run < 64; ++run) {
|
||||
for (int level = 1;; ++level) {
|
||||
// Escape code type 3 not last run (6 bits) marker marker
|
||||
unsigned code = (3 << 23) | (3 << 21) | (0 << 20) | (run << 14) | (1 << 13) | 1;
|
||||
// first the negative levels
|
||||
bits_tab[UNI_MPEG4_ENC_INDEX(0, run, -level)] = code | (-level & 0xfff) << 1;
|
||||
bits_tab[UNI_MPEG4_ENC_INDEX(1, run, -level)] =
|
||||
bits_tab[UNI_MPEG4_ENC_INDEX(0, run, -level)] | (1 << 20) /* last */;
|
||||
|
||||
av_assert0(MAX_LEVEL >= 64);
|
||||
av_assert0(MAX_RUN >= 63);
|
||||
if (level == 64) // positive levels have a range of 1..63
|
||||
break;
|
||||
bits_tab[UNI_MPEG4_ENC_INDEX(0, run, level)] = code | level << 1;
|
||||
bits_tab[UNI_MPEG4_ENC_INDEX(1, run, level)] =
|
||||
bits_tab[UNI_MPEG4_ENC_INDEX(0, run, level)] | (1 << 20) /* last */;
|
||||
}
|
||||
// Is this needed at all?
|
||||
len_tab[UNI_MPEG4_ENC_INDEX(0, run, 0)] =
|
||||
len_tab[UNI_MPEG4_ENC_INDEX(1, run, 0)] = 0;
|
||||
}
|
||||
|
||||
for (slevel = -64; slevel < 64; slevel++) {
|
||||
if (slevel == 0)
|
||||
continue;
|
||||
for (run = 0; run < 64; run++) {
|
||||
for (last = 0; last <= 1; last++) {
|
||||
const int index = UNI_MPEG4_ENC_INDEX(last, run, slevel + 64);
|
||||
int level = slevel < 0 ? -slevel : slevel;
|
||||
int sign = slevel < 0 ? 1 : 0;
|
||||
int bits, len, code;
|
||||
int level1, run1;
|
||||
uint8_t max_run[2][32] = { 0 };
|
||||
|
||||
len_tab[index] = 100;
|
||||
#define VLC_NUM_CODES 102 // excluding the escape
|
||||
av_assert2(rl->n == VLC_NUM_CODES);
|
||||
for (int i = VLC_NUM_CODES - 1, max_level, cur_run = 0; i >= 0; --i) {
|
||||
int run = rl->table_run[i], level = rl->table_level[i];
|
||||
int last = i >= rl->last;
|
||||
unsigned code = rl->table_vlc[i][0] << 1;
|
||||
int len = rl->table_vlc[i][1] + 1;
|
||||
|
||||
/* ESC0 */
|
||||
code = get_rl_index(rl, last, run, level);
|
||||
bits = rl->table_vlc[code][0];
|
||||
len = rl->table_vlc[code][1];
|
||||
bits = bits * 2 + sign;
|
||||
len++;
|
||||
bits_tab[UNI_MPEG4_ENC_INDEX(last, run, level)] = code;
|
||||
len_tab [UNI_MPEG4_ENC_INDEX(last, run, level)] = len;
|
||||
bits_tab[UNI_MPEG4_ENC_INDEX(last, run, -level)] = code | 1;
|
||||
len_tab [UNI_MPEG4_ENC_INDEX(last, run, -level)] = len;
|
||||
|
||||
if (code != rl->n && len < len_tab[index]) {
|
||||
bits_tab[index] = bits;
|
||||
len_tab[index] = len;
|
||||
}
|
||||
/* ESC1 */
|
||||
bits = rl->table_vlc[rl->n][0];
|
||||
len = rl->table_vlc[rl->n][1];
|
||||
bits = bits * 2;
|
||||
len++; // esc1
|
||||
level1 = level - rl->max_level[last][run];
|
||||
if (level1 > 0) {
|
||||
code = get_rl_index(rl, last, run, level1);
|
||||
bits <<= rl->table_vlc[code][1];
|
||||
len += rl->table_vlc[code][1];
|
||||
bits += rl->table_vlc[code][0];
|
||||
bits = bits * 2 + sign;
|
||||
len++;
|
||||
if (!max_run[last][level])
|
||||
max_run[last][level] = run + 1;
|
||||
av_assert2(run + 1 <= max_run[last][level]);
|
||||
|
||||
if (code != rl->n && len < len_tab[index]) {
|
||||
bits_tab[index] = bits;
|
||||
len_tab[index] = len;
|
||||
}
|
||||
}
|
||||
/* ESC2 */
|
||||
bits = rl->table_vlc[rl->n][0];
|
||||
len = rl->table_vlc[rl->n][1];
|
||||
bits = bits * 4 + 2;
|
||||
len += 2; // esc2
|
||||
run1 = run - rl->max_run[last][level] - 1;
|
||||
if (run1 >= 0) {
|
||||
code = get_rl_index(rl, last, run1, level);
|
||||
bits <<= rl->table_vlc[code][1];
|
||||
len += rl->table_vlc[code][1];
|
||||
bits += rl->table_vlc[code][0];
|
||||
bits = bits * 2 + sign;
|
||||
len++;
|
||||
int run3 = run + max_run[last][level];
|
||||
int len3 = len + 7 + 2;
|
||||
|
||||
if (code != rl->n && len < len_tab[index]) {
|
||||
bits_tab[index] = bits;
|
||||
len_tab[index] = len;
|
||||
if (run3 < 64 && len3 < len_tab[UNI_MPEG4_ENC_INDEX(last, run3, level)]) {
|
||||
unsigned code3 = code | (0x3 << 2 | 0x2) << len;
|
||||
bits_tab[UNI_MPEG4_ENC_INDEX(last, run3, level)] = code3;
|
||||
len_tab [UNI_MPEG4_ENC_INDEX(last, run3, level)] = len3;
|
||||
bits_tab[UNI_MPEG4_ENC_INDEX(last, run3, -level)] = code3 | 1;
|
||||
len_tab [UNI_MPEG4_ENC_INDEX(last, run3, -level)] = len3;
|
||||
}
|
||||
}
|
||||
/* ESC3 */
|
||||
bits = rl->table_vlc[rl->n][0];
|
||||
len = rl->table_vlc[rl->n][1];
|
||||
bits = bits * 4 + 3;
|
||||
len += 2; // esc3
|
||||
bits = bits * 2 + last;
|
||||
len++;
|
||||
bits = bits * 64 + run;
|
||||
len += 6;
|
||||
bits = bits * 2 + 1;
|
||||
len++; // marker
|
||||
bits = bits * 4096 + (slevel & 0xfff);
|
||||
len += 12;
|
||||
bits = bits * 2 + 1;
|
||||
len++; // marker
|
||||
// table_run and table_level are ordered so that all the entries
|
||||
// with the same last and run are consecutive and level is ascending
|
||||
// among these entries. By traversing downwards we therefore automatically
|
||||
// encounter max_level of a given run first, needed for escape method 1.
|
||||
if (run != cur_run) {
|
||||
max_level = level;
|
||||
cur_run = run;
|
||||
} else
|
||||
av_assert2(max_level > level);
|
||||
|
||||
if (len < len_tab[index]) {
|
||||
bits_tab[index] = bits;
|
||||
len_tab[index] = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
code |= 0x3 << (len + 1);
|
||||
len += 7 + 1;
|
||||
level += max_level;
|
||||
av_assert2(len_tab [UNI_MPEG4_ENC_INDEX(last, run, level)] >= len);
|
||||
bits_tab[UNI_MPEG4_ENC_INDEX(last, run, level)] = code;
|
||||
len_tab [UNI_MPEG4_ENC_INDEX(last, run, level)] = len;
|
||||
bits_tab[UNI_MPEG4_ENC_INDEX(last, run, -level)] = code | 1;
|
||||
len_tab [UNI_MPEG4_ENC_INDEX(last, run, -level)] = len;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1280,8 +1263,6 @@ static av_cold void mpeg4_encode_init_static(void)
|
||||
{
|
||||
init_uni_dc_tab();
|
||||
|
||||
ff_mpeg4_init_rl_intra();
|
||||
|
||||
init_uni_mpeg4_rl_tab(&ff_mpeg4_rl_intra, uni_mpeg4_intra_rl_bits, uni_mpeg4_intra_rl_len);
|
||||
init_uni_mpeg4_rl_tab(&ff_h263_rl_inter, uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len);
|
||||
|
||||
|
Reference in New Issue
Block a user