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
89OBJS-$(CONFIG_AVS_DECODER) += avs.o89OBJS-$(CONFIG_AVS_DECODER) += avs.o
90OBJS-$(CONFIG_BETHSOFTVID_DECODER) += bethsoftvideo.o90OBJS-$(CONFIG_BETHSOFTVID_DECODER) += bethsoftvideo.o
91OBJS-$(CONFIG_BFI_DECODER) += bfi.o91OBJS-$(CONFIG_BFI_DECODER) += bfi.o
92OBJS-$(CONFIG_BINK_DECODER) += bink.o binkidct.o92OBJS-$(CONFIG_BINK_DECODER) += bink.o binkdsp.o
93OBJS-$(CONFIG_BINKAUDIO_DCT_DECODER) += binkaudio.o wma.o93OBJS-$(CONFIG_BINKAUDIO_DCT_DECODER) += binkaudio.o wma.o
94OBJS-$(CONFIG_BINKAUDIO_RDFT_DECODER) += binkaudio.o wma.o94OBJS-$(CONFIG_BINKAUDIO_RDFT_DECODER) += binkaudio.o wma.o
95OBJS-$(CONFIG_BMP_DECODER) += bmp.o msrledec.o95OBJS-$(CONFIG_BMP_DECODER) += bmp.o msrledec.o
libavcodec/bink.c+30−28
@@ -24,6 +24,7 @@ · 23 unmodified lines
24#include "avcodec.h"24#include "avcodec.h"
25#include "dsputil.h"25#include "dsputil.h"
26#include "binkdata.h"26#include "binkdata.h"
27#include "binkdsp.h"
27#include "mathops.h"28#include "mathops.h"
28 29
29#define ALT_BITSTREAM_READER_LE30#define ALT_BITSTREAM_READER_LE
@@ -60,8 +61,8 @@ static const int binkb_bundle_signed[BINKB_NB_SRC] = { · 30 unmodified lines
60 0, 0, 0, 1, 1, 0, 1, 0, 0, 061 0, 0, 0, 1, 1, 0, 1, 0, 0, 0
61};62};
62 63
63static uint32_t binkb_intra_quant[16][64];64static int32_t binkb_intra_quant[16][64];
64static uint32_t binkb_inter_quant[16][64];65static int32_t binkb_inter_quant[16][64];
65 66
66/**67/**
67 * IDs for different data types used in Bink video codec68 * IDs for different data types used in Bink video codec
@@ -109,11 +110,11 @@ typedef struct Bundle { · 41 unmodified lines
109typedef struct BinkContext {110typedef struct BinkContext {
110 AVCodecContext *avctx;111 AVCodecContext *avctx;
111 DSPContext dsp;112 DSPContext dsp;
113 BinkDSPContext bdsp;
112 AVFrame pic, last;114 AVFrame pic, last;
113 int version; ///< internal Bink file version115 int version; ///< internal Bink file version
114 int has_alpha;116 int has_alpha;
115 int swap_planes;117 int swap_planes;
116 ScanTable scantable; ///< permutated scantable for DCT coeffs decoding
117 118
118 Bundle bundle[BINKB_NB_SRC]; ///< bundles for decoding all data types119 Bundle bundle[BINKB_NB_SRC]; ///< bundles for decoding all data types
119 Tree col_high[16]; ///< trees for decoding high nibble in "colours" data type120 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
580 * @param quant_matrices quantization matrices581 * @param quant_matrices quantization matrices
581 * @return 0 for success, negative value in other cases582 * @return 0 for success, negative value in other cases
582 */583 */
583static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *scan,584static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t *scan,
584 const uint32_t quant_matrices[16][64], int q)585 const int32_t quant_matrices[16][64], int q)
585{586{
586 int coef_list[128];587 int coef_list[128];
587 int mode_list[128];588 int mode_list[128];
@@ -590,7 +591,7 @@ static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t * · 2 unmodified lines
590 int coef_count = 0;591 int coef_count = 0;
591 int coef_idx[64];592 int coef_idx[64];
592 int quant_idx;593 int quant_idx;
593 const uint32_t *quant;594 const int32_t *quant;
594 595
595 coef_list[list_end] = 4; mode_list[list_end++] = 0;596 coef_list[list_end] = 4; mode_list[list_end++] = 0;
596 coef_list[list_end] = 24; mode_list[list_end++] = 0;597 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
791 const uint8_t *scan;792 const uint8_t *scan;
792 int xoff, yoff;793 int xoff, yoff;
793 LOCAL_ALIGNED_16(DCTELEM, block, [64]);794 LOCAL_ALIGNED_16(DCTELEM, block, [64]);
795 LOCAL_ALIGNED_16(int32_t, dctblock, [64]);
794 int coordmap[64];796 int coordmap[64];
795 int ybias = is_key ? -15 : 0;797 int ybias = is_key ? -15 : 0;
796 int qp;798 int qp;
@@ -845,11 +847,11 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, · 48 unmodified lines
845 dst[coordmap[*scan++]] = binkb_get_value(c, BINKB_SRC_COLORS);847 dst[coordmap[*scan++]] = binkb_get_value(c, BINKB_SRC_COLORS);
846 break;848 break;
847 case 2:849 case 2:
848 c->dsp.clear_block(block);850 memset(dctblock, 0, sizeof(*dctblock) * 64);
849 block[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC);851 dctblock[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC);
850 qp = binkb_get_value(c, BINKB_SRC_INTRA_Q);852 qp = binkb_get_value(c, BINKB_SRC_INTRA_Q);
851 read_dct_coeffs(gb, block, c->scantable.permutated, binkb_intra_quant, qp);853 read_dct_coeffs(gb, dctblock, bink_scan, binkb_intra_quant, qp);
852 c->dsp.idct_put(dst, stride, block);854 c->bdsp.idct_put(dst, stride, dctblock);
853 break;855 break;
854 case 3:856 case 3:
855 xoff = binkb_get_value(c, BINKB_SRC_X_OFF);857 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
878 } else {880 } else {
879 put_pixels8x8_overlapped(dst, ref, stride);881 put_pixels8x8_overlapped(dst, ref, stride);
880 }882 }
881 c->dsp.clear_block(block);883 memset(dctblock, 0, sizeof(*dctblock) * 64);
882 block[0] = binkb_get_value(c, BINKB_SRC_INTER_DC);884 dctblock[0] = binkb_get_value(c, BINKB_SRC_INTER_DC);
883 qp = binkb_get_value(c, BINKB_SRC_INTER_Q);885 qp = binkb_get_value(c, BINKB_SRC_INTER_Q);
884 read_dct_coeffs(gb, block, c->scantable.permutated, binkb_inter_quant, qp);886 read_dct_coeffs(gb, dctblock, bink_scan, binkb_inter_quant, qp);
885 c->dsp.idct_add(dst, stride, block);887 c->bdsp.idct_add(dst, stride, dctblock);
886 break;888 break;
887 case 5:889 case 5:
888 v = binkb_get_value(c, BINKB_SRC_COLORS);890 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
937 int xoff, yoff;939 int xoff, yoff;
938 LOCAL_ALIGNED_16(DCTELEM, block, [64]);940 LOCAL_ALIGNED_16(DCTELEM, block, [64]);
939 LOCAL_ALIGNED_16(uint8_t, ublock, [64]);941 LOCAL_ALIGNED_16(uint8_t, ublock, [64]);
942 LOCAL_ALIGNED_16(int32_t, dctblock, [64]);
940 int coordmap[64];943 int coordmap[64];
941 944
942 const int stride = c->pic.linesize[plane_idx];945 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
1019 ublock[*scan++] = get_value(c, BINK_SRC_COLORS);1022 ublock[*scan++] = get_value(c, BINK_SRC_COLORS);
1020 break;1023 break;
1021 case INTRA_BLOCK:1024 case INTRA_BLOCK:
1022 c->dsp.clear_block(block);1025 memset(dctblock, 0, sizeof(*dctblock) * 64);
1023 block[0] = get_value(c, BINK_SRC_INTRA_DC);1026 dctblock[0] = get_value(c, BINK_SRC_INTRA_DC);
1024 read_dct_coeffs(gb, block, c->scantable.permutated, bink_intra_quant, -1);1027 read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1);
1025 c->dsp.idct(block);1028 c->bdsp.idct_put(ublock, 8, dctblock);
1026 c->dsp.put_pixels_nonclamped(block, ublock, 8);
1027 break;1029 break;
1028 case FILL_BLOCK:1030 case FILL_BLOCK:
1029 v = get_value(c, BINK_SRC_COLORS);1031 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
1103 c->dsp.add_pixels8(dst, block, stride);1105 c->dsp.add_pixels8(dst, block, stride);
1104 break;1106 break;
1105 case INTRA_BLOCK:1107 case INTRA_BLOCK:
1106 c->dsp.clear_block(block);1108 memset(dctblock, 0, sizeof(*dctblock) * 64);
1107 block[0] = get_value(c, BINK_SRC_INTRA_DC);1109 dctblock[0] = get_value(c, BINK_SRC_INTRA_DC);
1108 read_dct_coeffs(gb, block, c->scantable.permutated, bink_intra_quant, -1);1110 read_dct_coeffs(gb, dctblock, bink_scan, bink_intra_quant, -1);
1109 c->dsp.idct_put(dst, stride, block);1111 c->bdsp.idct_put(dst, stride, dctblock);
1110 break;1112 break;
1111 case FILL_BLOCK:1113 case FILL_BLOCK:
1112 v = get_value(c, BINK_SRC_COLORS);1114 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
1117 yoff = get_value(c, BINK_SRC_Y_OFF);1119 yoff = get_value(c, BINK_SRC_Y_OFF);
1118 ref = prev + xoff + yoff * stride;1120 ref = prev + xoff + yoff * stride;
1119 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);1121 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
1120 c->dsp.clear_block(block);1122 memset(dctblock, 0, sizeof(*dctblock) * 64);
1121 block[0] = get_value(c, BINK_SRC_INTER_DC);1123 dctblock[0] = get_value(c, BINK_SRC_INTER_DC);
1122 read_dct_coeffs(gb, block, c->scantable.permutated, bink_inter_quant, -1);1124 read_dct_coeffs(gb, dctblock, bink_scan, bink_inter_quant, -1);
1123 c->dsp.idct_add(dst, stride, block);1125 c->bdsp.idct_add(dst, stride, dctblock);
1124 break;1126 break;
1125 case PATTERN_BLOCK:1127 case PATTERN_BLOCK:
1126 for (i = 0; i < 2; i++)1128 for (i = 0; i < 2; i++)
@@ -1288,7 +1290,7 @@ static av_cold int decode_init(AVCodecContext *avctx) · 161 unmodified lines
1288 1290
1289 avctx->idct_algo = FF_IDCT_BINK;1291 avctx->idct_algo = FF_IDCT_BINK;
1290 dsputil_init(&c->dsp, avctx);1292 dsputil_init(&c->dsp, avctx);
1291 ff_init_scantable(c->dsp.idct_permutation, &c->scantable, bink_scan);1293 ff_binkdsp_init(&c->bdsp);
1292 1294
1293 init_bundles(c);1295 init_bundles(c);
1294 1296
libavcodec/binkdata.h+2−2
@@ -285,7 +285,7 @@ static const uint8_t bink_patterns[16][64] = { · 284 unmodified lines
285 }285 }
286};286};
287 287
288static const uint32_t bink_intra_quant[16][64] = {288static const int32_t bink_intra_quant[16][64] = {
289{289{
290 0x010000, 0x016315, 0x01E83D, 0x02A535, 0x014E7B, 0x016577, 0x02F1E6, 0x02724C,290 0x010000, 0x016315, 0x01E83D, 0x02A535, 0x014E7B, 0x016577, 0x02F1E6, 0x02724C,
291 0x010000, 0x00EEDA, 0x024102, 0x017F9B, 0x00BE80, 0x00611E, 0x01083C, 0x00A552,291 0x010000, 0x00EEDA, 0x024102, 0x017F9B, 0x00BE80, 0x00611E, 0x01083C, 0x00A552,
@@ -448,7 +448,7 @@ static const uint32_t bink_intra_quant[16][64] = { · 156 unmodified lines
448},448},
449};449};
450 450
451static const uint32_t bink_inter_quant[16][64] = {451static const int32_t bink_inter_quant[16][64] = {
452{452{
453 0x010000, 0x017946, 0x01A5A9, 0x0248DC, 0x016363, 0x0152A7, 0x0243EC, 0x0209EA,453 0x010000, 0x017946, 0x01A5A9, 0x0248DC, 0x016363, 0x0152A7, 0x0243EC, 0x0209EA,
454 0x012000, 0x00E248, 0x01BBDA, 0x015CBC, 0x00A486, 0x0053E0, 0x00F036, 0x008095,454 0x012000, 0x00E248, 0x01BBDA, 0x015CBC, 0x00A486, 0x0053E0, 0x00F036, 0x008095,
libavcodec/binkdsp.crenamed from libavcodec/binkidct.c+14−7
@@ -1,5 +1,5 @@
1/*1/*
2 * Bink IDCT algorithm2 * Bink DSP routines
3 * Copyright (c) 2009 Kostya Shishkov3 * Copyright (c) 2009 Kostya Shishkov
4 *4 *
5 * This file is part of Libav.5 * This file is part of Libav.
@@ -21,10 +21,11 @@ · 15 unmodified lines
21 21
22/**22/**
23 * @file23 * @file
24 * Bink IDCT algorithm24 * Bink DSP routines
25 */25 */
26 26
27#include "dsputil.h"27#include "dsputil.h"
28#include "binkdsp.h"
28 29
29#define A1 2896 /* (1/sqrt(2))<<12 */30#define A1 2896 /* (1/sqrt(2))<<12 */
30#define A2 221731#define A2 2217
@@ -62,7 +63,7 @@ · 31 unmodified lines
62#define MUNGE_ROW(x) (((x) + 0x7F)>>8)63#define MUNGE_ROW(x) (((x) + 0x7F)>>8)
63#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)64#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)
64 65
65static inline void bink_idct_col(int *dest, const DCTELEM *src)66static inline void bink_idct_col(int *dest, const int32_t *src)
66{67{
67 if ((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) {68 if ((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) {
68 dest[0] =69 dest[0] =
@@ -78,7 +79,7 @@ static inline void bink_idct_col(int *dest, const DCTELEM *src) · 9 unmodified lines
78 }79 }
79}80}
80 81
81void ff_bink_idct_c(DCTELEM *block)82static void bink_idct_c(int32_t *block)
82{83{
83 int i;84 int i;
84 int temp[64];85 int temp[64];
@@ -90,17 +91,17 @@ void ff_bink_idct_c(DCTELEM *block) · 5 unmodified lines
90 }91 }
91}92}
92 93
93void ff_bink_idct_add_c(uint8_t *dest, int linesize, DCTELEM *block)94static void bink_idct_add_c(uint8_t *dest, int linesize, int32_t *block)
94{95{
95 int i, j;96 int i, j;
96 97
97 ff_bink_idct_c(block);98 bink_idct_c(block);
98 for (i = 0; i < 8; i++, dest += linesize, block += 8)99 for (i = 0; i < 8; i++, dest += linesize, block += 8)
99 for (j = 0; j < 8; j++)100 for (j = 0; j < 8; j++)
100 dest[j] += block[j];101 dest[j] += block[j];
101}102}
102 103
103void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block)104static void bink_idct_put_c(uint8_t *dest, int linesize, int32_t *block)
104{105{
105 int i;106 int i;
106 int temp[64];107 int temp[64];
@@ -110,3 +111,9 @@ void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block) · 3 unmodified lines
110 IDCT_ROW( (&dest[i*linesize]), (&temp[8*i]) );111 IDCT_ROW( (&dest[i*linesize]), (&temp[8*i]) );
111 }112 }
112}113}
114
115void 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
32typedef 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
37void 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
2894 }else if(CONFIG_EATGQ_DECODER && avctx->idct_algo==FF_IDCT_EA) {2894 }else if(CONFIG_EATGQ_DECODER && avctx->idct_algo==FF_IDCT_EA) {
2895 c->idct_put= ff_ea_idct_put_c;2895 c->idct_put= ff_ea_idct_put_c;
2896 c->idct_permutation_type= FF_NO_IDCT_PERM;2896 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;
2902 }else{ //accurate/default2897 }else{ //accurate/default
2903 c->idct_put = ff_simple_idct_put_8;2898 c->idct_put = ff_simple_idct_put_8;
2904 c->idct_add = ff_simple_idct_add_8;2899 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