diff mbox series

[FFmpeg-devel,3/9] avcodecc/asvdec: Avoid reversing input data twice

Message ID 20201013091017.1899676-3-andreas.rheinhardt@gmail.com
State Accepted
Commit cdf7619705611983724e98dee2c5659449fd0e30
Headers show
Series [FFmpeg-devel,1/9] avcodec/asvdec: Reduce the size of some VLCs | expand

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished

Commit Message

Andreas Rheinhardt Oct. 13, 2020, 9:10 a.m. UTC
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>
---
 libavcodec/asvdec.c | 77 ++++++++++++++++++++++++++-------------------
 1 file changed, 44 insertions(+), 33 deletions(-)

Comments

Andreas Rheinhardt Oct. 17, 2020, 6:17 p.m. UTC | #1
Andreas Rheinhardt:
> 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>
> ---
>  libavcodec/asvdec.c | 77 ++++++++++++++++++++++++++-------------------
>  1 file changed, 44 insertions(+), 33 deletions(-)
> 
> diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c
> index 6198188fc5..78e53b6402 100644
> --- a/libavcodec/asvdec.c
> +++ b/libavcodec/asvdec.c
> @@ -31,7 +31,6 @@
>  #include "blockdsp.h"
>  #include "idctdsp.h"
>  #include "internal.h"
> -#include "mathops.h"
>  #include "mpeg12data.h"
>  
>  #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,
>                          &ff_asv_ccp_tab[0][1], 2, 1,
>                          &ff_asv_ccp_tab[0][0], 2, 1, 32);
> -        INIT_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_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_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_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_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, 1024);
> +        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);
>      }
>  }
>  
> -// 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)
>  {
>      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;
>  }
>  
> +// 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)
>  {
> -    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)
> -        return (int8_t) asv2_get_bits(gb, 8);
> +        return (int8_t) get_bits_le(gb, 8);
>      else
>          return code - 31;
>  }
> @@ -132,11 +147,11 @@ static inline int asv2_decode_block(ASV1Context *a, int16_t block[64])
>  {
>      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 & 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++) {
> -        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 & 8)
> @@ -221,21 +236,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
>      p->pict_type = AV_PICTURE_TYPE_I;
>      p->key_frame = 1;
>  
> -    av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size,
> -                          buf_size);
> -    if (!a->bitstream_buffer)
> -        return AVERROR(ENOMEM);
> -
>      if (avctx->codec_id == AV_CODEC_ID_ASV1) {
> +        av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size,
> +                              buf_size);
> +        if (!a->bitstream_buffer)
> +            return AVERROR(ENOMEM);
> +
>          a->bbdsp.bswap_buf((uint32_t *) a->bitstream_buffer,
>                             (const uint32_t *) buf, buf_size / 4);
> +        ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size);
>      } else {
> -        int i;
> -        for (i = 0; i < buf_size; i++)
> -            a->bitstream_buffer[i] = ff_reverse[buf[i]];
> +        ret = init_get_bits8_le(&a->gb, buf, buf_size);
>      }
> -
> -    ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size);
>      if (ret < 0)
>          return ret;
>  
> @@ -342,7 +354,6 @@ AVCodec ff_asv2_decoder = {
>      .id             = AV_CODEC_ID_ASV2,
>      .priv_data_size = sizeof(ASV1Context),
>      .init           = decode_init,
> -    .close          = decode_end,
>      .decode         = decode_frame,
>      .capabilities   = AV_CODEC_CAP_DR1,
>  };
> 
Will apply this patch and the rest of this patchset tomorrow unless
there are objections.

- Andreas
diff mbox series

Patch

diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c
index 6198188fc5..78e53b6402 100644
--- a/libavcodec/asvdec.c
+++ b/libavcodec/asvdec.c
@@ -31,7 +31,6 @@ 
 #include "blockdsp.h"
 #include "idctdsp.h"
 #include "internal.h"
-#include "mathops.h"
 #include "mpeg12data.h"
 
 #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,
                         &ff_asv_ccp_tab[0][1], 2, 1,
                         &ff_asv_ccp_tab[0][0], 2, 1, 32);
-        INIT_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_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_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_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_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, 1024);
+        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);
     }
 }
 
-// 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)
 {
     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;
 }
 
+// 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)
 {
-    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)
-        return (int8_t) asv2_get_bits(gb, 8);
+        return (int8_t) get_bits_le(gb, 8);
     else
         return code - 31;
 }
@@ -132,11 +147,11 @@  static inline int asv2_decode_block(ASV1Context *a, int16_t block[64])
 {
     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 & 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++) {
-        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 & 8)
@@ -221,21 +236,18 @@  static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
 
-    av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size,
-                          buf_size);
-    if (!a->bitstream_buffer)
-        return AVERROR(ENOMEM);
-
     if (avctx->codec_id == AV_CODEC_ID_ASV1) {
+        av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size,
+                              buf_size);
+        if (!a->bitstream_buffer)
+            return AVERROR(ENOMEM);
+
         a->bbdsp.bswap_buf((uint32_t *) a->bitstream_buffer,
                            (const uint32_t *) buf, buf_size / 4);
+        ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size);
     } else {
-        int i;
-        for (i = 0; i < buf_size; i++)
-            a->bitstream_buffer[i] = ff_reverse[buf[i]];
+        ret = init_get_bits8_le(&a->gb, buf, buf_size);
     }
-
-    ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size);
     if (ret < 0)
         return ret;
 
@@ -342,7 +354,6 @@  AVCodec ff_asv2_decoder = {
     .id             = AV_CODEC_ID_ASV2,
     .priv_data_size = sizeof(ASV1Context),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = AV_CODEC_CAP_DR1,
 };