On 3/27/2019 5:21 PM, Paul B Mahol wrote: > Signed-off-by: Paul B Mahol <one...@gmail.com> > --- > Missing deblocking. > --- > configure | 1 + > libavcodec/Makefile | 1 + > libavcodec/allcodecs.c | 1 + > libavcodec/avcodec.h | 1 + > libavcodec/bink2.c | 787 +++++++++++++++++++++++ > libavcodec/bink2f.c | 1139 +++++++++++++++++++++++++++++++++ > libavcodec/bink2g.c | 1342 +++++++++++++++++++++++++++++++++++++++ > libavcodec/codec_desc.c | 7 + > libavformat/bink.c | 3 +- > 9 files changed, 3280 insertions(+), 2 deletions(-) > create mode 100644 libavcodec/bink2.c > create mode 100644 libavcodec/bink2f.c > create mode 100644 libavcodec/bink2g.c > > diff --git a/configure b/configure > index 331393f8d5..2fdb7e589c 100755 > --- a/configure > +++ b/configure > @@ -2643,6 +2643,7 @@ atrac3p_decoder_select="mdct sinewin" > atrac9_decoder_select="mdct" > avrn_decoder_select="exif jpegtables" > bink_decoder_select="blockdsp hpeldsp" > +bink2_decoder_select="blockdsp" > binkaudio_dct_decoder_select="mdct rdft dct sinewin wma_freqs" > binkaudio_rdft_decoder_select="mdct rdft sinewin wma_freqs" > cavs_decoder_select="blockdsp golomb h264chroma idctdsp qpeldsp videodsp" > diff --git a/libavcodec/Makefile b/libavcodec/Makefile > index 15c43a8a6a..d02240febc 100644 > --- a/libavcodec/Makefile > +++ b/libavcodec/Makefile > @@ -228,6 +228,7 @@ OBJS-$(CONFIG_AYUV_ENCODER) += v408enc.o > OBJS-$(CONFIG_BETHSOFTVID_DECODER) += bethsoftvideo.o > OBJS-$(CONFIG_BFI_DECODER) += bfi.o > OBJS-$(CONFIG_BINK_DECODER) += bink.o binkdsp.o > +OBJS-$(CONFIG_BINK2_DECODER) += bink2.o > OBJS-$(CONFIG_BINKAUDIO_DCT_DECODER) += binkaudio.o > OBJS-$(CONFIG_BINKAUDIO_RDFT_DECODER) += binkaudio.o > OBJS-$(CONFIG_BINTEXT_DECODER) += bintext.o cga_data.o > diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c > index b26aeca239..3a9ddb7b37 100644 > --- a/libavcodec/allcodecs.c > +++ b/libavcodec/allcodecs.c > @@ -59,6 +59,7 @@ extern AVCodec ff_ayuv_decoder; > extern AVCodec ff_bethsoftvid_decoder; > extern AVCodec ff_bfi_decoder; > extern AVCodec ff_bink_decoder; > +extern AVCodec ff_bink2_decoder; > extern AVCodec ff_bitpacked_decoder; > extern AVCodec ff_bmp_encoder; > extern AVCodec ff_bmp_decoder; > diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h > index 0ce22ec4fa..6b881ac351 100644 > --- a/libavcodec/avcodec.h > +++ b/libavcodec/avcodec.h > @@ -454,6 +454,7 @@ enum AVCodecID { > AV_CODEC_ID_RASC, > AV_CODEC_ID_HYMT, > AV_CODEC_ID_ARBC, > + AV_CODEC_ID_BINKVIDEO2, > > /* various PCM "codecs" */ > AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the > start of audio codecs > diff --git a/libavcodec/bink2.c b/libavcodec/bink2.c > new file mode 100644 > index 0000000000..5513710bae > --- /dev/null > +++ b/libavcodec/bink2.c > @@ -0,0 +1,787 @@ > +/* > + * Bink video 2 decoder > + * Copyright (c) 2014 Konstantin Shishkov > + * Copyright (c) 2019 Paul B Mahol > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + */ > + > +#define CACHED_BITSTREAM_READER 1 > +#define DEBUG 1 > +#define ASSERT_LEVEL 3 > +#include "libavutil/avassert.h" > +#include "libavutil/attributes.h" > +#include "libavutil/imgutils.h" > +#include "libavutil/internal.h" > +#include "avcodec.h" > +#include "blockdsp.h" > +#include "copy_block.h" > +#include "idctdsp.h"
Unused? > +#include "internal.h" > +#include "mathops.h" > + > +#define BITSTREAM_READER_LE > +#include "get_bits.h" > +#include "unary.h" > + > +#define BINK_FLAG_ALPHA 0x00100000 > +#define DC_MPRED(A, B, C) FFMIN(FFMAX((C) + (B) - (A), FFMIN3(A, B, C)), > FFMAX3(A, B, C)) > +#define DC_MPRED2(A, B) FFMIN(FFMAX((A), (B)), FFMAX(FFMIN((A), (B)), 2 * > (A) - (B))) > + > +static VLC bink2f_quant_vlc; > +static VLC bink2f_ac_val0_vlc; > +static VLC bink2f_ac_val1_vlc; > +static VLC bink2f_ac_skip0_vlc; > +static VLC bink2f_ac_skip1_vlc; > +static VLC bink2g_ac_skip0_vlc; > +static VLC bink2g_ac_skip1_vlc; > +static VLC bink2g_mv_vlc; > + > +static const uint8_t kb2h_num_slices[] = { > + 2, 3, 4, 8, > +}; > + > +static const uint8_t luma_repos[] = { > + 0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15, > +}; > + > +static const uint16_t bink2g_luma_intra_qmat[4][64] = { > + { > + 1024, 1432, 1506, 1181, > + 1843, 2025, 5271, 8592, > + 1313, 1669, 1630, 1672, > + 2625, 3442, 8023, 12794, > + 1076, 1755, 1808, 1950, > + 3980, 4875, 8813, 11909, > + 1350, 1868, 2127, 2016, > + 4725, 4450, 7712, 9637, > + 2458, 3103, 4303, 4303, > + 6963, 6835, 11079, 13365, > + 3375, 5704, 5052, 6049, > + 9198, 7232, 10725, 9834, > + 5486, 7521, 7797, 7091, > + 11079, 10016, 13559, 12912, > + 7279, 7649, 7020, 6097, > + 9189, 9047, 12661, 13768, > + }, > + { > + 1218, 1703, 1791, 1405, > + 2192, 2408, 6268, 10218, > + 1561, 1985, 1938, 1988, > + 3122, 4093, 9541, 15215, > + 1279, 2087, 2150, 2319, > + 4733, 5798, 10481, 14162, > + 1606, 2222, 2530, 2398, > + 5619, 5292, 9171, 11460, > + 2923, 3690, 5117, 5118, > + 8281, 8128, 13176, 15894, > + 4014, 6783, 6008, 7194, > + 10938, 8600, 12755, 11694, > + 6524, 8944, 9272, 8433, > + 13176, 11911, 16125, 15354, > + 8657, 9096, 8348, 7250, > + 10927, 10759, 15056, 16373, > + }, > + { > + 1448, 2025, 2130, 1671, > + 2607, 2864, 7454, 12151, > + 1856, 2360, 2305, 2364, > + 3713, 4867, 11346, 18094, > + 1521, 2482, 2557, 2758, > + 5628, 6894, 12464, 16841, > + 1909, 2642, 3008, 2852, > + 6683, 6293, 10906, 13629, > + 3476, 4388, 6085, 6086, > + 9847, 9666, 15668, 18901, > + 4773, 8066, 7145, 8555, > + 13007, 10227, 15168, 13907, > + 7758, 10637, 11026, 10028, > + 15668, 14165, 19175, 18259, > + 10294, 10817, 9927, 8622, > + 12995, 12794, 17905, 19470, > + }, > + { > + 1722, 2408, 2533, 1987, > + 3100, 3406, 8864, 14450, > + 2208, 2807, 2741, 2811, > + 4415, 5788, 13493, 21517, > + 1809, 2951, 3041, 3280, > + 6693, 8199, 14822, 20028, > + 2271, 3142, 3578, 3391, > + 7947, 7484, 12969, 16207, > + 4133, 5218, 7236, 7238, > + 11711, 11495, 18633, 22478, > + 5677, 9592, 8497, 10174, > + 15469, 12162, 18038, 16538, > + 9226, 12649, 13112, 11926, > + 18633, 16845, 22804, 21715, > + 12242, 12864, 11806, 10254, > + 15454, 15215, 21293, 23155, > + }, > +}; > + > +static const uint16_t bink2g_chroma_intra_qmat[4][64] = { > + { > + 1024, 1193, 1434, 2203, > + 5632, 4641, 5916, 6563, > + 1193, 1622, 1811, 3606, > + 6563, 5408, 6894, 7649, > + 1434, 1811, 3515, 4875, > + 5916, 4875, 6215, 6894, > + 2203, 3606, 4875, 3824, > + 4641, 3824, 4875, 5408, > + 5632, 6563, 5916, 4641, > + 5632, 4641, 5916, 6563, > + 4641, 5408, 4875, 3824, > + 4641, 3824, 4875, 5408, > + 5916, 6894, 6215, 4875, > + 5916, 4875, 6215, 6894, > + 6563, 7649, 6894, 5408, > + 6563, 5408, 6894, 7649, > + }, > + { > + 1218, 1419, 1706, 2620, > + 6698, 5519, 7035, 7805, > + 1419, 1929, 2153, 4288, > + 7805, 6432, 8199, 9096, > + 1706, 2153, 4180, 5798, > + 7035, 5798, 7390, 8199, > + 2620, 4288, 5798, 4548, > + 5519, 4548, 5798, 6432, > + 6698, 7805, 7035, 5519, > + 6698, 5519, 7035, 7805, > + 5519, 6432, 5798, 4548, > + 5519, 4548, 5798, 6432, > + 7035, 8199, 7390, 5798, > + 7035, 5798, 7390, 8199, > + 7805, 9096, 8199, 6432, > + 7805, 6432, 8199, 9096, > + }, > + { > + 1448, 1688, 2028, 3116, > + 7965, 6563, 8367, 9282, > + 1688, 2294, 2561, 5099, > + 9282, 7649, 9750, 10817, > + 2028, 2561, 4971, 6894, > + 8367, 6894, 8789, 9750, > + 3116, 5099, 6894, 5408, > + 6563, 5408, 6894, 7649, > + 7965, 9282, 8367, 6563, > + 7965, 6563, 8367, 9282, > + 6563, 7649, 6894, 5408, > + 6563, 5408, 6894, 7649, > + 8367, 9750, 8789, 6894, > + 8367, 6894, 8789, 9750, > + 9282, 10817, 9750, 7649, > + 9282, 7649, 9750, 10817, > + }, > + { > + 1722, 2007, 2412, 3706, > + 9472, 7805, 9950, 11038, > + 2007, 2729, 3045, 6064, > + 11038, 9096, 11595, 12864, > + 2412, 3045, 5912, 8199, > + 9950, 8199, 10452, 11595, > + 3706, 6064, 8199, 6432, > + 7805, 6432, 8199, 9096, > + 9472, 11038, 9950, 7805, > + 9472, 7805, 9950, 11038, > + 7805, 9096, 8199, 6432, > + 7805, 6432, 8199, 9096, > + 9950, 11595, 10452, 8199, > + 9950, 8199, 10452, 11595, > + 11038, 12864, 11595, 9096, > + 11038, 9096, 11595, 12864, > + }, > +}; > + > + > +static const uint16_t bink2g_inter_qmat[4][64] = { > + { > + 1024, 1193, 1076, 844, > + 1052, 914, 1225, 1492, > + 1193, 1391, 1254, 983, > + 1227, 1065, 1463, 1816, > + 1076, 1254, 1161, 936, > + 1195, 1034, 1444, 1741, > + 844, 983, 936, 811, > + 1055, 927, 1305, 1584, > + 1052, 1227, 1195, 1055, > + 1451, 1336, 1912, 2354, > + 914, 1065, 1034, 927, > + 1336, 1313, 1945, 2486, > + 1225, 1463, 1444, 1305, > + 1912, 1945, 3044, 4039, > + 1492, 1816, 1741, 1584, > + 2354, 2486, 4039, 5679, > + }, > + { > + 1218, 1419, 1279, 1003, > + 1252, 1087, 1457, 1774, > + 1419, 1654, 1491, 1169, > + 1459, 1267, 1739, 2159, > + 1279, 1491, 1381, 1113, > + 1421, 1230, 1717, 2070, > + 1003, 1169, 1113, 965, > + 1254, 1103, 1552, 1884, > + 1252, 1459, 1421, 1254, > + 1725, 1589, 2274, 2799, > + 1087, 1267, 1230, 1103, > + 1589, 1562, 2313, 2956, > + 1457, 1739, 1717, 1552, > + 2274, 2313, 3620, 4803, > + 1774, 2159, 2070, 1884, > + 2799, 2956, 4803, 6753, > + }, > + { > + 1448, 1688, 1521, 1193, > + 1488, 1293, 1732, 2110, > + 1688, 1967, 1773, 1391, > + 1735, 1507, 2068, 2568, > + 1521, 1773, 1642, 1323, > + 1690, 1462, 2042, 2462, > + 1193, 1391, 1323, 1147, > + 1492, 1311, 1845, 2241, > + 1488, 1735, 1690, 1492, > + 2052, 1889, 2704, 3328, > + 1293, 1507, 1462, 1311, > + 1889, 1857, 2751, 3515, > + 1732, 2068, 2042, 1845, > + 2704, 2751, 4306, 5712, > + 2110, 2568, 2462, 2241, > + 3328, 3515, 5712, 8031, > + }, > + { > + 1722, 2007, 1809, 1419, > + 1770, 1537, 2060, 2509, > + 2007, 2339, 2108, 1654, > + 2063, 1792, 2460, 3054, > + 1809, 2108, 1953, 1574, > + 2010, 1739, 2428, 2928, > + 1419, 1654, 1574, 1364, > + 1774, 1559, 2195, 2664, > + 1770, 2063, 2010, 1774, > + 2440, 2247, 3216, 3958, > + 1537, 1792, 1739, 1559, > + 2247, 2209, 3271, 4181, > + 2060, 2460, 2428, 2195, > + 3216, 3271, 5120, 6793, > + 2509, 3054, 2928, 2664, > + 3958, 4181, 6793, 9550, > + }, > +}; > + > +static uint8_t bink2g_chroma_cbp_pat[16] = { > + 0x00, 0x00, 0x00, 0x0F, > + 0x00, 0x0F, 0x0F, 0x0F, > + 0x00, 0x0F, 0x0F, 0x0F, > + 0x0F, 0x0F, 0x0F, 0x0F, > +}; > + > +static const int32_t bink2g_dc_pat[] = { > + 1024, 1218, 1448, 1722, 2048, > + 2435, 2896, 3444, 4096, 4871, > + 5793, 6889, 8192, 9742, 11585, 13777, 16384, > + 19484, 23170, 27555, 32768, 38968, 46341, > + 55109, 65536, 77936, 92682, 110218, 131072, > + 155872, 185364, 220436, 262144, 311744, > + 370728, 440872, 524288, > +}; > + > +static const uint8_t dq_patterns[8] = { 8, 0, 1, 0, 2, 0, 1, 0 }; > + > +static const uint8_t bink2f_quant_codes[16] = { > + 0x01, 0x02, 0x04, 0x08, 0x10, 0x30, 0x50, 0x70, > + 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, > +}; > + > +static const uint8_t bink2f_quant_bits[16] = { > + 1, 2, 3, 4, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, > +}; > + > +static const uint16_t bink2f_ac_val_codes[2][13] = { > + { > + 0x04, 0x01, 0x02, 0x00, 0x08, 0x18, 0xF8, 0x178, 0x138, > + 0x38, 0x1B8, 0x78, 0xB8 > + }, > + { > + 0x0A, 0x01, 0x04, 0x08, 0x06, 0x00, 0x02, 0x1A, 0x2A, > + 0x16A, 0x1EA, 0x6A, 0xEA > + }, > +}; > + > +static const uint8_t bink2f_ac_val_bits[2][13] = { > + { 3, 1, 2, 4, 5, 6, 8, 9, 9, 9, 9, 9, 9 }, > + { 6, 1, 3, 4, 3, 4, 4, 5, 7, 9, 9, 9, 9 }, > +}; > + > +#define NUM_AC_SKIPS 14 > +static const uint16_t bink2f_ac_skip_codes[2][NUM_AC_SKIPS] = { > + { > + 0x00, 0x01, 0x0D, 0x15, 0x45, 0x85, 0xA5, 0x165, > + 0x65, 0x1E5, 0xE5, 0x25, 0x03, 0x05 > + }, > + { > + 0x00, 0x01, 0x03, 0x07, 0x1F, 0x1B, 0x0F, 0x2F, > + 0x5B, 0xDB, 0x1DB, 0x3B, 0x05, 0x0B > + } > +}; > + > +static const uint8_t bink2f_ac_skip_bits[2][NUM_AC_SKIPS] = { > + { 1, 3, 4, 5, 7, 8, 8, 9, 9, 9, 9, 8, 2, 8 }, > + { 1, 3, 4, 4, 5, 7, 6, 6, 8, 9, 9, 6, 3, 5 } > +}; > + > +static const uint8_t bink2f_skips[] = { > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 62, 0, 0, 0, > +}; > + > +static const uint8_t bink2g_skips[] = { > + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 64, 0, 0, 0, > +}; > + > +static const uint8_t bink2f_next_skips[] = { > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, > +}; > + > +static const uint8_t bink2_next_skips[] = { > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, > +}; > + > +static const uint16_t bink2g_ac_skip_codes[2][NUM_AC_SKIPS] = { > + { > + 0x01, 0x00, 0x004, 0x02C, 0x06C, 0x0C, 0x4C, > + 0xAC, 0xEC, 0x12C, 0x16C, 0x1AC, 0x02, 0x1C, > + }, > + { > + 0x01, 0x04, 0x00, 0x08, 0x02, 0x32, 0x0A, > + 0x12, 0x3A, 0x7A, 0xFA, 0x72, 0x06, 0x1A, > + }, > +}; > + > +static const uint8_t bink2g_ac_skip_bits[2][NUM_AC_SKIPS] = { > + { 1, 3, 4, 9, 9, 7, 7, 9, 8, 9, 9, 9, 2, 5 }, > + { 1, 3, 4, 4, 5, 7, 5, 6, 7, 8, 8, 7, 3, 6 }, > +}; > + > +static const uint8_t bink2g_mv_codes[] = { > + 0x01, 0x06, 0x0C, 0x1C, 0x18, 0x38, 0x58, 0x78, > + 0x68, 0x48, 0x28, 0x08, 0x14, 0x04, 0x02, 0x00, > +}; > + > +static const uint8_t bink2g_mv_bits[] = { > + 1, 3, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 3, 4, > +}; > + > +static const float bink2f_dc_quant[16] = { > + 4, 4, 4, 4, 4, 6, 7, 8, 10, 12, 16, 24, 32, 48, 64, 128 > +}; > + > +static const float bink2f_ac_quant[16] = { > + 1.0, 2.0, 2.5, 3.0, 3.5, 4.0, 6.0, 7.0, 8.0, 12.0, 16.0, 24.0, 32.0, > 48.0, 64.0, 128.0 > +}; > + > +static const float bink2f_luma_intra_qmat[64] = { > + 0.125, 0.190718, 0.16332, 0.235175, 0.3, 0.392847, 0.345013, > 0.210373, > + 0.208056, 0.288582, 0.317145, 0.387359, 0.450788, 0.790098, 0.562995, > 0.263095, > + 0.228649, 0.294491, 0.341421, 0.460907, 0.653281, 0.731424, 0.60988, > 0.252336, > + 0.205778, 0.346585, 0.422498, 0.501223, 0.749621, 1.004719, 0.636379, > 0.251428, > + 0.225, 0.381436, 0.604285, 0.823113, 0.85, 1.070509, 0.69679, > 0.265553, > + 0.235708, 0.476783, 0.70576, 0.739104, 0.795516, 0.802512, 0.600616, > 0.249289, > + 0.331483, 0.600528, 0.689429, 0.692062, 0.69679, 0.643138, 0.43934, > 0.188511, > + 0.248309, 0.440086, 0.42807, 0.397419, 0.386259, 0.270966, 0.192244, > 0.094199, > +}; > + > +static const float bink2f_luma_inter_qmat[64] = { > + 0.125, 0.17338, 0.16332, 0.146984, 0.128475, 0.106393, 0.077046, > 0.043109, > + 0.17338, 0.240485, 0.226532, 0.203873, 0.1782, 0.147571, 0.109474, > 0.062454, > + 0.16332, 0.226532, 0.219321, 0.202722, 0.181465, 0.149711, 0.112943, > 0.062584, > + 0.146984, 0.203873, 0.202722, 0.201647, 0.183731, 0.153976, 0.11711, > 0.065335, > + 0.128475, 0.1782, 0.181465, 0.183731, 0.177088, 0.155499, 0.120267, > 0.068016, > + 0.106393, 0.147571, 0.149711, 0.153976, 0.155499, 0.145756, 0.116636, > 0.068495, > + 0.077046, 0.109474, 0.112943, 0.11711, 0.120267, 0.116636, 0.098646, > 0.060141, > + 0.043109, 0.062454, 0.062584, 0.065335, 0.068016, 0.068495, 0.060141, > 0.038853, > +}; > + > +static const float bink2f_chroma_qmat[64] = { > + 0.125, 0.17338, 0.217761, 0.383793, 0.6875, 0.54016501, > 0.37207201, 0.18968099, > + 0.17338, 0.28056601, 0.32721299, 0.74753499, 0.95358998, 0.74923098, > 0.51607901, 0.26309499, > + 0.217761, 0.32721299, 0.66387498, 1.056244, 0.89826202, 0.70576, > 0.48613599, 0.24783, > + 0.383793, 0.74753499, 1.056244, 0.95059502, 0.80841398, 0.635167, > 0.437511, 0.223041, > + 0.6875, 0.95358998, 0.89826202, 0.80841398, 0.6875, 0.54016501, > 0.37207201, 0.18968099, > + 0.54016501, 0.74923098, 0.70576, 0.635167, 0.54016501, 0.42440501, > 0.292335, 0.149031, > + 0.37207201, 0.51607901, 0.48613599, 0.437511, 0.37207201, 0.292335, > 0.201364, 0.102655, > + 0.18968099, 0.26309499, 0.24783, 0.223041, 0.18968099, 0.149031, > 0.102655, 0.052333001 > +}; > + > +static const uint8_t bink2f_luma_scan[64] = { > + 0, 2, 1, 8, 9, 17, 10, 16, > + 24, 3, 18, 25, 32, 11, 33, 26, > + 4, 40, 19, 12, 27, 41, 34, 5, > + 20, 48, 6, 28, 15, 42, 23, 35, > + 21, 13, 14, 7, 31, 43, 49, 36, > + 22, 56, 39, 50, 30, 44, 29, 51, > + 57, 47, 58, 59, 63, 61, 55, 38, > + 52, 62, 45, 37, 60, 46, 54, 53 > +}; > + > +static const uint8_t bink2f_chroma_scan[64] = { > + 0, 1, 8, 2, 9, 16, 10, 17, > + 3, 24, 11, 18, 25, 13, 14, 4, > + 15, 5, 6, 7, 12, 19, 20, 21, > + 22, 23, 26, 27, 28, 29, 30, 31, > + 32, 33, 34, 35, 36, 37, 38, 39, > + 40, 41, 42, 43, 44, 45, 46, 47, > + 48, 49, 50, 51, 52, 53, 54, 55, > + 56, 57, 58, 59, 60, 61, 62, 63 > +}; > + > +static const uint8_t bink2g_scan[64] = { > + 0, 8, 1, 2, 9, 16, 24, 17, > + 10, 3, 4, 11, 18, 25, 32, 40, > + 33, 26, 19, 12, 5, 6, 13, 20, > + 27, 34, 41, 48, 56, 49, 42, 35, > + 28, 21, 14, 7, 15, 22, 29, 36, > + 43, 50, 57, 58, 51, 44, 37, 30, > + 23, 31, 38, 45, 52, 59, 60, 53, > + 46, 39, 47, 54, 61, 62, 55, 63, > +}; All these tables could be in a separate file. > + > +typedef struct QuantPredict { > + int8_t intra_q; > + int8_t inter_q; > +} QuantPredict; > + > +typedef struct DCPredict { > + float dc[4][16]; > + int block_type; > +} DCPredict; > + > +typedef struct DCIPredict { > + int dc[4][16]; > + int block_type; > +} DCIPredict; > + > +typedef struct MVectors { > + int v[4][2]; > + int nb_vectors; > +} MVectors; > + > +typedef struct MVPredict { > + MVectors mv; > +} MVPredict; > + > +/* > + * Decoder context > + */ > +typedef struct Bink2Context { > + AVCodecContext *avctx; > + GetBitContext gb; > + BlockDSPContext dsp; > + AVFrame *last; > + int version; ///< internal Bink file version > + int has_alpha; > + > + DECLARE_ALIGNED(16, float, block[4][64]); > + DECLARE_ALIGNED(16, int16_t, iblock[4][64]); > + > + QuantPredict *current_q; > + QuantPredict *prev_q; > + > + DCPredict *current_dc; > + DCPredict *prev_dc; > + > + DCIPredict *current_idc; > + DCIPredict *prev_idc; > + > + MVPredict *current_mv; > + MVPredict *prev_mv; > + > + uint8_t *col_cbp; > + uint8_t *row_cbp; > + > + int num_slices; > + int slice_height[4]; > + > + int comp; > + int mb_pos; > + unsigned flags; > + unsigned frame_flags; > +} Bink2Context; > + > +/** > + * Bink2 video block types > + */ > +enum BlockTypes { > + INTRA_BLOCK = 0, ///< intra DCT block > + SKIP_BLOCK, ///< skipped block > + MOTION_BLOCK, ///< block is copied from previous frame with some > offset > + RESIDUE_BLOCK, ///< motion block with some difference added > +}; > + > +static const uint8_t ones_count[16] = { > + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 > +}; > + > +#include "bink2f.c" > +#include "bink2g.c" > + > +static int bink2_decode_frame(AVCodecContext *avctx, void *data, > + int *got_frame, AVPacket *pkt) > +{ > + Bink2Context * const c = avctx->priv_data; > + GetBitContext *gb = &c->gb; > + AVFrame *frame = data; > + uint8_t *dst[4]; > + uint8_t *src[4]; > + int stride[4]; > + int sstride[4]; > + uint32_t off = 0; > + int is_kf = !!(pkt->flags & AV_PKT_FLAG_KEY); > + int ret, w, h; > + int height_a; > + > + w = avctx->width; > + h = avctx->height; > + ret = ff_set_dimensions(avctx, FFALIGN(w, 32), FFALIGN(h, 32)); > + if (ret < 0) > + return ret; > + avctx->width = w; > + avctx->height = h; Why doing this on every frame? The result will always be the same. > + > + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) > + return ret; > + > + for (int i = 0; i < 4; i++) { > + src[i] = c->last->data[i]; > + dst[i] = frame->data[i]; > + stride[i] = frame->linesize[i]; > + sstride[i] = c->last->linesize[i]; > + } > + > + c->frame_flags = AV_RL32(pkt->data); > + ff_dlog(NULL, "frame flags %X\n", c->frame_flags); > + > + if ((ret = init_get_bits8(gb, pkt->data, pkt->size)) < 0) > + return ret; > + > + height_a = (avctx->height + 31) & 0xFFFFFFE0; > + if (c->version <= 'f') { > + c->num_slices = 2; > + c->slice_height[0] = (avctx->height / 2 + 16) & 0xFFFFFFE0; > + } else if (c->version == 'g') { > + if (height_a < 128) { > + c->num_slices = 1; > + } else { > + c->num_slices = 2; > + c->slice_height[0] = (avctx->height / 2 + 16) & 0xFFFFFFE0; > + } > + } else { > + int start, end; > + > + c->num_slices = kb2h_num_slices[c->flags & 3]; > + start = 0; > + end = height_a + 32 * c->num_slices - 1; > + for (int i = 0; i < c->num_slices - 1; i++) { > + start += ((end - start) / (c->num_slices - i)) & 0xFFFFFFE0; > + end -= 32; > + c->slice_height[i] = start; > + } > + } > + c->slice_height[c->num_slices - 1] = height_a; > + > + skip_bits_long(gb, 32 + 32 * (c->num_slices - 1)); > + > + if (c->frame_flags & 0x10000) { > + if (!(c->frame_flags & 0x8000)) > + bink2g_get_cbp_flags(gb, 1, (((avctx->height + 15) & ~15) >> 3) > - 1, c->row_cbp); > + if (!(c->frame_flags & 0x4000)) > + bink2g_get_cbp_flags(gb, 1, (((avctx->width + 15) & ~15) >> 3) - > 1, c->col_cbp); > + } > + > + for (int i = 0; i < c->num_slices; i++) { > + if (i == c->num_slices - 1) > + off = pkt->size; > + else > + off = AV_RL32(pkt->data + 4 + i * 4); > + > + if (c->version <= 'f') > + ret = bink2f_decode_slice(c, dst, stride, src, sstride, is_kf, i > ? c->slice_height[i-1] : 0, c->slice_height[i]); > + else > + ret = bink2g_decode_slice(c, dst, stride, src, sstride, is_kf, i > ? c->slice_height[i-1] : 0, c->slice_height[i]); > + if (0 && ret < 0) > + return ret; > + > + align_get_bits(gb); > + if (get_bits_left(gb) < 0) > + av_log(avctx, AV_LOG_WARNING, "slice %d: overread\n", i); > + if (8 * (off - (get_bits_count(gb) >> 3)) > 24) > + av_log(avctx, AV_LOG_WARNING, "slice %d: underread %d\n", i, 8 * > (off - (get_bits_count(gb) >> 3))); > + skip_bits_long(gb, 8 * (off - (get_bits_count(gb) >> 3))); > + > + dst[0] = frame->data[0] + c->slice_height[i] * stride[0]; > + dst[1] = frame->data[1] + c->slice_height[i]/2 * stride[1]; > + dst[2] = frame->data[2] + c->slice_height[i]/2 * stride[2]; > + dst[3] = frame->data[3] + c->slice_height[i] * stride[3]; > + } > + > + frame->key_frame = is_kf; > + frame->pict_type = is_kf ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; > + > + av_frame_unref(c->last); > + if ((ret = av_frame_ref(c->last, frame)) < 0) > + return ret; > + > + *got_frame = 1; > + > + /* always report that the buffer was completely consumed */ > + return pkt->size; > +} > + > +#define INIT_VLC_STATIC_LE(vlc, nb_bits, nb_codes, \ > + bits, bits_wrap, bits_size, \ > + codes, codes_wrap, codes_size, \ > + symbols, symbols_wrap, symbols_size, \ > + static_size) \ > + do { \ > + static VLC_TYPE table[static_size][2]; \ > + (vlc)->table = table; \ > + (vlc)->table_allocated = static_size; \ > + ff_init_vlc_sparse(vlc, nb_bits, nb_codes, \ > + bits, bits_wrap, bits_size, \ > + codes, codes_wrap, codes_size, \ > + symbols, symbols_wrap, symbols_size, \ > + INIT_VLC_LE | INIT_VLC_USE_NEW_STATIC); \ > + } while (0) > + > +static av_cold int bink2_decode_init(AVCodecContext *avctx) > +{ > + Bink2Context * const c = avctx->priv_data; > + int ret; > + > + c->version = avctx->codec_tag >> 24; > + if (avctx->extradata_size < 4) { > + av_log(avctx, AV_LOG_ERROR, "Extradata missing or too short\n"); > + return AVERROR_INVALIDDATA; > + } > + c->flags = AV_RL32(avctx->extradata); > + av_log(avctx, AV_LOG_DEBUG, "flags: 0x%X\n", c->flags); > + c->has_alpha = c->flags & BINK_FLAG_ALPHA; > + c->avctx = avctx; > + > + c->last = av_frame_alloc(); > + if (!c->last) > + return AVERROR(ENOMEM); > + > + if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < > 0) > + return ret; > + > + avctx->pix_fmt = c->has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P; > + > + ff_blockdsp_init(&c->dsp, avctx); > + > + INIT_VLC_STATIC_LE(&bink2f_quant_vlc, 9, > FF_ARRAY_ELEMS(bink2f_quant_codes), > + bink2f_quant_bits, 1, 1, bink2f_quant_codes, 1, 1, > NULL, 0, 0, 512); > + INIT_VLC_STATIC_LE(&bink2f_ac_val0_vlc, 9, > FF_ARRAY_ELEMS(bink2f_ac_val_bits[0]), > + bink2f_ac_val_bits[0], 1, 1, bink2f_ac_val_codes[0], > 2, 2, NULL, 0, 0, 512); > + INIT_VLC_STATIC_LE(&bink2f_ac_val1_vlc, 9, > FF_ARRAY_ELEMS(bink2f_ac_val_bits[1]), > + bink2f_ac_val_bits[1], 1, 1, bink2f_ac_val_codes[1], > 2, 2, NULL, 0, 0, 512); > + INIT_VLC_STATIC_LE(&bink2f_ac_skip0_vlc, 9, > FF_ARRAY_ELEMS(bink2f_ac_skip_bits[0]), > + bink2f_ac_skip_bits[0], 1, 1, > bink2f_ac_skip_codes[0], 2, 2, NULL, 0, 0, 512); > + INIT_VLC_STATIC_LE(&bink2f_ac_skip1_vlc, 9, > FF_ARRAY_ELEMS(bink2f_ac_skip_bits[1]), > + bink2f_ac_skip_bits[1], 1, 1, > bink2f_ac_skip_codes[1], 2, 2, NULL, 0, 0, 512); > + > + INIT_VLC_STATIC_LE(&bink2g_ac_skip0_vlc, 9, > FF_ARRAY_ELEMS(bink2g_ac_skip_bits[0]), > + bink2g_ac_skip_bits[0], 1, 1, > bink2g_ac_skip_codes[0], 2, 2, NULL, 0, 0, 512); > + INIT_VLC_STATIC_LE(&bink2g_ac_skip1_vlc, 9, > FF_ARRAY_ELEMS(bink2g_ac_skip_bits[1]), > + bink2g_ac_skip_bits[1], 1, 1, > bink2g_ac_skip_codes[1], 2, 2, NULL, 0, 0, 512); > + INIT_VLC_STATIC_LE(&bink2g_mv_vlc, 9, FF_ARRAY_ELEMS(bink2g_mv_bits), > + bink2g_mv_bits, 1, 1, bink2g_mv_codes, 1, 1, NULL, 0, > 0, 512); > + > + c->current_q = av_malloc_array((avctx->width + 31) / 32, > sizeof(*c->current_q)); > + if (!c->current_q) > + return AVERROR(ENOMEM); > + > + c->prev_q = av_malloc_array((avctx->width + 31) / 32, > sizeof(*c->prev_q)); > + if (!c->prev_q) > + return AVERROR(ENOMEM); > + > + c->current_dc = av_malloc_array((avctx->width + 31) / 32, > sizeof(*c->current_dc)); > + if (!c->current_dc) > + return AVERROR(ENOMEM); > + > + c->prev_dc = av_malloc_array((avctx->width + 31) / 32, > sizeof(*c->prev_dc)); > + if (!c->prev_dc) > + return AVERROR(ENOMEM); > + > + c->current_idc = av_malloc_array((avctx->width + 31) / 32, > sizeof(*c->current_idc)); > + if (!c->current_idc) > + return AVERROR(ENOMEM); > + > + c->prev_idc = av_malloc_array((avctx->width + 31) / 32, > sizeof(*c->prev_idc)); > + if (!c->prev_q) > + return AVERROR(ENOMEM); > + > + c->current_mv = av_malloc_array((avctx->width + 31) / 32, > sizeof(*c->current_mv)); > + if (!c->current_mv) > + return AVERROR(ENOMEM); > + > + c->prev_mv = av_malloc_array((avctx->width + 31) / 32, > sizeof(*c->prev_mv)); > + if (!c->prev_mv) > + return AVERROR(ENOMEM); > + > + c->col_cbp = av_calloc((((avctx->width + 31) >> 3) + 7) >> 3, > sizeof(*c->col_cbp)); > + if (!c->col_cbp) > + return AVERROR(ENOMEM); > + > + c->row_cbp = av_calloc((((avctx->height + 31) >> 3) + 7) >> 3, > sizeof(*c->row_cbp)); > + if (!c->row_cbp) > + return AVERROR(ENOMEM); > + > + return 0; > +} > + > +static av_cold int bink2_decode_end(AVCodecContext *avctx) > +{ > + Bink2Context * const c = avctx->priv_data; > + > + av_frame_free(&c->last); > + av_freep(&c->current_q); > + av_freep(&c->prev_q); > + av_freep(&c->current_dc); > + av_freep(&c->prev_dc); > + av_freep(&c->current_idc); > + av_freep(&c->prev_idc); > + av_freep(&c->current_mv); > + av_freep(&c->prev_mv); > + av_freep(&c->col_cbp); > + av_freep(&c->row_cbp); > + > + return 0; > +} > + > +AVCodec ff_bink2_decoder = { > + .name = "binkvideo2", > + .long_name = NULL_IF_CONFIG_SMALL("Bink video 2"), > + .type = AVMEDIA_TYPE_VIDEO, > + .id = AV_CODEC_ID_BINKVIDEO2, > + .priv_data_size = sizeof(Bink2Context), > + .init = bink2_decode_init, > + .close = bink2_decode_end, > + .decode = bink2_decode_frame, > + .capabilities = AV_CODEC_CAP_DR1, Missing FF_CODEC_CAP_INIT_CLEANUP, and a flush function to unref c->last and do any other potentially required cleaning. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".