avcodec/asvdec: Avoid reversing input data twice
Up until now the ASV2 decoder used an ordinary big-endian bitreader to read data actually destined for a little-endian bitreader; this is done by reversing the whole input packet bitwise, using the big-endian bigreader and reversing (and shifting) the result again. This commit stops this and instead uses a little-endian bitreader directly. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
This commit is contained in:
parent
62073cfa97
commit
cdf7619705
@ -31,7 +31,6 @@
|
|||||||
#include "blockdsp.h"
|
#include "blockdsp.h"
|
||||||
#include "idctdsp.h"
|
#include "idctdsp.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "mathops.h"
|
|
||||||
#include "mpeg12data.h"
|
#include "mpeg12data.h"
|
||||||
|
|
||||||
#define CCP_VLC_BITS 5
|
#define CCP_VLC_BITS 5
|
||||||
@ -56,27 +55,24 @@ static av_cold void init_vlcs(ASV1Context *a)
|
|||||||
INIT_VLC_STATIC(&ccp_vlc, CCP_VLC_BITS, 17,
|
INIT_VLC_STATIC(&ccp_vlc, CCP_VLC_BITS, 17,
|
||||||
&ff_asv_ccp_tab[0][1], 2, 1,
|
&ff_asv_ccp_tab[0][1], 2, 1,
|
||||||
&ff_asv_ccp_tab[0][0], 2, 1, 32);
|
&ff_asv_ccp_tab[0][0], 2, 1, 32);
|
||||||
INIT_VLC_STATIC(&dc_ccp_vlc, DC_CCP_VLC_BITS, 8,
|
INIT_CUSTOM_VLC_STATIC(&dc_ccp_vlc, DC_CCP_VLC_BITS, 8,
|
||||||
&ff_asv_dc_ccp_tab[0][1], 2, 1,
|
&ff_asv_dc_ccp_tab[0][1], 2, 1,
|
||||||
&ff_asv_dc_ccp_tab[0][0], 2, 1, 16);
|
&ff_asv_dc_ccp_tab[0][0], 2, 1,
|
||||||
INIT_VLC_STATIC(&ac_ccp_vlc, AC_CCP_VLC_BITS, 16,
|
INIT_VLC_OUTPUT_LE, 16);
|
||||||
|
INIT_CUSTOM_VLC_STATIC(&ac_ccp_vlc, AC_CCP_VLC_BITS, 16,
|
||||||
&ff_asv_ac_ccp_tab[0][1], 2, 1,
|
&ff_asv_ac_ccp_tab[0][1], 2, 1,
|
||||||
&ff_asv_ac_ccp_tab[0][0], 2, 1, 64);
|
&ff_asv_ac_ccp_tab[0][0], 2, 1,
|
||||||
|
INIT_VLC_OUTPUT_LE, 64);
|
||||||
INIT_VLC_STATIC(&level_vlc, ASV1_LEVEL_VLC_BITS, 7,
|
INIT_VLC_STATIC(&level_vlc, ASV1_LEVEL_VLC_BITS, 7,
|
||||||
&ff_asv_level_tab[0][1], 2, 1,
|
&ff_asv_level_tab[0][1], 2, 1,
|
||||||
&ff_asv_level_tab[0][0], 2, 1, 16);
|
&ff_asv_level_tab[0][0], 2, 1, 16);
|
||||||
INIT_VLC_STATIC(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63,
|
INIT_CUSTOM_VLC_STATIC(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63,
|
||||||
&ff_asv2_level_tab[0][1], 2, 1,
|
&ff_asv2_level_tab[0][1], 2, 1,
|
||||||
&ff_asv2_level_tab[0][0], 2, 1, 1024);
|
&ff_asv2_level_tab[0][0], 2, 1,
|
||||||
|
INIT_VLC_OUTPUT_LE, 1024);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME write a reversed bitstream reader to avoid the double reverse
|
|
||||||
static inline int asv2_get_bits(GetBitContext *gb, int n)
|
|
||||||
{
|
|
||||||
return ff_reverse[get_bits(gb, n) << (8 - n)];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int asv1_get_level(GetBitContext *gb)
|
static inline int asv1_get_level(GetBitContext *gb)
|
||||||
{
|
{
|
||||||
int code = get_vlc2(gb, level_vlc.table, ASV1_LEVEL_VLC_BITS, 1);
|
int code = get_vlc2(gb, level_vlc.table, ASV1_LEVEL_VLC_BITS, 1);
|
||||||
@ -87,12 +83,31 @@ static inline int asv1_get_level(GetBitContext *gb)
|
|||||||
return code - 3;
|
return code - 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get_vlc2() is big-endian in this file
|
||||||
|
static inline int asv2_get_vlc2(GetBitContext *gb, VLC_TYPE (*table)[2], int bits)
|
||||||
|
{
|
||||||
|
unsigned int index;
|
||||||
|
int code, n;
|
||||||
|
|
||||||
|
OPEN_READER(re, gb);
|
||||||
|
UPDATE_CACHE_LE(re, gb);
|
||||||
|
|
||||||
|
index = SHOW_UBITS_LE(re, gb, bits);
|
||||||
|
code = table[index][0];
|
||||||
|
n = table[index][1];
|
||||||
|
LAST_SKIP_BITS(re, gb, n);
|
||||||
|
|
||||||
|
CLOSE_READER(re, gb);
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int asv2_get_level(GetBitContext *gb)
|
static inline int asv2_get_level(GetBitContext *gb)
|
||||||
{
|
{
|
||||||
int code = get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1);
|
int code = asv2_get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS);
|
||||||
|
|
||||||
if (code == 31)
|
if (code == 31)
|
||||||
return (int8_t) asv2_get_bits(gb, 8);
|
return (int8_t) get_bits_le(gb, 8);
|
||||||
else
|
else
|
||||||
return code - 31;
|
return code - 31;
|
||||||
}
|
}
|
||||||
@ -132,11 +147,11 @@ static inline int asv2_decode_block(ASV1Context *a, int16_t block[64])
|
|||||||
{
|
{
|
||||||
int i, count, ccp;
|
int i, count, ccp;
|
||||||
|
|
||||||
count = asv2_get_bits(&a->gb, 4);
|
count = get_bits_le(&a->gb, 4);
|
||||||
|
|
||||||
block[0] = 8 * asv2_get_bits(&a->gb, 8);
|
block[0] = 8 * get_bits_le(&a->gb, 8);
|
||||||
|
|
||||||
ccp = get_vlc2(&a->gb, dc_ccp_vlc.table, DC_CCP_VLC_BITS, 1);
|
ccp = asv2_get_vlc2(&a->gb, dc_ccp_vlc.table, DC_CCP_VLC_BITS);
|
||||||
if (ccp) {
|
if (ccp) {
|
||||||
if (ccp & 4)
|
if (ccp & 4)
|
||||||
block[a->scantable.permutated[1]] = (asv2_get_level(&a->gb) * a->intra_matrix[1]) >> 4;
|
block[a->scantable.permutated[1]] = (asv2_get_level(&a->gb) * a->intra_matrix[1]) >> 4;
|
||||||
@ -147,7 +162,7 @@ static inline int asv2_decode_block(ASV1Context *a, int16_t block[64])
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 1; i < count + 1; i++) {
|
for (i = 1; i < count + 1; i++) {
|
||||||
const int ccp = get_vlc2(&a->gb, ac_ccp_vlc.table, AC_CCP_VLC_BITS, 1);
|
const int ccp = asv2_get_vlc2(&a->gb, ac_ccp_vlc.table, AC_CCP_VLC_BITS);
|
||||||
|
|
||||||
if (ccp) {
|
if (ccp) {
|
||||||
if (ccp & 8)
|
if (ccp & 8)
|
||||||
@ -221,21 +236,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
|
|||||||
p->pict_type = AV_PICTURE_TYPE_I;
|
p->pict_type = AV_PICTURE_TYPE_I;
|
||||||
p->key_frame = 1;
|
p->key_frame = 1;
|
||||||
|
|
||||||
|
if (avctx->codec_id == AV_CODEC_ID_ASV1) {
|
||||||
av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size,
|
av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size,
|
||||||
buf_size);
|
buf_size);
|
||||||
if (!a->bitstream_buffer)
|
if (!a->bitstream_buffer)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
if (avctx->codec_id == AV_CODEC_ID_ASV1) {
|
|
||||||
a->bbdsp.bswap_buf((uint32_t *) a->bitstream_buffer,
|
a->bbdsp.bswap_buf((uint32_t *) a->bitstream_buffer,
|
||||||
(const uint32_t *) buf, buf_size / 4);
|
(const uint32_t *) buf, buf_size / 4);
|
||||||
} else {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < buf_size; i++)
|
|
||||||
a->bitstream_buffer[i] = ff_reverse[buf[i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size);
|
ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size);
|
||||||
|
} else {
|
||||||
|
ret = init_get_bits8_le(&a->gb, buf, buf_size);
|
||||||
|
}
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -342,7 +354,6 @@ AVCodec ff_asv2_decoder = {
|
|||||||
.id = AV_CODEC_ID_ASV2,
|
.id = AV_CODEC_ID_ASV2,
|
||||||
.priv_data_size = sizeof(ASV1Context),
|
.priv_data_size = sizeof(ASV1Context),
|
||||||
.init = decode_init,
|
.init = decode_init,
|
||||||
.close = decode_end,
|
|
||||||
.decode = decode_frame,
|
.decode = decode_frame,
|
||||||
.capabilities = AV_CODEC_CAP_DR1,
|
.capabilities = AV_CODEC_CAP_DR1,
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user