mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
avcodec/asvenc: Avoid reversing output data twice
The ASUS V2 format is designed for a little-endian bitstream reader, yet our encoder used an ordinary big-endian bitstream writer to write it; the bits of every byte were swapped at the end and some data (namely the numbers not in static tables) had to be bitreversed before writing it at all, so that it would be reversed twice. This commit stops doing so; instead, a little-endian bitstream writer is used. This also necessitated to switch certain static tables, which required trivial modifications to the decoder (that uses the same tables). Reviewed-by: Michael Niedermayer <michael@niedermayer.cc> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
This commit is contained in:
parent
c9e8f03195
commit
746ab8327c
@ -53,31 +53,37 @@ const uint8_t ff_asv_level_tab[7][2] = {
|
||||
};
|
||||
|
||||
const uint8_t ff_asv_dc_ccp_tab[8][2] = {
|
||||
{ 0x1, 2 }, { 0xD, 4 }, { 0xF, 4 }, { 0xC, 4 },
|
||||
{ 0x5, 3 }, { 0xE, 4 }, { 0x4, 3 }, { 0x0, 2 },
|
||||
{ 0x2, 2 }, { 0xB, 4 }, { 0xF, 4 }, { 0x3, 4 },
|
||||
{ 0x5, 3 }, { 0x7, 4 }, { 0x1, 3 }, { 0x0, 2 },
|
||||
};
|
||||
|
||||
const uint8_t ff_asv_ac_ccp_tab[16][2] = {
|
||||
{ 0x00, 2 }, { 0x3B, 6 }, { 0x0A, 4 }, { 0x3A, 6 },
|
||||
{ 0x02, 3 }, { 0x39, 6 }, { 0x3C, 6 }, { 0x38, 6 },
|
||||
{ 0x03, 3 }, { 0x3D, 6 }, { 0x08, 4 }, { 0x1F, 5 },
|
||||
{ 0x09, 4 }, { 0x0B, 4 }, { 0x0D, 4 }, { 0x0C, 4 },
|
||||
{ 0x00, 2 }, { 0x37, 6 }, { 0x05, 4 }, { 0x17, 6 },
|
||||
{ 0x02, 3 }, { 0x27, 6 }, { 0x0F, 6 }, { 0x07, 6 },
|
||||
{ 0x06, 3 }, { 0x2F, 6 }, { 0x01, 4 }, { 0x1F, 5 },
|
||||
{ 0x09, 4 }, { 0x0D, 4 }, { 0x0B, 4 }, { 0x03, 4 },
|
||||
};
|
||||
|
||||
const uint8_t ff_asv2_level_tab[63][2] = {
|
||||
{ 0x3F, 10 }, { 0x2F, 10 }, { 0x37, 10 }, { 0x27, 10 }, { 0x3B, 10 }, { 0x2B, 10 }, { 0x33, 10 }, { 0x23, 10 },
|
||||
{ 0x3D, 10 }, { 0x2D, 10 }, { 0x35, 10 }, { 0x25, 10 }, { 0x39, 10 }, { 0x29, 10 }, { 0x31, 10 }, { 0x21, 10 },
|
||||
{ 0x1F, 8 }, { 0x17, 8 }, { 0x1B, 8 }, { 0x13, 8 }, { 0x1D, 8 }, { 0x15, 8 }, { 0x19, 8 }, { 0x11, 8 },
|
||||
{ 0x0F, 6 }, { 0x0B, 6 }, { 0x0D, 6 }, { 0x09, 6 },
|
||||
{ 0x07, 4 }, { 0x05, 4 },
|
||||
{ 0x03, 2 },
|
||||
{ 0x00, 5 },
|
||||
{ 0x02, 2 },
|
||||
{ 0x04, 4 }, { 0x06, 4 },
|
||||
{ 0x08, 6 }, { 0x0C, 6 }, { 0x0A, 6 }, { 0x0E, 6 },
|
||||
{ 0x10, 8 }, { 0x18, 8 }, { 0x14, 8 }, { 0x1C, 8 }, { 0x12, 8 }, { 0x1A, 8 }, { 0x16, 8 }, { 0x1E, 8 },
|
||||
{ 0x20, 10 }, { 0x30, 10 }, { 0x28, 10 }, { 0x38, 10 }, { 0x24, 10 }, { 0x34, 10 }, { 0x2C, 10 }, { 0x3C, 10 },
|
||||
{ 0x22, 10 }, { 0x32, 10 }, { 0x2A, 10 }, { 0x3A, 10 }, { 0x26, 10 }, { 0x36, 10 }, { 0x2E, 10 }, { 0x3E, 10 },
|
||||
const uint16_t ff_asv2_level_tab[63][2] = {
|
||||
{ 0x3F0, 10 }, { 0x3D0, 10 }, { 0x3B0, 10 }, { 0x390, 10 }, { 0x370, 10 },
|
||||
{ 0x350, 10 }, { 0x330, 10 }, { 0x310, 10 }, { 0x2F0, 10 }, { 0x2D0, 10 },
|
||||
{ 0x2B0, 10 }, { 0x290, 10 }, { 0x270, 10 }, { 0x250, 10 }, { 0x230, 10 },
|
||||
{ 0x210, 10 },
|
||||
{ 0x0F8, 8 }, { 0x0E8, 8 }, { 0x0D8, 8 }, { 0x0C8, 8 }, { 0x0B8, 8 },
|
||||
{ 0x0A8, 8 }, { 0x098, 8 }, { 0x088, 8 },
|
||||
{ 0x03C, 6 }, { 0x034, 6 }, { 0x02C, 6 }, { 0x024, 6 },
|
||||
{ 0x00E, 4 }, { 0x00A, 4 },
|
||||
{ 0x003, 2 },
|
||||
{ 0x000, 5 },
|
||||
{ 0x001, 2 },
|
||||
{ 0x002, 4 }, { 0x006, 4 },
|
||||
{ 0x004, 6 }, { 0x00C, 6 }, { 0x014, 6 }, { 0x01C, 6 },
|
||||
{ 0x008, 8 }, { 0x018, 8 }, { 0x028, 8 }, { 0x038, 8 }, { 0x048, 8 },
|
||||
{ 0x058, 8 }, { 0x068, 8 }, { 0x078, 8 },
|
||||
{ 0x010, 10 }, { 0x030, 10 }, { 0x050, 10 }, { 0x070, 10 }, { 0x090, 10 },
|
||||
{ 0x0B0, 10 }, { 0x0D0, 10 }, { 0x0F0, 10 }, { 0x110, 10 }, { 0x130, 10 },
|
||||
{ 0x150, 10 }, { 0x170, 10 }, { 0x190, 10 }, { 0x1B0, 10 }, { 0x1D0, 10 },
|
||||
{ 0x1F0, 10 }
|
||||
};
|
||||
|
||||
av_cold void ff_asv_common_init(AVCodecContext *avctx)
|
||||
|
@ -66,7 +66,7 @@ extern const uint8_t ff_asv_ccp_tab[17][2];
|
||||
extern const uint8_t ff_asv_level_tab[7][2];
|
||||
extern const uint8_t ff_asv_dc_ccp_tab[8][2];
|
||||
extern const uint8_t ff_asv_ac_ccp_tab[16][2];
|
||||
extern const uint8_t ff_asv2_level_tab[63][2];
|
||||
extern const uint16_t ff_asv2_level_tab[63][2];
|
||||
|
||||
void ff_asv_common_init(AVCodecContext *avctx);
|
||||
|
||||
|
@ -55,21 +55,18 @@ static av_cold void init_vlcs(ASV1Context *a)
|
||||
INIT_VLC_STATIC(&ccp_vlc, CCP_VLC_BITS, 17,
|
||||
&ff_asv_ccp_tab[0][1], 2, 1,
|
||||
&ff_asv_ccp_tab[0][0], 2, 1, 32);
|
||||
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][0], 2, 1,
|
||||
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][0], 2, 1,
|
||||
INIT_VLC_OUTPUT_LE, 64);
|
||||
INIT_LE_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][0], 2, 1, 16);
|
||||
INIT_LE_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][0], 2, 1, 64);
|
||||
INIT_VLC_STATIC(&level_vlc, ASV1_LEVEL_VLC_BITS, 7,
|
||||
&ff_asv_level_tab[0][1], 2, 1,
|
||||
&ff_asv_level_tab[0][0], 2, 1, 16);
|
||||
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][0], 2, 1,
|
||||
INIT_VLC_OUTPUT_LE, 1024);
|
||||
INIT_LE_VLC_STATIC(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63,
|
||||
&ff_asv2_level_tab[0][1], 4, 2,
|
||||
&ff_asv2_level_tab[0][0], 4, 2, 1024);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,14 +32,8 @@
|
||||
#include "dct.h"
|
||||
#include "fdctdsp.h"
|
||||
#include "internal.h"
|
||||
#include "mathops.h"
|
||||
#include "mpeg12data.h"
|
||||
|
||||
static inline void asv2_put_bits(PutBitContext *pb, int n, int v)
|
||||
{
|
||||
put_bits(pb, n, ff_reverse[v << (8 - n)]);
|
||||
}
|
||||
|
||||
static inline void asv1_put_level(PutBitContext *pb, int level)
|
||||
{
|
||||
unsigned int index = level + 3;
|
||||
@ -57,14 +51,14 @@ static inline void asv2_put_level(ASV1Context *a, PutBitContext *pb, int level)
|
||||
unsigned int index = level + 31;
|
||||
|
||||
if (index <= 62) {
|
||||
put_bits(pb, ff_asv2_level_tab[index][1], ff_asv2_level_tab[index][0]);
|
||||
put_bits_le(pb, ff_asv2_level_tab[index][1], ff_asv2_level_tab[index][0]);
|
||||
} else {
|
||||
put_bits(pb, 5, 0); /* Escape code */
|
||||
put_bits_le(pb, 5, 0); /* Escape code */
|
||||
if (level < -128 || level > 127) {
|
||||
av_log(a->avctx, AV_LOG_WARNING, "Clipping level %d, increase qscale\n", level);
|
||||
level = av_clip_int8(level);
|
||||
}
|
||||
asv2_put_bits(pb, 8, level & 0xFF);
|
||||
put_bits_le(pb, 8, level & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,8 +121,8 @@ static inline void asv2_encode_block(ASV1Context *a, int16_t block[64])
|
||||
|
||||
count >>= 2;
|
||||
|
||||
asv2_put_bits(&a->pb, 4, count);
|
||||
asv2_put_bits(&a->pb, 8, (block[0] + 32) >> 6);
|
||||
put_bits_le(&a->pb, 4, count);
|
||||
put_bits_le(&a->pb, 8, (block[0] + 32) >> 6);
|
||||
block[0] = 0;
|
||||
|
||||
for (i = 0; i <= count; i++) {
|
||||
@ -150,9 +144,9 @@ static inline void asv2_encode_block(ASV1Context *a, int16_t block[64])
|
||||
|
||||
av_assert2(i || ccp < 8);
|
||||
if (i)
|
||||
put_bits(&a->pb, ff_asv_ac_ccp_tab[ccp][1], ff_asv_ac_ccp_tab[ccp][0]);
|
||||
put_bits_le(&a->pb, ff_asv_ac_ccp_tab[ccp][1], ff_asv_ac_ccp_tab[ccp][0]);
|
||||
else
|
||||
put_bits(&a->pb, ff_asv_dc_ccp_tab[ccp][1], ff_asv_dc_ccp_tab[ccp][0]);
|
||||
put_bits_le(&a->pb, ff_asv_dc_ccp_tab[ccp][1], ff_asv_dc_ccp_tab[ccp][0]);
|
||||
|
||||
if (ccp) {
|
||||
if (ccp & 8)
|
||||
@ -291,17 +285,16 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
||||
}
|
||||
emms_c();
|
||||
|
||||
flush_put_bits(&a->pb);
|
||||
if (avctx->codec_id == AV_CODEC_ID_ASV1)
|
||||
flush_put_bits(&a->pb);
|
||||
else
|
||||
flush_put_bits_le(&a->pb);
|
||||
AV_WN32(put_bits_ptr(&a->pb), 0);
|
||||
size = (put_bits_count(&a->pb) + 31) / 32;
|
||||
|
||||
if (avctx->codec_id == AV_CODEC_ID_ASV1) {
|
||||
a->bbdsp.bswap_buf((uint32_t *) pkt->data,
|
||||
(uint32_t *) pkt->data, size);
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < 4 * size; i++)
|
||||
pkt->data[i] = ff_reverse[pkt->data[i]];
|
||||
}
|
||||
|
||||
pkt->size = size * 4;
|
||||
|
Loading…
Reference in New Issue
Block a user