You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
avcodec/sheervideo: Reduce the size of static arrays
The SheerVideo decoder uses VLC tables which are currently stored in large arrays that contain the length of each leaf of the corresponding tree from left to right, taking 15.5KB of space. But all these arrays follow a common pattern: First the entries are ascending and then they are descending with lots of successive entries have the same value. Therefore it makes sense to use a run-length encoding to store them, as this commit does. Notice that the length 16 has to be treated specially because there are arrays with more than 256 consecutive entries with value 16 and because the length of the entries start to descend from this length onward. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
This commit is contained in:
@@ -1781,21 +1781,32 @@ static void decode_rgb(AVCodecContext *avctx, AVFrame *p, GetBitContext *gb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int build_vlc(VLC *vlc, const uint8_t *len, int count)
|
static int build_vlc(VLC *vlc, const SheerTable *table)
|
||||||
{
|
{
|
||||||
|
const uint8_t *cur = table->lens;
|
||||||
uint16_t codes[1024];
|
uint16_t codes[1024];
|
||||||
unsigned index;
|
uint8_t lens[1024];
|
||||||
int i;
|
unsigned count = 0;
|
||||||
|
|
||||||
index = 0;
|
for (unsigned step = 1, len = 1, index = 0; len > 0; len += step) {
|
||||||
for (i = 0; i < count; i++) {
|
unsigned new_count = count;
|
||||||
codes[i] = index >> (32 - len[i]);
|
|
||||||
index += 1U << (32 - len[i]);
|
if (len == 16) {
|
||||||
|
new_count += table->nb_16s;
|
||||||
|
step = -1;
|
||||||
|
} else
|
||||||
|
new_count += *cur++;
|
||||||
|
|
||||||
|
for (; count < new_count; count++) {
|
||||||
|
codes[count] = index >> (32 - len);
|
||||||
|
index += 1U << (32 - len);
|
||||||
|
lens[count] = len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ff_free_vlc(vlc);
|
ff_free_vlc(vlc);
|
||||||
return init_vlc(vlc, SHEER_VLC_BITS, count,
|
return init_vlc(vlc, SHEER_VLC_BITS, count,
|
||||||
len, sizeof(*len), sizeof(*len),
|
lens, sizeof(*lens), sizeof(*lens),
|
||||||
codes, sizeof(*codes), sizeof(*codes), 0);
|
codes, sizeof(*codes), sizeof(*codes), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1825,64 +1836,64 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
avctx->pix_fmt = AV_PIX_FMT_RGB0;
|
avctx->pix_fmt = AV_PIX_FMT_RGB0;
|
||||||
s->decode_frame = decode_rgb;
|
s->decode_frame = decode_rgb;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_r_rgb, 256);
|
ret = build_vlc(&s->vlc[0], &l_r_rgb);
|
||||||
ret |= build_vlc(&s->vlc[1], l_g_rgb, 256);
|
ret |= build_vlc(&s->vlc[1], &l_g_rgb);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG(' ', 'r', 'G', 'B'):
|
case MKTAG(' ', 'r', 'G', 'B'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_RGB0;
|
avctx->pix_fmt = AV_PIX_FMT_RGB0;
|
||||||
s->decode_frame = decode_rgbi;
|
s->decode_frame = decode_rgbi;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_r_rgbi, 256);
|
ret = build_vlc(&s->vlc[0], &l_r_rgbi);
|
||||||
ret |= build_vlc(&s->vlc[1], l_g_rgbi, 256);
|
ret |= build_vlc(&s->vlc[1], &l_g_rgbi);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('A', 'R', 'G', 'X'):
|
case MKTAG('A', 'R', 'G', 'X'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
|
avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
|
||||||
s->decode_frame = decode_argx;
|
s->decode_frame = decode_argx;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_r_rgbx, 1024);
|
ret = build_vlc(&s->vlc[0], &l_r_rgbx);
|
||||||
ret |= build_vlc(&s->vlc[1], l_g_rgbx, 1024);
|
ret |= build_vlc(&s->vlc[1], &l_g_rgbx);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('A', 'r', 'G', 'X'):
|
case MKTAG('A', 'r', 'G', 'X'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
|
avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
|
||||||
s->decode_frame = decode_argxi;
|
s->decode_frame = decode_argxi;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_r_rgbxi, 1024);
|
ret = build_vlc(&s->vlc[0], &l_r_rgbxi);
|
||||||
ret |= build_vlc(&s->vlc[1], l_g_rgbxi, 1024);
|
ret |= build_vlc(&s->vlc[1], &l_g_rgbxi);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('R', 'G', 'B', 'X'):
|
case MKTAG('R', 'G', 'B', 'X'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_GBRP10;
|
avctx->pix_fmt = AV_PIX_FMT_GBRP10;
|
||||||
s->decode_frame = decode_rgbx;
|
s->decode_frame = decode_rgbx;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_r_rgbx, 1024);
|
ret = build_vlc(&s->vlc[0], &l_r_rgbx);
|
||||||
ret |= build_vlc(&s->vlc[1], l_g_rgbx, 1024);
|
ret |= build_vlc(&s->vlc[1], &l_g_rgbx);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('r', 'G', 'B', 'X'):
|
case MKTAG('r', 'G', 'B', 'X'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_GBRP10;
|
avctx->pix_fmt = AV_PIX_FMT_GBRP10;
|
||||||
s->decode_frame = decode_rgbxi;
|
s->decode_frame = decode_rgbxi;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_r_rgbxi, 1024);
|
ret = build_vlc(&s->vlc[0], &l_r_rgbxi);
|
||||||
ret |= build_vlc(&s->vlc[1], l_g_rgbxi, 1024);
|
ret |= build_vlc(&s->vlc[1], &l_g_rgbxi);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('A', 'R', 'G', 'B'):
|
case MKTAG('A', 'R', 'G', 'B'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_ARGB;
|
avctx->pix_fmt = AV_PIX_FMT_ARGB;
|
||||||
s->decode_frame = decode_argb;
|
s->decode_frame = decode_argb;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_r_rgb, 256);
|
ret = build_vlc(&s->vlc[0], &l_r_rgb);
|
||||||
ret |= build_vlc(&s->vlc[1], l_g_rgb, 256);
|
ret |= build_vlc(&s->vlc[1], &l_g_rgb);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('A', 'r', 'G', 'B'):
|
case MKTAG('A', 'r', 'G', 'B'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_ARGB;
|
avctx->pix_fmt = AV_PIX_FMT_ARGB;
|
||||||
s->decode_frame = decode_argbi;
|
s->decode_frame = decode_argbi;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_r_rgbi, 256);
|
ret = build_vlc(&s->vlc[0], &l_r_rgbi);
|
||||||
ret |= build_vlc(&s->vlc[1], l_g_rgbi, 256);
|
ret |= build_vlc(&s->vlc[1], &l_g_rgbi);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('A', 'Y', 'B', 'R'):
|
case MKTAG('A', 'Y', 'B', 'R'):
|
||||||
@@ -1891,8 +1902,8 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
|
avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
|
||||||
s->decode_frame = decode_aybr;
|
s->decode_frame = decode_aybr;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_ybr, 256);
|
ret = build_vlc(&s->vlc[0], &l_y_ybr);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_ybr, 256);
|
ret |= build_vlc(&s->vlc[1], &l_u_ybr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('A', 'y', 'B', 'R'):
|
case MKTAG('A', 'y', 'B', 'R'):
|
||||||
@@ -1901,8 +1912,8 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
|
avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
|
||||||
s->decode_frame = decode_aybri;
|
s->decode_frame = decode_aybri;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_ybri, 256);
|
ret = build_vlc(&s->vlc[0], &l_y_ybri);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_ybri, 256);
|
ret |= build_vlc(&s->vlc[1], &l_u_ybri);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG(' ', 'Y', 'B', 'R'):
|
case MKTAG(' ', 'Y', 'B', 'R'):
|
||||||
@@ -1911,8 +1922,8 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
avctx->pix_fmt = AV_PIX_FMT_YUV444P;
|
avctx->pix_fmt = AV_PIX_FMT_YUV444P;
|
||||||
s->decode_frame = decode_ybr;
|
s->decode_frame = decode_ybr;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_ybr, 256);
|
ret = build_vlc(&s->vlc[0], &l_y_ybr);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_ybr, 256);
|
ret |= build_vlc(&s->vlc[1], &l_u_ybr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG(' ', 'y', 'B', 'R'):
|
case MKTAG(' ', 'y', 'B', 'R'):
|
||||||
@@ -1921,112 +1932,112 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
avctx->pix_fmt = AV_PIX_FMT_YUV444P;
|
avctx->pix_fmt = AV_PIX_FMT_YUV444P;
|
||||||
s->decode_frame = decode_ybri;
|
s->decode_frame = decode_ybri;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_ybri, 256);
|
ret = build_vlc(&s->vlc[0], &l_y_ybri);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_ybri, 256);
|
ret |= build_vlc(&s->vlc[1], &l_u_ybri);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('Y', 'B', 'R', 0x0a):
|
case MKTAG('Y', 'B', 'R', 0x0a):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
|
avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
|
||||||
s->decode_frame = decode_ybr10;
|
s->decode_frame = decode_ybr10;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_ybr10, 1024);
|
ret = build_vlc(&s->vlc[0], &l_y_ybr10);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_ybr10, 1024);
|
ret |= build_vlc(&s->vlc[1], &l_u_ybr10);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('y', 'B', 'R', 0x0a):
|
case MKTAG('y', 'B', 'R', 0x0a):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
|
avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
|
||||||
s->decode_frame = decode_ybr10i;
|
s->decode_frame = decode_ybr10i;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_ybr10i, 1024);
|
ret = build_vlc(&s->vlc[0], &l_y_ybr10i);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_ybr10i, 1024);
|
ret |= build_vlc(&s->vlc[1], &l_u_ybr10i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('C', 'A', '4', 'p'):
|
case MKTAG('C', 'A', '4', 'p'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_YUVA444P10;
|
avctx->pix_fmt = AV_PIX_FMT_YUVA444P10;
|
||||||
s->decode_frame = decode_ca4p;
|
s->decode_frame = decode_ca4p;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_ybr10, 1024);
|
ret = build_vlc(&s->vlc[0], &l_y_ybr10);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_ybr10, 1024);
|
ret |= build_vlc(&s->vlc[1], &l_u_ybr10);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('C', 'A', '4', 'i'):
|
case MKTAG('C', 'A', '4', 'i'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_YUVA444P10;
|
avctx->pix_fmt = AV_PIX_FMT_YUVA444P10;
|
||||||
s->decode_frame = decode_ca4i;
|
s->decode_frame = decode_ca4i;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_ybr10i, 1024);
|
ret = build_vlc(&s->vlc[0], &l_y_ybr10i);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_ybr10i, 1024);
|
ret |= build_vlc(&s->vlc[1], &l_u_ybr10i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('B', 'Y', 'R', 'Y'):
|
case MKTAG('B', 'Y', 'R', 'Y'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_YUV422P;
|
avctx->pix_fmt = AV_PIX_FMT_YUV422P;
|
||||||
s->decode_frame = decode_byry;
|
s->decode_frame = decode_byry;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_byry, 256);
|
ret = build_vlc(&s->vlc[0], &l_y_byry);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_byry, 256);
|
ret |= build_vlc(&s->vlc[1], &l_u_byry);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('B', 'Y', 'R', 'y'):
|
case MKTAG('B', 'Y', 'R', 'y'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_YUV422P;
|
avctx->pix_fmt = AV_PIX_FMT_YUV422P;
|
||||||
s->decode_frame = decode_byryi;
|
s->decode_frame = decode_byryi;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_byryi, 256);
|
ret = build_vlc(&s->vlc[0], &l_y_byryi);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_byryi, 256);
|
ret |= build_vlc(&s->vlc[1], &l_u_byryi);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('Y', 'b', 'Y', 'r'):
|
case MKTAG('Y', 'b', 'Y', 'r'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_YUV422P;
|
avctx->pix_fmt = AV_PIX_FMT_YUV422P;
|
||||||
s->decode_frame = decode_ybyr;
|
s->decode_frame = decode_ybyr;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_ybyr, 256);
|
ret = build_vlc(&s->vlc[0], &l_y_ybyr);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_ybyr, 256);
|
ret |= build_vlc(&s->vlc[1], &l_u_ybyr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('C', '8', '2', 'p'):
|
case MKTAG('C', '8', '2', 'p'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
|
avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
|
||||||
s->decode_frame = decode_c82p;
|
s->decode_frame = decode_c82p;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_byry, 256);
|
ret = build_vlc(&s->vlc[0], &l_y_byry);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_byry, 256);
|
ret |= build_vlc(&s->vlc[1], &l_u_byry);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('C', '8', '2', 'i'):
|
case MKTAG('C', '8', '2', 'i'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
|
avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
|
||||||
s->decode_frame = decode_c82i;
|
s->decode_frame = decode_c82i;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_byryi, 256);
|
ret = build_vlc(&s->vlc[0], &l_y_byryi);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_byryi, 256);
|
ret |= build_vlc(&s->vlc[1], &l_u_byryi);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG(0xa2, 'Y', 'R', 'Y'):
|
case MKTAG(0xa2, 'Y', 'R', 'Y'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
|
avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
|
||||||
s->decode_frame = decode_yry10;
|
s->decode_frame = decode_yry10;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_yry10, 1024);
|
ret = build_vlc(&s->vlc[0], &l_y_yry10);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_yry10, 1024);
|
ret |= build_vlc(&s->vlc[1], &l_u_yry10);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG(0xa2, 'Y', 'R', 'y'):
|
case MKTAG(0xa2, 'Y', 'R', 'y'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
|
avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
|
||||||
s->decode_frame = decode_yry10i;
|
s->decode_frame = decode_yry10i;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_yry10i, 1024);
|
ret = build_vlc(&s->vlc[0], &l_y_yry10i);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_yry10i, 1024);
|
ret |= build_vlc(&s->vlc[1], &l_u_yry10i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('C', 'A', '2', 'p'):
|
case MKTAG('C', 'A', '2', 'p'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_YUVA422P10;
|
avctx->pix_fmt = AV_PIX_FMT_YUVA422P10;
|
||||||
s->decode_frame = decode_ca2p;
|
s->decode_frame = decode_ca2p;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_yry10, 1024);
|
ret = build_vlc(&s->vlc[0], &l_y_yry10);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_yry10, 1024);
|
ret |= build_vlc(&s->vlc[1], &l_u_yry10);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MKTAG('C', 'A', '2', 'i'):
|
case MKTAG('C', 'A', '2', 'i'):
|
||||||
avctx->pix_fmt = AV_PIX_FMT_YUVA422P10;
|
avctx->pix_fmt = AV_PIX_FMT_YUVA422P10;
|
||||||
s->decode_frame = decode_ca2i;
|
s->decode_frame = decode_ca2i;
|
||||||
if (s->format != format) {
|
if (s->format != format) {
|
||||||
ret = build_vlc(&s->vlc[0], l_y_yry10i, 1024);
|
ret = build_vlc(&s->vlc[0], &l_y_yry10i);
|
||||||
ret |= build_vlc(&s->vlc[1], l_u_yry10i, 1024);
|
ret |= build_vlc(&s->vlc[1], &l_u_yry10i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user