]> git.sesse.net Git - ffmpeg/commitdiff
avcodec/asvenc: Avoid reversing output data twice
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
Tue, 13 Oct 2020 01:11:37 +0000 (03:11 +0200)
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
Sun, 18 Oct 2020 13:29:34 +0000 (15:29 +0200)
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>
libavcodec/asv.c
libavcodec/asv.h
libavcodec/asvdec.c
libavcodec/asvenc.c

index 14fdf73333893fdca8c208c3ab608b0339b16b9f..dcae90982acddb0430611cbfccddfa7d7585d135 100644 (file)
@@ -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)
index a1366b6fe45c4b5a015606f1884971d1b6fc5364..e778c72d340b7bcf891891f64b951348e3e13e71 100644 (file)
@@ -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);
 
index 78e53b64026970624e44a04134a3a9eeb7dc629a..6b6d7b3fa7e832998be248c266f215cefd379539 100644 (file)
@@ -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);
     }
 }
 
index 49df3ffbe1cc18e67c63544f6a735d28f13543f1..718ffa1836a0d09c0510266a358d8429d9afb298 100644 (file)
 #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;