History

bink: make IDCT take 32-bit input

Since IDCT transforming 32-bit input to 8-bit output is unusual and unpractical for most codecs, move Bink IDCT into separate context. Get rid of an additional permutation table while at it since SIMD support for Bink IDCT is unlikely to be implemented in foreseeable future. Quantisation tables also have to change type to signed for proper dequantisation of DCT coefficients.

Kostya Shishkov committed 15 years ago

Commit 2968bed1 parent 001e6006 files · +86 −43Browse files

Unified · Split

6 files
  1. libavcodec/Makefile +1 −1
  2. libavcodec/bink.c +30 −28
  3. libavcodec/binkdata.h +2 −2
  4. libavcodec/binkdsp.c +14 −7
  5. libavcodec/binkdsp.h +39 −0
  6. libavcodec/dsputil.c +0 −5
libavcodec/Makefile+1−1
@@ -89,7 +89,7 @@ OBJS-$(CONFIG_AURA2_DECODER) += aura.o · 88 unmodified lines
8989 OBJS-$(CONFIG_AVS_DECODER) += avs.o
9090 OBJS-$(CONFIG_BETHSOFTVID_DECODER) += bethsoftvideo.o
9191 OBJS-$(CONFIG_BFI_DECODER) += bfi.o
92−OBJS-$(CONFIG_BINK_DECODER) += bink.o binkidct.o
92+OBJS-$(CONFIG_BINK_DECODER) += bink.o binkdsp.o
9393 OBJS-$(CONFIG_BINKAUDIO_DCT_DECODER) += binkaudio.o wma.o
9494 OBJS-$(CONFIG_BINKAUDIO_RDFT_DECODER) += binkaudio.o wma.o
9595 OBJS-$(CONFIG_BMP_DECODER) += bmp.o msrledec.o
libavcodec/bink.c+30−28
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424 #include "avcodec.h"
2525 #include "dsputil.h"
2626 #include "binkdata.h"
27+#include "binkdsp.h"
2728 #include "mathops.h"
2829
2930 #define ALT_BITSTREAM_READER_LE
@@ -60,8 +61,8 @@ static const int binkb_bundle_signed[BINKB_NB_SRC] = { · 30 unmodified lines
6061 0, 0, 0, 1, 1, 0, 1, 0, 0, 0
6162 };
6263
63−static uint32_t binkb_intra_quant[16][64];
64−static uint32_t binkb_inter_quant[16][64];
64+static int32_t binkb_intra_quant[16][64];
65+static int32_t binkb_inter_quant[16][64];
6566
6667 /**
6768 * IDs for different data types used in Bink video codec
@@ -109,11 +110,11 @@ typedef struct Bundle { · 41 unmodified lines
109110 typedef struct BinkContext {
110111 AVCodecContext *avctx;
111112 DSPContext dsp;
113+ BinkDSPContext bdsp;
112114 AVFrame pic, last;
113115 int version; ///< internal Bink file version
114116 int has_alpha;
115117 int swap_planes;
116− ScanTable scantable; ///< permutated scantable for DCT coeffs decoding
117118
118119 Bundle bundle[BINKB_NB_SRC]; ///< bundles for decoding all data types
119120 Tree col_high[16]; ///< trees for decoding high nibble in "colours" data type
@@ -580,8 +581,8 @@ static inline int binkb_get_value(BinkContext *c, int bundle_num) · 460 unmodified lines
580581 * @param quant_matrices quantization matrices
581582 * @return 0 for success, negative value in other cases
582583 */
583−static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *scan,
584− const uint32_t quant_matrices[16][64], int q)
584+static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t *scan,
585+ const int32_t quant_matrices[16][64], int q)
585586 {
586587 int coef_list[128];
587588 int mode_list[128];
@@ -590,7 +591,7 @@ static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t * · 2 unmodified lines
590591 int coef_count = 0;
591592 int coef_idx[64];
592593 int quant_idx;
593− const uint32_t *quant;
594+ const int32_t *quant;
594595
595596 coef_list[list_end] = 4; mode_list[list_end++] = 0;
596597 coef_list[list_end] = 24; mode_list[list_end++] = 0;
@@ -791,6 +792,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, · 194 unmodified lines
791792 const uint8_t *scan;
792793 int xoff, yoff;
793794 LOCAL_ALIGNED_16(DCTELEM, block, [64]);
795+ LOCAL_ALIGNED_16(int32_t, dctblock, [64]);
794796 int coordmap[64];
795797 int ybias = is_key ? -15 : 0;
796798 int qp;
@@ -845,11 +847,11 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, · 48 unmodified lines
845847 dst[coordmap[*scan++]] = binkb_get_value(c, BINKB_SRC_COLORS);
846848 break;
847849 case 2:
848− c->dsp.clear_block(block);
849− block[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC);
850+ memset(dctblock, 0, sizeof(*dctblock) * 64);
851+ dctblock[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC);
850852 qp = binkb_get_value(c, BINKB_SRC_INTRA_Q);
851− read_dct_coeffs(gb, block, c->scantable.permutated, binkb_intra_quant, qp);
852− c->dsp.idct_put(dst, stride, block);
853+ read_dct_coeffs(gb, dctblock, bink_scan, binkb_intra_quant, qp);
854+ c->bdsp.idct_put(dst, stride, dctblock);
853855 break;
854856 case 3:
855857 xoff = binkb_get_value(c, BINKB_SRC_X_OFF);
@@ -878,11 +880,11 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, · 22 unmodified lines
878880 } else {
879881 put_pixels8x8_overlapped(dst, ref, stride);
880882 }
881− c->dsp.clear_block(block);
882− block[0] = binkb_get_value(c, BINKB_SRC_INTER_DC);
883+ memset(dctblock, 0, sizeof(*dctblock) * 64);
884+ dctblock[0] = binkb_get_value(c, BINKB_SRC_INTER_DC);
883885 qp = binkb_get_value(c, BINKB_SRC_INTER_Q);
884− read_dct_coeffs(gb, block, c->scantable.permutated, binkb_inter_quant, qp);
885− c->dsp.idct_add(dst, stride, block);
886+ read_dct_coeffs(gb, dctblock, bink_scan, binkb_inter_quant, qp);
887+ c->bdsp.idct_add(dst, stride, dctblock);
886888 break;
887889 case 5:
888890 v = binkb_get_value(c, BINKB_SRC_COLORS);
@@ -937,6 +939,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, · 48 unmodified lines
937939 int xoff, yoff;
938940 LOCAL_ALIGNED_16(DCTELEM, block, [64]);
939941 LOCAL_ALIGNED_16(uint8_t, ublock, [64]);
942+ LOCAL_ALIGNED_16(int32_t, dctblock, [64]);
940943 int coordmap[64];
941944
942945 const int stride = c->pic.linesize[plane_idx];
@@ -1019,11 +1022,10 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, · 76 unmodified lines
10191022 ublock[*scan++] = get_value(c, BINK_SRC_COLORS);
10201023 break;
10211024 case INTRA_BLOCK:
1022− c->dsp.clear_block(block);
1023− block[0] = get_value(c, BINK_SRC_INTRA_DC);
1024− read_dct_coeffs(gb, block, c->scantable.permutated, bink_intra_quant, -1);
1025− c->dsp.idct(block);
1026− c->dsp.put_pixels_nonclamped(block, ublock, 8);
1025+ memset(dctblock, 0, sizeof(*dctblock) * 64);
1026+ dctblock[0] = get_value(c, BINK_SRC_INTRA_DC);
1027+ read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1);
1028+ c->bdsp.idct_put(ublock, 8, dctblock);
10271029 break;
10281030 case FILL_BLOCK:
10291031 v = get_value(c, BINK_SRC_COLORS);
@@ -1103,10 +1105,10 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, · 73 unmodified lines
11031105 c->dsp.add_pixels8(dst, block, stride);
11041106 break;
11051107 case INTRA_BLOCK:
1106− c->dsp.clear_block(block);
1107− block[0] = get_value(c, BINK_SRC_INTRA_DC);
1108− read_dct_coeffs(gb, block, c->scantable.permutated, bink_intra_quant, -1);
1109− c->dsp.idct_put(dst, stride, block);
1108+ memset(dctblock, 0, sizeof(*dctblock) * 64);
1109+ dctblock[0] = get_value(c, BINK_SRC_INTRA_DC);
1110+ read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1);
1111+ c->bdsp.idct_put(dst, stride, dctblock);
11101112 break;
11111113 case FILL_BLOCK:
11121114 v = get_value(c, BINK_SRC_COLORS);
@@ -1117,10 +1119,10 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, · 4 unmodified lines
11171119 yoff = get_value(c, BINK_SRC_Y_OFF);
11181120 ref = prev + xoff + yoff * stride;
11191121 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
1120− c->dsp.clear_block(block);
1121− block[0] = get_value(c, BINK_SRC_INTER_DC);
1122− read_dct_coeffs(gb, block, c->scantable.permutated, bink_inter_quant, -1);
1123− c->dsp.idct_add(dst, stride, block);
1122+ memset(dctblock, 0, sizeof(*dctblock) * 64);
1123+ dctblock[0] = get_value(c, BINK_SRC_INTER_DC);
1124+ read_dct_coeffs(gb, dctblock, bink_scan, bink_inter_quant, -1);
1125+ c->bdsp.idct_add(dst, stride, dctblock);
11241126 break;
11251127 case PATTERN_BLOCK:
11261128 for (i = 0; i < 2; i++)
@@ -1288,7 +1290,7 @@ static av_cold int decode_init(AVCodecContext *avctx) · 161 unmodified lines
12881290
12891291 avctx->idct_algo = FF_IDCT_BINK;
12901292 dsputil_init(&c->dsp, avctx);
1291− ff_init_scantable(c->dsp.idct_permutation, &c->scantable, bink_scan);
1293+ ff_binkdsp_init(&c->bdsp);
12921294
12931295 init_bundles(c);
12941296
libavcodec/binkdata.h+2−2
@@ -285,7 +285,7 @@ static const uint8_t bink_patterns[16][64] = { · 284 unmodified lines
285285 }
286286 };
287287
288−static const uint32_t bink_intra_quant[16][64] = {
288+static const int32_t bink_intra_quant[16][64] = {
289289 {
290290 0x010000, 0x016315, 0x01E83D, 0x02A535, 0x014E7B, 0x016577, 0x02F1E6, 0x02724C,
291291 0x010000, 0x00EEDA, 0x024102, 0x017F9B, 0x00BE80, 0x00611E, 0x01083C, 0x00A552,
@@ -448,7 +448,7 @@ static const uint32_t bink_intra_quant[16][64] = { · 156 unmodified lines
448448 },
449449 };
450450
451−static const uint32_t bink_inter_quant[16][64] = {
451+static const int32_t bink_inter_quant[16][64] = {
452452 {
453453 0x010000, 0x017946, 0x01A5A9, 0x0248DC, 0x016363, 0x0152A7, 0x0243EC, 0x0209EA,
454454 0x012000, 0x00E248, 0x01BBDA, 0x015CBC, 0x00A486, 0x0053E0, 0x00F036, 0x008095,
libavcodec/binkdsp.crenamed from libavcodec/binkidct.c+14−7
@@ -1,5 +1,5 @@
11 /*
2− * Bink IDCT algorithm
2+ * Bink DSP routines
33 * Copyright (c) 2009 Kostya Shishkov
44 *
55 * This file is part of Libav.
@@ -21,10 +21,11 @@ · 15 unmodified lines
2121
2222 /**
2323 * @file
24− * Bink IDCT algorithm
24+ * Bink DSP routines
2525 */
2626
2727 #include "dsputil.h"
28+#include "binkdsp.h"
2829
2930 #define A1 2896 /* (1/sqrt(2))<<12 */
3031 #define A2 2217
@@ -62,7 +63,7 @@ · 31 unmodified lines
6263 #define MUNGE_ROW(x) (((x) + 0x7F)>>8)
6364 #define IDCT_ROW(dest,src) IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_ROW,src)
6465
65−static inline void bink_idct_col(int *dest, const DCTELEM *src)
66+static inline void bink_idct_col(int *dest, const int32_t *src)
6667 {
6768 if ((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) {
6869 dest[0] =
@@ -78,7 +79,7 @@ static inline void bink_idct_col(int *dest, const DCTELEM *src) · 9 unmodified lines
7879 }
7980 }
8081
81−void ff_bink_idct_c(DCTELEM *block)
82+static void bink_idct_c(int32_t *block)
8283 {
8384 int i;
8485 int temp[64];
@@ -90,17 +91,17 @@ void ff_bink_idct_c(DCTELEM *block) · 5 unmodified lines
9091 }
9192 }
9293
93−void ff_bink_idct_add_c(uint8_t *dest, int linesize, DCTELEM *block)
94+static void bink_idct_add_c(uint8_t *dest, int linesize, int32_t *block)
9495 {
9596 int i, j;
9697
97− ff_bink_idct_c(block);
98+ bink_idct_c(block);
9899 for (i = 0; i < 8; i++, dest += linesize, block += 8)
99100 for (j = 0; j < 8; j++)
100101 dest[j] += block[j];
101102 }
102103
103−void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block)
104+static void bink_idct_put_c(uint8_t *dest, int linesize, int32_t *block)
104105 {
105106 int i;
106107 int temp[64];
@@ -110,3 +111,9 @@ void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block) · 3 unmodified lines
110111 IDCT_ROW( (&dest[i*linesize]), (&temp[8*i]) );
111112 }
112113 }
114+
115+void ff_binkdsp_init(BinkDSPContext *c)
116+{
117+ c->idct_add = bink_idct_add_c;
118+ c->idct_put = bink_idct_put_c;
119+}
libavcodec/binkdsp.h+39−0
@@ -0,0 +1,39 @@
1+/*
2+ * Bink DSP routines
3+ * Copyright (c) 2009 Kostya Shishkov
4+ *
5+ * This file is part of Libav.
6+ *
7+ * Libav is free software; you can redistribute it and/or
8+ * modify it under the terms of the GNU Lesser General Public
9+ * License as published by the Free Software Foundation; either
10+ * version 2.1 of the License, or (at your option) any later version.
11+ *
12+ * Libav is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+ * Lesser General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU Lesser General Public
18+ * License along with Libav; if not, write to the Free Software
19+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+ */
21+
22+/**
23+ * @file
24+ * Bink DSP routines
25+ */
26+
27+#ifndef AVCODEC_BINKDSP_H
28+#define AVCODEC_BINKDSP_H
29+
30+#include "dsputil.h"
31+
32+typedef struct BinkDSPContext {
33+ void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, int32_t *block/*align 16*/);
34+ void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, int32_t *block/*align 16*/);
35+} BinkDSPContext;
36+
37+void ff_binkdsp_init(BinkDSPContext *c);
38+
39+#endif /* AVCODEC_BINKDSP_H */
libavcodec/dsputil.c+0−5
@@ -2894,11 +2894,6 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) · 2893 unmodified lines
28942894 }else if(CONFIG_EATGQ_DECODER && avctx->idct_algo==FF_IDCT_EA) {
28952895 c->idct_put= ff_ea_idct_put_c;
28962896 c->idct_permutation_type= FF_NO_IDCT_PERM;
2897− }else if(CONFIG_BINK_DECODER && avctx->idct_algo==FF_IDCT_BINK) {
2898− c->idct = ff_bink_idct_c;
2899− c->idct_add = ff_bink_idct_add_c;
2900− c->idct_put = ff_bink_idct_put_c;
2901− c->idct_permutation_type = FF_NO_IDCT_PERM;
29022897 }else{ //accurate/default
29032898 c->idct_put = ff_simple_idct_put_8;
29042899 c->idct_add = ff_simple_idct_add_8;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t