Commit 72ca830f authored by Ronald S. Bultje's avatar Ronald S. Bultje Committed by Luca Barbato

lavc: VP9 decoder

Originally written by Ronald S. Bultje <rsbultje@gmail.com> and
Clément Bœsch <u@pkh.me>

Further contributions by:
Anton Khirnov <anton@khirnov.net>
Diego Biurrun <diego@biurrun.de>
Luca Barbato <lu_zero@gentoo.org>
Martin Storsjö <martin@martin.st>
Signed-off-by: 's avatarLuca Barbato <lu_zero@gentoo.org>
Signed-off-by: 's avatarAnton Khirnov <anton@khirnov.net>
parent 458446ac
......@@ -47,6 +47,7 @@ version 10:
- Live HDS muxer
- setsar/setdar filters now support variables in ratio expressions
- dar variable in the scale filter now returns the actual DAR (i.e. a * sar)
- VP9 decoder
version 9:
......
......@@ -1702,6 +1702,7 @@ vp6_decoder_select="h264chroma hpeldsp huffman videodsp vp3dsp"
vp6a_decoder_select="vp6_decoder"
vp6f_decoder_select="vp6_decoder"
vp8_decoder_select="h264pred videodsp"
vp9_decoder_select="videodsp"
webp_decoder_select="vp8_decoder"
wmapro_decoder_select="mdct sinewin"
wmav1_decoder_select="mdct sinewin"
......
......@@ -594,6 +594,8 @@ following image formats are supported:
@tab fourcc: VP60,VP61,VP62
@item VP8 @tab E @tab X
@tab fourcc: VP80, encoding supported through external library libvpx
@item VP9 @tab E @tab X
@tab Encoding supported through external library libvpx
@item planar RGB @tab @tab X
@tab fourcc: 8BPS
@item Q-team QPEG @tab @tab X
......
......@@ -392,6 +392,8 @@ OBJS-$(CONFIG_VP5_DECODER) += vp5.o vp56.o vp56data.o vp56dsp.o \
OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o vp56dsp.o \
vp6dsp.o vp56rac.o
OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp8dsp.o vp56rac.o
OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o \
vp9block.o vp9prob.o vp9mvs.o vp56rac.o
OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o
OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o
OBJS-$(CONFIG_WEBP_DECODER) += webp.o
......
......@@ -257,6 +257,7 @@ void avcodec_register_all(void)
REGISTER_DECODER(VP6A, vp6a);
REGISTER_DECODER(VP6F, vp6f);
REGISTER_DECODER(VP8, vp8);
REGISTER_DECODER(VP9, vp9);
REGISTER_DECODER(VQA, vqa);
REGISTER_DECODER(WEBP, webp);
REGISTER_ENCDEC (WMV1, wmv1);
......
......@@ -27,7 +27,7 @@
*/
#define LIBAVCODEC_VERSION_MAJOR 55
#define LIBAVCODEC_VERSION_MINOR 27
#define LIBAVCODEC_VERSION_MINOR 28
#define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
......
/*
* VP9 compatible video decoder
*
* Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
* Copyright (C) 2013 Clément Bœsch <u pkh me>
*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/avassert.h"
#include "avcodec.h"
#include "get_bits.h"
#include "internal.h"
#include "videodsp.h"
#include "vp56.h"
#include "vp9.h"
#include "vp9data.h"
#define VP9_SYNCCODE 0x498342
#define MAX_PROB 255
static void vp9_decode_flush(AVCodecContext *avctx)
{
VP9Context *s = avctx->priv_data;
int i;
for (i = 0; i < FF_ARRAY_ELEMS(s->refs); i++)
av_frame_unref(s->refs[i]);
}
static int update_size(AVCodecContext *avctx, int w, int h)
{
VP9Context *s = avctx->priv_data;
uint8_t *p;
if (s->above_partition_ctx && w == avctx->width && h == avctx->height)
return 0;
vp9_decode_flush(avctx);
if (w <= 0 || h <= 0)
return AVERROR_INVALIDDATA;
avctx->width = w;
avctx->height = h;
s->sb_cols = (w + 63) >> 6;
s->sb_rows = (h + 63) >> 6;
s->cols = (w + 7) >> 3;
s->rows = (h + 7) >> 3;
#define assign(var, type, n) var = (type)p; p += s->sb_cols * n * sizeof(*var)
av_free(s->above_partition_ctx);
p = av_malloc(s->sb_cols *
(240 + sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx) +
64 * s->sb_rows * (1 + sizeof(*s->mv[0]) * 2)));
if (!p)
return AVERROR(ENOMEM);
assign(s->above_partition_ctx, uint8_t *, 8);
assign(s->above_skip_ctx, uint8_t *, 8);
assign(s->above_txfm_ctx, uint8_t *, 8);
assign(s->above_mode_ctx, uint8_t *, 16);
assign(s->above_y_nnz_ctx, uint8_t *, 16);
assign(s->above_uv_nnz_ctx[0], uint8_t *, 8);
assign(s->above_uv_nnz_ctx[1], uint8_t *, 8);
assign(s->intra_pred_data[0], uint8_t *, 64);
assign(s->intra_pred_data[1], uint8_t *, 32);
assign(s->intra_pred_data[2], uint8_t *, 32);
assign(s->above_segpred_ctx, uint8_t *, 8);
assign(s->above_intra_ctx, uint8_t *, 8);
assign(s->above_comp_ctx, uint8_t *, 8);
assign(s->above_ref_ctx, uint8_t *, 8);
assign(s->above_filter_ctx, uint8_t *, 8);
assign(s->lflvl, VP9Filter *, 1);
assign(s->above_mv_ctx, VP56mv(*)[2], 16);
assign(s->segmentation_map, uint8_t *, 64 * s->sb_rows);
assign(s->mv[0], VP9MVRefPair *, 64 * s->sb_rows);
assign(s->mv[1], VP9MVRefPair *, 64 * s->sb_rows);
#undef assign
return 0;
}
// The sign bit is at the end, not the start, of a bit sequence
static av_always_inline int get_bits_with_sign(GetBitContext *gb, int n)
{
int v = get_bits(gb, n);
return get_bits1(gb) ? -v : v;
}
static av_always_inline int inv_recenter_nonneg(int v, int m)
{
if (v > 2 * m)
return v;
if (v & 1)
return m - ((v + 1) >> 1);
return m + (v >> 1);
}
// differential forward probability updates
static int update_prob(VP56RangeCoder *c, int p)
{
static const int inv_map_table[MAX_PROB - 1] = {
7, 20, 33, 46, 59, 72, 85, 98, 111, 124, 137, 150, 163, 176,
189, 202, 215, 228, 241, 254, 1, 2, 3, 4, 5, 6, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, 58, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 99, 100,
101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 112, 113, 114, 115,
116, 117, 118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 130,
131, 132, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143, 144, 145,
146, 147, 148, 149, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160,
161, 162, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 190, 191,
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 203, 204, 205, 206,
207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219, 220, 221,
222, 223, 224, 225, 226, 227, 229, 230, 231, 232, 233, 234, 235, 236,
237, 238, 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
252, 253,
};
int d;
/* This code is trying to do a differential probability update. For a
* current probability A in the range [1, 255], the difference to a new
* probability of any value can be expressed differentially as 1-A, 255-A
* where some part of this (absolute range) exists both in positive as
* well as the negative part, whereas another part only exists in one
* half. We're trying to code this shared part differentially, i.e.
* times two where the value of the lowest bit specifies the sign, and
* the single part is then coded on top of this. This absolute difference
* then again has a value of [0, 254], but a bigger value in this range
* indicates that we're further away from the original value A, so we
* can code this as a VLC code, since higher values are increasingly
* unlikely. The first 20 values in inv_map_table[] allow 'cheap, rough'
* updates vs. the 'fine, exact' updates further down the range, which
* adds one extra dimension to this differential update model. */
if (!vp8_rac_get(c)) {
d = vp8_rac_get_uint(c, 4) + 0;
} else if (!vp8_rac_get(c)) {
d = vp8_rac_get_uint(c, 4) + 16;
} else if (!vp8_rac_get(c)) {
d = vp8_rac_get_uint(c, 5) + 32;
} else {
d = vp8_rac_get_uint(c, 7);
if (d >= 65) {
d = (d << 1) - 65 + vp8_rac_get(c);
d = av_clip(d, 0, MAX_PROB - 65 - 1);
}
d += 64;
}
return p <= 128
? 1 + inv_recenter_nonneg(inv_map_table[d], p - 1)
: 255 - inv_recenter_nonneg(inv_map_table[d], 255 - p);
}
static int decode_frame_header(AVCodecContext *avctx,
const uint8_t *data, int size, int *ref)
{
VP9Context *s = avctx->priv_data;
int c, i, j, k, l, m, n, w, h, max, size2, ret, sharp;
int last_invisible;
const uint8_t *data2;
/* general header */
if ((ret = init_get_bits8(&s->gb, data, size)) < 0) {
av_log(avctx, AV_LOG_ERROR, "Failed to initialize bitstream reader\n");
return ret;
}
if (get_bits(&s->gb, 2) != 0x2) { // frame marker
av_log(avctx, AV_LOG_ERROR, "Invalid frame marker\n");
return AVERROR_INVALIDDATA;
}
s->profile = get_bits1(&s->gb);
if (get_bits1(&s->gb)) { // reserved bit
av_log(avctx, AV_LOG_ERROR, "Reserved bit should be zero\n");
return AVERROR_INVALIDDATA;
}
if (get_bits1(&s->gb)) {
*ref = get_bits(&s->gb, 3);
return 0;
}
s->last_keyframe = s->keyframe;
s->keyframe = !get_bits1(&s->gb);
last_invisible = s->invisible;
s->invisible = !get_bits1(&s->gb);
s->errorres = get_bits1(&s->gb);
// FIXME disable this upon resolution change
s->use_last_frame_mvs = !s->errorres && !last_invisible;
if (s->keyframe) {
if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode
av_log(avctx, AV_LOG_ERROR, "Invalid sync code\n");
return AVERROR_INVALIDDATA;
}
s->colorspace = get_bits(&s->gb, 3);
if (s->colorspace == 7) { // RGB = profile 1
av_log(avctx, AV_LOG_ERROR, "RGB not supported in profile 0\n");
return AVERROR_INVALIDDATA;
}
s->fullrange = get_bits1(&s->gb);
// for profile 1, here follows the subsampling bits
s->refreshrefmask = 0xff;
w = get_bits(&s->gb, 16) + 1;
h = get_bits(&s->gb, 16) + 1;
if (get_bits1(&s->gb)) // display size
skip_bits(&s->gb, 32);
} else {
s->intraonly = s->invisible ? get_bits1(&s->gb) : 0;
s->resetctx = s->errorres ? 0 : get_bits(&s->gb, 2);
if (s->intraonly) {
if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode
av_log(avctx, AV_LOG_ERROR, "Invalid sync code\n");
return AVERROR_INVALIDDATA;
}
s->refreshrefmask = get_bits(&s->gb, 8);
w = get_bits(&s->gb, 16) + 1;
h = get_bits(&s->gb, 16) + 1;
if (get_bits1(&s->gb)) // display size
skip_bits(&s->gb, 32);
} else {
s->refreshrefmask = get_bits(&s->gb, 8);
s->refidx[0] = get_bits(&s->gb, 3);
s->signbias[0] = get_bits1(&s->gb);
s->refidx[1] = get_bits(&s->gb, 3);
s->signbias[1] = get_bits1(&s->gb);
s->refidx[2] = get_bits(&s->gb, 3);
s->signbias[2] = get_bits1(&s->gb);
if (!s->refs[s->refidx[0]]->buf[0] ||
!s->refs[s->refidx[1]]->buf[0] ||
!s->refs[s->refidx[2]]->buf[0]) {
av_log(avctx, AV_LOG_ERROR,
"Not all references are available\n");
return AVERROR_INVALIDDATA;
}
if (get_bits1(&s->gb)) {
w = s->refs[s->refidx[0]]->width;
h = s->refs[s->refidx[0]]->height;
} else if (get_bits1(&s->gb)) {
w = s->refs[s->refidx[1]]->width;
h = s->refs[s->refidx[1]]->height;
} else if (get_bits1(&s->gb)) {
w = s->refs[s->refidx[2]]->width;
h = s->refs[s->refidx[2]]->height;
} else {
w = get_bits(&s->gb, 16) + 1;
h = get_bits(&s->gb, 16) + 1;
}
if (get_bits1(&s->gb)) // display size
skip_bits(&s->gb, 32);
s->highprecisionmvs = get_bits1(&s->gb);
s->filtermode = get_bits1(&s->gb) ? FILTER_SWITCHABLE :
get_bits(&s->gb, 2);
s->allowcompinter = s->signbias[0] != s->signbias[1] ||
s->signbias[0] != s->signbias[2];
if (s->allowcompinter) {
if (s->signbias[0] == s->signbias[1]) {
s->fixcompref = 2;
s->varcompref[0] = 0;
s->varcompref[1] = 1;
} else if (s->signbias[0] == s->signbias[2]) {
s->fixcompref = 1;
s->varcompref[0] = 0;
s->varcompref[1] = 2;
} else {
s->fixcompref = 0;
s->varcompref[0] = 1;
s->varcompref[1] = 2;
}
}
}
}
s->refreshctx = s->errorres ? 0 : get_bits1(&s->gb);
s->parallelmode = s->errorres ? 1 : get_bits1(&s->gb);
s->framectxid = c = get_bits(&s->gb, 2);
/* loopfilter header data */
s->filter.level = get_bits(&s->gb, 6);
sharp = get_bits(&s->gb, 3);
/* If sharpness changed, reinit lim/mblim LUTs. if it didn't change,
* keep the old cache values since they are still valid. */
if (s->filter.sharpness != sharp)
memset(s->filter.lim_lut, 0, sizeof(s->filter.lim_lut));
s->filter.sharpness = sharp;
if ((s->lf_delta.enabled = get_bits1(&s->gb))) {
if (get_bits1(&s->gb)) {
for (i = 0; i < 4; i++)
if (get_bits1(&s->gb))
s->lf_delta.ref[i] = get_bits_with_sign(&s->gb, 6);
for (i = 0; i < 2; i++)
if (get_bits1(&s->gb))
s->lf_delta.mode[i] = get_bits_with_sign(&s->gb, 6);
}
} else {
memset(&s->lf_delta, 0, sizeof(s->lf_delta));
}
/* quantization header data */
s->yac_qi = get_bits(&s->gb, 8);
s->ydc_qdelta = get_bits1(&s->gb) ? get_bits_with_sign(&s->gb, 4) : 0;
s->uvdc_qdelta = get_bits1(&s->gb) ? get_bits_with_sign(&s->gb, 4) : 0;
s->uvac_qdelta = get_bits1(&s->gb) ? get_bits_with_sign(&s->gb, 4) : 0;
s->lossless = s->yac_qi == 0 && s->ydc_qdelta == 0 &&
s->uvdc_qdelta == 0 && s->uvac_qdelta == 0;
/* segmentation header info */
if ((s->segmentation.enabled = get_bits1(&s->gb))) {
if ((s->segmentation.update_map = get_bits1(&s->gb))) {
for (i = 0; i < 7; i++)
s->prob.seg[i] = get_bits1(&s->gb) ?
get_bits(&s->gb, 8) : 255;
if ((s->segmentation.temporal = get_bits1(&s->gb)))
for (i = 0; i < 3; i++)
s->prob.segpred[i] = get_bits1(&s->gb) ?
get_bits(&s->gb, 8) : 255;
}
if (get_bits1(&s->gb)) {
s->segmentation.absolute_vals = get_bits1(&s->gb);
for (i = 0; i < 8; i++) {
if ((s->segmentation.feat[i].q_enabled = get_bits1(&s->gb)))
s->segmentation.feat[i].q_val = get_bits_with_sign(&s->gb, 8);
if ((s->segmentation.feat[i].lf_enabled = get_bits1(&s->gb)))
s->segmentation.feat[i].lf_val = get_bits_with_sign(&s->gb, 6);
if ((s->segmentation.feat[i].ref_enabled = get_bits1(&s->gb)))
s->segmentation.feat[i].ref_val = get_bits(&s->gb, 2);
s->segmentation.feat[i].skip_enabled = get_bits1(&s->gb);
}
}
} else {
s->segmentation.feat[0].q_enabled = 0;
s->segmentation.feat[0].lf_enabled = 0;
s->segmentation.feat[0].skip_enabled = 0;
s->segmentation.feat[0].ref_enabled = 0;
}
// set qmul[] based on Y/UV, AC/DC and segmentation Q idx deltas
for (i = 0; i < (s->segmentation.enabled ? 8 : 1); i++) {
int qyac, qydc, quvac, quvdc, lflvl, sh;
if (s->segmentation.feat[i].q_enabled) {
if (s->segmentation.absolute_vals)
qyac = s->segmentation.feat[i].q_val;
else
qyac = s->yac_qi + s->segmentation.feat[i].q_val;
} else {
qyac = s->yac_qi;
}
qydc = av_clip_uintp2(qyac + s->ydc_qdelta, 8);
quvdc = av_clip_uintp2(qyac + s->uvdc_qdelta, 8);
quvac = av_clip_uintp2(qyac + s->uvac_qdelta, 8);
qyac = av_clip_uintp2(qyac, 8);
s->segmentation.feat[i].qmul[0][0] = ff_vp9_dc_qlookup[qydc];
s->segmentation.feat[i].qmul[0][1] = ff_vp9_ac_qlookup[qyac];
s->segmentation.feat[i].qmul[1][0] = ff_vp9_dc_qlookup[quvdc];
s->segmentation.feat[i].qmul[1][1] = ff_vp9_ac_qlookup[quvac];
sh = s->filter.level >= 32;
if (s->segmentation.feat[i].lf_enabled) {
if (s->segmentation.absolute_vals)
lflvl = s->segmentation.feat[i].lf_val;
else
lflvl = s->filter.level + s->segmentation.feat[i].lf_val;
} else {
lflvl = s->filter.level;
}
s->segmentation.feat[i].lflvl[0][0] =
s->segmentation.feat[i].lflvl[0][1] =
av_clip_uintp2(lflvl + (s->lf_delta.ref[0] << sh), 6);
for (j = 1; j < 4; j++) {
s->segmentation.feat[i].lflvl[j][0] =
av_clip_uintp2(lflvl + ((s->lf_delta.ref[j] +
s->lf_delta.mode[0]) << sh), 6);
s->segmentation.feat[i].lflvl[j][1] =
av_clip_uintp2(lflvl + ((s->lf_delta.ref[j] +
s->lf_delta.mode[1]) << sh), 6);
}
}
/* tiling info */
if ((ret = update_size(avctx, w, h)) < 0) {
av_log(avctx, AV_LOG_ERROR,
"Failed to initialize decoder for %dx%d\n", w, h);
return ret;
}
for (s->tiling.log2_tile_cols = 0;
(s->sb_cols >> s->tiling.log2_tile_cols) > 64;
s->tiling.log2_tile_cols++) ;
for (max = 0; (s->sb_cols >> max) >= 4; max++) ;
max = FFMAX(0, max - 1);
while (max > s->tiling.log2_tile_cols) {
if (get_bits1(&s->gb))
s->tiling.log2_tile_cols++;
else
break;
}
s->tiling.log2_tile_rows = decode012(&s->gb);
s->tiling.tile_rows = 1 << s->tiling.log2_tile_rows;
if (s->tiling.tile_cols != (1 << s->tiling.log2_tile_cols)) {
s->tiling.tile_cols = 1 << s->tiling.log2_tile_cols;
s->c_b = av_fast_realloc(s->c_b, &s->c_b_size,
sizeof(VP56RangeCoder) *
s->tiling.tile_cols);
if (!s->c_b) {
av_log(avctx, AV_LOG_ERROR,
"Ran out of memory during range coder init\n");
return AVERROR(ENOMEM);
}
}
if (s->keyframe || s->errorres || s->intraonly) {
s->prob_ctx[0].p =
s->prob_ctx[1].p =
s->prob_ctx[2].p =
s->prob_ctx[3].p = ff_vp9_default_probs;
memcpy(s->prob_ctx[0].coef, ff_vp9_default_coef_probs,
sizeof(ff_vp9_default_coef_probs));
memcpy(s->prob_ctx[1].coef, ff_vp9_default_coef_probs,
sizeof(ff_vp9_default_coef_probs));
memcpy(s->prob_ctx[2].coef, ff_vp9_default_coef_probs,
sizeof(ff_vp9_default_coef_probs));
memcpy(s->prob_ctx[3].coef, ff_vp9_default_coef_probs,
sizeof(ff_vp9_default_coef_probs));
}
// next 16 bits is size of the rest of the header (arith-coded)
size2 = get_bits(&s->gb, 16);
data2 = align_get_bits(&s->gb);
if (size2 > size - (data2 - data)) {
av_log(avctx, AV_LOG_ERROR, "Invalid compressed header size\n");
return AVERROR_INVALIDDATA;
}
ff_vp56_init_range_decoder(&s->c, data2, size2);
if (vp56_rac_get_prob_branchy(&s->c, 128)) { // marker bit
av_log(avctx, AV_LOG_ERROR, "Marker bit was set\n");
return AVERROR_INVALIDDATA;
}
if (s->keyframe || s->intraonly)
memset(s->counts.coef, 0,
sizeof(s->counts.coef) + sizeof(s->counts.eob));
else
memset(&s->counts, 0, sizeof(s->counts));
/* FIXME is it faster to not copy here, but do it down in the fw updates
* as explicit copies if the fw update is missing (and skip the copy upon
* fw update)? */
s->prob.p = s->prob_ctx[c].p;
// txfm updates
if (s->lossless) {
s->txfmmode = TX_4X4;
} else {
s->txfmmode = vp8_rac_get_uint(&s->c, 2);
if (s->txfmmode == 3)
s->txfmmode += vp8_rac_get(&s->c);
if (s->txfmmode == TX_SWITCHABLE) {
for (i = 0; i < 2; i++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.tx8p[i] = update_prob(&s->c, s->prob.p.tx8p[i]);
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.tx16p[i][j] =
update_prob(&s->c, s->prob.p.tx16p[i][j]);
for (i = 0; i < 2; i++)
for (j = 0; j < 3; j++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.tx32p[i][j] =
update_prob(&s->c, s->prob.p.tx32p[i][j]);
}
}
// coef updates
for (i = 0; i < 4; i++) {
uint8_t (*ref)[2][6][6][3] = s->prob_ctx[c].coef[i];
if (vp8_rac_get(&s->c)) {
for (j = 0; j < 2; j++)
for (k = 0; k < 2; k++)
for (l = 0; l < 6; l++)
for (m = 0; m < 6; m++) {
uint8_t *p = s->prob.coef[i][j][k][l][m];
uint8_t *r = ref[j][k][l][m];
if (m >= 3 && l == 0) // dc only has 3 pt
break;
for (n = 0; n < 3; n++) {
if (vp56_rac_get_prob_branchy(&s->c, 252))
p[n] = update_prob(&s->c, r[n]);
else
p[n] = r[n];
}
p[3] = 0;
}
} else {
for (j = 0; j < 2; j++)
for (k = 0; k < 2; k++)
for (l = 0; l < 6; l++)
for (m = 0; m < 6; m++) {
uint8_t *p = s->prob.coef[i][j][k][l][m];
uint8_t *r = ref[j][k][l][m];
if (m > 3 && l == 0) // dc only has 3 pt
break;
memcpy(p, r, 3);
p[3] = 0;
}
}
if (s->txfmmode == i)
break;
}
// mode updates
for (i = 0; i < 3; i++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.skip[i] = update_prob(&s->c, s->prob.p.skip[i]);
if (!s->keyframe && !s->intraonly) {
for (i = 0; i < 7; i++)
for (j = 0; j < 3; j++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.mv_mode[i][j] =
update_prob(&s->c, s->prob.p.mv_mode[i][j]);
if (s->filtermode == FILTER_SWITCHABLE)
for (i = 0; i < 4; i++)
for (j = 0; j < 2; j++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.filter[i][j] =
update_prob(&s->c, s->prob.p.filter[i][j]);
for (i = 0; i < 4; i++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.intra[i] = update_prob(&s->c, s->prob.p.intra[i]);
if (s->allowcompinter) {
s->comppredmode = vp8_rac_get(&s->c);
if (s->comppredmode)
s->comppredmode += vp8_rac_get(&s->c);
if (s->comppredmode == PRED_SWITCHABLE)
for (i = 0; i < 5; i++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.comp[i] =
update_prob(&s->c, s->prob.p.comp[i]);
} else {
s->comppredmode = PRED_SINGLEREF;
}
if (s->comppredmode != PRED_COMPREF) {
for (i = 0; i < 5; i++) {
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.single_ref[i][0] =
update_prob(&s->c, s->prob.p.single_ref[i][0]);
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.single_ref[i][1] =
update_prob(&s->c, s->prob.p.single_ref[i][1]);
}
}
if (s->comppredmode != PRED_SINGLEREF) {
for (i = 0; i < 5; i++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.comp_ref[i] =
update_prob(&s->c, s->prob.p.comp_ref[i]);
}
for (i = 0; i < 4; i++)
for (j = 0; j < 9; j++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.y_mode[i][j] =
update_prob(&s->c, s->prob.p.y_mode[i][j]);
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
for (k = 0; k < 3; k++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.partition[3 - i][j][k] =
update_prob(&s->c,
s->prob.p.partition[3 - i][j][k]);
// mv fields don't use the update_prob subexp model for some reason
for (i = 0; i < 3; i++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.mv_joint[i] = (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
for (i = 0; i < 2; i++) {
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.mv_comp[i].sign =
(vp8_rac_get_uint(&s->c, 7) << 1) | 1;
for (j = 0; j < 10; j++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.mv_comp[i].classes[j] =
(vp8_rac_get_uint(&s->c, 7) << 1) | 1;
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.mv_comp[i].class0 =
(vp8_rac_get_uint(&s->c, 7) << 1) | 1;
for (j = 0; j < 10; j++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.mv_comp[i].bits[j] =
(vp8_rac_get_uint(&s->c, 7) << 1) | 1;
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++)
for (k = 0; k < 3; k++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.mv_comp[i].class0_fp[j][k] =
(vp8_rac_get_uint(&s->c, 7) << 1) | 1;
for (j = 0; j < 3; j++)
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.mv_comp[i].fp[j] =
(vp8_rac_get_uint(&s->c, 7) << 1) | 1;
}
if (s->highprecisionmvs) {
for (i = 0; i < 2; i++) {
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.mv_comp[i].class0_hp =
(vp8_rac_get_uint(&s->c, 7) << 1) | 1;
if (vp56_rac_get_prob_branchy(&s->c, 252))
s->prob.p.mv_comp[i].hp =
(vp8_rac_get_uint(&s->c, 7) << 1) | 1;
}
}
}
return (data2 - data) + size2;
}
static int decode_subblock(AVCodecContext *avctx, int row, int col,
VP9Filter *lflvl,
ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl)
{
VP9Context *s = avctx->priv_data;
int c = ((s->above_partition_ctx[col] >> (3 - bl)) & 1) |
(((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1);
int ret;
const uint8_t *p = s->keyframe ? ff_vp9_default_kf_partition_probs[bl][c]
: s->prob.p.partition[bl][c];
enum BlockPartition bp;
ptrdiff_t hbs = 4 >> bl;
if (bl == BL_8X8) {
bp = vp8_rac_get_tree(&s->c, ff_vp9_partition_tree, p);
ret = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp);
} else if (col + hbs < s->cols) {
if (row + hbs < s->rows) {
bp = vp8_rac_get_tree(&s->c, ff_vp9_partition_tree, p);
switch (bp) {
case PARTITION_NONE:
ret = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff,
bl, bp);
break;
case PARTITION_H:
ret = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff,
bl, bp);
if (!ret) {
yoff += hbs * 8 * s->cur_frame->linesize[0];
uvoff += hbs * 4 * s->cur_frame->linesize[1];
ret = ff_vp9_decode_block(avctx, row + hbs, col, lflvl,
yoff, uvoff, bl, bp);
}
break;
case PARTITION_V:
ret = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff,
bl, bp);
if (!ret) {
yoff += hbs * 8;
uvoff += hbs * 4;
ret = ff_vp9_decode_block(avctx, row, col + hbs, lflvl,
yoff, uvoff, bl, bp);
}
break;
case PARTITION_SPLIT:
ret = decode_subblock(avctx, row, col, lflvl,
yoff, uvoff, bl + 1);
if (!ret) {
ret = decode_subblock(avctx, row, col + hbs, lflvl,
yoff + 8 * hbs, uvoff + 4 * hbs,
bl + 1);
if (!ret) {
yoff += hbs * 8 * s->cur_frame->linesize[0];
uvoff += hbs * 4 * s->cur_frame->linesize[1];
ret = decode_subblock(avctx, row + hbs, col, lflvl,
yoff, uvoff, bl + 1);
if (!ret) {
ret = decode_subblock(avctx, row + hbs, col + hbs,
lflvl, yoff + 8 * hbs,
uvoff + 4 * hbs, bl + 1);
}
}
}
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unexpected partition %d.", bp);
return AVERROR_INVALIDDATA;
}
} else if (vp56_rac_get_prob_branchy(&s->c, p[1])) {
bp = PARTITION_SPLIT;
ret = decode_subblock(avctx, row, col, lflvl, yoff, uvoff, bl + 1);
if (!ret)
ret = decode_subblock(avctx, row, col + hbs, lflvl,
yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
} else {
bp = PARTITION_H;
ret = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff,
bl, bp);
}
} else if (row + hbs < s->rows) {
if (vp56_rac_get_prob_branchy(&s->c, p[2])) {
bp = PARTITION_SPLIT;
ret = decode_subblock(avctx, row, col, lflvl, yoff, uvoff, bl + 1);
if (!ret) {
yoff += hbs * 8 * s->cur_frame->linesize[0];
uvoff += hbs * 4 * s->cur_frame->linesize[1];
ret = decode_subblock(avctx, row + hbs, col, lflvl,
yoff, uvoff, bl + 1);
}
} else {
bp = PARTITION_V;
ret = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff,
bl, bp);
}
} else {
bp = PARTITION_SPLIT;
ret = decode_subblock(avctx, row, col, lflvl, yoff, uvoff, bl + 1);
}
s->counts.partition[bl][c][bp]++;
return ret;
}
static void loopfilter_subblock(AVCodecContext *avctx, VP9Filter *lflvl,
int row, int col,
ptrdiff_t yoff, ptrdiff_t uvoff)
{
VP9Context *s = avctx->priv_data;
uint8_t *dst = s->cur_frame->data[0] + yoff, *lvl = lflvl->level;
ptrdiff_t ls_y = s->cur_frame->linesize[0], ls_uv = s->cur_frame->linesize[1];
int y, x, p;
/* FIXME: In how far can we interleave the v/h loopfilter calls? E.g.
* if you think of them as acting on a 8x8 block max, we can interleave
* each v/h within the single x loop, but that only works if we work on
* 8 pixel blocks, and we won't always do that (we want at least 16px
* to use SSE2 optimizations, perhaps 32 for AVX2). */
// filter edges between columns, Y plane (e.g. block1 | block2)
for (y = 0; y < 8; y += 2, dst += 16 * ls_y, lvl += 16) {
uint8_t *ptr = dst, *l = lvl, *hmask1 = lflvl->mask[0][0][y];
uint8_t *hmask2 = lflvl->mask[0][0][y + 1];
unsigned hm1 = hmask1[0] | hmask1[1] | hmask1[2], hm13 = hmask1[3];
unsigned hm2 = hmask2[1] | hmask2[2], hm23 = hmask2[3];
unsigned hm = hm1 | hm2 | hm13 | hm23;
for (x = 1; hm & ~(x - 1); x <<= 1, ptr += 8, l++) {
if (hm1 & x) {
int L = *l, H = L >> 4;
int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
if (col || x > 1) {
if (hmask1[0] & x) {
if (hmask2[0] & x) {
av_assert2(l[8] == L);
s->dsp.loop_filter_16[0](ptr, ls_y, E, I, H);
} else {
s->dsp.loop_filter_8[2][0](ptr, ls_y, E, I, H);
}
} else if (hm2 & x) {
L = l[8];
H |= (L >> 4) << 8;
E |= s->filter.mblim_lut[L] << 8;
I |= s->filter.lim_lut[L] << 8;
s->dsp.loop_filter_mix2[!!(hmask1[1] & x)]
[!!(hmask2[1] & x)]
[0](ptr, ls_y, E, I, H);
} else {
s->dsp.loop_filter_8[!!(hmask1[1] & x)]
[0](ptr, ls_y, E, I, H);
}
}
} else if (hm2 & x) {
int L = l[8], H = L >> 4;
int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
if (col || x > 1) {
s->dsp.loop_filter_8[!!(hmask2[1] & x)]
[0](ptr + 8 * ls_y, ls_y, E, I, H);
}
}
if (hm13 & x) {
int L = *l, H = L >> 4;
int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
if (hm23 & x) {
L = l[8];
H |= (L >> 4) << 8;
E |= s->filter.mblim_lut[L] << 8;
I |= s->filter.lim_lut[L] << 8;
s->dsp.loop_filter_mix2[0][0][0](ptr + 4, ls_y, E, I, H);
} else {
s->dsp.loop_filter_8[0][0](ptr + 4, ls_y, E, I, H);
}
} else if (hm23 & x) {
int L = l[8], H = L >> 4;
int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
s->dsp.loop_filter_8[0][0](ptr + 8 * ls_y + 4, ls_y, E, I, H);
}
}
}
// block1
// filter edges between rows, Y plane (e.g. ------)
// block2
dst = s->cur_frame->data[0] + yoff;
lvl = lflvl->level;
for (y = 0; y < 8; y++, dst += 8 * ls_y, lvl += 8) {
uint8_t *ptr = dst, *l = lvl, *vmask = lflvl->mask[0][1][y];
unsigned vm = vmask[0] | vmask[1] | vmask[2], vm3 = vmask[3];
for (x = 1; vm & ~(x - 1); x <<= 2, ptr += 16, l += 2) {
if (row || y) {
if (vm & x) {
int L = *l, H = L >> 4;
int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
if (vmask[0] & x) {
if (vmask[0] & (x << 1)) {
av_assert2(l[1] == L);
s->dsp.loop_filter_16[1](ptr, ls_y, E, I, H);
} else {
s->dsp.loop_filter_8[2][1](ptr, ls_y, E, I, H);
}
} else if (vm & (x << 1)) {
L = l[1];
H |= (L >> 4) << 8;
E |= s->filter.mblim_lut[L] << 8;
I |= s->filter.lim_lut[L] << 8;
s->dsp.loop_filter_mix2[!!(vmask[1] & x)]
[!!(vmask[1] & (x << 1))]
[1](ptr, ls_y, E, I, H);
} else {
s->dsp.loop_filter_8[!!(vmask[1] & x)]
[1](ptr, ls_y, E, I, H);
}
} else if (vm & (x << 1)) {
int L = l[1], H = L >> 4;
int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
s->dsp.loop_filter_8[!!(vmask[1] & (x << 1))]
[1](ptr + 8, ls_y, E, I, H);
}
}
if (vm3 & x) {
int L = *l, H = L >> 4;
int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
if (vm3 & (x << 1)) {
L = l[1];
H |= (L >> 4) << 8;
E |= s->filter.mblim_lut[L] << 8;
I |= s->filter.lim_lut[L] << 8;
s->dsp.loop_filter_mix2[0][0][1](ptr + ls_y * 4, ls_y, E, I, H);
} else {
s->dsp.loop_filter_8[0][1](ptr + ls_y * 4, ls_y, E, I, H);
}
} else if (vm3 & (x << 1)) {
int L = l[1], H = L >> 4;
int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
s->dsp.loop_filter_8[0][1](ptr + ls_y * 4 + 8, ls_y, E, I, H);
}
}
}
// same principle but for U/V planes
for (p = 0; p < 2; p++) {
lvl = lflvl->level;
dst = s->cur_frame->data[1 + p] + uvoff;
for (y = 0; y < 8; y += 4, dst += 16 * ls_uv, lvl += 32) {
uint8_t *ptr = dst, *l = lvl, *hmask1 = lflvl->mask[1][0][y];
uint8_t *hmask2 = lflvl->mask[1][0][y + 2];
unsigned hm1 = hmask1[0] | hmask1[1] | hmask1[2];
unsigned hm2 = hmask2[1] | hmask2[2], hm = hm1 | hm2;
for (x = 1; hm & ~(x - 1); x <<= 1, ptr += 4) {
if (col || x > 1) {
if (hm1 & x) {
int L = *l, H = L >> 4;
int E = s->filter.mblim_lut[L];
int I = s->filter.lim_lut[L];
if (hmask1[0] & x) {
if (hmask2[0] & x) {
av_assert2(l[16] == L);
s->dsp.loop_filter_16[0](ptr, ls_uv, E, I, H);
} else {
s->dsp.loop_filter_8[2][0](ptr, ls_uv, E, I, H);
}
} else if (hm2 & x) {
L = l[16];
H |= (L >> 4) << 8;
E |= s->filter.mblim_lut[L] << 8;
I |= s->filter.lim_lut[L] << 8;
s->dsp.loop_filter_mix2[!!(hmask1[1] & x)]
[!!(hmask2[1] & x)]
[0](ptr, ls_uv, E, I, H);
} else {
s->dsp.loop_filter_8[!!(hmask1[1] & x)]
[0](ptr, ls_uv, E, I, H);
}
} else if (hm2 & x) {
int L = l[16], H = L >> 4;
int E = s->filter.mblim_lut[L];
int I = s->filter.lim_lut[L];
s->dsp.loop_filter_8[!!(hmask2[1] & x)]
[0](ptr + 8 * ls_uv, ls_uv, E, I, H);
}
}
if (x & 0xAA)
l += 2;
}
}
lvl = lflvl->level;
dst = s->cur_frame->data[1 + p] + uvoff;
for (y = 0; y < 8; y++, dst += 4 * ls_uv) {
uint8_t *ptr = dst, *l = lvl, *vmask = lflvl->mask[1][1][y];
unsigned vm = vmask[0] | vmask[1] | vmask[2];
for (x = 1; vm & ~(x - 1); x <<= 4, ptr += 16, l += 4) {
if (row || y) {
if (vm & x) {
int L = *l, H = L >> 4;
int E = s->filter.mblim_lut[L];
int I = s->filter.lim_lut[L];
if (vmask[0] & x) {
if (vmask[0] & (x << 2)) {
av_assert2(l[2] == L);
s->dsp.loop_filter_16[1](ptr, ls_uv, E, I, H);
} else {
s->dsp.loop_filter_8[2][1](ptr, ls_uv, E, I, H);
}
} else if (vm & (x << 2)) {
L = l[2];
H |= (L >> 4) << 8;
E |= s->filter.mblim_lut[L] << 8;
I |= s->filter.lim_lut[L] << 8;
s->dsp.loop_filter_mix2[!!(vmask[1] & x)]
[!!(vmask[1] & (x << 2))]
[1](ptr, ls_uv, E, I, H);
} else {
s->dsp.loop_filter_8[!!(vmask[1] & x)]
[1](ptr, ls_uv, E, I, H);
}
} else if (vm & (x << 2)) {
int L = l[2], H = L >> 4;
int E = s->filter.mblim_lut[L];
int I = s->filter.lim_lut[L];
s->dsp.loop_filter_8[!!(vmask[1] & (x << 2))]
[1](ptr + 8, ls_uv, E, I, H);
}
}
}
if (y & 1)
lvl += 16;
}
}
}
static void set_tile_offset(int *start, int *end, int idx, int log2_n, int n)
{
int sb_start = (idx * n) >> log2_n;
int sb_end = ((idx + 1) * n) >> log2_n;
*start = FFMIN(sb_start, n) << 3;
*end = FFMIN(sb_end, n) << 3;
}
static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame,
int *got_frame, const uint8_t *data, int size)
{
VP9Context *s = avctx->priv_data;
int ret, tile_row, tile_col, i, ref = -1, row, col;
ptrdiff_t yoff = 0, uvoff = 0;
ret = decode_frame_header(avctx, data, size, &ref);
if (ret < 0) {
return ret;
} else if (!ret) {
if (!s->refs[ref]->buf[0]) {
av_log(avctx, AV_LOG_ERROR,
"Requested reference %d not available\n", ref);
return AVERROR_INVALIDDATA;
}
ret = av_frame_ref(frame, s->refs[ref]);
if (ret < 0)
return ret;
*got_frame = 1;
return 0;
}
data += ret;
size -= ret;
s->cur_frame = frame;
av_frame_unref(s->cur_frame);
if ((ret = ff_get_buffer(avctx, s->cur_frame,
s->refreshrefmask ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
return ret;
s->cur_frame->key_frame = s->keyframe;
s->cur_frame->pict_type = s->keyframe ? AV_PICTURE_TYPE_I
: AV_PICTURE_TYPE_P;
// main tile decode loop
memset(s->above_partition_ctx, 0, s->cols);
memset(s->above_skip_ctx, 0, s->cols);
if (s->keyframe || s->intraonly)
memset(s->above_mode_ctx, DC_PRED, s->cols * 2);
else
memset(s->above_mode_ctx, NEARESTMV, s->cols);
memset(s->above_y_nnz_ctx, 0, s->sb_cols * 16);
memset(s->above_uv_nnz_ctx[0], 0, s->sb_cols * 8);
memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 8);
memset(s->above_segpred_ctx, 0, s->cols);
for (tile_row = 0; tile_row < s->tiling.tile_rows; tile_row++) {
set_tile_offset(&s->tiling.tile_row_start, &s->tiling.tile_row_end,
tile_row, s->tiling.log2_tile_rows, s->sb_rows);
for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
int64_t tile_size;
if (tile_col == s->tiling.tile_cols - 1 &&
tile_row == s->tiling.tile_rows - 1) {
tile_size = size;
} else {
tile_size = AV_RB32(data);
data += 4;
size -= 4;
}
if (tile_size > size)
return AVERROR_INVALIDDATA;
ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size);
if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) // marker bit
return AVERROR_INVALIDDATA;
data += tile_size;
size -= tile_size;
}
for (row = s->tiling.tile_row_start;
row < s->tiling.tile_row_end;
row += 8, yoff += s->cur_frame->linesize[0] * 64,
uvoff += s->cur_frame->linesize[1] * 32) {
VP9Filter *lflvl = s->lflvl;
ptrdiff_t yoff2 = yoff, uvoff2 = uvoff;
for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
set_tile_offset(&s->tiling.tile_col_start,
&s->tiling.tile_col_end,
tile_col, s->tiling.log2_tile_cols, s->sb_cols);
memset(s->left_partition_ctx, 0, 8);
memset(s->left_skip_ctx, 0, 8);
if (s->keyframe || s->intraonly)
memset(s->left_mode_ctx, DC_PRED, 16);
else
memset(s->left_mode_ctx, NEARESTMV, 8);
memset(s->left_y_nnz_ctx, 0, 16);
memset(s->left_uv_nnz_ctx, 0, 16);
memset(s->left_segpred_ctx, 0, 8);
memcpy(&s->c, &s->c_b[tile_col], sizeof(s->c));
for (col = s->tiling.tile_col_start;
col < s->tiling.tile_col_end;
col += 8, yoff2 += 64, uvoff2 += 32, lflvl++) {
// FIXME integrate with lf code (i.e. zero after each
// use, similar to invtxfm coefficients, or similar)
memset(lflvl->mask, 0, sizeof(lflvl->mask));
if ((ret = decode_subblock(avctx, row, col, lflvl,
yoff2, uvoff2, BL_64X64)) < 0)
return ret;
}
memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c));
}
// backup pre-loopfilter reconstruction data for intra
// prediction of next row of sb64s
if (row + 8 < s->rows) {
memcpy(s->intra_pred_data[0],
s->cur_frame->data[0] + yoff +
63 * s->cur_frame->linesize[0],
8 * s->cols);
memcpy(s->intra_pred_data[1],
s->cur_frame->data[1] + uvoff +
31 * s->cur_frame->linesize[1],
4 * s->cols);
memcpy(s->intra_pred_data[2],
s->cur_frame->data[2] + uvoff +
31 * s->cur_frame->linesize[2],
4 * s->cols);
}
// loopfilter one row
if (s->filter.level) {
yoff2 = yoff;
uvoff2 = uvoff;
lflvl = s->lflvl;
for (col = 0; col < s->cols;
col += 8, yoff2 += 64, uvoff2 += 32, lflvl++)
loopfilter_subblock(avctx, lflvl, row, col, yoff2, uvoff2);
}
}
}
// bw adaptivity (or in case of parallel decoding mode, fw adaptivity
// probability maintenance between frames)
if (s->refreshctx) {
if (s->parallelmode) {
memcpy(s->prob_ctx[s->framectxid].coef, s->prob.coef,
sizeof(s->prob.coef));
s->prob_ctx[s->framectxid].p = s->prob.p;
} else {
ff_vp9_adapt_probs(s);
}
}
FFSWAP(VP9MVRefPair *, s->mv[0], s->mv[1]);
// ref frame setup
for (i = 0; i < 8; i++)
if (s->refreshrefmask & (1 << i)) {
av_frame_unref(s->refs[i]);
ret = av_frame_ref(s->refs[i], s->cur_frame);
if (ret < 0)
return ret;
}
if (s->invisible)
av_frame_unref(s->cur_frame);
else
*got_frame = 1;
return 0;
}
static int vp9_decode_packet(AVCodecContext *avctx, void *frame,
int *got_frame, AVPacket *avpkt)
{
const uint8_t *data = avpkt->data;
int size = avpkt->size;
int marker, ret;
/* Read superframe index - this is a collection of individual frames
* that together lead to one visible frame */
marker = data[size - 1];
if ((marker & 0xe0) == 0xc0) {
int nbytes = 1 + ((marker >> 3) & 0x3);
int n_frames = 1 + (marker & 0x7);
int idx_sz = 2 + n_frames * nbytes;
if (size >= idx_sz && data[size - idx_sz] == marker) {
const uint8_t *idx = data + size + 1 - idx_sz;
while (n_frames--) {
int sz = AV_RL32(idx);
if (nbytes < 4)
sz &= (1 << (8 * nbytes)) - 1;
idx += nbytes;
if (sz > size) {
av_log(avctx, AV_LOG_ERROR,
"Superframe packet size too big: %d > %d\n",
sz, size);
return AVERROR_INVALIDDATA;
}
ret = vp9_decode_frame(avctx, frame, got_frame, data, sz);
if (ret < 0)
return ret;
data += sz;
size -= sz;
}
return size;
}
}
/* If we get here, there was no valid superframe index, i.e. this is just
* one whole single frame. Decode it as such from the complete input buf. */
if ((ret = vp9_decode_frame(avctx, frame, got_frame, data, size)) < 0)
return ret;
return size;
}
static av_cold int vp9_decode_free(AVCodecContext *avctx)
{
VP9Context *s = avctx->priv_data;
int i;
for (i = 0; i < FF_ARRAY_ELEMS(s->refs); i++)
av_frame_free(&s->refs[i]);
av_freep(&s->c_b);
av_freep(&s->above_partition_ctx);
return 0;
}
static av_cold int vp9_decode_init(AVCodecContext *avctx)
{
VP9Context *s = avctx->priv_data;
int i;
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
ff_vp9dsp_init(&s->dsp);
ff_videodsp_init(&s->vdsp, 8);
for (i = 0; i < FF_ARRAY_ELEMS(s->refs); i++) {
s->refs[i] = av_frame_alloc();
if (!s->refs[i]) {
vp9_decode_free(avctx);
return AVERROR(ENOMEM);
}
}
s->filter.sharpness = -1;
return 0;
}
AVCodec ff_vp9_decoder = {
.name = "vp9",
.long_name = NULL_IF_CONFIG_SMALL("Google VP9"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_VP9,
.priv_data_size = sizeof(VP9Context),
.init = vp9_decode_init,
.decode = vp9_decode_packet,
.flush = vp9_decode_flush,
.close = vp9_decode_free,
.capabilities = CODEC_CAP_DR1,
};
/*
* VP9 compatible video decoder
*
* Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
* Copyright (C) 2013 Clément Bœsch <u pkh me>
*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_VP9_H
#define AVCODEC_VP9_H
#include <stddef.h>
#include <stdint.h>
#include "libavutil/internal.h"
#include "avcodec.h"
#include "vp56.h"
enum TxfmMode {
TX_4X4,
TX_8X8,
TX_16X16,
TX_32X32,
N_TXFM_SIZES,
TX_SWITCHABLE = N_TXFM_SIZES,
N_TXFM_MODES
};
enum TxfmType {
DCT_DCT,
DCT_ADST,
ADST_DCT,
ADST_ADST,
N_TXFM_TYPES
};
enum IntraPredMode {
VERT_PRED,
HOR_PRED,
DC_PRED,
DIAG_DOWN_LEFT_PRED,
DIAG_DOWN_RIGHT_PRED,
VERT_RIGHT_PRED,
HOR_DOWN_PRED,
VERT_LEFT_PRED,
HOR_UP_PRED,
TM_VP8_PRED,
LEFT_DC_PRED,
TOP_DC_PRED,
DC_128_PRED,
DC_127_PRED,
DC_129_PRED,
N_INTRA_PRED_MODES
};
enum FilterMode {
FILTER_8TAP_SMOOTH,
FILTER_8TAP_REGULAR,
FILTER_8TAP_SHARP,
FILTER_BILINEAR,
FILTER_SWITCHABLE,
};
enum BlockPartition {
PARTITION_NONE, // [ ] <-.
PARTITION_H, // [-] |
PARTITION_V, // [|] |
PARTITION_SPLIT, // [+] --'
};
enum InterPredMode {
NEARESTMV = 10,
NEARMV = 11,
ZEROMV = 12,
NEWMV = 13,
};
enum MVJoint {
MV_JOINT_ZERO,
MV_JOINT_H,
MV_JOINT_V,
MV_JOINT_HV,
};
typedef struct ProbContext {
uint8_t y_mode[4][9];
uint8_t uv_mode[10][9];
uint8_t filter[4][2];
uint8_t mv_mode[7][3];
uint8_t intra[4];
uint8_t comp[5];
uint8_t single_ref[5][2];
uint8_t comp_ref[5];
uint8_t tx32p[2][3];
uint8_t tx16p[2][2];
uint8_t tx8p[2];
uint8_t skip[3];
uint8_t mv_joint[3];
struct {
uint8_t sign;
uint8_t classes[10];
uint8_t class0;
uint8_t bits[10];
uint8_t class0_fp[2][3];
uint8_t fp[3];
uint8_t class0_hp;
uint8_t hp;
} mv_comp[2];
uint8_t partition[4][4][3];
} ProbContext;
typedef void (*vp9_mc_func)(uint8_t *dst, const uint8_t *ref,
ptrdiff_t dst_stride,
ptrdiff_t ref_stride,
int h, int mx, int my);
typedef struct VP9DSPContext {
/*
* dimension 1: 0=4x4, 1=8x8, 2=16x16, 3=32x32
* dimension 2: intra prediction modes
*
* dst/left/top is aligned by transform-size (i.e. 4, 8, 16 or 32 pixels)
* stride is aligned by 16 pixels
* top[-1] is top/left; top[4,7] is top-right for 4x4
*/
// FIXME(rbultje) maybe replace left/top pointers with HAVE_TOP/
// HAVE_LEFT/HAVE_TOPRIGHT flags instead, and then handle it in-place?
// also needs to fit in with what h264/vp8/etc do
void (*intra_pred[N_TXFM_SIZES][N_INTRA_PRED_MODES])(uint8_t *dst,
ptrdiff_t stride,
const uint8_t *left,
const uint8_t *top);
/*
* dimension 1: 0=4x4, 1=8x8, 2=16x16, 3=32x32, 4=lossless (3-4=dct only)
* dimension 2: 0=dct/dct, 1=dct/adst, 2=adst/dct, 3=adst/adst
*
* dst is aligned by transform-size (i.e. 4, 8, 16 or 32 pixels)
* stride is aligned by 16 pixels
* block is 16-byte aligned
* eob indicates the position (+1) of the last non-zero coefficient,
* in scan-order. This can be used to write faster versions, e.g. a
* dc-only 4x4/8x8/16x16/32x32, or a 4x4-only (eob<10) 8x8/16x16/32x32,
* etc.
*/
// FIXME also write idct_add_block() versions for whole (inter) pred
// blocks, so we can do 2 4x4s at once
void (*itxfm_add[N_TXFM_SIZES + 1][N_TXFM_TYPES])(uint8_t *dst,
ptrdiff_t stride,
int16_t *block, int eob);
/*
* dimension 1: width of filter (0=4, 1=8, 2=16)
* dimension 2: 0=col-edge filter (h), 1=row-edge filter (v)
*
* dst/stride are aligned by 8
*/
void (*loop_filter_8[3][2])(uint8_t *dst, ptrdiff_t stride,
int mb_lim, int lim, int hev_thr);
/*
* dimension 1: 0=col-edge filter (h), 1=row-edge filter (v)
*
* The width of filter is assumed to be 16; dst/stride are aligned by 16
*/
void (*loop_filter_16[2])(uint8_t *dst, ptrdiff_t stride,
int mb_lim, int lim, int hev_thr);
/*
* dimension 1/2: width of filter (0=4, 1=8) for each filter half
* dimension 3: 0=col-edge filter (h), 1=row-edge filter (v)
*
* dst/stride are aligned by operation size
* this basically calls loop_filter[d1][d3][0](), followed by
* loop_filter[d2][d3][0]() on the next 8 pixels
* mb_lim/lim/hev_thr contain two values in the lowest two bytes of the
* integer.
*/
// FIXME perhaps a mix4 that operates on 32px (for AVX2)
void (*loop_filter_mix2[2][2][2])(uint8_t *dst, ptrdiff_t stride,
int mb_lim, int lim, int hev_thr);
/*
* dimension 1: hsize (0: 64, 1: 32, 2: 16, 3: 8, 4: 4)
* dimension 2: filter type (0: smooth, 1: regular, 2: sharp, 3: bilin)
* dimension 3: averaging type (0: put, 1: avg)
* dimension 4: x subpel interpolation (0: none, 1: 8tap/bilin)
* dimension 5: y subpel interpolation (1: none, 1: 8tap/bilin)
*
* dst/stride are aligned by hsize
*/
vp9_mc_func mc[5][4][2][2][2];
} VP9DSPContext;
enum CompPredMode {
PRED_SINGLEREF,
PRED_COMPREF,
PRED_SWITCHABLE,
};
typedef struct VP9MVRefPair {
VP56mv mv[2];
int8_t ref[2];
} VP9MVRefPair;
typedef struct VP9Filter {
uint8_t level[8 * 8];
uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */]
[8 /* rows */][4 /* 0=16, 1=8, 2=4, 3=inner4 */];
} VP9Filter;
enum BlockLevel {
BL_64X64,
BL_32X32,
BL_16X16,
BL_8X8,
};
enum BlockSize {
BS_64x64,
BS_64x32,
BS_32x64,
BS_32x32,
BS_32x16,
BS_16x32,
BS_16x16,
BS_16x8,
BS_8x16,
BS_8x8,
BS_8x4,
BS_4x8,
BS_4x4,
N_BS_SIZES,
};
typedef struct VP9Block {
uint8_t seg_id, intra, comp, ref[2], mode[4], uvmode, skip;
enum FilterMode filter;
VP56mv mv[4 /* b_idx */][2 /* ref */];
enum BlockSize bs;
enum TxfmMode tx, uvtx;
int row, row7, col, col7;
uint8_t *dst[3];
ptrdiff_t y_stride, uv_stride;
} VP9Block;
typedef struct VP9Context {
VP9DSPContext dsp;
VideoDSPContext vdsp;
GetBitContext gb;
VP56RangeCoder c;
VP56RangeCoder *c_b;
unsigned c_b_size;
VP9Block b;
// bitstream header
uint8_t profile;
uint8_t keyframe, last_keyframe;
uint8_t invisible;
uint8_t use_last_frame_mvs;
uint8_t errorres;
uint8_t colorspace;
uint8_t fullrange;
uint8_t intraonly;
uint8_t resetctx;
uint8_t refreshrefmask;
uint8_t highprecisionmvs;
enum FilterMode filtermode;
uint8_t allowcompinter;
uint8_t fixcompref;
uint8_t refreshctx;
uint8_t parallelmode;
uint8_t framectxid;
uint8_t refidx[3];
uint8_t signbias[3];
uint8_t varcompref[2];
AVFrame *refs[8];
AVFrame *cur_frame;
struct {
uint8_t level;
int8_t sharpness;
uint8_t lim_lut[64];
uint8_t mblim_lut[64];
} filter;
struct {
uint8_t enabled;
int8_t mode[2];
int8_t ref[4];
} lf_delta;
uint8_t yac_qi;
int8_t ydc_qdelta, uvdc_qdelta, uvac_qdelta;
uint8_t lossless;
struct {
uint8_t enabled;
uint8_t temporal;
uint8_t absolute_vals;
uint8_t update_map;
struct {
uint8_t q_enabled;
uint8_t lf_enabled;
uint8_t ref_enabled;
uint8_t skip_enabled;
uint8_t ref_val;
int16_t q_val;
int8_t lf_val;
int16_t qmul[2][2];
uint8_t lflvl[4][2];
} feat[8];
} segmentation;
struct {
unsigned log2_tile_cols, log2_tile_rows;
unsigned tile_cols, tile_rows;
unsigned tile_row_start, tile_row_end, tile_col_start, tile_col_end;
} tiling;
unsigned sb_cols, sb_rows, rows, cols;
struct {
ProbContext p;
uint8_t coef[4][2][2][6][6][3];
} prob_ctx[4];
struct {
ProbContext p;
uint8_t coef[4][2][2][6][6][11];
uint8_t seg[7];
uint8_t segpred[3];
} prob;
struct {
unsigned y_mode[4][10];
unsigned uv_mode[10][10];
unsigned filter[4][3];
unsigned mv_mode[7][4];
unsigned intra[4][2];
unsigned comp[5][2];
unsigned single_ref[5][2][2];
unsigned comp_ref[5][2];
unsigned tx32p[2][4];
unsigned tx16p[2][3];
unsigned tx8p[2][2];
unsigned skip[3][2];
unsigned mv_joint[4];
struct {
unsigned sign[2];
unsigned classes[11];
unsigned class0[2];
unsigned bits[10][2];
unsigned class0_fp[2][4];
unsigned fp[4];
unsigned class0_hp[2];
unsigned hp[2];
} mv_comp[2];
unsigned partition[4][4][4];
unsigned coef[4][2][2][6][6][3];
unsigned eob[4][2][2][6][6][2];
} counts;
enum TxfmMode txfmmode;
enum CompPredMode comppredmode;
// contextual (left/above) cache
uint8_t left_partition_ctx[8], *above_partition_ctx;
uint8_t left_mode_ctx[16], *above_mode_ctx;
// FIXME maybe merge some of the below in a flags field?
uint8_t left_y_nnz_ctx[16], *above_y_nnz_ctx;
uint8_t left_uv_nnz_ctx[2][8], *above_uv_nnz_ctx[2];
uint8_t left_skip_ctx[8], *above_skip_ctx; // 1bit
uint8_t left_txfm_ctx[8], *above_txfm_ctx; // 2bit
uint8_t left_segpred_ctx[8], *above_segpred_ctx; // 1bit
uint8_t left_intra_ctx[8], *above_intra_ctx; // 1bit
uint8_t left_comp_ctx[8], *above_comp_ctx; // 1bit
uint8_t left_ref_ctx[8], *above_ref_ctx; // 2bit
uint8_t left_filter_ctx[8], *above_filter_ctx;
VP56mv left_mv_ctx[16][2], (*above_mv_ctx)[2];
// whole-frame cache
uint8_t *intra_pred_data[3];
uint8_t *segmentation_map;
VP9MVRefPair *mv[2];
VP9Filter *lflvl;
DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[71 * 80];
// block reconstruction intermediates
DECLARE_ALIGNED(32, int16_t, block)[4096];
DECLARE_ALIGNED(32, int16_t, uvblock)[2][1024];
uint8_t eob[256];
uint8_t uveob[2][64];
VP56mv min_mv, max_mv;
DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64];
DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][32 * 32];
} VP9Context;
void ff_vp9dsp_init(VP9DSPContext *dsp);
void ff_vp9dsp_init_x86(VP9DSPContext *dsp);
void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb);
void ff_vp9_adapt_probs(VP9Context *s);
int ff_vp9_decode_block(AVCodecContext *avctx, int row, int col,
VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff,
enum BlockLevel bl, enum BlockPartition bp);
#endif /* AVCODEC_VP9_H */
/*
* VP9 compatible video decoder
*
* Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
* Copyright (C) 2013 Clément Bœsch <u pkh me>
*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/avassert.h"
#include "avcodec.h"
#include "get_bits.h"
#include "internal.h"
#include "videodsp.h"
#include "vp56.h"
#include "vp9.h"
#include "vp9data.h"
static const uint8_t bwh_tab[2][N_BS_SIZES][2] = {
{
{ 16, 16 }, { 16, 8 }, { 8, 16 }, { 8, 8 }, { 8, 4 }, { 4, 8 },
{ 4, 4 }, { 4, 2 }, { 2, 4 }, { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 },
}, {
{ 8, 8 }, { 8, 4 }, { 4, 8 }, { 4, 4 }, { 4, 2 }, { 2, 4 },
{ 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 },
}
};
// differential forward probability updates
static void decode_mode(VP9Context *s, VP9Block *const b)
{
static const uint8_t left_ctx[N_BS_SIZES] = {
0x0, 0x8, 0x0, 0x8, 0xc, 0x8, 0xc, 0xe, 0xc, 0xe, 0xf, 0xe, 0xf
};
static const uint8_t above_ctx[N_BS_SIZES] = {
0x0, 0x0, 0x8, 0x8, 0x8, 0xc, 0xc, 0xc, 0xe, 0xe, 0xe, 0xf, 0xf
};
static const uint8_t max_tx_for_bl_bp[N_BS_SIZES] = {
TX_32X32, TX_32X32, TX_32X32, TX_32X32, TX_16X16, TX_16X16,
TX_16X16, TX_8X8, TX_8X8, TX_8X8, TX_4X4, TX_4X4, TX_4X4
};
int row = b->row, col = b->col, row7 = b->row7;
enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs];
int w4 = FFMIN(s->cols - col, bwh_tab[1][b->bs][0]);
int h4 = FFMIN(s->rows - row, bwh_tab[1][b->bs][1]);
int have_a = row > 0, have_l = col > s->tiling.tile_col_start;
int y;
if (!s->segmentation.enabled) {
b->seg_id = 0;
} else if (s->keyframe || s->intraonly) {
b->seg_id = s->segmentation.update_map ?
vp8_rac_get_tree(&s->c, ff_vp9_segmentation_tree, s->prob.seg) : 0;
} else if (!s->segmentation.update_map ||
(s->segmentation.temporal &&
vp56_rac_get_prob_branchy(&s->c,
s->prob.segpred[s->above_segpred_ctx[col] +
s->left_segpred_ctx[row7]]))) {
int pred = 8, x;
for (y = 0; y < h4; y++)
for (x = 0; x < w4; x++)
pred = FFMIN(pred,
s->segmentation_map[(y + row) * 8 * s->sb_cols + x + col]);
b->seg_id = pred;
memset(&s->above_segpred_ctx[col], 1, w4);
memset(&s->left_segpred_ctx[row7], 1, h4);
} else {
b->seg_id = vp8_rac_get_tree(&s->c, ff_vp9_segmentation_tree,
s->prob.seg);
memset(&s->above_segpred_ctx[col], 0, w4);
memset(&s->left_segpred_ctx[row7], 0, h4);
}
if ((s->segmentation.enabled && s->segmentation.update_map) || s->keyframe) {
for (y = 0; y < h4; y++)
memset(&s->segmentation_map[(y + row) * 8 * s->sb_cols + col],
b->seg_id, w4);
}
b->skip = s->segmentation.enabled &&
s->segmentation.feat[b->seg_id].skip_enabled;
if (!b->skip) {
int c = s->left_skip_ctx[row7] + s->above_skip_ctx[col];
b->skip = vp56_rac_get_prob(&s->c, s->prob.p.skip[c]);
s->counts.skip[c][b->skip]++;
}
if (s->keyframe || s->intraonly) {
b->intra = 1;
} else if (s->segmentation.feat[b->seg_id].ref_enabled) {
b->intra = !s->segmentation.feat[b->seg_id].ref_val;
} else {
int c, bit;
if (have_a && have_l) {
c = s->above_intra_ctx[col] + s->left_intra_ctx[row7];
c += (c == 2);
} else {
c = have_a ? 2 * s->above_intra_ctx[col] :
have_l ? 2 * s->left_intra_ctx[row7] : 0;
}
bit = vp56_rac_get_prob(&s->c, s->prob.p.intra[c]);
s->counts.intra[c][bit]++;
b->intra = !bit;
}
if ((b->intra || !b->skip) && s->txfmmode == TX_SWITCHABLE) {
int c;
if (have_a) {
if (have_l) {
c = (s->above_skip_ctx[col] ? max_tx :
s->above_txfm_ctx[col]) +
(s->left_skip_ctx[row7] ? max_tx :
s->left_txfm_ctx[row7]) > max_tx;
} else {
c = s->above_skip_ctx[col] ? 1 :
(s->above_txfm_ctx[col] * 2 > max_tx);
}
} else if (have_l) {
c = s->left_skip_ctx[row7] ? 1 :
(s->left_txfm_ctx[row7] * 2 > max_tx);
} else {
c = 1;
}
switch (max_tx) {
case TX_32X32:
b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][0]);
if (b->tx) {
b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][1]);
if (b->tx == 2)
b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][2]);
}
s->counts.tx32p[c][b->tx]++;
break;
case TX_16X16:
b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][0]);
if (b->tx)
b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][1]);
s->counts.tx16p[c][b->tx]++;
break;
case TX_8X8:
b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx8p[c]);
s->counts.tx8p[c][b->tx]++;
break;
case TX_4X4:
b->tx = TX_4X4;
break;
}
} else {
b->tx = FFMIN(max_tx, s->txfmmode);
}
if (s->keyframe || s->intraonly) {
uint8_t *a = &s->above_mode_ctx[col * 2];
uint8_t *l = &s->left_mode_ctx[(row7) << 1];
b->comp = 0;
if (b->bs > BS_8x8) {
// FIXME the memory storage intermediates here aren't really
// necessary, they're just there to make the code slightly
// simpler for now
b->mode[0] =
a[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
ff_vp9_default_kf_ymode_probs[a[0]][l[0]]);
if (b->bs != BS_8x4) {
b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
ff_vp9_default_kf_ymode_probs[a[1]][b->mode[0]]);
l[0] =
a[1] = b->mode[1];
} else {
l[0] =
a[1] =
b->mode[1] = b->mode[0];
}
if (b->bs != BS_4x8) {
b->mode[2] =
a[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
ff_vp9_default_kf_ymode_probs[a[0]][l[1]]);
if (b->bs != BS_8x4) {
b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
ff_vp9_default_kf_ymode_probs[a[1]][b->mode[2]]);
l[1] =
a[1] = b->mode[3];
} else {
l[1] =
a[1] =
b->mode[3] = b->mode[2];
}
} else {
b->mode[2] = b->mode[0];
l[1] =
a[1] =
b->mode[3] = b->mode[1];
}
} else {
b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
ff_vp9_default_kf_ymode_probs[*a][*l]);
b->mode[3] =
b->mode[2] =
b->mode[1] = b->mode[0];
// FIXME this can probably be optimized
memset(a, b->mode[0], bwh_tab[0][b->bs][0]);
memset(l, b->mode[0], bwh_tab[0][b->bs][1]);
}
b->uvmode = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
ff_vp9_default_kf_uvmode_probs[b->mode[3]]);
} else if (b->intra) {
b->comp = 0;
if (b->bs > BS_8x8) {
b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
s->prob.p.y_mode[0]);
s->counts.y_mode[0][b->mode[0]]++;
if (b->bs != BS_8x4) {
b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
s->prob.p.y_mode[0]);
s->counts.y_mode[0][b->mode[1]]++;
} else {
b->mode[1] = b->mode[0];
}
if (b->bs != BS_4x8) {
b->mode[2] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
s->prob.p.y_mode[0]);
s->counts.y_mode[0][b->mode[2]]++;
if (b->bs != BS_8x4) {
b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
s->prob.p.y_mode[0]);
s->counts.y_mode[0][b->mode[3]]++;
} else {
b->mode[3] = b->mode[2];
}
} else {
b->mode[2] = b->mode[0];
b->mode[3] = b->mode[1];
}
} else {
static const uint8_t size_group[10] = {
3, 3, 3, 3, 2, 2, 2, 1, 1, 1
};
int sz = size_group[b->bs];
b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
s->prob.p.y_mode[sz]);
b->mode[1] =
b->mode[2] =
b->mode[3] = b->mode[0];
s->counts.y_mode[sz][b->mode[3]]++;
}
b->uvmode = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
s->prob.p.uv_mode[b->mode[3]]);
s->counts.uv_mode[b->mode[3]][b->uvmode]++;
} else {
static const uint8_t inter_mode_ctx_lut[14][14] = {
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 },
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 },
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 0, 3 },
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 4 },
};
if (s->segmentation.feat[b->seg_id].ref_enabled) {
av_assert2(s->segmentation.feat[b->seg_id].ref_val != 0);
b->comp = 0;
b->ref[0] = s->segmentation.feat[b->seg_id].ref_val - 1;
} else {
// read comp_pred flag
if (s->comppredmode != PRED_SWITCHABLE) {
b->comp = s->comppredmode == PRED_COMPREF;
} else {
int c;
// FIXME add intra as ref=0xff (or -1) to make these easier?
if (have_a) {
if (have_l) {
if (s->above_comp_ctx[col] && s->left_comp_ctx[row7]) {
c = 4;
} else if (s->above_comp_ctx[col]) {
c = 2 + (s->left_intra_ctx[row7] ||
s->left_ref_ctx[row7] == s->fixcompref);
} else if (s->left_comp_ctx[row7]) {
c = 2 + (s->above_intra_ctx[col] ||
s->above_ref_ctx[col] == s->fixcompref);
} else {
c = (!s->above_intra_ctx[col] &&
s->above_ref_ctx[col] == s->fixcompref) ^
(!s->left_intra_ctx[row7] &&
s->left_ref_ctx[row & 7] == s->fixcompref);
}
} else {
c = s->above_comp_ctx[col] ? 3 :
(!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->fixcompref);
}
} else if (have_l) {
c = s->left_comp_ctx[row7] ? 3 :
(!s->left_intra_ctx[row7] && s->left_ref_ctx[row7] == s->fixcompref);
} else {
c = 1;
}
b->comp = vp56_rac_get_prob(&s->c, s->prob.p.comp[c]);
s->counts.comp[c][b->comp]++;
}
// read actual references
// FIXME probably cache a few variables here to prevent repetitive
// memory accesses below
if (b->comp) { /* two references */
int fix_idx = s->signbias[s->fixcompref], var_idx = !fix_idx, c, bit;
b->ref[fix_idx] = s->fixcompref;
// FIXME can this codeblob be replaced by some sort of LUT?
if (have_a) {
if (have_l) {
if (s->above_intra_ctx[col]) {
if (s->left_intra_ctx[row7]) {
c = 2;
} else {
c = 1 + 2 * (s->left_ref_ctx[row7] != s->varcompref[1]);
}
} else if (s->left_intra_ctx[row7]) {
c = 1 + 2 * (s->above_ref_ctx[col] != s->varcompref[1]);
} else {
int refl = s->left_ref_ctx[row7], refa = s->above_ref_ctx[col];
if (refl == refa && refa == s->varcompref[1]) {
c = 0;
} else if (!s->left_comp_ctx[row7] && !s->above_comp_ctx[col]) {
if ((refa == s->fixcompref && refl == s->varcompref[0]) ||
(refl == s->fixcompref && refa == s->varcompref[0])) {
c = 4;
} else {
c = (refa == refl) ? 3 : 1;
}
} else if (!s->left_comp_ctx[row7]) {
if (refa == s->varcompref[1] && refl != s->varcompref[1]) {
c = 1;
} else {
c = (refl == s->varcompref[1] &&
refa != s->varcompref[1]) ? 2 : 4;
}
} else if (!s->above_comp_ctx[col]) {
if (refl == s->varcompref[1] && refa != s->varcompref[1]) {
c = 1;
} else {
c = (refa == s->varcompref[1] &&
refl != s->varcompref[1]) ? 2 : 4;
}
} else {
c = (refl == refa) ? 4 : 2;
}
}
} else {
if (s->above_intra_ctx[col]) {
c = 2;
} else if (s->above_comp_ctx[col]) {
c = 4 * (s->above_ref_ctx[col] != s->varcompref[1]);
} else {
c = 3 * (s->above_ref_ctx[col] != s->varcompref[1]);
}
}
} else if (have_l) {
if (s->left_intra_ctx[row7]) {
c = 2;
} else if (s->left_comp_ctx[row7]) {
c = 4 * (s->left_ref_ctx[row7] != s->varcompref[1]);
} else {
c = 3 * (s->left_ref_ctx[row7] != s->varcompref[1]);
}
} else {
c = 2;
}
bit = vp56_rac_get_prob(&s->c, s->prob.p.comp_ref[c]);
b->ref[var_idx] = s->varcompref[bit];
s->counts.comp_ref[c][bit]++;
} else { /* single reference */
int bit, c;
if (have_a && !s->above_intra_ctx[col]) {
if (have_l && !s->left_intra_ctx[row7]) {
if (s->left_comp_ctx[row7]) {
if (s->above_comp_ctx[col]) {
c = 1 + (!s->fixcompref || !s->left_ref_ctx[row7] ||
!s->above_ref_ctx[col]);
} else {
c = (3 * !s->above_ref_ctx[col]) +
(!s->fixcompref || !s->left_ref_ctx[row7]);
}
} else if (s->above_comp_ctx[col]) {
c = (3 * !s->left_ref_ctx[row7]) +
(!s->fixcompref || !s->above_ref_ctx[col]);
} else {
c = 2 * !s->left_ref_ctx[row7] + 2 * !s->above_ref_ctx[col];
}
} else if (s->above_intra_ctx[col]) {
c = 2;
} else if (s->above_comp_ctx[col]) {
c = 1 + (!s->fixcompref || !s->above_ref_ctx[col]);
} else {
c = 4 * (!s->above_ref_ctx[col]);
}
} else if (have_l && !s->left_intra_ctx[row7]) {
if (s->left_intra_ctx[row7]) {
c = 2;
} else if (s->left_comp_ctx[row7]) {
c = 1 + (!s->fixcompref || !s->left_ref_ctx[row7]);
} else {
c = 4 * (!s->left_ref_ctx[row7]);
}
} else {
c = 2;
}
bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][0]);
s->counts.single_ref[c][0][bit]++;
if (!bit) {
b->ref[0] = 0;
} else {
// FIXME can this codeblob be replaced by some sort of LUT?
if (have_a) {
if (have_l) {
if (s->left_intra_ctx[row7]) {
if (s->above_intra_ctx[col]) {
c = 2;
} else if (s->above_comp_ctx[col]) {
c = 1 + 2 * (s->fixcompref == 1 ||
s->above_ref_ctx[col] == 1);
} else if (!s->above_ref_ctx[col]) {
c = 3;
} else {
c = 4 * (s->above_ref_ctx[col] == 1);
}
} else if (s->above_intra_ctx[col]) {
if (s->left_intra_ctx[row7]) {
c = 2;
} else if (s->left_comp_ctx[row7]) {
c = 1 + 2 * (s->fixcompref == 1 ||
s->left_ref_ctx[row7] == 1);
} else if (!s->left_ref_ctx[row7]) {
c = 3;
} else {
c = 4 * (s->left_ref_ctx[row7] == 1);
}
} else if (s->above_comp_ctx[col]) {
if (s->left_comp_ctx[row7]) {
if (s->left_ref_ctx[row7] == s->above_ref_ctx[col]) {
c = 3 * (s->fixcompref == 1 ||
s->left_ref_ctx[row7] == 1);
} else {
c = 2;
}
} else if (!s->left_ref_ctx[row7]) {
c = 1 + 2 * (s->fixcompref == 1 ||
s->above_ref_ctx[col] == 1);
} else {
c = 3 * (s->left_ref_ctx[row7] == 1) +
(s->fixcompref == 1 || s->above_ref_ctx[col] == 1);
}
} else if (s->left_comp_ctx[row7]) {
if (!s->above_ref_ctx[col]) {
c = 1 + 2 * (s->fixcompref == 1 ||
s->left_ref_ctx[row7] == 1);
} else {
c = 3 * (s->above_ref_ctx[col] == 1) +
(s->fixcompref == 1 || s->left_ref_ctx[row7] == 1);
}
} else if (!s->above_ref_ctx[col]) {
if (!s->left_ref_ctx[row7]) {
c = 3;
} else {
c = 4 * (s->left_ref_ctx[row7] == 1);
}
} else if (!s->left_ref_ctx[row7]) {
c = 4 * (s->above_ref_ctx[col] == 1);
} else {
c = 2 * (s->left_ref_ctx[row7] == 1) +
2 * (s->above_ref_ctx[col] == 1);
}
} else {
if (s->above_intra_ctx[col] ||
(!s->above_comp_ctx[col] && !s->above_ref_ctx[col])) {
c = 2;
} else if (s->above_comp_ctx[col]) {
c = 3 * (s->fixcompref == 1 || s->above_ref_ctx[col] == 1);
} else {
c = 4 * (s->above_ref_ctx[col] == 1);
}
}
} else if (have_l) {
if (s->left_intra_ctx[row7] ||
(!s->left_comp_ctx[row7] && !s->left_ref_ctx[row7])) {
c = 2;
} else if (s->left_comp_ctx[row7]) {
c = 3 * (s->fixcompref == 1 || s->left_ref_ctx[row7] == 1);
} else {
c = 4 * (s->left_ref_ctx[row7] == 1);
}
} else {
c = 2;
}
bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][1]);
s->counts.single_ref[c][1][bit]++;
b->ref[0] = 1 + bit;
}
}
}
if (b->bs <= BS_8x8) {
if (s->segmentation.feat[b->seg_id].skip_enabled) {
b->mode[0] =
b->mode[1] =
b->mode[2] =
b->mode[3] = ZEROMV;
} else {
static const uint8_t off[10] = {
3, 0, 0, 1, 0, 0, 0, 0, 0, 0
};
// FIXME this needs to use the LUT tables from find_ref_mvs
// because not all are -1,0/0,-1
int c = inter_mode_ctx_lut[s->above_mode_ctx[col + off[b->bs]]]
[s->left_mode_ctx[row7 + off[b->bs]]];
b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree,
s->prob.p.mv_mode[c]);
b->mode[1] =
b->mode[2] =
b->mode[3] = b->mode[0];
s->counts.mv_mode[c][b->mode[0] - 10]++;
}
}
if (s->filtermode == FILTER_SWITCHABLE) {
int c;
if (have_a && s->above_mode_ctx[col] >= NEARESTMV) {
if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) {
c = s->above_filter_ctx[col] == s->left_filter_ctx[row7] ?
s->left_filter_ctx[row7] : 3;
} else {
c = s->above_filter_ctx[col];
}
} else if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) {
c = s->left_filter_ctx[row7];
} else {
c = 3;
}
b->filter = vp8_rac_get_tree(&s->c, ff_vp9_filter_tree,
s->prob.p.filter[c]);
s->counts.filter[c][b->filter]++;
} else {
b->filter = s->filtermode;
}
if (b->bs > BS_8x8) {
int c = inter_mode_ctx_lut[s->above_mode_ctx[col]][s->left_mode_ctx[row7]];
b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree,
s->prob.p.mv_mode[c]);
s->counts.mv_mode[c][b->mode[0] - 10]++;
ff_vp9_fill_mv(s, b->mv[0], b->mode[0], 0);
if (b->bs != BS_8x4) {
b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree,
s->prob.p.mv_mode[c]);
s->counts.mv_mode[c][b->mode[1] - 10]++;
ff_vp9_fill_mv(s, b->mv[1], b->mode[1], 1);
} else {
b->mode[1] = b->mode[0];
AV_COPY32(&b->mv[1][0], &b->mv[0][0]);
AV_COPY32(&b->mv[1][1], &b->mv[0][1]);
}
if (b->bs != BS_4x8) {
b->mode[2] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree,
s->prob.p.mv_mode[c]);
s->counts.mv_mode[c][b->mode[2] - 10]++;
ff_vp9_fill_mv(s, b->mv[2], b->mode[2], 2);
if (b->bs != BS_8x4) {
b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree,
s->prob.p.mv_mode[c]);
s->counts.mv_mode[c][b->mode[3] - 10]++;
ff_vp9_fill_mv(s, b->mv[3], b->mode[3], 3);
} else {
b->mode[3] = b->mode[2];
AV_COPY32(&b->mv[3][0], &b->mv[2][0]);
AV_COPY32(&b->mv[3][1], &b->mv[2][1]);
}
} else {
b->mode[2] = b->mode[0];
AV_COPY32(&b->mv[2][0], &b->mv[0][0]);
AV_COPY32(&b->mv[2][1], &b->mv[0][1]);
b->mode[3] = b->mode[1];
AV_COPY32(&b->mv[3][0], &b->mv[1][0]);
AV_COPY32(&b->mv[3][1], &b->mv[1][1]);
}
} else {
ff_vp9_fill_mv(s, b->mv[0], b->mode[0], -1);
AV_COPY32(&b->mv[1][0], &b->mv[0][0]);
AV_COPY32(&b->mv[2][0], &b->mv[0][0]);
AV_COPY32(&b->mv[3][0], &b->mv[0][0]);
AV_COPY32(&b->mv[1][1], &b->mv[0][1]);
AV_COPY32(&b->mv[2][1], &b->mv[0][1]);
AV_COPY32(&b->mv[3][1], &b->mv[0][1]);
}
}
// FIXME this can probably be optimized
memset(&s->above_skip_ctx[col], b->skip, w4);
memset(&s->left_skip_ctx[row7], b->skip, h4);
memset(&s->above_txfm_ctx[col], b->tx, w4);
memset(&s->left_txfm_ctx[row7], b->tx, h4);
memset(&s->above_partition_ctx[col], above_ctx[b->bs], w4);
memset(&s->left_partition_ctx[row7], left_ctx[b->bs], h4);
if (!s->keyframe && !s->intraonly) {
memset(&s->above_intra_ctx[col], b->intra, w4);
memset(&s->left_intra_ctx[row7], b->intra, h4);
memset(&s->above_comp_ctx[col], b->comp, w4);
memset(&s->left_comp_ctx[row7], b->comp, h4);
memset(&s->above_mode_ctx[col], b->mode[3], w4);
memset(&s->left_mode_ctx[row7], b->mode[3], h4);
if (s->filtermode == FILTER_SWITCHABLE && !b->intra) {
memset(&s->above_filter_ctx[col], b->filter, w4);
memset(&s->left_filter_ctx[row7], b->filter, h4);
b->filter = ff_vp9_filter_lut[b->filter];
}
if (b->bs > BS_8x8) {
int mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]);
AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][0], &b->mv[1][0]);
AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][1], &b->mv[1][1]);
AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][0], mv0);
AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][1], mv1);
AV_COPY32(&s->above_mv_ctx[col * 2 + 0][0], &b->mv[2][0]);
AV_COPY32(&s->above_mv_ctx[col * 2 + 0][1], &b->mv[2][1]);
AV_WN32A(&s->above_mv_ctx[col * 2 + 1][0], mv0);
AV_WN32A(&s->above_mv_ctx[col * 2 + 1][1], mv1);
} else {
int n, mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]);
for (n = 0; n < w4 * 2; n++) {
AV_WN32A(&s->above_mv_ctx[col * 2 + n][0], mv0);
AV_WN32A(&s->above_mv_ctx[col * 2 + n][1], mv1);
}
for (n = 0; n < h4 * 2; n++) {
AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][0], mv0);
AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][1], mv1);
}
}
if (!b->intra) { // FIXME write 0xff or -1 if intra, so we can use this
// as a direct check in above branches
int vref = b->ref[b->comp ? s->signbias[s->varcompref[0]] : 0];
memset(&s->above_ref_ctx[col], vref, w4);
memset(&s->left_ref_ctx[row7], vref, h4);
}
}
// FIXME kinda ugly
for (y = 0; y < h4; y++) {
int x, o = (row + y) * s->sb_cols * 8 + col;
if (b->intra) {
for (x = 0; x < w4; x++) {
s->mv[0][o + x].ref[0] =
s->mv[0][o + x].ref[1] = -1;
}
} else if (b->comp) {
for (x = 0; x < w4; x++) {
s->mv[0][o + x].ref[0] = b->ref[0];
s->mv[0][o + x].ref[1] = b->ref[1];
AV_COPY32(&s->mv[0][o + x].mv[0], &b->mv[3][0]);
AV_COPY32(&s->mv[0][o + x].mv[1], &b->mv[3][1]);
}
} else {
for (x = 0; x < w4; x++) {
s->mv[0][o + x].ref[0] = b->ref[0];
s->mv[0][o + x].ref[1] = -1;
AV_COPY32(&s->mv[0][o + x].mv[0], &b->mv[3][0]);
}
}
}
}
// FIXME remove tx argument, and merge cnt/eob arguments?
static int decode_block_coeffs(VP56RangeCoder *c, int16_t *coef, int n_coeffs,
enum TxfmMode tx, unsigned (*cnt)[6][3],
unsigned (*eob)[6][2], uint8_t(*p)[6][11],
int nnz, const int16_t *scan,
const int16_t(*nb)[2],
const int16_t *band_counts, const int16_t *qmul)
{
int i = 0, band = 0, band_left = band_counts[band];
uint8_t *tp = p[0][nnz];
uint8_t cache[1024];
do {
int val, rc;
val = vp56_rac_get_prob_branchy(c, tp[0]); // eob
eob[band][nnz][val]++;
if (!val)
break;
skip_eob:
if (!vp56_rac_get_prob_branchy(c, tp[1])) { // zero
cnt[band][nnz][0]++;
if (!--band_left)
band_left = band_counts[++band];
cache[scan[i]] = 0;
nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1;
tp = p[band][nnz];
if (++i == n_coeffs)
break; //invalid input; blocks should end with EOB
goto skip_eob;
}
rc = scan[i];
if (!vp56_rac_get_prob_branchy(c, tp[2])) { // one
cnt[band][nnz][1]++;
val = 1;
cache[rc] = 1;
} else {
// fill in p[3-10] (model fill) - only once per frame for each pos
if (!tp[3])
memcpy(&tp[3], ff_vp9_model_pareto8[tp[2]], 8);
cnt[band][nnz][2]++;
if (!vp56_rac_get_prob_branchy(c, tp[3])) { // 2, 3, 4
if (!vp56_rac_get_prob_branchy(c, tp[4])) {
cache[rc] = val = 2;
} else {
val = 3 + vp56_rac_get_prob(c, tp[5]);
cache[rc] = 3;
}
} else if (!vp56_rac_get_prob_branchy(c, tp[6])) { // cat1/2
cache[rc] = 4;
if (!vp56_rac_get_prob_branchy(c, tp[7])) {
val = vp56_rac_get_prob(c, 159) + 5;
} else {
val = (vp56_rac_get_prob(c, 165) << 1) + 7;
val += vp56_rac_get_prob(c, 145);
}
} else { // cat 3-6
cache[rc] = 5;
if (!vp56_rac_get_prob_branchy(c, tp[8])) {
if (!vp56_rac_get_prob_branchy(c, tp[9])) {
val = (vp56_rac_get_prob(c, 173) << 2) + 11;
val += (vp56_rac_get_prob(c, 148) << 1);
val += vp56_rac_get_prob(c, 140);
} else {
val = (vp56_rac_get_prob(c, 176) << 3) + 19;
val += (vp56_rac_get_prob(c, 155) << 2);
val += (vp56_rac_get_prob(c, 140) << 1);
val += vp56_rac_get_prob(c, 135);
}
} else if (!vp56_rac_get_prob_branchy(c, tp[10])) {
val = (vp56_rac_get_prob(c, 180) << 4) + 35;
val += (vp56_rac_get_prob(c, 157) << 3);
val += (vp56_rac_get_prob(c, 141) << 2);
val += (vp56_rac_get_prob(c, 134) << 1);
val += vp56_rac_get_prob(c, 130);
} else {
val = (vp56_rac_get_prob(c, 254) << 13) + 67;
val += (vp56_rac_get_prob(c, 254) << 12);
val += (vp56_rac_get_prob(c, 254) << 11);
val += (vp56_rac_get_prob(c, 252) << 10);
val += (vp56_rac_get_prob(c, 249) << 9);
val += (vp56_rac_get_prob(c, 243) << 8);
val += (vp56_rac_get_prob(c, 230) << 7);
val += (vp56_rac_get_prob(c, 196) << 6);
val += (vp56_rac_get_prob(c, 177) << 5);
val += (vp56_rac_get_prob(c, 153) << 4);
val += (vp56_rac_get_prob(c, 140) << 3);
val += (vp56_rac_get_prob(c, 133) << 2);
val += (vp56_rac_get_prob(c, 130) << 1);
val += vp56_rac_get_prob(c, 129);
}
}
}
if (!--band_left)
band_left = band_counts[++band];
if (tx == TX_32X32) // FIXME slow
coef[rc] = ((vp8_rac_get(c) ? -val : val) * qmul[!!i]) / 2;
else
coef[rc] = (vp8_rac_get(c) ? -val : val) * qmul[!!i];
nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1;
tp = p[band][nnz];
} while (++i < n_coeffs);
return i;
}
static int decode_coeffs(AVCodecContext *avctx)
{
VP9Context *s = avctx->priv_data;
VP9Block *const b = &s->b;
int row = b->row, col = b->col;
uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra];
unsigned (*c)[6][3] = s->counts.coef[b->tx][0 /* y */][!b->intra];
unsigned (*e)[6][2] = s->counts.eob[b->tx][0 /* y */][!b->intra];
int w4 = bwh_tab[1][b->bs][0] << 1, h4 = bwh_tab[1][b->bs][1] << 1;
int end_x = FFMIN(2 * (s->cols - col), w4);
int end_y = FFMIN(2 * (s->rows - row), h4);
int n, pl, x, y, step1d = 1 << b->tx, step = 1 << (b->tx * 2);
int uvstep1d = 1 << b->uvtx, uvstep = 1 << (b->uvtx * 2), ret;
int16_t (*qmul)[2] = s->segmentation.feat[b->seg_id].qmul;
int tx = 4 * s->lossless + b->tx;
const int16_t **yscans = ff_vp9_scans[tx];
const int16_t (**ynbs)[2] = ff_vp9_scans_nb[tx];
const int16_t *uvscan = ff_vp9_scans[b->uvtx][DCT_DCT];
const int16_t (*uvnb)[2] = ff_vp9_scans_nb[b->uvtx][DCT_DCT];
uint8_t *a = &s->above_y_nnz_ctx[col * 2];
uint8_t *l = &s->left_y_nnz_ctx[(row & 7) << 1];
static const int16_t band_counts[4][8] = {
{ 1, 2, 3, 4, 3, 16 - 13, 0 },
{ 1, 2, 3, 4, 11, 64 - 21, 0 },
{ 1, 2, 3, 4, 11, 256 - 21, 0 },
{ 1, 2, 3, 4, 11, 1024 - 21, 0 },
};
const int16_t *y_band_counts = band_counts[b->tx];
const int16_t *uv_band_counts = band_counts[b->uvtx];
/* y tokens */
if (b->tx > TX_4X4) { // FIXME slow
for (y = 0; y < end_y; y += step1d)
for (x = 1; x < step1d; x++)
l[y] |= l[y + x];
for (x = 0; x < end_x; x += step1d)
for (y = 1; y < step1d; y++)
a[x] |= a[x + y];
}
for (n = 0, y = 0; y < end_y; y += step1d) {
for (x = 0; x < end_x; x += step1d, n += step) {
enum TxfmType txtp = ff_vp9_intra_txfm_type[b->mode[b->tx == TX_4X4 &&
b->bs > BS_8x8 ?
n : 0]];
int nnz = a[x] + l[y];
if ((ret = decode_block_coeffs(&s->c, s->block + 16 * n, 16 * step,
b->tx, c, e, p, nnz, yscans[txtp],
ynbs[txtp], y_band_counts,
qmul[0])) < 0)
return ret;
a[x] = l[y] = !!ret;
if (b->tx > TX_8X8)
AV_WN16A(&s->eob[n], ret);
else
s->eob[n] = ret;
}
}
if (b->tx > TX_4X4) { // FIXME slow
for (y = 0; y < end_y; y += step1d)
memset(&l[y + 1], l[y], FFMIN(end_y - y - 1, step1d - 1));
for (x = 0; x < end_x; x += step1d)
memset(&a[x + 1], a[x], FFMIN(end_x - x - 1, step1d - 1));
}
p = s->prob.coef[b->uvtx][1 /* uv */][!b->intra];
c = s->counts.coef[b->uvtx][1 /* uv */][!b->intra];
e = s->counts.eob[b->uvtx][1 /* uv */][!b->intra];
w4 >>= 1;
h4 >>= 1;
end_x >>= 1;
end_y >>= 1;
for (pl = 0; pl < 2; pl++) {
a = &s->above_uv_nnz_ctx[pl][col];
l = &s->left_uv_nnz_ctx[pl][row & 7];
if (b->uvtx > TX_4X4) { // FIXME slow
for (y = 0; y < end_y; y += uvstep1d)
for (x = 1; x < uvstep1d; x++)
l[y] |= l[y + x];
for (x = 0; x < end_x; x += uvstep1d)
for (y = 1; y < uvstep1d; y++)
a[x] |= a[x + y];
}
for (n = 0, y = 0; y < end_y; y += uvstep1d) {
for (x = 0; x < end_x; x += uvstep1d, n += uvstep) {
int nnz = a[x] + l[y];
if ((ret = decode_block_coeffs(&s->c, s->uvblock[pl] + 16 * n,
16 * uvstep, b->uvtx, c, e, p,
nnz, uvscan, uvnb,
uv_band_counts, qmul[1])) < 0)
return ret;
a[x] = l[y] = !!ret;
if (b->uvtx > TX_8X8)
AV_WN16A(&s->uveob[pl][n], ret);
else
s->uveob[pl][n] = ret;
}
}
if (b->uvtx > TX_4X4) { // FIXME slow
for (y = 0; y < end_y; y += uvstep1d)
memset(&l[y + 1], l[y], FFMIN(end_y - y - 1, uvstep1d - 1));
for (x = 0; x < end_x; x += uvstep1d)
memset(&a[x + 1], a[x], FFMIN(end_x - x - 1, uvstep1d - 1));
}
}
return 0;
}
static av_always_inline int check_intra_mode(VP9Context *s, int mode,
uint8_t **a,
uint8_t *dst_edge,
ptrdiff_t stride_edge,
uint8_t *dst_inner,
ptrdiff_t stride_inner,
uint8_t *l, int col, int x, int w,
int row, int y, enum TxfmMode tx,
int p)
{
int have_top = row > 0 || y > 0;
int have_left = col > s->tiling.tile_col_start || x > 0;
int have_right = x < w - 1;
static const uint8_t mode_conv[10][2 /* have_left */][2 /* have_top */] = {
[VERT_PRED] = { { DC_127_PRED, VERT_PRED },
{ DC_127_PRED, VERT_PRED } },
[HOR_PRED] = { { DC_129_PRED, DC_129_PRED },
{ HOR_PRED, HOR_PRED } },
[DC_PRED] = { { DC_128_PRED, TOP_DC_PRED },
{ LEFT_DC_PRED, DC_PRED } },
[DIAG_DOWN_LEFT_PRED] = { { DC_127_PRED, DIAG_DOWN_LEFT_PRED },
{ DC_127_PRED, DIAG_DOWN_LEFT_PRED } },
[DIAG_DOWN_RIGHT_PRED] = { { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED },
{ DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED } },
[VERT_RIGHT_PRED] = { { VERT_RIGHT_PRED, VERT_RIGHT_PRED },
{ VERT_RIGHT_PRED, VERT_RIGHT_PRED } },
[HOR_DOWN_PRED] = { { HOR_DOWN_PRED, HOR_DOWN_PRED },
{ HOR_DOWN_PRED, HOR_DOWN_PRED } },
[VERT_LEFT_PRED] = { { DC_127_PRED, VERT_LEFT_PRED },
{ DC_127_PRED, VERT_LEFT_PRED } },
[HOR_UP_PRED] = { { DC_129_PRED, DC_129_PRED },
{ HOR_UP_PRED, HOR_UP_PRED } },
[TM_VP8_PRED] = { { DC_129_PRED, VERT_PRED },
{ HOR_PRED, TM_VP8_PRED } },
};
static const struct {
uint8_t needs_left:1;
uint8_t needs_top:1;
uint8_t needs_topleft:1;
uint8_t needs_topright:1;
} edges[N_INTRA_PRED_MODES] = {
[VERT_PRED] = { .needs_top = 1 },
[HOR_PRED] = { .needs_left = 1 },
[DC_PRED] = { .needs_top = 1, .needs_left = 1 },
[DIAG_DOWN_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 },
[DIAG_DOWN_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1,
.needs_topleft = 1 },
[VERT_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1,
.needs_topleft = 1 },
[HOR_DOWN_PRED] = { .needs_left = 1, .needs_top = 1,
.needs_topleft = 1 },
[VERT_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 },
[HOR_UP_PRED] = { .needs_left = 1 },
[TM_VP8_PRED] = { .needs_left = 1, .needs_top = 1,
.needs_topleft = 1 },
[LEFT_DC_PRED] = { .needs_left = 1 },
[TOP_DC_PRED] = { .needs_top = 1 },
[DC_128_PRED] = { 0 },
[DC_127_PRED] = { 0 },
[DC_129_PRED] = { 0 }
};
av_assert2(mode >= 0 && mode < 10);
mode = mode_conv[mode][have_left][have_top];
if (edges[mode].needs_top) {
uint8_t *top = NULL, *topleft = NULL;
int n_px_need = 4 << tx, n_px_have = (((s->cols - col) << !p) - x) * 4;
int n_px_need_tr = 0;
if (tx == TX_4X4 && edges[mode].needs_topright && have_right)
n_px_need_tr = 4;
// if top of sb64-row, use s->intra_pred_data[] instead of
// dst[-stride] for intra prediction (it contains pre- instead of
// post-loopfilter data)
if (have_top) {
top = !(row & 7) && !y ?
s->intra_pred_data[p] + col * (8 >> !!p) + x * 4 :
y == 0 ? &dst_edge[-stride_edge] : &dst_inner[-stride_inner];
if (have_left)
topleft = !(row & 7) && !y ?
s->intra_pred_data[p] + col * (8 >> !!p) + x * 4 :
y == 0 || x == 0 ? &dst_edge[-stride_edge] :
&dst_inner[-stride_inner];
}
if (have_top &&
(!edges[mode].needs_topleft || (have_left && top == topleft)) &&
(tx != TX_4X4 || !edges[mode].needs_topright || have_right) &&
n_px_need + n_px_need_tr <= n_px_have) {
*a = top;
} else {
if (have_top) {
if (n_px_need <= n_px_have) {
memcpy(*a, top, n_px_need);
} else {
memcpy(*a, top, n_px_have);
memset(&(*a)[n_px_have], (*a)[n_px_have - 1],
n_px_need - n_px_have);
}
} else {
memset(*a, 127, n_px_need);
}
if (edges[mode].needs_topleft) {
if (have_left && have_top)
(*a)[-1] = topleft[-1];
else
(*a)[-1] = have_top ? 129 : 127;
}
if (tx == TX_4X4 && edges[mode].needs_topright) {
if (have_top && have_right &&
n_px_need + n_px_need_tr <= n_px_have) {
memcpy(&(*a)[4], &top[4], 4);
} else {
memset(&(*a)[4], (*a)[3], 4);
}
}
}
}
if (edges[mode].needs_left) {
if (have_left) {
int i;
int n_px_need = 4 << tx;
int n_px_have = (((s->rows - row) << !p) - y) * 4;
uint8_t *dst = x == 0 ? dst_edge : dst_inner;
ptrdiff_t stride = x == 0 ? stride_edge : stride_inner;
if (n_px_need <= n_px_have) {
for (i = 0; i < n_px_need; i++)
l[i] = dst[i * stride - 1];
} else {
for (i = 0; i < n_px_have; i++)
l[i] = dst[i * stride - 1];
memset(&l[i], l[i - 1], n_px_need - n_px_have);
}
} else {
memset(l, 129, 4 << tx);
}
}
return mode;
}
static void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off)
{
VP9Context *s = avctx->priv_data;
VP9Block *const b = &s->b;
int row = b->row, col = b->col;
int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n;
int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2);
int end_x = FFMIN(2 * (s->cols - col), w4);
int end_y = FFMIN(2 * (s->rows - row), h4);
int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless;
int uvstep1d = 1 << b->uvtx, p;
uint8_t *dst = b->dst[0], *dst_r = s->cur_frame->data[0] + y_off;
for (n = 0, y = 0; y < end_y; y += step1d) {
uint8_t *ptr = dst, *ptr_r = dst_r;
for (x = 0; x < end_x;
x += step1d, ptr += 4 * step1d, ptr_r += 4 * step1d, n += step) {
int mode = b->mode[b->bs > BS_8x8 && b->tx == TX_4X4 ?
y * 2 + x : 0];
LOCAL_ALIGNED_16(uint8_t, a_buf, [48]);
uint8_t *a = &a_buf[16], l[32];
enum TxfmType txtp = ff_vp9_intra_txfm_type[mode];
int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
mode = check_intra_mode(s, mode, &a, ptr_r,
s->cur_frame->linesize[0],
ptr, b->y_stride, l,
col, x, w4, row, y, b->tx, 0);
s->dsp.intra_pred[b->tx][mode](ptr, b->y_stride, l, a);
if (eob)
s->dsp.itxfm_add[tx][txtp](ptr, b->y_stride,
s->block + 16 * n, eob);
}
dst_r += 4 * s->cur_frame->linesize[0] * step1d;
dst += 4 * b->y_stride * step1d;
}
// U/V
h4 >>= 1;
w4 >>= 1;
end_x >>= 1;
end_y >>= 1;
step = 1 << (b->uvtx * 2);
for (p = 0; p < 2; p++) {
dst = b->dst[1 + p];
dst_r = s->cur_frame->data[1 + p] + uv_off;
for (n = 0, y = 0; y < end_y; y += uvstep1d) {
uint8_t *ptr = dst, *ptr_r = dst_r;
for (x = 0; x < end_x;
x += uvstep1d, ptr += 4 * uvstep1d,
ptr_r += 4 * uvstep1d, n += step) {
int mode = b->uvmode;
LOCAL_ALIGNED_16(uint8_t, a_buf, [48]);
uint8_t *a = &a_buf[16], l[32];
int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n])
: s->uveob[p][n];
mode = check_intra_mode(s, mode, &a, ptr_r,
s->cur_frame->linesize[1],
ptr, b->uv_stride, l,
col, x, w4, row, y, b->uvtx, p + 1);
s->dsp.intra_pred[b->uvtx][mode](ptr, b->uv_stride, l, a);
if (eob)
s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, b->uv_stride,
s->uvblock[p] + 16 * n,
eob);
}
dst_r += 4 * uvstep1d * s->cur_frame->linesize[1];
dst += 4 * uvstep1d * b->uv_stride;
}
}
}
static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func(*mc)[2],
uint8_t *dst, ptrdiff_t dst_stride,
const uint8_t *ref,
ptrdiff_t ref_stride,
ptrdiff_t y, ptrdiff_t x,
const VP56mv *mv,
int bw, int bh, int w, int h)
{
int mx = mv->x, my = mv->y;
y += my >> 3;
x += mx >> 3;
ref += y * ref_stride + x;
mx &= 7;
my &= 7;
// FIXME bilinear filter only needs 0/1 pixels, not 3/4
if (x < !!mx * 3 || y < !!my * 3 ||
x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) {
s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
ref - !!my * 3 * ref_stride - !!mx * 3,
80,
ref_stride,
bw + !!mx * 7, bh + !!my * 7,
x - !!mx * 3, y - !!my * 3, w, h);
ref = s->edge_emu_buffer + !!my * 3 * 80 + !!mx * 3;
ref_stride = 80;
}
mc[!!mx][!!my](dst, ref, dst_stride, ref_stride, bh, mx << 1, my << 1);
}
static av_always_inline void mc_chroma_dir(VP9Context *s, vp9_mc_func(*mc)[2],
uint8_t *dst_u, uint8_t *dst_v,
ptrdiff_t dst_stride,
const uint8_t *ref_u,
ptrdiff_t src_stride_u,
const uint8_t *ref_v,
ptrdiff_t src_stride_v,
ptrdiff_t y, ptrdiff_t x,
const VP56mv *mv,
int bw, int bh, int w, int h)
{
int mx = mv->x, my = mv->y;
y += my >> 4;
x += mx >> 4;
ref_u += y * src_stride_u + x;
ref_v += y * src_stride_v + x;
mx &= 15;
my &= 15;
// FIXME bilinear filter only needs 0/1 pixels, not 3/4
if (x < !!mx * 3 || y < !!my * 3 ||
x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) {
s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
ref_u - !!my * 3 * src_stride_u - !!mx * 3,
80,
src_stride_u,
bw + !!mx * 7, bh + !!my * 7,
x - !!mx * 3, y - !!my * 3, w, h);
ref_u = s->edge_emu_buffer + !!my * 3 * 80 + !!mx * 3;
mc[!!mx][!!my](dst_u, ref_u, dst_stride, 80, bh, mx, my);
s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
ref_v - !!my * 3 * src_stride_v - !!mx * 3,
80,
src_stride_v,
bw + !!mx * 7, bh + !!my * 7,
x - !!mx * 3, y - !!my * 3, w, h);
ref_v = s->edge_emu_buffer + !!my * 3 * 80 + !!mx * 3;
mc[!!mx][!!my](dst_v, ref_v, dst_stride, 80, bh, mx, my);
} else {
mc[!!mx][!!my](dst_u, ref_u, dst_stride, src_stride_u, bh, mx, my);
mc[!!mx][!!my](dst_v, ref_v, dst_stride, src_stride_v, bh, mx, my);
}
}
static int inter_recon(AVCodecContext *avctx)
{
static const uint8_t bwlog_tab[2][N_BS_SIZES] = {
{ 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 },
{ 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 },
};
VP9Context *s = avctx->priv_data;
VP9Block *const b = &s->b;
int row = b->row, col = b->col;
AVFrame *ref1 = s->refs[s->refidx[b->ref[0]]];
AVFrame *ref2 = b->comp ? s->refs[s->refidx[b->ref[1]]] : NULL;
int w = avctx->width, h = avctx->height;
ptrdiff_t ls_y = b->y_stride, ls_uv = b->uv_stride;
if (!ref1->data[0] || (b->comp && !ref2->data[0]))
return AVERROR_INVALIDDATA;
// y inter pred
if (b->bs > BS_8x8) {
if (b->bs == BS_8x4) {
mc_luma_dir(s, s->dsp.mc[3][b->filter][0], b->dst[0], ls_y,
ref1->data[0], ref1->linesize[0],
row << 3, col << 3, &b->mv[0][0], 8, 4, w, h);
mc_luma_dir(s, s->dsp.mc[3][b->filter][0],
b->dst[0] + 4 * ls_y, ls_y,
ref1->data[0], ref1->linesize[0],
(row << 3) + 4, col << 3, &b->mv[2][0], 8, 4, w, h);
if (b->comp) {
mc_luma_dir(s, s->dsp.mc[3][b->filter][1], b->dst[0], ls_y,
ref2->data[0], ref2->linesize[0],
row << 3, col << 3, &b->mv[0][1], 8, 4, w, h);
mc_luma_dir(s, s->dsp.mc[3][b->filter][1],
b->dst[0] + 4 * ls_y, ls_y,
ref2->data[0], ref2->linesize[0],
(row << 3) + 4, col << 3, &b->mv[2][1], 8, 4, w, h);
}
} else if (b->bs == BS_4x8) {
mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0], ls_y,
ref1->data[0], ref1->linesize[0],
row << 3, col << 3, &b->mv[0][0], 4, 8, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0] + 4, ls_y,
ref1->data[0], ref1->linesize[0],
row << 3, (col << 3) + 4, &b->mv[1][0], 4, 8, w, h);
if (b->comp) {
mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0], ls_y,
ref2->data[0], ref2->linesize[0],
row << 3, col << 3, &b->mv[0][1], 4, 8, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0] + 4, ls_y,
ref2->data[0], ref2->linesize[0],
row << 3, (col << 3) + 4, &b->mv[1][1], 4, 8, w, h);
}
} else {
av_assert2(b->bs == BS_4x4);
// FIXME if two horizontally adjacent blocks have the same MV,
// do a w8 instead of a w4 call
mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0], ls_y,
ref1->data[0], ref1->linesize[0],
row << 3, col << 3, &b->mv[0][0], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0] + 4, ls_y,
ref1->data[0], ref1->linesize[0],
row << 3, (col << 3) + 4, &b->mv[1][0], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][0],
b->dst[0] + 4 * ls_y, ls_y,
ref1->data[0], ref1->linesize[0],
(row << 3) + 4, col << 3, &b->mv[2][0], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][0],
b->dst[0] + 4 * ls_y + 4, ls_y,
ref1->data[0], ref1->linesize[0],
(row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, w, h);
if (b->comp) {
mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0], ls_y,
ref2->data[0], ref2->linesize[0],
row << 3, col << 3, &b->mv[0][1], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0] + 4, ls_y,
ref2->data[0], ref2->linesize[0],
row << 3, (col << 3) + 4, &b->mv[1][1], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][1],
b->dst[0] + 4 * ls_y, ls_y,
ref2->data[0], ref2->linesize[0],
(row << 3) + 4, col << 3, &b->mv[2][1], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][1],
b->dst[0] + 4 * ls_y + 4, ls_y,
ref2->data[0], ref2->linesize[0],
(row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, w, h);
}
}
} else {
int bwl = bwlog_tab[0][b->bs];
int bw = bwh_tab[0][b->bs][0] * 4;
int bh = bwh_tab[0][b->bs][1] * 4;
mc_luma_dir(s, s->dsp.mc[bwl][b->filter][0], b->dst[0], ls_y,
ref1->data[0], ref1->linesize[0],
row << 3, col << 3, &b->mv[0][0], bw, bh, w, h);
if (b->comp)
mc_luma_dir(s, s->dsp.mc[bwl][b->filter][1], b->dst[0], ls_y,
ref2->data[0], ref2->linesize[0],
row << 3, col << 3, &b->mv[0][1], bw, bh, w, h);
}
// uv inter pred
{
int bwl = bwlog_tab[1][b->bs];
int bw = bwh_tab[1][b->bs][0] * 4, bh = bwh_tab[1][b->bs][1] * 4;
VP56mv mvuv;
w = (w + 1) >> 1;
h = (h + 1) >> 1;
if (b->bs > BS_8x8) {
mvuv.x = ROUNDED_DIV(b->mv[0][0].x + b->mv[1][0].x +
b->mv[2][0].x + b->mv[3][0].x, 4);
mvuv.y = ROUNDED_DIV(b->mv[0][0].y + b->mv[1][0].y +
b->mv[2][0].y + b->mv[3][0].y, 4);
} else {
mvuv = b->mv[0][0];
}
mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][0],
b->dst[1], b->dst[2], ls_uv,
ref1->data[1], ref1->linesize[1],
ref1->data[2], ref1->linesize[2],
row << 2, col << 2, &mvuv, bw, bh, w, h);
if (b->comp) {
if (b->bs > BS_8x8) {
mvuv.x = ROUNDED_DIV(b->mv[0][1].x + b->mv[1][1].x +
b->mv[2][1].x + b->mv[3][1].x, 4);
mvuv.y = ROUNDED_DIV(b->mv[0][1].y + b->mv[1][1].y +
b->mv[2][1].y + b->mv[3][1].y, 4);
} else {
mvuv = b->mv[0][1];
}
mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][1],
b->dst[1], b->dst[2], ls_uv,
ref2->data[1], ref2->linesize[1],
ref2->data[2], ref2->linesize[2],
row << 2, col << 2, &mvuv, bw, bh, w, h);
}
}
if (!b->skip) {
/* mostly copied intra_reconn() */
int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n;
int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2);
int end_x = FFMIN(2 * (s->cols - col), w4);
int end_y = FFMIN(2 * (s->rows - row), h4);
int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless;
int uvstep1d = 1 << b->uvtx, p;
uint8_t *dst = b->dst[0];
// y itxfm add
for (n = 0, y = 0; y < end_y; y += step1d) {
uint8_t *ptr = dst;
for (x = 0; x < end_x; x += step1d, ptr += 4 * step1d, n += step) {
int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
if (eob)
s->dsp.itxfm_add[tx][DCT_DCT](ptr, b->y_stride,
s->block + 16 * n, eob);
}
dst += 4 * b->y_stride * step1d;
}
// uv itxfm add
h4 >>= 1;
w4 >>= 1;
end_x >>= 1;
end_y >>= 1;
step = 1 << (b->uvtx * 2);
for (p = 0; p < 2; p++) {
dst = b->dst[p + 1];
for (n = 0, y = 0; y < end_y; y += uvstep1d) {
uint8_t *ptr = dst;
for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d, n += step) {
int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n])
: s->uveob[p][n];
if (eob)
s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, b->uv_stride,
s->uvblock[p] + 16 * n, eob);
}
dst += 4 * uvstep1d * b->uv_stride;
}
}
}
return 0;
}
static av_always_inline void mask_edges(VP9Filter *lflvl, int is_uv,
int row_and_7, int col_and_7,
int w, int h, int col_end, int row_end,
enum TxfmMode tx, int skip_inter)
{
// FIXME I'm pretty sure all loops can be replaced by a single LUT if
// we make VP9Filter.mask uint64_t (i.e. row/col all single variable)
// and make the LUT 5-indexed (bl, bp, is_uv, tx and row/col), and then
// use row_and_7/col_and_7 as shifts (1*col_and_7+8*row_and_7)
// the intended behaviour of the vp9 loopfilter is to work on 8-pixel
// edges. This means that for UV, we work on two subsampled blocks at
// a time, and we only use the topleft block's mode information to set
// things like block strength. Thus, for any block size smaller than
// 16x16, ignore the odd portion of the block.
if (tx == TX_4X4 && is_uv) {
if (h == 1) {
if (row_and_7 & 1)
return;
if (!row_end)
h += 1;
}
if (w == 1) {
if (col_and_7 & 1)
return;
if (!col_end)
w += 1;
}
}
if (tx == TX_4X4 && !skip_inter) {
int t = 1 << col_and_7, m_col = (t << w) - t, y;
int m_col_odd = (t << (w - 1)) - t;
// on 32-px edges, use the 8-px wide loopfilter; else, use 4-px wide
if (is_uv) {
int m_row_8 = m_col & 0x01, m_row_4 = m_col - m_row_8;
for (y = row_and_7; y < h + row_and_7; y++) {
int col_mask_id = 2 - !(y & 7);
lflvl->mask[is_uv][0][y][1] |= m_row_8;
lflvl->mask[is_uv][0][y][2] |= m_row_4;
// for odd lines, if the odd col is not being filtered,
// skip odd row also:
// .---. <-- a
// | |
// |___| <-- b
// ^ ^
// c d
//
// if a/c are even row/col and b/d are odd, and d is skipped,
// e.g. right edge of size-66x66.webm, then skip b also (bug)
if ((col_end & 1) && (y & 1)) {
lflvl->mask[is_uv][1][y][col_mask_id] |= m_col_odd;
} else {
lflvl->mask[is_uv][1][y][col_mask_id] |= m_col;
}
}
} else {
int m_row_8 = m_col & 0x11, m_row_4 = m_col - m_row_8;
for (y = row_and_7; y < h + row_and_7; y++) {
int col_mask_id = 2 - !(y & 3);
lflvl->mask[is_uv][0][y][1] |= m_row_8; // row edge
lflvl->mask[is_uv][0][y][2] |= m_row_4;
lflvl->mask[is_uv][1][y][col_mask_id] |= m_col; // col edge
lflvl->mask[is_uv][0][y][3] |= m_col;
lflvl->mask[is_uv][1][y][3] |= m_col;
}
}
} else {
int y, t = 1 << col_and_7, m_col = (t << w) - t;
if (!skip_inter) {
int mask_id = (tx == TX_8X8);
int l2 = tx + is_uv - 1, step1d = 1 << l2;
static const unsigned masks[4] = { 0xff, 0x55, 0x11, 0x01 };
int m_row = m_col & masks[l2];
// at odd UV col/row edges tx16/tx32 loopfilter edges, force
// 8wd loopfilter to prevent going off the visible edge.
if (is_uv && tx > TX_8X8 && (w ^ (w - 1)) == 1) {
int m_row_16 = ((t << (w - 1)) - t) & masks[l2];
int m_row_8 = m_row - m_row_16;
for (y = row_and_7; y < h + row_and_7; y++) {
lflvl->mask[is_uv][0][y][0] |= m_row_16;
lflvl->mask[is_uv][0][y][1] |= m_row_8;
}
} else {
for (y = row_and_7; y < h + row_and_7; y++)
lflvl->mask[is_uv][0][y][mask_id] |= m_row;
}
if (is_uv && tx > TX_8X8 && (h ^ (h - 1)) == 1) {
for (y = row_and_7; y < h + row_and_7 - 1; y += step1d)
lflvl->mask[is_uv][1][y][0] |= m_col;
if (y - row_and_7 == h - 1)
lflvl->mask[is_uv][1][y][1] |= m_col;
} else {
for (y = row_and_7; y < h + row_and_7; y += step1d)
lflvl->mask[is_uv][1][y][mask_id] |= m_col;
}
} else if (tx != TX_4X4) {
int mask_id;
mask_id = (tx == TX_8X8) || (is_uv && h == 1);
lflvl->mask[is_uv][1][row_and_7][mask_id] |= m_col;
mask_id = (tx == TX_8X8) || (is_uv && w == 1);
for (y = row_and_7; y < h + row_and_7; y++)
lflvl->mask[is_uv][0][y][mask_id] |= t;
} else if (is_uv) {
int t8 = t & 0x01, t4 = t - t8;
for (y = row_and_7; y < h + row_and_7; y++) {
lflvl->mask[is_uv][0][y][2] |= t4;
lflvl->mask[is_uv][0][y][1] |= t8;
}
lflvl->mask[is_uv][1][row_and_7][2 - !(row_and_7 & 7)] |= m_col;
} else {
int t8 = t & 0x11, t4 = t - t8;
for (y = row_and_7; y < h + row_and_7; y++) {
lflvl->mask[is_uv][0][y][2] |= t4;
lflvl->mask[is_uv][0][y][1] |= t8;
}
lflvl->mask[is_uv][1][row_and_7][2 - !(row_and_7 & 3)] |= m_col;
}
}
}
int ff_vp9_decode_block(AVCodecContext *avctx, int row, int col,
VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff,
enum BlockLevel bl, enum BlockPartition bp)
{
VP9Context *s = avctx->priv_data;
VP9Block *const b = &s->b;
enum BlockSize bs = bl * 3 + bp;
int ret, y, w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl;
int emu[2];
b->row = row;
b->row7 = row & 7;
b->col = col;
b->col7 = col & 7;
s->min_mv.x = -(128 + col * 64);
s->min_mv.y = -(128 + row * 64);
s->max_mv.x = 128 + (s->cols - col - w4) * 64;
s->max_mv.y = 128 + (s->rows - row - h4) * 64;
b->bs = bs;
decode_mode(s, b);
b->uvtx = b->tx - (w4 * 2 == (1 << b->tx) || h4 * 2 == (1 << b->tx));
if (!b->skip) {
if ((ret = decode_coeffs(avctx)) < 0)
return ret;
} else {
int pl;
memset(&s->above_y_nnz_ctx[col * 2], 0, w4 * 2);
memset(&s->left_y_nnz_ctx[(row & 7) << 1], 0, h4 * 2);
for (pl = 0; pl < 2; pl++) {
memset(&s->above_uv_nnz_ctx[pl][col], 0, w4);
memset(&s->left_uv_nnz_ctx[pl][row & 7], 0, h4);
}
}
/* Emulated overhangs if the stride of the target buffer can't hold.
* This allows to support emu-edge and so on even if we have large
* block overhangs. */
emu[0] = (col + w4) * 8 > s->cur_frame->linesize[0] ||
(row + h4) > s->rows + 2 * !(avctx->flags & CODEC_FLAG_EMU_EDGE);
emu[1] = (col + w4) * 4 > s->cur_frame->linesize[1] ||
(row + h4) > s->rows + 2 * !(avctx->flags & CODEC_FLAG_EMU_EDGE);
if (emu[0]) {
b->dst[0] = s->tmp_y;
b->y_stride = 64;
} else {
b->dst[0] = s->cur_frame->data[0] + yoff;
b->y_stride = s->cur_frame->linesize[0];
}
if (emu[1]) {
b->dst[1] = s->tmp_uv[0];
b->dst[2] = s->tmp_uv[1];
b->uv_stride = 32;
} else {
b->dst[1] = s->cur_frame->data[1] + uvoff;
b->dst[2] = s->cur_frame->data[2] + uvoff;
b->uv_stride = s->cur_frame->linesize[1];
}
if (b->intra) {
intra_recon(avctx, yoff, uvoff);
} else {
if ((ret = inter_recon(avctx)) < 0)
return ret;
}
if (emu[0]) {
int w = FFMIN(s->cols - col, w4) * 8;
int h = FFMIN(s->rows - row, h4) * 8;
int n, o = 0;
for (n = 0; o < w; n++) {
int bw = 64 >> n;
av_assert2(n <= 4);
if (w & bw) {
s->dsp.mc[n][0][0][0][0](s->cur_frame->data[0] + yoff + o,
s->tmp_y + o,
s->cur_frame->linesize[0],
64, h, 0, 0);
o += bw;
}
}
}
if (emu[1]) {
int w = FFMIN(s->cols - col, w4) * 4;
int h = FFMIN(s->rows - row, h4) * 4;
int n, o = 0;
for (n = 1; o < w; n++) {
int bw = 64 >> n;
av_assert2(n <= 4);
if (w & bw) {
s->dsp.mc[n][0][0][0][0](s->cur_frame->data[1] + uvoff + o,
s->tmp_uv[0] + o,
s->cur_frame->linesize[1],
32, h, 0, 0);
s->dsp.mc[n][0][0][0][0](s->cur_frame->data[2] + uvoff + o,
s->tmp_uv[1] + o,
s->cur_frame->linesize[2],
32, h, 0, 0);
o += bw;
}
}
}
// pick filter level and find edges to apply filter to
if (s->filter.level &&
(lvl = s->segmentation.feat[b->seg_id].lflvl[b->intra ? 0 : b->ref[0] + 1]
[b->mode[3] != ZEROMV]) > 0) {
int x_end = FFMIN(s->cols - col, w4);
int y_end = FFMIN(s->rows - row, h4);
int skip_inter = !b->intra && b->skip;
for (y = 0; y < h4; y++)
memset(&lflvl->level[((row & 7) + y) * 8 + (col & 7)], lvl, w4);
mask_edges(lflvl, 0, row & 7, col & 7, x_end, y_end, 0, 0, b->tx, skip_inter);
mask_edges(lflvl, 1, row & 7, col & 7, x_end, y_end,
s->cols & 1 && col + w4 >= s->cols ? s->cols & 7 : 0,
s->rows & 1 && row + h4 >= s->rows ? s->rows & 7 : 0,
b->uvtx, skip_inter);
if (!s->filter.lim_lut[lvl]) {
int sharp = s->filter.sharpness;
int limit = lvl;
if (sharp > 0) {
limit >>= (sharp + 3) >> 2;
limit = FFMIN(limit, 9 - sharp);
}
limit = FFMAX(limit, 1);
s->filter.lim_lut[lvl] = limit;
s->filter.mblim_lut[lvl] = 2 * (lvl + 2) + limit;
}
}
return 0;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
* Copyright (C) 2013 Clément Bœsch <u pkh me>
*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_VP9DATA_H
#define AVCODEC_VP9DATA_H
#include <stdint.h>
#include "vp9.h"
extern const int8_t ff_vp9_partition_tree[3][2];
extern const uint8_t ff_vp9_default_kf_partition_probs[4][4][3];
extern const int8_t ff_vp9_segmentation_tree[7][2];
extern const int8_t ff_vp9_intramode_tree[9][2];
extern const uint8_t ff_vp9_default_kf_ymode_probs[10][10][9];
extern const uint8_t ff_vp9_default_kf_uvmode_probs[10][9];
extern const int8_t ff_vp9_inter_mode_tree[3][2];
extern const int8_t ff_vp9_filter_tree[2][2];
extern const enum FilterMode ff_vp9_filter_lut[3];
extern const int16_t ff_vp9_dc_qlookup[256];
extern const int16_t ff_vp9_ac_qlookup[256];
extern const enum TxfmType ff_vp9_intra_txfm_type[14];
extern const int16_t ff_vp9_default_scan_4x4[16];
extern const int16_t ff_vp9_col_scan_4x4[16];
extern const int16_t ff_vp9_row_scan_4x4[16];
extern const int16_t ff_vp9_default_scan_8x8[64];
extern const int16_t ff_vp9_col_scan_8x8[64];
extern const int16_t ff_vp9_row_scan_8x8[64];
extern const int16_t ff_vp9_default_scan_16x16[256];
extern const int16_t ff_vp9_col_scan_16x16[256];
extern const int16_t ff_vp9_row_scan_16x16[256];
extern const int16_t ff_vp9_default_scan_32x32[1024];
extern const int16_t *ff_vp9_scans[5][4];
extern const int16_t ff_vp9_default_scan_4x4_nb[16][2];
extern const int16_t ff_vp9_col_scan_4x4_nb[16][2];
extern const int16_t ff_vp9_row_scan_4x4_nb[16][2];
extern const int16_t ff_vp9_default_scan_8x8_nb[64][2];
extern const int16_t ff_vp9_col_scan_8x8_nb[64][2];
extern const int16_t ff_vp9_row_scan_8x8_nb[64][2];
extern const int16_t ff_vp9_default_scan_16x16_nb[256][2];
extern const int16_t ff_vp9_col_scan_16x16_nb[256][2];
extern const int16_t ff_vp9_row_scan_16x16_nb[256][2];
extern const int16_t ff_vp9_default_scan_32x32_nb[1024][2];
extern const int16_t (*ff_vp9_scans_nb[5][4])[2];
extern const uint8_t ff_vp9_model_pareto8[256][8];
extern const ProbContext ff_vp9_default_probs;
extern const uint8_t ff_vp9_default_coef_probs[4][2][2][6][6][3];
extern const int8_t ff_vp9_mv_joint_tree[3][2];
extern const int8_t ff_vp9_mv_class_tree[10][2];
extern const int8_t ff_vp9_mv_fp_tree[3][2];
#endif /* AVCODEC_VP9DATA_H */
/*
* VP9 compatible video decoder
*
* Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
* Copyright (C) 2013 Clément Bœsch <u pkh me>
*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/common.h"
#include "libavutil/intreadwrite.h"
#include "rnd_avg.h"
#include "vp9.h"
// FIXME see whether we can merge parts of this (perhaps at least 4x4 and 8x8)
// back with h264pred.[ch]
static void vert_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
unsigned p4 = AV_RN32A(top);
AV_WN32A(dst + stride * 0, p4);
AV_WN32A(dst + stride * 1, p4);
AV_WN32A(dst + stride * 2, p4);
AV_WN32A(dst + stride * 3, p4);
}
static void vert_8x8_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
uint64_t p8 = AV_RN64A(top);
int y;
for (y = 0; y < 8; y++) {
AV_WN64A(dst, p8);
dst += stride;
}
}
static void vert_16x16_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
uint64_t p8a = AV_RN64A(top + 0), p8b = AV_RN64A(top + 8);
int y;
for (y = 0; y < 16; y++) {
AV_WN64A(dst + 0, p8a);
AV_WN64A(dst + 8, p8b);
dst += stride;
}
}
static void vert_32x32_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
uint64_t p8a = AV_RN64A(top + 0), p8b = AV_RN64A(top + 8),
p8c = AV_RN64A(top + 16), p8d = AV_RN64A(top + 24);
int y;
for (y = 0; y < 32; y++) {
AV_WN64A(dst + 0, p8a);
AV_WN64A(dst + 8, p8b);
AV_WN64A(dst + 16, p8c);
AV_WN64A(dst + 24, p8d);
dst += stride;
}
}
static void hor_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
AV_WN32A(dst + stride * 0, left[0] * 0x01010101U);
AV_WN32A(dst + stride * 1, left[1] * 0x01010101U);
AV_WN32A(dst + stride * 2, left[2] * 0x01010101U);
AV_WN32A(dst + stride * 3, left[3] * 0x01010101U);
}
static void hor_8x8_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y;
for (y = 0; y < 8; y++) {
AV_WN64A(dst, left[y] * 0x0101010101010101ULL);
dst += stride;
}
}
static void hor_16x16_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y;
for (y = 0; y < 16; y++) {
uint64_t p8 = left[y] * 0x0101010101010101ULL;
AV_WN64A(dst + 0, p8);
AV_WN64A(dst + 8, p8);
dst += stride;
}
}
static void hor_32x32_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y;
for (y = 0; y < 32; y++) {
uint64_t p8 = left[y] * 0x0101010101010101ULL;
AV_WN64A(dst + 0, p8);
AV_WN64A(dst + 8, p8);
AV_WN64A(dst + 16, p8);
AV_WN64A(dst + 24, p8);
dst += stride;
}
}
static void tm_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y, tl = top[-1];
for (y = 0; y < 4; y++) {
int l_m_tl = left[y] - tl;
dst[0] = av_clip_uint8(top[0] + l_m_tl);
dst[1] = av_clip_uint8(top[1] + l_m_tl);
dst[2] = av_clip_uint8(top[2] + l_m_tl);
dst[3] = av_clip_uint8(top[3] + l_m_tl);
dst += stride;
}
}
static void tm_8x8_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y, tl = top[-1];
for (y = 0; y < 8; y++) {
int l_m_tl = left[y] - tl;
dst[0] = av_clip_uint8(top[0] + l_m_tl);
dst[1] = av_clip_uint8(top[1] + l_m_tl);
dst[2] = av_clip_uint8(top[2] + l_m_tl);
dst[3] = av_clip_uint8(top[3] + l_m_tl);
dst[4] = av_clip_uint8(top[4] + l_m_tl);
dst[5] = av_clip_uint8(top[5] + l_m_tl);
dst[6] = av_clip_uint8(top[6] + l_m_tl);
dst[7] = av_clip_uint8(top[7] + l_m_tl);
dst += stride;
}
}
static void tm_16x16_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y, tl = top[-1];
for (y = 0; y < 16; y++) {
int l_m_tl = left[y] - tl;
dst[0] = av_clip_uint8(top[0] + l_m_tl);
dst[1] = av_clip_uint8(top[1] + l_m_tl);
dst[2] = av_clip_uint8(top[2] + l_m_tl);
dst[3] = av_clip_uint8(top[3] + l_m_tl);
dst[4] = av_clip_uint8(top[4] + l_m_tl);
dst[5] = av_clip_uint8(top[5] + l_m_tl);
dst[6] = av_clip_uint8(top[6] + l_m_tl);
dst[7] = av_clip_uint8(top[7] + l_m_tl);
dst[8] = av_clip_uint8(top[8] + l_m_tl);
dst[9] = av_clip_uint8(top[9] + l_m_tl);
dst[10] = av_clip_uint8(top[10] + l_m_tl);
dst[11] = av_clip_uint8(top[11] + l_m_tl);
dst[12] = av_clip_uint8(top[12] + l_m_tl);
dst[13] = av_clip_uint8(top[13] + l_m_tl);
dst[14] = av_clip_uint8(top[14] + l_m_tl);
dst[15] = av_clip_uint8(top[15] + l_m_tl);
dst += stride;
}
}
static void tm_32x32_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y, tl = top[-1];
for (y = 0; y < 32; y++) {
int l_m_tl = left[y] - tl;
dst[0] = av_clip_uint8(top[0] + l_m_tl);
dst[1] = av_clip_uint8(top[1] + l_m_tl);
dst[2] = av_clip_uint8(top[2] + l_m_tl);
dst[3] = av_clip_uint8(top[3] + l_m_tl);
dst[4] = av_clip_uint8(top[4] + l_m_tl);
dst[5] = av_clip_uint8(top[5] + l_m_tl);
dst[6] = av_clip_uint8(top[6] + l_m_tl);
dst[7] = av_clip_uint8(top[7] + l_m_tl);
dst[8] = av_clip_uint8(top[8] + l_m_tl);
dst[9] = av_clip_uint8(top[9] + l_m_tl);
dst[10] = av_clip_uint8(top[10] + l_m_tl);
dst[11] = av_clip_uint8(top[11] + l_m_tl);
dst[12] = av_clip_uint8(top[12] + l_m_tl);
dst[13] = av_clip_uint8(top[13] + l_m_tl);
dst[14] = av_clip_uint8(top[14] + l_m_tl);
dst[15] = av_clip_uint8(top[15] + l_m_tl);
dst[16] = av_clip_uint8(top[16] + l_m_tl);
dst[17] = av_clip_uint8(top[17] + l_m_tl);
dst[18] = av_clip_uint8(top[18] + l_m_tl);
dst[19] = av_clip_uint8(top[19] + l_m_tl);
dst[20] = av_clip_uint8(top[20] + l_m_tl);
dst[21] = av_clip_uint8(top[21] + l_m_tl);
dst[22] = av_clip_uint8(top[22] + l_m_tl);
dst[23] = av_clip_uint8(top[23] + l_m_tl);
dst[24] = av_clip_uint8(top[24] + l_m_tl);
dst[25] = av_clip_uint8(top[25] + l_m_tl);
dst[26] = av_clip_uint8(top[26] + l_m_tl);
dst[27] = av_clip_uint8(top[27] + l_m_tl);
dst[28] = av_clip_uint8(top[28] + l_m_tl);
dst[29] = av_clip_uint8(top[29] + l_m_tl);
dst[30] = av_clip_uint8(top[30] + l_m_tl);
dst[31] = av_clip_uint8(top[31] + l_m_tl);
dst += stride;
}
}
static void dc_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
unsigned dc = 0x01010101U *
((left[0] + left[1] + left[2] + left[3] +
top[0] + top[1] + top[2] + top[3] + 4) >> 3);
AV_WN32A(dst + stride * 0, dc);
AV_WN32A(dst + stride * 1, dc);
AV_WN32A(dst + stride * 2, dc);
AV_WN32A(dst + stride * 3, dc);
}
static void dc_8x8_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
uint64_t dc = 0x0101010101010101ULL *
((left[0] + left[1] + left[2] + left[3] +
left[4] + left[5] + left[6] + left[7] +
top[0] + top[1] + top[2] + top[3] +
top[4] + top[5] + top[6] + top[7] + 8) >> 4);
int y;
for (y = 0; y < 8; y++) {
AV_WN64A(dst, dc);
dst += stride;
}
}
static void dc_16x16_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
uint64_t dc = 0x0101010101010101ULL *
((left[0] + left[1] + left[2] + left[3] +
left[4] + left[5] + left[6] + left[7] +
left[8] + left[9] + left[10] + left[11] +
left[12] + left[13] + left[14] + left[15] +
top[0] + top[1] + top[2] + top[3] +
top[4] + top[5] + top[6] + top[7] +
top[8] + top[9] + top[10] + top[11] +
top[12] + top[13] + top[14] + top[15] + 16) >> 5);
int y;
for (y = 0; y < 16; y++) {
AV_WN64A(dst + 0, dc);
AV_WN64A(dst + 8, dc);
dst += stride;
}
}
static void dc_32x32_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
uint64_t dc = 0x0101010101010101ULL *
((left[0] + left[1] + left[2] + left[3] +
left[4] + left[5] + left[6] + left[7] +
left[8] + left[9] + left[10] + left[11] +
left[12] + left[13] + left[14] + left[15] +
left[16] + left[17] + left[18] + left[19] +
left[20] + left[21] + left[22] + left[23] +
left[24] + left[25] + left[26] + left[27] +
left[28] + left[29] + left[30] + left[31] +
top[0] + top[1] + top[2] + top[3] +
top[4] + top[5] + top[6] + top[7] +
top[8] + top[9] + top[10] + top[11] +
top[12] + top[13] + top[14] + top[15] +
top[16] + top[17] + top[18] + top[19] +
top[20] + top[21] + top[22] + top[23] +
top[24] + top[25] + top[26] + top[27] +
top[28] + top[29] + top[30] + top[31] + 32) >> 6);
int y;
for (y = 0; y < 32; y++) {
AV_WN64A(dst + 0, dc);
AV_WN64A(dst + 8, dc);
AV_WN64A(dst + 16, dc);
AV_WN64A(dst + 24, dc);
dst += stride;
}
}
static void dc_left_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
unsigned dc = 0x01010101U *
((left[0] + left[1] + left[2] + left[3] + 2) >> 2);
AV_WN32A(dst + stride * 0, dc);
AV_WN32A(dst + stride * 1, dc);
AV_WN32A(dst + stride * 2, dc);
AV_WN32A(dst + stride * 3, dc);
}
static void dc_left_8x8_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
uint64_t dc = 0x0101010101010101ULL *
((left[0] + left[1] + left[2] + left[3] +
left[4] + left[5] + left[6] + left[7] + 4) >> 3);
int y;
for (y = 0; y < 8; y++) {
AV_WN64A(dst, dc);
dst += stride;
}
}
static void dc_left_16x16_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
uint64_t dc = 0x0101010101010101ULL *
((left[0] + left[1] + left[2] + left[3] +
left[4] + left[5] + left[6] + left[7] +
left[8] + left[9] + left[10] + left[11] +
left[12] + left[13] + left[14] + left[15] + 8) >> 4);
int y;
for (y = 0; y < 16; y++) {
AV_WN64A(dst + 0, dc);
AV_WN64A(dst + 8, dc);
dst += stride;
}
}
static void dc_left_32x32_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
uint64_t dc = 0x0101010101010101ULL *
((left[0] + left[1] + left[2] + left[3] +
left[4] + left[5] + left[6] + left[7] +
left[8] + left[9] + left[10] + left[11] +
left[12] + left[13] + left[14] + left[15] +
left[16] + left[17] + left[18] + left[19] +
left[20] + left[21] + left[22] + left[23] +
left[24] + left[25] + left[26] + left[27] +
left[28] + left[29] + left[30] + left[31] + 16) >> 5);
int y;
for (y = 0; y < 32; y++) {
AV_WN64A(dst + 0, dc);
AV_WN64A(dst + 8, dc);
AV_WN64A(dst + 16, dc);
AV_WN64A(dst + 24, dc);
dst += stride;
}
}
static void dc_top_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
unsigned dc = 0x01010101U * ((top[0] + top[1] + top[2] + top[3] + 2) >> 2);
AV_WN32A(dst + stride * 0, dc);
AV_WN32A(dst + stride * 1, dc);
AV_WN32A(dst + stride * 2, dc);
AV_WN32A(dst + stride * 3, dc);
}
static void dc_top_8x8_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
uint64_t dc = 0x0101010101010101ULL *
((top[0] + top[1] + top[2] + top[3] +
top[4] + top[5] + top[6] + top[7] + 4) >> 3);
int y;
for (y = 0; y < 8; y++) {
AV_WN64A(dst, dc);
dst += stride;
}
}
static void dc_top_16x16_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
uint64_t dc = 0x0101010101010101ULL *
((top[0] + top[1] + top[2] + top[3] +
top[4] + top[5] + top[6] + top[7] +
top[8] + top[9] + top[10] + top[11] +
top[12] + top[13] + top[14] + top[15] + 8) >> 4);
int y;
for (y = 0; y < 16; y++) {
AV_WN64A(dst + 0, dc);
AV_WN64A(dst + 8, dc);
dst += stride;
}
}
static void dc_top_32x32_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
uint64_t dc = 0x0101010101010101ULL *
((top[0] + top[1] + top[2] + top[3] +
top[4] + top[5] + top[6] + top[7] +
top[8] + top[9] + top[10] + top[11] +
top[12] + top[13] + top[14] + top[15] +
top[16] + top[17] + top[18] + top[19] +
top[20] + top[21] + top[22] + top[23] +
top[24] + top[25] + top[26] + top[27] +
top[28] + top[29] + top[30] + top[31] + 16) >> 5);
int y;
for (y = 0; y < 32; y++) {
AV_WN64A(dst + 0, dc);
AV_WN64A(dst + 8, dc);
AV_WN64A(dst + 16, dc);
AV_WN64A(dst + 24, dc);
dst += stride;
}
}
static void dc_128_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
AV_WN32A(dst + stride * 0, 0x80808080U);
AV_WN32A(dst + stride * 1, 0x80808080U);
AV_WN32A(dst + stride * 2, 0x80808080U);
AV_WN32A(dst + stride * 3, 0x80808080U);
}
static void dc_128_8x8_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y;
for (y = 0; y < 8; y++) {
AV_WN64A(dst, 0x8080808080808080ULL);
dst += stride;
}
}
static void dc_128_16x16_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y;
for (y = 0; y < 16; y++) {
AV_WN64A(dst + 0, 0x8080808080808080ULL);
AV_WN64A(dst + 8, 0x8080808080808080ULL);
dst += stride;
}
}
static void dc_128_32x32_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y;
for (y = 0; y < 32; y++) {
AV_WN64A(dst + 0, 0x8080808080808080ULL);
AV_WN64A(dst + 8, 0x8080808080808080ULL);
AV_WN64A(dst + 16, 0x8080808080808080ULL);
AV_WN64A(dst + 24, 0x8080808080808080ULL);
dst += stride;
}
}
static void dc_127_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
AV_WN32A(dst + stride * 0, 0x7F7F7F7FU);
AV_WN32A(dst + stride * 1, 0x7F7F7F7FU);
AV_WN32A(dst + stride * 2, 0x7F7F7F7FU);
AV_WN32A(dst + stride * 3, 0x7F7F7F7FU);
}
static void dc_127_8x8_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y;
for (y = 0; y < 8; y++) {
AV_WN64A(dst, 0x7F7F7F7F7F7F7F7FULL);
dst += stride;
}
}
static void dc_127_16x16_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y;
for (y = 0; y < 16; y++) {
AV_WN64A(dst + 0, 0x7F7F7F7F7F7F7F7FULL);
AV_WN64A(dst + 8, 0x7F7F7F7F7F7F7F7FULL);
dst += stride;
}
}
static void dc_127_32x32_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y;
for (y = 0; y < 32; y++) {
AV_WN64A(dst + 0, 0x7F7F7F7F7F7F7F7FULL);
AV_WN64A(dst + 8, 0x7F7F7F7F7F7F7F7FULL);
AV_WN64A(dst + 16, 0x7F7F7F7F7F7F7F7FULL);
AV_WN64A(dst + 24, 0x7F7F7F7F7F7F7F7FULL);
dst += stride;
}
}
static void dc_129_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
AV_WN32A(dst + stride * 0, 0x81818181U);
AV_WN32A(dst + stride * 1, 0x81818181U);
AV_WN32A(dst + stride * 2, 0x81818181U);
AV_WN32A(dst + stride * 3, 0x81818181U);
}
static void dc_129_8x8_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y;
for (y = 0; y < 8; y++) {
AV_WN64A(dst, 0x8181818181818181ULL);
dst += stride;
}
}
static void dc_129_16x16_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y;
for (y = 0; y < 16; y++) {
AV_WN64A(dst + 0, 0x8181818181818181ULL);
AV_WN64A(dst + 8, 0x8181818181818181ULL);
dst += stride;
}
}
static void dc_129_32x32_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int y;
for (y = 0; y < 32; y++) {
AV_WN64A(dst + 0, 0x8181818181818181ULL);
AV_WN64A(dst + 8, 0x8181818181818181ULL);
AV_WN64A(dst + 16, 0x8181818181818181ULL);
AV_WN64A(dst + 24, 0x8181818181818181ULL);
dst += stride;
}
}
#define DST(x, y) dst[(x) + (y) * stride]
static void diag_downleft_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int a0 = top[0], a1 = top[1], a2 = top[2], a3 = top[3],
a4 = top[4], a5 = top[5], a6 = top[6], a7 = top[7];
DST(0, 0) = (a0 + a1 * 2 + a2 + 2) >> 2;
DST(1, 0) =
DST(0, 1) = (a1 + a2 * 2 + a3 + 2) >> 2;
DST(2, 0) =
DST(1, 1) =
DST(0, 2) = (a2 + a3 * 2 + a4 + 2) >> 2;
DST(3, 0) =
DST(2, 1) =
DST(1, 2) =
DST(0, 3) = (a3 + a4 * 2 + a5 + 2) >> 2;
DST(3, 1) =
DST(2, 2) =
DST(1, 3) = (a4 + a5 * 2 + a6 + 2) >> 2;
DST(3, 2) =
DST(2, 3) = (a5 + a6 * 2 + a7 + 2) >> 2;
DST(3, 3) = a7; // note: this is different from vp8 and such
}
#define def_diag_downleft(size) \
static void diag_downleft_ ## size ## x ## size ## _c(uint8_t *dst, \
ptrdiff_t stride, \
const uint8_t *left, \
const uint8_t *top) \
{ \
int i, j; \
uint8_t v[size - 1]; \
\
for (i = 0; i < size - 2; i++) \
v[i] = (top[i] + top[i + 1] * 2 + top[i + 2] + 2) >> 2; \
v[size - 2] = (top[size - 2] + top[size - 1] * 3 + 2) >> 2; \
\
for (j = 0; j < size; j++) { \
memcpy(dst + j * stride, v + j, size - 1 - j); \
memset(dst + j * stride + size - 1 - j, top[size - 1], j + 1); \
} \
}
def_diag_downleft(8)
def_diag_downleft(16)
def_diag_downleft(32)
static void diag_downright_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int tl = top[-1], a0 = top[0], a1 = top[1], a2 = top[2], a3 = top[3],
l0 = left[0], l1 = left[1], l2 = left[2], l3 = left[3];
DST(0, 3) = (l1 + l2 * 2 + l3 + 2) >> 2;
DST(0, 2) =
DST(1, 3) = (l0 + l1 * 2 + l2 + 2) >> 2;
DST(0, 1) =
DST(1, 2) =
DST(2, 3) = (tl + l0 * 2 + l1 + 2) >> 2;
DST(0, 0) =
DST(1, 1) =
DST(2, 2) =
DST(3, 3) = (l0 + tl * 2 + a0 + 2) >> 2;
DST(1, 0) =
DST(2, 1) =
DST(3, 2) = (tl + a0 * 2 + a1 + 2) >> 2;
DST(2, 0) =
DST(3, 1) = (a0 + a1 * 2 + a2 + 2) >> 2;
DST(3, 0) = (a1 + a2 * 2 + a3 + 2) >> 2;
}
#define def_diag_downright(size) \
static void diag_downright_ ## size ## x ## size ## _c(uint8_t *dst, \
ptrdiff_t stride, \
const uint8_t *left, \
const uint8_t *top) \
{ \
int i, j; \
uint8_t v[size + size - 1]; \
\
for (i = 0; i < size - 2; i++) { \
v[i] = (left[size - 1 - i] + \
left[size - 2 - i] * 2 + \
left[size - 3 - i] + 2) >> 2; \
v[size + 1 + i] = (top[i] + \
top[i + 1] * 2 + \
top[i + 2] + 2) >> 2; \
} \
v[size - 2] = (left[1] + left[0] * 2 + top[-1] + 2) >> 2; \
v[size - 1] = (left[0] + top[-1] * 2 + top[0] + 2) >> 2; \
v[size] = (top[-1] + top[0] * 2 + top[1] + 2) >> 2; \
\
for (j = 0; j < size; j++) \
memcpy(dst + j * stride, v + size - 1 - j, size); \
}
def_diag_downright(8)
def_diag_downright(16)
def_diag_downright(32)
static void vert_right_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int tl = top[-1], a0 = top[0], a1 = top[1], a2 = top[2], a3 = top[3],
l0 = left[0], l1 = left[1], l2 = left[2];
DST(0, 3) = (l0 + l1 * 2 + l2 + 2) >> 2;
DST(0, 2) = (tl + l0 * 2 + l1 + 2) >> 2;
DST(0, 0) =
DST(1, 2) = (tl + a0 + 1) >> 1;
DST(0, 1) =
DST(1, 3) = (l0 + tl * 2 + a0 + 2) >> 2;
DST(1, 0) =
DST(2, 2) = (a0 + a1 + 1) >> 1;
DST(1, 1) =
DST(2, 3) = (tl + a0 * 2 + a1 + 2) >> 2;
DST(2, 0) =
DST(3, 2) = (a1 + a2 + 1) >> 1;
DST(2, 1) =
DST(3, 3) = (a0 + a1 * 2 + a2 + 2) >> 2;
DST(3, 0) = (a2 + a3 + 1) >> 1;
DST(3, 1) = (a1 + a2 * 2 + a3 + 2) >> 2;
}
#define def_vert_right(size) \
static void vert_right_ ## size ## x ## size ## _c(uint8_t *dst, \
ptrdiff_t stride, \
const uint8_t *left, \
const uint8_t *top) \
{ \
int i, j; \
uint8_t ve[size + size / 2 - 1], vo[size + size / 2 - 1]; \
\
for (i = 0; i < size / 2 - 2; i++) { \
vo[i] = (left[size - 4 - i * 2] + \
left[size - 3 - i * 2] * 2 + \
left[size - 2 - i * 2] + 2) >> 2; \
ve[i] = (left[size - 5 - i * 2] + \
left[size - 4 - i * 2] * 2 + \
left[size - 3 - i * 2] + 2) >> 2; \
} \
vo[size / 2 - 2] = (left[0] + left[1] * 2 + left[2] + 2) >> 2; \
ve[size / 2 - 2] = (top[-1] + left[0] * 2 + left[1] + 2) >> 2; \
\
ve[size / 2 - 1] = (top[-1] + top[0] + 1) >> 1; \
vo[size / 2 - 1] = (left[0] + top[-1] * 2 + top[0] + 2) >> 2; \
for (i = 0; i < size - 1; i++) { \
ve[size / 2 + i] = (top[i] + top[i + 1] + 1) >> 1; \
vo[size / 2 + i] = (top[i - 1] + top[i] * 2 + top[i + 1] + 2) >> 2; \
} \
\
for (j = 0; j < size / 2; j++) { \
memcpy(dst + j * 2 * stride, ve + size / 2 - 1 - j, size); \
memcpy(dst + (j * 2 + 1) * stride, vo + size / 2 - 1 - j, size); \
} \
}
def_vert_right(8)
def_vert_right(16)
def_vert_right(32)
static void hor_down_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int l0 = left[0], l1 = left[1], l2 = left[2], l3 = left[3],
tl = top[-1], a0 = top[0], a1 = top[1], a2 = top[2];
DST(2, 0) = (tl + a0 * 2 + a1 + 2) >> 2;
DST(3, 0) = (a0 + a1 * 2 + a2 + 2) >> 2;
DST(0, 0) =
DST(2, 1) = (tl + l0 + 1) >> 1;
DST(1, 0) =
DST(3, 1) = (a0 + tl * 2 + l0 + 2) >> 2;
DST(0, 1) =
DST(2, 2) = (l0 + l1 + 1) >> 1;
DST(1, 1) =
DST(3, 2) = (tl + l0 * 2 + l1 + 2) >> 2;
DST(0, 2) =
DST(2, 3) = (l1 + l2 + 1) >> 1;
DST(1, 2) =
DST(3, 3) = (l0 + l1 * 2 + l2 + 2) >> 2;
DST(0, 3) = (l2 + l3 + 1) >> 1;
DST(1, 3) = (l1 + l2 * 2 + l3 + 2) >> 2;
}
#define def_hor_down(size) \
static void hor_down_ ## size ## x ## size ## _c(uint8_t *dst, \
ptrdiff_t stride, \
const uint8_t *left, \
const uint8_t *top) \
{ \
int i, j; \
uint8_t v[size * 3 - 2]; \
\
for (i = 0; i < size - 2; i++) { \
v[i * 2] = (left[size - 2 - i] + \
left[size - 1 - i] + 1) >> 1; \
v[i * 2 + 1] = (left[size - 3 - i] + \
left[size - 2 - i] * 2 + \
left[size - 1 - i] + 2) >> 2; \
v[size * 2 + i] = (top[i - 1] + \
top[i] * 2 + \
top[i + 1] + 2) >> 2; \
} \
v[size * 2 - 2] = (top[-1] + left[0] + 1) >> 1; \
v[size * 2 - 4] = (left[0] + left[1] + 1) >> 1; \
v[size * 2 - 1] = (top[0] + top[-1] * 2 + left[0] + 2) >> 2; \
v[size * 2 - 3] = (top[-1] + left[0] * 2 + left[1] + 2) >> 2; \
\
for (j = 0; j < size; j++) \
memcpy(dst + j * stride, v + size * 2 - 2 - j * 2, size); \
}
def_hor_down(8)
def_hor_down(16)
def_hor_down(32)
static void vert_left_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int a0 = top[0], a1 = top[1], a2 = top[2], a3 = top[3],
a4 = top[4], a5 = top[5], a6 = top[6];
DST(0, 0) = (a0 + a1 + 1) >> 1;
DST(0, 1) = (a0 + a1 * 2 + a2 + 2) >> 2;
DST(1, 0) =
DST(0, 2) = (a1 + a2 + 1) >> 1;
DST(1, 1) =
DST(0, 3) = (a1 + a2 * 2 + a3 + 2) >> 2;
DST(2, 0) =
DST(1, 2) = (a2 + a3 + 1) >> 1;
DST(2, 1) =
DST(1, 3) = (a2 + a3 * 2 + a4 + 2) >> 2;
DST(3, 0) =
DST(2, 2) = (a3 + a4 + 1) >> 1;
DST(3, 1) =
DST(2, 3) = (a3 + a4 * 2 + a5 + 2) >> 2;
DST(3, 2) = (a4 + a5 + 1) >> 1;
DST(3, 3) = (a4 + a5 * 2 + a6 + 2) >> 2;
}
#define def_vert_left(size) \
static void vert_left_ ## size ## x ## size ## _c(uint8_t *dst, \
ptrdiff_t stride, \
const uint8_t *left, \
const uint8_t *top) \
{ \
int i, j; \
uint8_t ve[size - 1], vo[size - 1]; \
\
for (i = 0; i < size - 2; i++) { \
ve[i] = (top[i] + top[i + 1] + 1) >> 1; \
vo[i] = (top[i] + top[i + 1] * 2 + top[i + 2] + 2) >> 2; \
} \
ve[size - 2] = (top[size - 2] + top[size - 1] + 1) >> 1; \
vo[size - 2] = (top[size - 2] + top[size - 1] * 3 + 2) >> 2; \
\
for (j = 0; j < size / 2; j++) { \
memcpy(dst + j * 2 * stride, ve + j, size - (j + 1)); \
memset(dst + j * 2 * stride + size - j - 1, \
top[size - 1], j + 1); \
memcpy(dst + (j * 2 + 1) * stride, vo + j, size - (j + 1)); \
memset(dst + (j * 2 + 1) * stride + size - j - 1, \
top[size - 1], j + 1); \
} \
}
def_vert_left(8)
def_vert_left(16)
def_vert_left(32)
static void hor_up_4x4_c(uint8_t *dst, ptrdiff_t stride,
const uint8_t *left, const uint8_t *top)
{
int l0 = left[0], l1 = left[1], l2 = left[2], l3 = left[3];
DST(0, 0) = (l0 + l1 + 1) >> 1;
DST(1, 0) = (l0 + l1 * 2 + l2 + 2) >> 2;
DST(0, 1) =
DST(2, 0) = (l1 + l2 + 1) >> 1;
DST(1, 1) =
DST(3, 0) = (l1 + l2 * 2 + l3 + 2) >> 2;
DST(0, 2) =
DST(2, 1) = (l2 + l3 + 1) >> 1;
DST(1, 2) =
DST(3, 1) = (l2 + l3 * 3 + 2) >> 2;
DST(0, 3) =
DST(1, 3) =
DST(2, 2) =
DST(2, 3) =
DST(3, 2) =
DST(3, 3) = l3;
}
#define def_hor_up(size) \
static void hor_up_ ## size ## x ## size ## _c(uint8_t *dst, \
ptrdiff_t stride, \
const uint8_t *left, \
const uint8_t *top) \
{ \
int i, j; \
uint8_t v[size * 2 - 2]; \
\
for (i = 0; i < size - 2; i++) { \
v[i * 2] = (left[i] + left[i + 1] + 1) >> 1; \
v[i * 2 + 1] = (left[i] + left[i + 1] * 2 + left[i + 2] + 2) >> 2; \
} \
v[size * 2 - 4] = (left[size - 2] + left[size - 1] + 1) >> 1; \
v[size * 2 - 3] = (left[size - 2] + left[size - 1] * 3 + 2) >> 2; \
\
for (j = 0; j < size / 2; j++) \
memcpy(dst + j * stride, v + j * 2, size); \
for (j = size / 2; j < size; j++) { \
memcpy(dst + j * stride, v + j * 2, size * 2 - 2 - j * 2); \
memset(dst + j * stride + size * 2 - 2 - j * 2, left[size - 1], \
2 + j * 2 - size); \
} \
}
def_hor_up(8)
def_hor_up(16)
def_hor_up(32)
#undef DST
static av_cold void vp9dsp_intrapred_init(VP9DSPContext *dsp)
{
#define init_intra_pred(tx, sz) \
dsp->intra_pred[tx][VERT_PRED] = vert_ ## sz ## _c; \
dsp->intra_pred[tx][HOR_PRED] = hor_ ## sz ## _c; \
dsp->intra_pred[tx][DC_PRED] = dc_ ## sz ## _c; \
dsp->intra_pred[tx][DIAG_DOWN_LEFT_PRED] = diag_downleft_ ## sz ## _c; \
dsp->intra_pred[tx][DIAG_DOWN_RIGHT_PRED] = diag_downright_ ## sz ## _c; \
dsp->intra_pred[tx][VERT_RIGHT_PRED] = vert_right_ ## sz ## _c; \
dsp->intra_pred[tx][HOR_DOWN_PRED] = hor_down_ ## sz ## _c; \
dsp->intra_pred[tx][VERT_LEFT_PRED] = vert_left_ ## sz ## _c; \
dsp->intra_pred[tx][HOR_UP_PRED] = hor_up_ ## sz ## _c; \
dsp->intra_pred[tx][TM_VP8_PRED] = tm_ ## sz ## _c; \
dsp->intra_pred[tx][LEFT_DC_PRED] = dc_left_ ## sz ## _c; \
dsp->intra_pred[tx][TOP_DC_PRED] = dc_top_ ## sz ## _c; \
dsp->intra_pred[tx][DC_128_PRED] = dc_128_ ## sz ## _c; \
dsp->intra_pred[tx][DC_127_PRED] = dc_127_ ## sz ## _c; \
dsp->intra_pred[tx][DC_129_PRED] = dc_129_ ## sz ## _c
init_intra_pred(TX_4X4, 4x4);
init_intra_pred(TX_8X8, 8x8);
init_intra_pred(TX_16X16, 16x16);
init_intra_pred(TX_32X32, 32x32);
#undef init_intra_pred
}
#define itxfm_wrapper(type_a, type_b, sz, bits) \
static void \
type_a ## _ ## type_b ## _ ## sz ## x ## sz ## _add_c(uint8_t *dst, \
ptrdiff_t stride, \
int16_t *block, \
int eob) \
{ \
int i, j; \
int16_t tmp[sz * sz], out[sz]; \
for (i = 0; i < sz; i++) \
type_a ## sz ## _1d(tmp + i * sz, block + i, sz, 0); \
memset(block, 0, sz * sz * sizeof(*block)); \
for (i = 0; i < sz; i++) { \
type_b ## sz ## _1d(out, tmp + i, sz, 1); \
for (j = 0; j < sz; j++) \
dst[j * stride] = \
av_clip_uint8(dst[j * stride] + \
(bits ? (out[j] + (1 << (bits - 1))) >> bits \
: out[j])); \
dst++; \
} \
}
#define itxfm_wrap(sz, bits) \
itxfm_wrapper(idct, idct, sz, bits) \
itxfm_wrapper(iadst, idct, sz, bits) \
itxfm_wrapper(idct, iadst, sz, bits) \
itxfm_wrapper(iadst, iadst, sz, bits)
#define IN(x) in[x * stride]
static av_always_inline void idct4_1d(int16_t *out, const int16_t *in,
ptrdiff_t stride, int pass)
{
int t0, t1, t2, t3;
t0 = ((IN(0) + IN(2)) * 11585 + (1 << 13)) >> 14;
t1 = ((IN(0) - IN(2)) * 11585 + (1 << 13)) >> 14;
t2 = (IN(1) * 6270 - IN(3) * 15137 + (1 << 13)) >> 14;
t3 = (IN(1) * 15137 + IN(3) * 6270 + (1 << 13)) >> 14;
out[0] = t0 + t3;
out[1] = t1 + t2;
out[2] = t1 - t2;
out[3] = t0 - t3;
}
static av_always_inline void iadst4_1d(int16_t *out, const int16_t *in,
ptrdiff_t stride, int pass)
{
int t0, t1, t2, t3;
t0 = 5283 * IN(0) + 15212 * IN(2) + 9929 * IN(3);
t1 = 9929 * IN(0) - 5283 * IN(2) - 15212 * IN(3);
t2 = 13377 * (IN(0) - IN(2) + IN(3));
t3 = 13377 * IN(1);
out[0] = (t0 + t3 + (1 << 13)) >> 14;
out[1] = (t1 + t3 + (1 << 13)) >> 14;
out[2] = (t2 + (1 << 13)) >> 14;
out[3] = (t0 + t1 - t3 + (1 << 13)) >> 14;
}
itxfm_wrap(4, 4)
static av_always_inline void idct8_1d(int16_t *out, const int16_t *in,
ptrdiff_t stride, int pass)
{
int t0, t0a, t1, t1a, t2, t2a, t3, t3a, t4, t4a, t5, t5a, t6, t6a, t7, t7a;
t0a = ((IN(0) + IN(4)) * 11585 + (1 << 13)) >> 14;
t1a = ((IN(0) - IN(4)) * 11585 + (1 << 13)) >> 14;
t2a = (IN(2) * 6270 - IN(6) * 15137 + (1 << 13)) >> 14;
t3a = (IN(2) * 15137 + IN(6) * 6270 + (1 << 13)) >> 14;
t4a = (IN(1) * 3196 - IN(7) * 16069 + (1 << 13)) >> 14;
t5a = (IN(5) * 13623 - IN(3) * 9102 + (1 << 13)) >> 14;
t6a = (IN(5) * 9102 + IN(3) * 13623 + (1 << 13)) >> 14;
t7a = (IN(1) * 16069 + IN(7) * 3196 + (1 << 13)) >> 14;
t0 = t0a + t3a;
t1 = t1a + t2a;
t2 = t1a - t2a;
t3 = t0a - t3a;
t4 = t4a + t5a;
t5a = t4a - t5a;
t7 = t7a + t6a;
t6a = t7a - t6a;
t5 = ((t6a - t5a) * 11585 + (1 << 13)) >> 14;
t6 = ((t6a + t5a) * 11585 + (1 << 13)) >> 14;
out[0] = t0 + t7;
out[1] = t1 + t6;
out[2] = t2 + t5;
out[3] = t3 + t4;
out[4] = t3 - t4;
out[5] = t2 - t5;
out[6] = t1 - t6;
out[7] = t0 - t7;
}
static av_always_inline void iadst8_1d(int16_t *out, const int16_t *in,
ptrdiff_t stride, int pass)
{
int t0, t0a, t1, t1a, t2, t2a, t3, t3a, t4, t4a, t5, t5a, t6, t6a, t7, t7a;
t0a = 16305 * IN(7) + 1606 * IN(0);
t1a = 1606 * IN(7) - 16305 * IN(0);
t2a = 14449 * IN(5) + 7723 * IN(2);
t3a = 7723 * IN(5) - 14449 * IN(2);
t4a = 10394 * IN(3) + 12665 * IN(4);
t5a = 12665 * IN(3) - 10394 * IN(4);
t6a = 4756 * IN(1) + 15679 * IN(6);
t7a = 15679 * IN(1) - 4756 * IN(6);
t0 = (t0a + t4a + (1 << 13)) >> 14;
t1 = (t1a + t5a + (1 << 13)) >> 14;
t2 = (t2a + t6a + (1 << 13)) >> 14;
t3 = (t3a + t7a + (1 << 13)) >> 14;
t4 = (t0a - t4a + (1 << 13)) >> 14;
t5 = (t1a - t5a + (1 << 13)) >> 14;
t6 = (t2a - t6a + (1 << 13)) >> 14;
t7 = (t3a - t7a + (1 << 13)) >> 14;
t4a = 15137 * t4 + 6270 * t5;
t5a = 6270 * t4 - 15137 * t5;
t6a = 15137 * t7 - 6270 * t6;
t7a = 6270 * t7 + 15137 * t6;
out[0] = t0 + t2;
out[7] = -(t1 + t3);
t2 = t0 - t2;
t3 = t1 - t3;
out[1] = -((t4a + t6a + (1 << 13)) >> 14);
out[6] = (t5a + t7a + (1 << 13)) >> 14;
t6 = (t4a - t6a + (1 << 13)) >> 14;
t7 = (t5a - t7a + (1 << 13)) >> 14;
out[3] = -(((t2 + t3) * 11585 + (1 << 13)) >> 14);
out[4] = ((t2 - t3) * 11585 + (1 << 13)) >> 14;
out[2] = ((t6 + t7) * 11585 + (1 << 13)) >> 14;
out[5] = -(((t6 - t7) * 11585 + (1 << 13)) >> 14);
}
itxfm_wrap(8, 5)
static av_always_inline void idct16_1d(int16_t *out, const int16_t *in,
ptrdiff_t stride, int pass)
{
int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15;
int t0a, t1a, t2a, t3a, t4a, t5a, t6a, t7a;
int t8a, t9a, t10a, t11a, t12a, t13a, t14a, t15a;
t0a = ((IN(0) + IN(8)) * 11585 + (1 << 13)) >> 14;
t1a = ((IN(0) - IN(8)) * 11585 + (1 << 13)) >> 14;
t2a = (IN(4) * 6270 - IN(12) * 15137 + (1 << 13)) >> 14;
t3a = (IN(4) * 15137 + IN(12) * 6270 + (1 << 13)) >> 14;
t4a = (IN(2) * 3196 - IN(14) * 16069 + (1 << 13)) >> 14;
t7a = (IN(2) * 16069 + IN(14) * 3196 + (1 << 13)) >> 14;
t5a = (IN(10) * 13623 - IN(6) * 9102 + (1 << 13)) >> 14;
t6a = (IN(10) * 9102 + IN(6) * 13623 + (1 << 13)) >> 14;
t8a = (IN(1) * 1606 - IN(15) * 16305 + (1 << 13)) >> 14;
t15a = (IN(1) * 16305 + IN(15) * 1606 + (1 << 13)) >> 14;
t9a = (IN(9) * 12665 - IN(7) * 10394 + (1 << 13)) >> 14;
t14a = (IN(9) * 10394 + IN(7) * 12665 + (1 << 13)) >> 14;
t10a = (IN(5) * 7723 - IN(11) * 14449 + (1 << 13)) >> 14;
t13a = (IN(5) * 14449 + IN(11) * 7723 + (1 << 13)) >> 14;
t11a = (IN(13) * 15679 - IN(3) * 4756 + (1 << 13)) >> 14;
t12a = (IN(13) * 4756 + IN(3) * 15679 + (1 << 13)) >> 14;
t0 = t0a + t3a;
t1 = t1a + t2a;
t2 = t1a - t2a;
t3 = t0a - t3a;
t4 = t4a + t5a;
t5 = t4a - t5a;
t6 = t7a - t6a;
t7 = t7a + t6a;
t8 = t8a + t9a;
t9 = t8a - t9a;
t10 = t11a - t10a;
t11 = t11a + t10a;
t12 = t12a + t13a;
t13 = t12a - t13a;
t14 = t15a - t14a;
t15 = t15a + t14a;
t5a = ((t6 - t5) * 11585 + (1 << 13)) >> 14;
t6a = ((t6 + t5) * 11585 + (1 << 13)) >> 14;
t9a = (t14 * 6270 - t9 * 15137 + (1 << 13)) >> 14;
t14a = (t14 * 15137 + t9 * 6270 + (1 << 13)) >> 14;
t10a = (-(t13 * 15137 + t10 * 6270) + (1 << 13)) >> 14;
t13a = (t13 * 6270 - t10 * 15137 + (1 << 13)) >> 14;
t0a = t0 + t7;
t1a = t1 + t6a;
t2a = t2 + t5a;
t3a = t3 + t4;
t4 = t3 - t4;
t5 = t2 - t5a;
t6 = t1 - t6a;
t7 = t0 - t7;
t8a = t8 + t11;
t9 = t9a + t10a;
t10 = t9a - t10a;
t11a = t8 - t11;
t12a = t15 - t12;
t13 = t14a - t13a;
t14 = t14a + t13a;
t15a = t15 + t12;
t10a = ((t13 - t10) * 11585 + (1 << 13)) >> 14;
t13a = ((t13 + t10) * 11585 + (1 << 13)) >> 14;
t11 = ((t12a - t11a) * 11585 + (1 << 13)) >> 14;
t12 = ((t12a + t11a) * 11585 + (1 << 13)) >> 14;
out[0] = t0a + t15a;
out[1] = t1a + t14;
out[2] = t2a + t13a;
out[3] = t3a + t12;
out[4] = t4 + t11;
out[5] = t5 + t10a;
out[6] = t6 + t9;
out[7] = t7 + t8a;
out[8] = t7 - t8a;
out[9] = t6 - t9;
out[10] = t5 - t10a;
out[11] = t4 - t11;
out[12] = t3a - t12;
out[13] = t2a - t13a;
out[14] = t1a - t14;
out[15] = t0a - t15a;
}
static av_always_inline void iadst16_1d(int16_t *out, const int16_t *in,
ptrdiff_t stride, int pass)
{
int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15;
int t0a, t1a, t2a, t3a, t4a, t5a, t6a, t7a;
int t8a, t9a, t10a, t11a, t12a, t13a, t14a, t15a;
t0 = IN(15) * 16364 + IN(0) * 804;
t1 = IN(15) * 804 - IN(0) * 16364;
t2 = IN(13) * 15893 + IN(2) * 3981;
t3 = IN(13) * 3981 - IN(2) * 15893;
t4 = IN(11) * 14811 + IN(4) * 7005;
t5 = IN(11) * 7005 - IN(4) * 14811;
t6 = IN(9) * 13160 + IN(6) * 9760;
t7 = IN(9) * 9760 - IN(6) * 13160;
t8 = IN(7) * 11003 + IN(8) * 12140;
t9 = IN(7) * 12140 - IN(8) * 11003;
t10 = IN(5) * 8423 + IN(10) * 14053;
t11 = IN(5) * 14053 - IN(10) * 8423;
t12 = IN(3) * 5520 + IN(12) * 15426;
t13 = IN(3) * 15426 - IN(12) * 5520;
t14 = IN(1) * 2404 + IN(14) * 16207;
t15 = IN(1) * 16207 - IN(14) * 2404;
t0a = (t0 + t8 + (1 << 13)) >> 14;
t1a = (t1 + t9 + (1 << 13)) >> 14;
t2a = (t2 + t10 + (1 << 13)) >> 14;
t3a = (t3 + t11 + (1 << 13)) >> 14;
t4a = (t4 + t12 + (1 << 13)) >> 14;
t5a = (t5 + t13 + (1 << 13)) >> 14;
t6a = (t6 + t14 + (1 << 13)) >> 14;
t7a = (t7 + t15 + (1 << 13)) >> 14;
t8a = (t0 - t8 + (1 << 13)) >> 14;
t9a = (t1 - t9 + (1 << 13)) >> 14;
t10a = (t2 - t10 + (1 << 13)) >> 14;
t11a = (t3 - t11 + (1 << 13)) >> 14;
t12a = (t4 - t12 + (1 << 13)) >> 14;
t13a = (t5 - t13 + (1 << 13)) >> 14;
t14a = (t6 - t14 + (1 << 13)) >> 14;
t15a = (t7 - t15 + (1 << 13)) >> 14;
t8 = t8a * 16069 + t9a * 3196;
t9 = t8a * 3196 - t9a * 16069;
t10 = t10a * 9102 + t11a * 13623;
t11 = t10a * 13623 - t11a * 9102;
t12 = t13a * 16069 - t12a * 3196;
t13 = t13a * 3196 + t12a * 16069;
t14 = t15a * 9102 - t14a * 13623;
t15 = t15a * 13623 + t14a * 9102;
t0 = t0a + t4a;
t1 = t1a + t5a;
t2 = t2a + t6a;
t3 = t3a + t7a;
t4 = t0a - t4a;
t5 = t1a - t5a;
t6 = t2a - t6a;
t7 = t3a - t7a;
t8a = (t8 + t12 + (1 << 13)) >> 14;
t9a = (t9 + t13 + (1 << 13)) >> 14;
t10a = (t10 + t14 + (1 << 13)) >> 14;
t11a = (t11 + t15 + (1 << 13)) >> 14;
t12a = (t8 - t12 + (1 << 13)) >> 14;
t13a = (t9 - t13 + (1 << 13)) >> 14;
t14a = (t10 - t14 + (1 << 13)) >> 14;
t15a = (t11 - t15 + (1 << 13)) >> 14;
t4a = t4 * 15137 + t5 * 6270;
t5a = t4 * 6270 - t5 * 15137;
t6a = t7 * 15137 - t6 * 6270;
t7a = t7 * 6270 + t6 * 15137;
t12 = t12a * 15137 + t13a * 6270;
t13 = t12a * 6270 - t13a * 15137;
t14 = t15a * 15137 - t14a * 6270;
t15 = t15a * 6270 + t14a * 15137;
out[0] = t0 + t2;
out[15] = -(t1 + t3);
t2a = t0 - t2;
t3a = t1 - t3;
out[3] = -((t4a + t6a + (1 << 13)) >> 14);
out[12] = (t5a + t7a + (1 << 13)) >> 14;
t6 = (t4a - t6a + (1 << 13)) >> 14;
t7 = (t5a - t7a + (1 << 13)) >> 14;
out[1] = -(t8a + t10a);
out[14] = t9a + t11a;
t10 = t8a - t10a;
t11 = t9a - t11a;
out[2] = (t12 + t14 + (1 << 13)) >> 14;
out[13] = -((t13 + t15 + (1 << 13)) >> 14);
t14a = (t12 - t14 + (1 << 13)) >> 14;
t15a = (t13 - t15 + (1 << 13)) >> 14;
out[7] = ((t2a + t3a) * -11585 + (1 << 13)) >> 14;
out[8] = ((t2a - t3a) * 11585 + (1 << 13)) >> 14;
out[4] = ((t7 + t6) * 11585 + (1 << 13)) >> 14;
out[11] = ((t7 - t6) * 11585 + (1 << 13)) >> 14;
out[6] = ((t11 + t10) * 11585 + (1 << 13)) >> 14;
out[9] = ((t11 - t10) * 11585 + (1 << 13)) >> 14;
out[5] = ((t14a + t15a) * -11585 + (1 << 13)) >> 14;
out[10] = ((t14a - t15a) * 11585 + (1 << 13)) >> 14;
}
itxfm_wrap(16, 6)
static av_always_inline void idct32_1d(int16_t *out, const int16_t *in,
ptrdiff_t stride, int pass)
{
int t0a = ((IN(0) + IN(16)) * 11585 + (1 << 13)) >> 14;
int t1a = ((IN(0) - IN(16)) * 11585 + (1 << 13)) >> 14;
int t2a = (IN(8) * 6270 - IN(24) * 15137 + (1 << 13)) >> 14;
int t3a = (IN(8) * 15137 + IN(24) * 6270 + (1 << 13)) >> 14;
int t4a = (IN(4) * 3196 - IN(28) * 16069 + (1 << 13)) >> 14;
int t7a = (IN(4) * 16069 + IN(28) * 3196 + (1 << 13)) >> 14;
int t5a = (IN(20) * 13623 - IN(12) * 9102 + (1 << 13)) >> 14;
int t6a = (IN(20) * 9102 + IN(12) * 13623 + (1 << 13)) >> 14;
int t8a = (IN(2) * 1606 - IN(30) * 16305 + (1 << 13)) >> 14;
int t15a = (IN(2) * 16305 + IN(30) * 1606 + (1 << 13)) >> 14;
int t9a = (IN(18) * 12665 - IN(14) * 10394 + (1 << 13)) >> 14;
int t14a = (IN(18) * 10394 + IN(14) * 12665 + (1 << 13)) >> 14;
int t10a = (IN(10) * 7723 - IN(22) * 14449 + (1 << 13)) >> 14;
int t13a = (IN(10) * 14449 + IN(22) * 7723 + (1 << 13)) >> 14;
int t11a = (IN(26) * 15679 - IN(6) * 4756 + (1 << 13)) >> 14;
int t12a = (IN(26) * 4756 + IN(6) * 15679 + (1 << 13)) >> 14;
int t16a = (IN(1) * 804 - IN(31) * 16364 + (1 << 13)) >> 14;
int t31a = (IN(1) * 16364 + IN(31) * 804 + (1 << 13)) >> 14;
int t17a = (IN(17) * 12140 - IN(15) * 11003 + (1 << 13)) >> 14;
int t30a = (IN(17) * 11003 + IN(15) * 12140 + (1 << 13)) >> 14;
int t18a = (IN(9) * 7005 - IN(23) * 14811 + (1 << 13)) >> 14;
int t29a = (IN(9) * 14811 + IN(23) * 7005 + (1 << 13)) >> 14;
int t19a = (IN(25) * 15426 - IN(7) * 5520 + (1 << 13)) >> 14;
int t28a = (IN(25) * 5520 + IN(7) * 15426 + (1 << 13)) >> 14;
int t20a = (IN(5) * 3981 - IN(27) * 15893 + (1 << 13)) >> 14;
int t27a = (IN(5) * 15893 + IN(27) * 3981 + (1 << 13)) >> 14;
int t21a = (IN(21) * 14053 - IN(11) * 8423 + (1 << 13)) >> 14;
int t26a = (IN(21) * 8423 + IN(11) * 14053 + (1 << 13)) >> 14;
int t22a = (IN(13) * 9760 - IN(19) * 13160 + (1 << 13)) >> 14;
int t25a = (IN(13) * 13160 + IN(19) * 9760 + (1 << 13)) >> 14;
int t23a = (IN(29) * 16207 - IN(3) * 2404 + (1 << 13)) >> 14;
int t24a = (IN(29) * 2404 + IN(3) * 16207 + (1 << 13)) >> 14;
int t0 = t0a + t3a;
int t1 = t1a + t2a;
int t2 = t1a - t2a;
int t3 = t0a - t3a;
int t4 = t4a + t5a;
int t5 = t4a - t5a;
int t6 = t7a - t6a;
int t7 = t7a + t6a;
int t8 = t8a + t9a;
int t9 = t8a - t9a;
int t10 = t11a - t10a;
int t11 = t11a + t10a;
int t12 = t12a + t13a;
int t13 = t12a - t13a;
int t14 = t15a - t14a;
int t15 = t15a + t14a;
int t16 = t16a + t17a;
int t17 = t16a - t17a;
int t18 = t19a - t18a;
int t19 = t19a + t18a;
int t20 = t20a + t21a;
int t21 = t20a - t21a;
int t22 = t23a - t22a;
int t23 = t23a + t22a;
int t24 = t24a + t25a;
int t25 = t24a - t25a;
int t26 = t27a - t26a;
int t27 = t27a + t26a;
int t28 = t28a + t29a;
int t29 = t28a - t29a;
int t30 = t31a - t30a;
int t31 = t31a + t30a;
t5a = ((t6 - t5) * 11585 + (1 << 13)) >> 14;
t6a = ((t6 + t5) * 11585 + (1 << 13)) >> 14;
t9a = (t14 * 6270 - t9 * 15137 + (1 << 13)) >> 14;
t14a = (t14 * 15137 + t9 * 6270 + (1 << 13)) >> 14;
t10a = (-(t13 * 15137 + t10 * 6270) + (1 << 13)) >> 14;
t13a = (t13 * 6270 - t10 * 15137 + (1 << 13)) >> 14;
t17a = (t30 * 3196 - t17 * 16069 + (1 << 13)) >> 14;
t30a = (t30 * 16069 + t17 * 3196 + (1 << 13)) >> 14;
t18a = (-(t29 * 16069 + t18 * 3196) + (1 << 13)) >> 14;
t29a = (t29 * 3196 - t18 * 16069 + (1 << 13)) >> 14;
t21a = (t26 * 13623 - t21 * 9102 + (1 << 13)) >> 14;
t26a = (t26 * 9102 + t21 * 13623 + (1 << 13)) >> 14;
t22a = (-(t25 * 9102 + t22 * 13623) + (1 << 13)) >> 14;
t25a = (t25 * 13623 - t22 * 9102 + (1 << 13)) >> 14;
t0a = t0 + t7;
t1a = t1 + t6a;
t2a = t2 + t5a;
t3a = t3 + t4;
t4a = t3 - t4;
t5 = t2 - t5a;
t6 = t1 - t6a;
t7a = t0 - t7;
t8a = t8 + t11;
t9 = t9a + t10a;
t10 = t9a - t10a;
t11a = t8 - t11;
t12a = t15 - t12;
t13 = t14a - t13a;
t14 = t14a + t13a;
t15a = t15 + t12;
t16a = t16 + t19;
t17 = t17a + t18a;
t18 = t17a - t18a;
t19a = t16 - t19;
t20a = t23 - t20;
t21 = t22a - t21a;
t22 = t22a + t21a;
t23a = t23 + t20;
t24a = t24 + t27;
t25 = t25a + t26a;
t26 = t25a - t26a;
t27a = t24 - t27;
t28a = t31 - t28;
t29 = t30a - t29a;
t30 = t30a + t29a;
t31a = t31 + t28;
t10a = ((t13 - t10) * 11585 + (1 << 13)) >> 14;
t13a = ((t13 + t10) * 11585 + (1 << 13)) >> 14;
t11 = ((t12a - t11a) * 11585 + (1 << 13)) >> 14;
t12 = ((t12a + t11a) * 11585 + (1 << 13)) >> 14;
t18a = (t29 * 6270 - t18 * 15137 + (1 << 13)) >> 14;
t29a = (t29 * 15137 + t18 * 6270 + (1 << 13)) >> 14;
t19 = (t28a * 6270 - t19a * 15137 + (1 << 13)) >> 14;
t28 = (t28a * 15137 + t19a * 6270 + (1 << 13)) >> 14;
t20 = (-(t27a * 15137 + t20a * 6270) + (1 << 13)) >> 14;
t27 = (t27a * 6270 - t20a * 15137 + (1 << 13)) >> 14;
t21a = (-(t26 * 15137 + t21 * 6270) + (1 << 13)) >> 14;
t26a = (t26 * 6270 - t21 * 15137 + (1 << 13)) >> 14;
t0 = t0a + t15a;
t1 = t1a + t14;
t2 = t2a + t13a;
t3 = t3a + t12;
t4 = t4a + t11;
t5a = t5 + t10a;
t6a = t6 + t9;
t7 = t7a + t8a;
t8 = t7a - t8a;
t9a = t6 - t9;
t10 = t5 - t10a;
t11a = t4a - t11;
t12a = t3a - t12;
t13 = t2a - t13a;
t14a = t1a - t14;
t15 = t0a - t15a;
t16 = t16a + t23a;
t17a = t17 + t22;
t18 = t18a + t21a;
t19a = t19 + t20;
t20a = t19 - t20;
t21 = t18a - t21a;
t22a = t17 - t22;
t23 = t16a - t23a;
t24 = t31a - t24a;
t25a = t30 - t25;
t26 = t29a - t26a;
t27a = t28 - t27;
t28a = t28 + t27;
t29 = t29a + t26a;
t30a = t30 + t25;
t31 = t31a + t24a;
t20 = ((t27a - t20a) * 11585 + (1 << 13)) >> 14;
t27 = ((t27a + t20a) * 11585 + (1 << 13)) >> 14;
t21a = ((t26 - t21) * 11585 + (1 << 13)) >> 14;
t26a = ((t26 + t21) * 11585 + (1 << 13)) >> 14;
t22 = ((t25a - t22a) * 11585 + (1 << 13)) >> 14;
t25 = ((t25a + t22a) * 11585 + (1 << 13)) >> 14;
t23a = ((t24 - t23) * 11585 + (1 << 13)) >> 14;
t24a = ((t24 + t23) * 11585 + (1 << 13)) >> 14;
out[0] = t0 + t31;
out[1] = t1 + t30a;
out[2] = t2 + t29;
out[3] = t3 + t28a;
out[4] = t4 + t27;
out[5] = t5a + t26a;
out[6] = t6a + t25;
out[7] = t7 + t24a;
out[8] = t8 + t23a;
out[9] = t9a + t22;
out[10] = t10 + t21a;
out[11] = t11a + t20;
out[12] = t12a + t19a;
out[13] = t13 + t18;
out[14] = t14a + t17a;
out[15] = t15 + t16;
out[16] = t15 - t16;
out[17] = t14a - t17a;
out[18] = t13 - t18;
out[19] = t12a - t19a;
out[20] = t11a - t20;
out[21] = t10 - t21a;
out[22] = t9a - t22;
out[23] = t8 - t23a;
out[24] = t7 - t24a;
out[25] = t6a - t25;
out[26] = t5a - t26a;
out[27] = t4 - t27;
out[28] = t3 - t28a;
out[29] = t2 - t29;
out[30] = t1 - t30a;
out[31] = t0 - t31;
}
itxfm_wrapper(idct, idct, 32, 6)
static av_always_inline void iwht4_1d(int16_t *out, const int16_t *in,
ptrdiff_t stride, int pass)
{
int t0, t1, t2, t3, t4;
if (pass == 0) {
t0 = IN(0) >> 2;
t1 = IN(3) >> 2;
t2 = IN(1) >> 2;
t3 = IN(2) >> 2;
} else {
t0 = IN(0);
t1 = IN(3);
t2 = IN(1);
t3 = IN(2);
}
t0 += t2;
t3 -= t1;
t4 = (t0 - t3) >> 1;
t1 = t4 - t1;
t2 = t4 - t2;
t0 -= t1;
t3 += t2;
out[0] = t0;
out[1] = t1;
out[2] = t2;
out[3] = t3;
}
itxfm_wrapper(iwht, iwht, 4, 0)
#undef IN
#undef itxfm_wrapper
#undef itxfm_wrap
static av_cold void vp9dsp_itxfm_init(VP9DSPContext *dsp)
{
#define init_itxfm(tx, sz) \
dsp->itxfm_add[tx][DCT_DCT] = idct_idct_ ## sz ## _add_c; \
dsp->itxfm_add[tx][DCT_ADST] = iadst_idct_ ## sz ## _add_c; \
dsp->itxfm_add[tx][ADST_DCT] = idct_iadst_ ## sz ## _add_c; \
dsp->itxfm_add[tx][ADST_ADST] = iadst_iadst_ ## sz ## _add_c
#define init_idct(tx, nm) \
dsp->itxfm_add[tx][DCT_DCT] = \
dsp->itxfm_add[tx][ADST_DCT] = \
dsp->itxfm_add[tx][DCT_ADST] = \
dsp->itxfm_add[tx][ADST_ADST] = nm ## _add_c
init_itxfm(TX_4X4, 4x4);
init_itxfm(TX_8X8, 8x8);
init_itxfm(TX_16X16, 16x16);
init_idct(TX_32X32, idct_idct_32x32);
init_idct(4 /* lossless */, iwht_iwht_4x4);
#undef init_itxfm
#undef init_idct
}
static av_always_inline void loop_filter(uint8_t *dst, ptrdiff_t stride,
int E, int I, int H,
ptrdiff_t stridea, ptrdiff_t strideb,
int wd)
{
int i;
for (i = 0; i < 8; i++, dst += stridea) {
int p7, p6, p5, p4;
int p3 = dst[strideb * -4], p2 = dst[strideb * -3];
int p1 = dst[strideb * -2], p0 = dst[strideb * -1];
int q0 = dst[strideb * +0], q1 = dst[strideb * +1];
int q2 = dst[strideb * +2], q3 = dst[strideb * +3];
int q4, q5, q6, q7;
int fm = FFABS(p3 - p2) <= I && FFABS(p2 - p1) <= I &&
FFABS(p1 - p0) <= I && FFABS(q1 - q0) <= I &&
FFABS(q2 - q1) <= I && FFABS(q3 - q2) <= I &&
FFABS(p0 - q0) * 2 + (FFABS(p1 - q1) >> 1) <= E;
int flat8out, flat8in;
if (!fm)
continue;
if (wd >= 16) {
p7 = dst[strideb * -8];
p6 = dst[strideb * -7];
p5 = dst[strideb * -6];
p4 = dst[strideb * -5];
q4 = dst[strideb * +4];
q5 = dst[strideb * +5];
q6 = dst[strideb * +6];
q7 = dst[strideb * +7];
flat8out = FFABS(p7 - p0) <= 1 && FFABS(p6 - p0) <= 1 &&
FFABS(p5 - p0) <= 1 && FFABS(p4 - p0) <= 1 &&
FFABS(q4 - q0) <= 1 && FFABS(q5 - q0) <= 1 &&
FFABS(q6 - q0) <= 1 && FFABS(q7 - q0) <= 1;
}
if (wd >= 8)
flat8in = FFABS(p3 - p0) <= 1 && FFABS(p2 - p0) <= 1 &&
FFABS(p1 - p0) <= 1 && FFABS(q1 - q0) <= 1 &&
FFABS(q2 - q0) <= 1 && FFABS(q3 - q0) <= 1;
if (wd >= 16 && flat8out && flat8in) {
dst[strideb * -7] = (p7 + p7 + p7 + p7 + p7 + p7 + p7 + p6 * 2 +
p5 + p4 + p3 + p2 + p1 + p0 + q0 + 8) >> 4;
dst[strideb * -6] = (p7 + p7 + p7 + p7 + p7 + p7 + p6 + p5 * 2 +
p4 + p3 + p2 + p1 + p0 + q0 + q1 + 8) >> 4;
dst[strideb * -5] = (p7 + p7 + p7 + p7 + p7 + p6 + p5 + p4 * 2 +
p3 + p2 + p1 + p0 + q0 + q1 + q2 + 8) >> 4;
dst[strideb * -4] = (p7 + p7 + p7 + p7 + p6 + p5 + p4 + p3 * 2 +
p2 + p1 + p0 + q0 + q1 + q2 + q3 + 8) >> 4;
dst[strideb * -3] = (p7 + p7 + p7 + p6 + p5 + p4 + p3 + p2 * 2 +
p1 + p0 + q0 + q1 + q2 + q3 + q4 + 8) >> 4;
dst[strideb * -2] = (p7 + p7 + p6 + p5 + p4 + p3 + p2 + p1 * 2 +
p0 + q0 + q1 + q2 + q3 + q4 + q5 + 8) >> 4;
dst[strideb * -1] = (p7 + p6 + p5 + p4 + p3 + p2 + p1 + p0 * 2 +
q0 + q1 + q2 + q3 + q4 + q5 + q6 + 8) >> 4;
dst[strideb * +0] = (p6 + p5 + p4 + p3 + p2 + p1 + p0 + q0 * 2 +
q1 + q2 + q3 + q4 + q5 + q6 + q7 + 8) >> 4;
dst[strideb * +1] = (p5 + p4 + p3 + p2 + p1 + p0 + q0 + q1 * 2 +
q2 + q3 + q4 + q5 + q6 + q7 + q7 + 8) >> 4;
dst[strideb * +2] = (p4 + p3 + p2 + p1 + p0 + q0 + q1 + q2 * 2 +
q3 + q4 + q5 + q6 + q7 + q7 + q7 + 8) >> 4;
dst[strideb * +3] = (p3 + p2 + p1 + p0 + q0 + q1 + q2 + q3 * 2 +
q4 + q5 + q6 + q7 + q7 + q7 + q7 + 8) >> 4;
dst[strideb * +4] = (p2 + p1 + p0 + q0 + q1 + q2 + q3 + q4 * 2 +
q5 + q6 + q7 + q7 + q7 + q7 + q7 + 8) >> 4;
dst[strideb * +5] = (p1 + p0 + q0 + q1 + q2 + q3 + q4 + q5 * 2 +
q6 + q7 + q7 + q7 + q7 + q7 + q7 + 8) >> 4;
dst[strideb * +6] = (p0 + q0 + q1 + q2 + q3 + q4 + q5 + q6 * 2 +
q7 + q7 + q7 + q7 + q7 + q7 + q7 + 8) >> 4;
} else if (wd >= 8 && flat8in) {
dst[strideb * -3] = (p3 + p3 + p3 + 2 * p2 + p1 + p0 + q0 + 4) >> 3;
dst[strideb * -2] = (p3 + p3 + p2 + 2 * p1 + p0 + q0 + q1 + 4) >> 3;
dst[strideb * -1] = (p3 + p2 + p1 + 2 * p0 + q0 + q1 + q2 + 4) >> 3;
dst[strideb * +0] = (p2 + p1 + p0 + 2 * q0 + q1 + q2 + q3 + 4) >> 3;
dst[strideb * +1] = (p1 + p0 + q0 + 2 * q1 + q2 + q3 + q3 + 4) >> 3;
dst[strideb * +2] = (p0 + q0 + q1 + 2 * q2 + q3 + q3 + q3 + 4) >> 3;
} else {
int hev = FFABS(p1 - p0) > H || FFABS(q1 - q0) > H;
if (hev) {
int f = av_clip_int8(3 * (q0 - p0) + av_clip_int8(p1 - q1));
int f1 = FFMIN(f + 4, 127) >> 3;
int f2 = FFMIN(f + 3, 127) >> 3;
dst[strideb * -1] = av_clip_uint8(p0 + f2);
dst[strideb * +0] = av_clip_uint8(q0 - f1);
} else {
int f = av_clip_int8(3 * (q0 - p0));
int f1 = FFMIN(f + 4, 127) >> 3;
int f2 = FFMIN(f + 3, 127) >> 3;
dst[strideb * -1] = av_clip_uint8(p0 + f2);
dst[strideb * +0] = av_clip_uint8(q0 - f1);
f = (f1 + 1) >> 1;
dst[strideb * -2] = av_clip_uint8(p1 + f);
dst[strideb * +1] = av_clip_uint8(q1 - f);
}
}
}
}
#define lf_8_fn(dir, wd, stridea, strideb) \
static void loop_filter_ ## dir ## _ ## wd ## _8_c(uint8_t *dst, \
ptrdiff_t stride, \
int E, int I, int H) \
{ \
loop_filter(dst, stride, E, I, H, stridea, strideb, wd); \
}
#define lf_8_fns(wd) \
lf_8_fn(h, wd, stride, 1) \
lf_8_fn(v, wd, 1, stride)
lf_8_fns(4)
lf_8_fns(8)
lf_8_fns(16)
#undef lf_8_fn
#undef lf_8_fns
#define lf_16_fn(dir, stridea) \
static void loop_filter_ ## dir ## _16_16_c(uint8_t *dst, \
ptrdiff_t stride, \
int E, int I, int H) \
{ \
loop_filter_ ## dir ## _16_8_c(dst, stride, E, I, H); \
loop_filter_ ## dir ## _16_8_c(dst + 8 * stridea, stride, E, I, H); \
}
lf_16_fn(h, stride)
lf_16_fn(v, 1)
#undef lf_16_fn
#define lf_mix_fn(dir, wd1, wd2, stridea) \
static void loop_filter_ ## dir ## _ ## wd1 ## wd2 ## _16_c(uint8_t *dst, \
ptrdiff_t stride, \
int E, int I, \
int H) \
{ \
loop_filter_ ## dir ## _ ## wd1 ## _8_c(dst, stride, E & 0xff, \
I & 0xff, H & 0xff); \
loop_filter_ ## dir ## _ ## wd2 ## _8_c(dst + 8 * stridea, stride, \
E >> 8, I >> 8, H >> 8); \
}
#define lf_mix_fns(wd1, wd2) \
lf_mix_fn(h, wd1, wd2, stride) \
lf_mix_fn(v, wd1, wd2, 1)
lf_mix_fns(4, 4)
lf_mix_fns(4, 8)
lf_mix_fns(8, 4)
lf_mix_fns(8, 8)
#undef lf_mix_fn
#undef lf_mix_fns
static av_cold void vp9dsp_loopfilter_init(VP9DSPContext *dsp)
{
dsp->loop_filter_8[0][0] = loop_filter_h_4_8_c;
dsp->loop_filter_8[0][1] = loop_filter_v_4_8_c;
dsp->loop_filter_8[1][0] = loop_filter_h_8_8_c;
dsp->loop_filter_8[1][1] = loop_filter_v_8_8_c;
dsp->loop_filter_8[2][0] = loop_filter_h_16_8_c;
dsp->loop_filter_8[2][1] = loop_filter_v_16_8_c;
dsp->loop_filter_16[0] = loop_filter_h_16_16_c;
dsp->loop_filter_16[1] = loop_filter_v_16_16_c;
dsp->loop_filter_mix2[0][0][0] = loop_filter_h_44_16_c;
dsp->loop_filter_mix2[0][0][1] = loop_filter_v_44_16_c;
dsp->loop_filter_mix2[0][1][0] = loop_filter_h_48_16_c;
dsp->loop_filter_mix2[0][1][1] = loop_filter_v_48_16_c;
dsp->loop_filter_mix2[1][0][0] = loop_filter_h_84_16_c;
dsp->loop_filter_mix2[1][0][1] = loop_filter_v_84_16_c;
dsp->loop_filter_mix2[1][1][0] = loop_filter_h_88_16_c;
dsp->loop_filter_mix2[1][1][1] = loop_filter_v_88_16_c;
}
static av_always_inline void copy_c(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride,
ptrdiff_t src_stride,
int w, int h)
{
do {
memcpy(dst, src, w);
dst += dst_stride;
src += src_stride;
} while (--h);
}
static av_always_inline void avg_c(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride,
ptrdiff_t src_stride,
int w, int h)
{
do {
int x;
for (x = 0; x < w; x += 4)
AV_WN32A(&dst[x], rnd_avg32(AV_RN32A(&dst[x]), AV_RN32(&src[x])));
dst += dst_stride;
src += src_stride;
} while (--h);
}
#define fpel_fn(type, sz) \
static void type ## sz ## _c(uint8_t *dst, const uint8_t *src, \
ptrdiff_t dst_stride, \
ptrdiff_t src_stride, \
int h, int mx, int my) \
{ \
type ## _c(dst, src, dst_stride, src_stride, sz, h); \
}
#define copy_avg_fn(sz) \
fpel_fn(copy, sz) \
fpel_fn(avg, sz)
copy_avg_fn(64)
copy_avg_fn(32)
copy_avg_fn(16)
copy_avg_fn(8)
copy_avg_fn(4)
#undef fpel_fn
#undef copy_avg_fn
static const int8_t vp9_subpel_filters[3][15][8] = {
[FILTER_8TAP_REGULAR] = {
{ 0, 1, -5, 126, 8, -3, 1, 0 },
{ -1, 3, -10, 122, 18, -6, 2, 0 },
{ -1, 4, -13, 118, 27, -9, 3, -1 },
{ -1, 4, -16, 112, 37, -11, 4, -1 },
{ -1, 5, -18, 105, 48, -14, 4, -1 },
{ -1, 5, -19, 97, 58, -16, 5, -1 },
{ -1, 6, -19, 88, 68, -18, 5, -1 },
{ -1, 6, -19, 78, 78, -19, 6, -1 },
{ -1, 5, -18, 68, 88, -19, 6, -1 },
{ -1, 5, -16, 58, 97, -19, 5, -1 },
{ -1, 4, -14, 48, 105, -18, 5, -1 },
{ -1, 4, -11, 37, 112, -16, 4, -1 },
{ -1, 3, -9, 27, 118, -13, 4, -1 },
{ 0, 2, -6, 18, 122, -10, 3, -1 },
{ 0, 1, -3, 8, 126, -5, 1, 0 },
}, [FILTER_8TAP_SHARP] = {
{ -1, 3, -7, 127, 8, -3, 1, 0 },
{ -2, 5, -13, 125, 17, -6, 3, -1 },
{ -3, 7, -17, 121, 27, -10, 5, -2 },
{ -4, 9, -20, 115, 37, -13, 6, -2 },
{ -4, 10, -23, 108, 48, -16, 8, -3 },
{ -4, 10, -24, 100, 59, -19, 9, -3 },
{ -4, 11, -24, 90, 70, -21, 10, -4 },
{ -4, 11, -23, 80, 80, -23, 11, -4 },
{ -4, 10, -21, 70, 90, -24, 11, -4 },
{ -3, 9, -19, 59, 100, -24, 10, -4 },
{ -3, 8, -16, 48, 108, -23, 10, -4 },
{ -2, 6, -13, 37, 115, -20, 9, -4 },
{ -2, 5, -10, 27, 121, -17, 7, -3 },
{ -1, 3, -6, 17, 125, -13, 5, -2 },
{ 0, 1, -3, 8, 127, -7, 3, -1 },
}, [FILTER_8TAP_SMOOTH] = {
{ -3, -1, 32, 64, 38, 1, -3, 0 },
{ -2, -2, 29, 63, 41, 2, -3, 0 },
{ -2, -2, 26, 63, 43, 4, -4, 0 },
{ -2, -3, 24, 62, 46, 5, -4, 0 },
{ -2, -3, 21, 60, 49, 7, -4, 0 },
{ -1, -4, 18, 59, 51, 9, -4, 0 },
{ -1, -4, 16, 57, 53, 12, -4, -1 },
{ -1, -4, 14, 55, 55, 14, -4, -1 },
{ -1, -4, 12, 53, 57, 16, -4, -1 },
{ 0, -4, 9, 51, 59, 18, -4, -1 },
{ 0, -4, 7, 49, 60, 21, -3, -2 },
{ 0, -4, 5, 46, 62, 24, -3, -2 },
{ 0, -4, 4, 43, 63, 26, -2, -2 },
{ 0, -3, 2, 41, 63, 29, -2, -2 },
{ 0, -3, 1, 38, 64, 32, -1, -3 },
}
};
#define FILTER_8TAP(src, x, F, stride) \
av_clip_uint8((F[0] * src[x + -3 * stride] + \
F[1] * src[x + -2 * stride] + \
F[2] * src[x + -1 * stride] + \
F[3] * src[x + +0 * stride] + \
F[4] * src[x + +1 * stride] + \
F[5] * src[x + +2 * stride] + \
F[6] * src[x + +3 * stride] + \
F[7] * src[x + +4 * stride] + 64) >> 7)
static av_always_inline void do_8tap_1d_c(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride,
ptrdiff_t src_stride,
int w, int h, ptrdiff_t ds,
const int8_t *filter, int avg)
{
do {
int x;
for (x = 0; x < w; x++)
if (avg)
dst[x] = (dst[x] + FILTER_8TAP(src, x, filter, ds) + 1) >> 1;
else
dst[x] = FILTER_8TAP(src, x, filter, ds);
dst += dst_stride;
src += src_stride;
} while (--h);
}
#define filter_8tap_1d_fn(opn, opa, dir, ds) \
static av_noinline void opn ## _8tap_1d_ ## dir ## _c(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t dst_stride, \
ptrdiff_t src_stride, \
int w, int h, \
const int8_t *filter) \
{ \
do_8tap_1d_c(dst, src, dst_stride, src_stride, w, h, ds, filter, opa); \
}
filter_8tap_1d_fn(put, 0, v, src_stride)
filter_8tap_1d_fn(put, 0, h, 1)
filter_8tap_1d_fn(avg, 1, v, src_stride)
filter_8tap_1d_fn(avg, 1, h, 1)
#undef filter_8tap_1d_fn
static av_always_inline void do_8tap_2d_c(uint8_t *dst, const uint8_t *src,
ptrdiff_t dst_stride,
ptrdiff_t src_stride,
int w, int h, const int8_t *filterx,
const int8_t *filtery, int avg)
{
int tmp_h = h + 7;
uint8_t tmp[64 * 71], *tmp_ptr = tmp;
src -= src_stride * 3;
do {
int x;
for (x = 0; x < w; x++)
tmp_ptr[x] = FILTER_8TAP(src, x, filterx, 1);
tmp_ptr += 64;
src += src_stride;
} while (--tmp_h);
tmp_ptr = tmp + 64 * 3;
do {
int x;
for (x = 0; x < w; x++)
if (avg)
dst[x] = (dst[x] + FILTER_8TAP(tmp_ptr, x, filtery, 64) + 1) >> 1;
else
dst[x] = FILTER_8TAP(tmp_ptr, x, filtery, 64);
tmp_ptr += 64;
dst += dst_stride;
} while (--h);
}
#define filter_8tap_2d_fn(opn, opa) \
static av_noinline void opn ## _8tap_2d_hv_c(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t dst_stride, \
ptrdiff_t src_stride, \
int w, int h, \
const int8_t *filterx, \
const int8_t *filtery) \
{ \
do_8tap_2d_c(dst, src, dst_stride, src_stride, \
w, h, filterx, filtery, opa); \
}
filter_8tap_2d_fn(put, 0)
filter_8tap_2d_fn(avg, 1)
#undef filter_8tap_2d_fn
#undef FILTER_8TAP
#define filter_fn_1d(sz, dir, dir_m, type, type_idx, avg) \
static void \
avg ## _8tap_ ## type ## _ ## sz ## dir ## _c(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t dst_stride, \
ptrdiff_t src_stride, \
int h, int mx, int my) \
{ \
avg ## _8tap_1d_ ## dir ## _c(dst, src, dst_stride, src_stride, sz, h, \
vp9_subpel_filters[type_idx][dir_m - 1]); \
}
#define filter_fn_2d(sz, type, type_idx, avg) \
static void avg ## _8tap_ ## type ## _ ## sz ## hv_c(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t dst_stride, \
ptrdiff_t src_stride, \
int h, int mx, int my) \
{ \
avg ## _8tap_2d_hv_c(dst, src, dst_stride, src_stride, sz, h, \
vp9_subpel_filters[type_idx][mx - 1], \
vp9_subpel_filters[type_idx][my - 1]); \
}
#define FILTER_BILIN(src, x, mxy, stride) \
(src[x] + ((mxy * (src[x + stride] - src[x]) + 8) >> 4))
static av_always_inline void do_bilin_1d_c(uint8_t *dst,
const uint8_t *src,
ptrdiff_t dst_stride,
ptrdiff_t src_stride,
int w, int h, ptrdiff_t ds,
int mxy, int avg)
{
do {
int x;
for (x = 0; x < w; x++)
if (avg)
dst[x] = (dst[x] + FILTER_BILIN(src, x, mxy, ds) + 1) >> 1;
else
dst[x] = FILTER_BILIN(src, x, mxy, ds);
dst += dst_stride;
src += src_stride;
} while (--h);
}
#define bilin_1d_fn(opn, opa, dir, ds) \
static av_noinline void opn ## _bilin_1d_ ## dir ## _c(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t dst_stride, \
ptrdiff_t src_stride, \
int w, int h, int mxy) \
{ \
do_bilin_1d_c(dst, src, dst_stride, src_stride, w, h, ds, mxy, opa); \
}
bilin_1d_fn(put, 0, v, src_stride)
bilin_1d_fn(put, 0, h, 1)
bilin_1d_fn(avg, 1, v, src_stride)
bilin_1d_fn(avg, 1, h, 1)
#undef bilin_1d_fn
static av_always_inline void do_bilin_2d_c(uint8_t *dst,
const uint8_t *src,
ptrdiff_t dst_stride,
ptrdiff_t src_stride,
int w, int h, int mx, int my,
int avg)
{
uint8_t tmp[64 * 65], *tmp_ptr = tmp;
int tmp_h = h + 1;
do {
int x;
for (x = 0; x < w; x++)
tmp_ptr[x] = FILTER_BILIN(src, x, mx, 1);
tmp_ptr += 64;
src += src_stride;
} while (--tmp_h);
tmp_ptr = tmp;
do {
int x;
for (x = 0; x < w; x++)
if (avg)
dst[x] = (dst[x] + FILTER_BILIN(tmp_ptr, x, my, 64) + 1) >> 1;
else
dst[x] = FILTER_BILIN(tmp_ptr, x, my, 64);
tmp_ptr += 64;
dst += dst_stride;
} while (--h);
}
#define bilin_2d_fn(opn, opa) \
static av_noinline void opn ## _bilin_2d_hv_c(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t dst_stride, \
ptrdiff_t src_stride, \
int w, int h, \
int mx, int my) \
{ \
do_bilin_2d_c(dst, src, dst_stride, src_stride, w, h, mx, my, opa); \
}
bilin_2d_fn(put, 0)
bilin_2d_fn(avg, 1)
#undef bilin_2d_fn
#undef FILTER_BILIN
#define bilinf_fn_1d(sz, dir, dir_m, avg) \
static void avg ## _bilin_ ## sz ## dir ## _c(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t dst_stride, \
ptrdiff_t src_stride, \
int h, int mx, int my) \
{ \
avg ## _bilin_1d_ ## dir ## _c(dst, src, dst_stride, src_stride, \
sz, h, dir_m); \
}
#define bilinf_fn_2d(sz, avg) \
static void avg ## _bilin_ ## sz ## hv_c(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t dst_stride, \
ptrdiff_t src_stride, \
int h, int mx, int my) \
{ \
avg ## _bilin_2d_hv_c(dst, src, dst_stride, src_stride, \
sz, h, mx, my); \
}
#define filter_fn(sz, avg) \
filter_fn_1d(sz, h, mx, regular, FILTER_8TAP_REGULAR, avg) \
filter_fn_1d(sz, v, my, regular, FILTER_8TAP_REGULAR, avg) \
filter_fn_2d(sz, regular, FILTER_8TAP_REGULAR, avg) \
filter_fn_1d(sz, h, mx, smooth, FILTER_8TAP_SMOOTH, avg) \
filter_fn_1d(sz, v, my, smooth, FILTER_8TAP_SMOOTH, avg) \
filter_fn_2d(sz, smooth, FILTER_8TAP_SMOOTH, avg) \
filter_fn_1d(sz, h, mx, sharp, FILTER_8TAP_SHARP, avg) \
filter_fn_1d(sz, v, my, sharp, FILTER_8TAP_SHARP, avg) \
filter_fn_2d(sz, sharp, FILTER_8TAP_SHARP, avg) \
bilinf_fn_1d(sz, h, mx, avg) \
bilinf_fn_1d(sz, v, my, avg) \
bilinf_fn_2d(sz, avg)
#define filter_fn_set(avg) \
filter_fn(64, avg) \
filter_fn(32, avg) \
filter_fn(16, avg) \
filter_fn(8, avg) \
filter_fn(4, avg)
filter_fn_set(put)
filter_fn_set(avg)
#undef filter_fn
#undef filter_fn_set
#undef filter_fn_1d
#undef filter_fn_2d
#undef bilinf_fn_1d
#undef bilinf_fn_2d
static av_cold void vp9dsp_mc_init(VP9DSPContext *dsp)
{
#define init_fpel(idx1, idx2, sz, type) \
dsp->mc[idx1][FILTER_8TAP_SMOOTH][idx2][0][0] = type ## sz ## _c; \
dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][0][0] = type ## sz ## _c; \
dsp->mc[idx1][FILTER_8TAP_SHARP][idx2][0][0] = type ## sz ## _c; \
dsp->mc[idx1][FILTER_BILINEAR][idx2][0][0] = type ## sz ## _c
#define init_copy_avg(idx, sz) \
init_fpel(idx, 0, sz, copy); \
init_fpel(idx, 1, sz, avg)
init_copy_avg(0, 64);
init_copy_avg(1, 32);
init_copy_avg(2, 16);
init_copy_avg(3, 8);
init_copy_avg(4, 4);
#undef init_copy_avg
#undef init_fpel
#define init_subpel1(idx1, idx2, idxh, idxv, sz, dir, type) \
dsp->mc[idx1][FILTER_8TAP_SMOOTH][idx2][idxh][idxv] = type ## _8tap_smooth_ ## sz ## dir ## _c; \
dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][idxh][idxv] = type ## _8tap_regular_ ## sz ## dir ## _c; \
dsp->mc[idx1][FILTER_8TAP_SHARP][idx2][idxh][idxv] = type ## _8tap_sharp_ ## sz ## dir ## _c; \
dsp->mc[idx1][FILTER_BILINEAR][idx2][idxh][idxv] = type ## _bilin_ ## sz ## dir ## _c
#define init_subpel2(idx, idxh, idxv, dir, type) \
init_subpel1(0, idx, idxh, idxv, 64, dir, type); \
init_subpel1(1, idx, idxh, idxv, 32, dir, type); \
init_subpel1(2, idx, idxh, idxv, 16, dir, type); \
init_subpel1(3, idx, idxh, idxv, 8, dir, type); \
init_subpel1(4, idx, idxh, idxv, 4, dir, type)
#define init_subpel3(idx, type) \
init_subpel2(idx, 1, 1, hv, type); \
init_subpel2(idx, 0, 1, v, type); \
init_subpel2(idx, 1, 0, h, type)
init_subpel3(0, put);
init_subpel3(1, avg);
#undef init_subpel1
#undef init_subpel2
#undef init_subpel3
}
av_cold void ff_vp9dsp_init(VP9DSPContext *dsp)
{
vp9dsp_intrapred_init(dsp);
vp9dsp_itxfm_init(dsp);
vp9dsp_loopfilter_init(dsp);
vp9dsp_mc_init(dsp);
if (ARCH_X86)
ff_vp9dsp_init_x86(dsp);
}
/*
* VP9 compatible video decoder
*
* Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
* Copyright (C) 2013 Clément Bœsch <u pkh me>
*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "internal.h"
#include "vp56.h"
#include "vp9.h"
#include "vp9data.h"
static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src,
VP9Context *s)
{
dst->x = av_clip(src->x, s->min_mv.x, s->max_mv.x);
dst->y = av_clip(src->y, s->min_mv.y, s->max_mv.y);
}
static void find_ref_mvs(VP9Context *s,
VP56mv *pmv, int ref, int z, int idx, int sb)
{
static const int8_t mv_ref_blk_off[N_BS_SIZES][8][2] = {
[BS_64x64] = { { 3, -1 }, { -1, 3 }, { 4, -1 }, { -1, 4 },
{ -1, -1 }, { 0, -1 }, { -1, 0 }, { 6, -1 } },
[BS_64x32] = { { 0, -1 }, { -1, 0 }, { 4, -1 }, { -1, 2 },
{ -1, -1 }, { 0, -3 }, { -3, 0 }, { 2, -1 } },
[BS_32x64] = { { -1, 0 }, { 0, -1 }, { -1, 4 }, { 2, -1 },
{ -1, -1 }, { -3, 0 }, { 0, -3 }, { -1, 2 } },
[BS_32x32] = { { 1, -1 }, { -1, 1 }, { 2, -1 }, { -1, 2 },
{ -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 } },
[BS_32x16] = { { 0, -1 }, { -1, 0 }, { 2, -1 }, { -1, -1 },
{ -1, 1 }, { 0, -3 }, { -3, 0 }, { -3, -3 } },
[BS_16x32] = { { -1, 0 }, { 0, -1 }, { -1, 2 }, { -1, -1 },
{ 1, -1 }, { -3, 0 }, { 0, -3 }, { -3, -3 } },
[BS_16x16] = { { 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, 1 },
{ -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 } },
[BS_16x8] = { { 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, -1 },
{ 0, -2 }, { -2, 0 }, { -2, -1 }, { -1, -2 } },
[BS_8x16] = { { -1, 0 }, { 0, -1 }, { -1, 1 }, { -1, -1 },
{ -2, 0 }, { 0, -2 }, { -1, -2 }, { -2, -1 } },
[BS_8x8] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
{ -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
[BS_8x4] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
{ -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
[BS_4x8] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
{ -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
[BS_4x4] = { { 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
{ -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
};
VP9Block *const b = &s->b;
int row = b->row, col = b->col, row7 = b->row7;
const int8_t (*p)[2] = mv_ref_blk_off[b->bs];
#define INVALID_MV 0x80008000U
uint32_t mem = INVALID_MV;
int i;
#define RETURN_DIRECT_MV(mv) \
do { \
uint32_t m = AV_RN32A(&mv); \
if (!idx) { \
AV_WN32A(pmv, m); \
return; \
} else if (mem == INVALID_MV) { \
mem = m; \
} else if (m != mem) { \
AV_WN32A(pmv, m); \
return; \
} \
} while (0)
if (sb >= 0) {
if (sb == 2 || sb == 1) {
RETURN_DIRECT_MV(b->mv[0][z]);
} else if (sb == 3) {
RETURN_DIRECT_MV(b->mv[2][z]);
RETURN_DIRECT_MV(b->mv[1][z]);
RETURN_DIRECT_MV(b->mv[0][z]);
}
#define RETURN_MV(mv) \
do { \
if (sb > 0) { \
VP56mv tmp; \
uint32_t m; \
clamp_mv(&tmp, &mv, s); \
m = AV_RN32A(&tmp); \
if (!idx) { \
AV_WN32A(pmv, m); \
return; \
} else if (mem == INVALID_MV) { \
mem = m; \
} else if (m != mem) { \
AV_WN32A(pmv, m); \
return; \
} \
} else { \
uint32_t m = AV_RN32A(&mv); \
if (!idx) { \
clamp_mv(pmv, &mv, s); \
return; \
} else if (mem == INVALID_MV) { \
mem = m; \
} else if (m != mem) { \
clamp_mv(pmv, &mv, s); \
return; \
} \
} \
} while (0)
if (row > 0) {
VP9MVRefPair *mv = &s->mv[0][(row - 1) * s->sb_cols * 8 + col];
if (mv->ref[0] == ref)
RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]);
else if (mv->ref[1] == ref)
RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]);
}
if (col > s->tiling.tile_col_start) {
VP9MVRefPair *mv = &s->mv[0][row * s->sb_cols * 8 + col - 1];
if (mv->ref[0] == ref)
RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][0]);
else if (mv->ref[1] == ref)
RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][1]);
}
i = 2;
} else {
i = 0;
}
// previously coded MVs in the neighborhood, using same reference frame
for (; i < 8; i++) {
int c = p[i][0] + col, r = p[i][1] + row;
if (c >= s->tiling.tile_col_start && c < s->cols &&
r >= 0 && r < s->rows) {
VP9MVRefPair *mv = &s->mv[0][r * s->sb_cols * 8 + c];
if (mv->ref[0] == ref)
RETURN_MV(mv->mv[0]);
else if (mv->ref[1] == ref)
RETURN_MV(mv->mv[1]);
}
}
// MV at this position in previous frame, using same reference frame
if (s->use_last_frame_mvs) {
VP9MVRefPair *mv = &s->mv[1][row * s->sb_cols * 8 + col];
if (mv->ref[0] == ref)
RETURN_MV(mv->mv[0]);
else if (mv->ref[1] == ref)
RETURN_MV(mv->mv[1]);
}
#define RETURN_SCALE_MV(mv, scale) \
do { \
if (scale) { \
VP56mv mv_temp = { -mv.x, -mv.y }; \
RETURN_MV(mv_temp); \
} else { \
RETURN_MV(mv); \
} \
} while (0)
// previously coded MVs in the neighborhood, using different reference frame
for (i = 0; i < 8; i++) {
int c = p[i][0] + col, r = p[i][1] + row;
if (c >= s->tiling.tile_col_start && c < s->cols &&
r >= 0 && r < s->rows) {
VP9MVRefPair *mv = &s->mv[0][r * s->sb_cols * 8 + c];
if (mv->ref[0] != ref && mv->ref[0] >= 0)
RETURN_SCALE_MV(mv->mv[0],
s->signbias[mv->ref[0]] != s->signbias[ref]);
if (mv->ref[1] != ref && mv->ref[1] >= 0)
RETURN_SCALE_MV(mv->mv[1],
s->signbias[mv->ref[1]] != s->signbias[ref]);
}
}
// MV at this position in previous frame, using different reference frame
if (s->use_last_frame_mvs) {
VP9MVRefPair *mv = &s->mv[1][row * s->sb_cols * 8 + col];
if (mv->ref[0] != ref && mv->ref[0] >= 0)
RETURN_SCALE_MV(mv->mv[0],
s->signbias[mv->ref[0]] != s->signbias[ref]);
if (mv->ref[1] != ref && mv->ref[1] >= 0)
RETURN_SCALE_MV(mv->mv[1],
s->signbias[mv->ref[1]] != s->signbias[ref]);
}
AV_ZERO32(pmv);
#undef INVALID_MV
#undef RETURN_MV
#undef RETURN_SCALE_MV
}
static av_always_inline int read_mv_component(VP9Context *s, int idx, int hp)
{
int bit, sign = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].sign);
int n, c = vp8_rac_get_tree(&s->c, ff_vp9_mv_class_tree,
s->prob.p.mv_comp[idx].classes);
s->counts.mv_comp[idx].sign[sign]++;
s->counts.mv_comp[idx].classes[c]++;
if (c) {
int m;
for (n = 0, m = 0; m < c; m++) {
bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].bits[m]);
n |= bit << m;
s->counts.mv_comp[idx].bits[m][bit]++;
}
n <<= 3;
bit = vp8_rac_get_tree(&s->c, ff_vp9_mv_fp_tree,
s->prob.p.mv_comp[idx].fp);
n |= bit << 1;
s->counts.mv_comp[idx].fp[bit]++;
if (hp) {
bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].hp);
s->counts.mv_comp[idx].hp[bit]++;
n |= bit;
} else {
n |= 1;
// bug in libvpx - we count for bw entropy purposes even if the
// bit wasn't coded
s->counts.mv_comp[idx].hp[1]++;
}
n += 8 << c;
} else {
n = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0);
s->counts.mv_comp[idx].class0[n]++;
bit = vp8_rac_get_tree(&s->c, ff_vp9_mv_fp_tree,
s->prob.p.mv_comp[idx].class0_fp[n]);
s->counts.mv_comp[idx].class0_fp[n][bit]++;
n = (n << 3) | (bit << 1);
if (hp) {
bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0_hp);
s->counts.mv_comp[idx].class0_hp[bit]++;
n |= bit;
} else {
n |= 1;
// bug in libvpx - we count for bw entropy purposes even if the
// bit wasn't coded
s->counts.mv_comp[idx].class0_hp[1]++;
}
}
return sign ? -(n + 1) : (n + 1);
}
void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb)
{
VP9Block *const b = &s->b;
if (mode == ZEROMV) {
memset(mv, 0, sizeof(*mv) * 2);
} else {
int hp;
// FIXME cache this value and reuse for other subblocks
find_ref_mvs(s, &mv[0], b->ref[0], 0, mode == NEARMV,
mode == NEWMV ? -1 : sb);
// FIXME maybe move this code into find_ref_mvs()
if ((mode == NEWMV || sb == -1) &&
!(hp = s->highprecisionmvs &&
abs(mv[0].x) < 64 && abs(mv[0].y) < 64)) {
if (mv[0].y & 1) {
if (mv[0].y < 0)
mv[0].y++;
else
mv[0].y--;
}
if (mv[0].x & 1) {
if (mv[0].x < 0)
mv[0].x++;
else
mv[0].x--;
}
}
if (mode == NEWMV) {
enum MVJoint j = vp8_rac_get_tree(&s->c, ff_vp9_mv_joint_tree,
s->prob.p.mv_joint);
s->counts.mv_joint[j]++;
if (j >= MV_JOINT_V)
mv[0].y += read_mv_component(s, 0, hp);
if (j & 1)
mv[0].x += read_mv_component(s, 1, hp);
}
if (b->comp) {
// FIXME cache this value and reuse for other subblocks
find_ref_mvs(s, &mv[1], b->ref[1], 1, mode == NEARMV,
mode == NEWMV ? -1 : sb);
if ((mode == NEWMV || sb == -1) &&
!(hp = s->highprecisionmvs &&
abs(mv[1].x) < 64 && abs(mv[1].y) < 64)) {
if (mv[1].y & 1) {
if (mv[1].y < 0)
mv[1].y++;
else
mv[1].y--;
}
if (mv[1].x & 1) {
if (mv[1].x < 0)
mv[1].x++;
else
mv[1].x--;
}
}
if (mode == NEWMV) {
enum MVJoint j = vp8_rac_get_tree(&s->c, ff_vp9_mv_joint_tree,
s->prob.p.mv_joint);
s->counts.mv_joint[j]++;
if (j >= MV_JOINT_V)
mv[1].y += read_mv_component(s, 0, hp);
if (j & 1)
mv[1].x += read_mv_component(s, 1, hp);
}
}
}
}
/*
* VP9 compatible video decoder
*
* Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
* Copyright (C) 2013 Clément Bœsch <u pkh me>
*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "vp56.h"
#include "vp9.h"
#include "vp9data.h"
static av_always_inline void adapt_prob(uint8_t *p, unsigned ct0, unsigned ct1,
int max_count, int update_factor)
{
unsigned ct = ct0 + ct1, p2, p1;
if (!ct)
return;
p1 = *p;
p2 = ((ct0 << 8) + (ct >> 1)) / ct;
p2 = av_clip(p2, 1, 255);
ct = FFMIN(ct, max_count);
update_factor = FASTDIV(update_factor * ct, max_count);
// (p1 * (256 - update_factor) + p2 * update_factor + 128) >> 8
*p = p1 + (((p2 - p1) * update_factor + 128) >> 8);
}
void ff_vp9_adapt_probs(VP9Context *s)
{
int i, j, k, l, m;
ProbContext *p = &s->prob_ctx[s->framectxid].p;
int uf = (s->keyframe || s->intraonly || !s->last_keyframe) ? 112 : 128;
// coefficients
for (i = 0; i < 4; i++)
for (j = 0; j < 2; j++)
for (k = 0; k < 2; k++)
for (l = 0; l < 6; l++)
for (m = 0; m < 6; m++) {
uint8_t *pp = s->prob_ctx[s->framectxid].coef[i][j][k][l][m];
unsigned *e = s->counts.eob[i][j][k][l][m];
unsigned *c = s->counts.coef[i][j][k][l][m];
if (l == 0 && m >= 3) // dc only has 3 pt
break;
adapt_prob(&pp[0], e[0], e[1], 24, uf);
adapt_prob(&pp[1], c[0], c[1] + c[2], 24, uf);
adapt_prob(&pp[2], c[1], c[2], 24, uf);
}
if (s->keyframe || s->intraonly) {
memcpy(p->skip, s->prob.p.skip, sizeof(p->skip));
memcpy(p->tx32p, s->prob.p.tx32p, sizeof(p->tx32p));
memcpy(p->tx16p, s->prob.p.tx16p, sizeof(p->tx16p));
memcpy(p->tx8p, s->prob.p.tx8p, sizeof(p->tx8p));
return;
}
// skip flag
for (i = 0; i < 3; i++)
adapt_prob(&p->skip[i], s->counts.skip[i][0],
s->counts.skip[i][1], 20, 128);
// intra/inter flag
for (i = 0; i < 4; i++)
adapt_prob(&p->intra[i], s->counts.intra[i][0],
s->counts.intra[i][1], 20, 128);
// comppred flag
if (s->comppredmode == PRED_SWITCHABLE) {
for (i = 0; i < 5; i++)
adapt_prob(&p->comp[i], s->counts.comp[i][0],
s->counts.comp[i][1], 20, 128);
}
// reference frames
if (s->comppredmode != PRED_SINGLEREF) {
for (i = 0; i < 5; i++)
adapt_prob(&p->comp_ref[i], s->counts.comp_ref[i][0],
s->counts.comp_ref[i][1], 20, 128);
}
if (s->comppredmode != PRED_COMPREF) {
for (i = 0; i < 5; i++) {
uint8_t *pp = p->single_ref[i];
unsigned (*c)[2] = s->counts.single_ref[i];
adapt_prob(&pp[0], c[0][0], c[0][1], 20, 128);
adapt_prob(&pp[1], c[1][0], c[1][1], 20, 128);
}
}
// block partitioning
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++) {
uint8_t *pp = p->partition[i][j];
unsigned *c = s->counts.partition[i][j];
adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
adapt_prob(&pp[2], c[2], c[3], 20, 128);
}
// tx size
if (s->txfmmode == TX_SWITCHABLE) {
for (i = 0; i < 2; i++) {
unsigned *c16 = s->counts.tx16p[i], *c32 = s->counts.tx32p[i];
adapt_prob(&p->tx8p[i], s->counts.tx8p[i][0],
s->counts.tx8p[i][1], 20, 128);
adapt_prob(&p->tx16p[i][0], c16[0], c16[1] + c16[2], 20, 128);
adapt_prob(&p->tx16p[i][1], c16[1], c16[2], 20, 128);
adapt_prob(&p->tx32p[i][0], c32[0], c32[1] + c32[2] + c32[3], 20, 128);
adapt_prob(&p->tx32p[i][1], c32[1], c32[2] + c32[3], 20, 128);
adapt_prob(&p->tx32p[i][2], c32[2], c32[3], 20, 128);
}
}
// interpolation filter
if (s->filtermode == FILTER_SWITCHABLE) {
for (i = 0; i < 4; i++) {
uint8_t *pp = p->filter[i];
unsigned *c = s->counts.filter[i];
adapt_prob(&pp[0], c[0], c[1] + c[2], 20, 128);
adapt_prob(&pp[1], c[1], c[2], 20, 128);
}
}
// inter modes
for (i = 0; i < 7; i++) {
uint8_t *pp = p->mv_mode[i];
unsigned *c = s->counts.mv_mode[i];
adapt_prob(&pp[0], c[2], c[1] + c[0] + c[3], 20, 128);
adapt_prob(&pp[1], c[0], c[1] + c[3], 20, 128);
adapt_prob(&pp[2], c[1], c[3], 20, 128);
}
// mv joints
{
uint8_t *pp = p->mv_joint;
unsigned *c = s->counts.mv_joint;
adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
adapt_prob(&pp[2], c[2], c[3], 20, 128);
}
// mv components
for (i = 0; i < 2; i++) {
uint8_t *pp;
unsigned *c, (*c2)[2], sum;
adapt_prob(&p->mv_comp[i].sign, s->counts.mv_comp[i].sign[0],
s->counts.mv_comp[i].sign[1], 20, 128);
pp = p->mv_comp[i].classes;
c = s->counts.mv_comp[i].classes;
sum = c[1] + c[2] + c[3] + c[4] + c[5] +
c[6] + c[7] + c[8] + c[9] + c[10];
adapt_prob(&pp[0], c[0], sum, 20, 128);
sum -= c[1];
adapt_prob(&pp[1], c[1], sum, 20, 128);
sum -= c[2] + c[3];
adapt_prob(&pp[2], c[2] + c[3], sum, 20, 128);
adapt_prob(&pp[3], c[2], c[3], 20, 128);
sum -= c[4] + c[5];
adapt_prob(&pp[4], c[4] + c[5], sum, 20, 128);
adapt_prob(&pp[5], c[4], c[5], 20, 128);
sum -= c[6];
adapt_prob(&pp[6], c[6], sum, 20, 128);
adapt_prob(&pp[7], c[7] + c[8], c[9] + c[10], 20, 128);
adapt_prob(&pp[8], c[7], c[8], 20, 128);
adapt_prob(&pp[9], c[9], c[10], 20, 128);
adapt_prob(&p->mv_comp[i].class0, s->counts.mv_comp[i].class0[0],
s->counts.mv_comp[i].class0[1], 20, 128);
pp = p->mv_comp[i].bits;
c2 = s->counts.mv_comp[i].bits;
for (j = 0; j < 10; j++)
adapt_prob(&pp[j], c2[j][0], c2[j][1], 20, 128);
for (j = 0; j < 2; j++) {
pp = p->mv_comp[i].class0_fp[j];
c = s->counts.mv_comp[i].class0_fp[j];
adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
adapt_prob(&pp[2], c[2], c[3], 20, 128);
}
pp = p->mv_comp[i].fp;
c = s->counts.mv_comp[i].fp;
adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
adapt_prob(&pp[2], c[2], c[3], 20, 128);
if (s->highprecisionmvs) {
adapt_prob(&p->mv_comp[i].class0_hp,
s->counts.mv_comp[i].class0_hp[0],
s->counts.mv_comp[i].class0_hp[1], 20, 128);
adapt_prob(&p->mv_comp[i].hp, s->counts.mv_comp[i].hp[0],
s->counts.mv_comp[i].hp[1], 20, 128);
}
}
// y intra modes
for (i = 0; i < 4; i++) {
uint8_t *pp = p->y_mode[i];
unsigned *c = s->counts.y_mode[i], sum, s2;
sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9];
adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128);
sum -= c[TM_VP8_PRED];
adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128);
sum -= c[VERT_PRED];
adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128);
s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED];
sum -= s2;
adapt_prob(&pp[3], s2, sum, 20, 128);
s2 -= c[HOR_PRED];
adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128);
adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED],
20, 128);
sum -= c[DIAG_DOWN_LEFT_PRED];
adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128);
sum -= c[VERT_LEFT_PRED];
adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128);
adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128);
}
// uv intra modes
for (i = 0; i < 10; i++) {
uint8_t *pp = p->uv_mode[i];
unsigned *c = s->counts.uv_mode[i], sum, s2;
sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9];
adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128);
sum -= c[TM_VP8_PRED];
adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128);
sum -= c[VERT_PRED];
adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128);
s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED];
sum -= s2;
adapt_prob(&pp[3], s2, sum, 20, 128);
s2 -= c[HOR_PRED];
adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128);
adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED],
20, 128);
sum -= c[DIAG_DOWN_LEFT_PRED];
adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128);
sum -= c[VERT_LEFT_PRED];
adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128);
adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128);
}
}
......@@ -35,6 +35,7 @@ OBJS-$(CONFIG_VORBIS_DECODER) += x86/vorbisdsp_init.o
OBJS-$(CONFIG_VP3DSP) += x86/vp3dsp_init.o
OBJS-$(CONFIG_VP6_DECODER) += x86/vp6dsp_init.o
OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp_init.o
OBJS-$(CONFIG_VP9_DECODER) += x86/vp9dsp_init.o
OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o
MMX-OBJS-$(CONFIG_DSPUTIL) += x86/dsputil_mmx.o \
......@@ -90,3 +91,4 @@ YASM-OBJS-$(CONFIG_VP3DSP) += x86/vp3dsp.o
YASM-OBJS-$(CONFIG_VP6_DECODER) += x86/vp6dsp.o
YASM-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp.o \
x86/vp8dsp_loopfilter.o
YASM-OBJS-$(CONFIG_VP9_DECODER) += x86/vp9dsp.o
;******************************************************************************
;* VP9 SIMD optimizations
;*
;* Copyright (c) 2013 Ronald S. Bultje <rsbultje gmail com>
;*
;* This file is part of Libav.
;*
;* Libav 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.
;*
;* Libav 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 Libav; if not, write to the Free Software
;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
;******************************************************************************
%include "libavutil/x86/x86util.asm"
SECTION_RODATA
; FIXME share with vp8dsp.asm
pw_256: times 8 dw 256
%macro F8_TAPS 8
times 8 db %1, %2
times 8 db %3, %4
times 8 db %5, %6
times 8 db %7, %8
%endmacro
; int8_t ff_filters_ssse3[3][15][4][16]
const filters_ssse3 ; smooth
F8_TAPS -3, -1, 32, 64, 38, 1, -3, 0
F8_TAPS -2, -2, 29, 63, 41, 2, -3, 0
F8_TAPS -2, -2, 26, 63, 43, 4, -4, 0
F8_TAPS -2, -3, 24, 62, 46, 5, -4, 0
F8_TAPS -2, -3, 21, 60, 49, 7, -4, 0
F8_TAPS -1, -4, 18, 59, 51, 9, -4, 0
F8_TAPS -1, -4, 16, 57, 53, 12, -4, -1
F8_TAPS -1, -4, 14, 55, 55, 14, -4, -1
F8_TAPS -1, -4, 12, 53, 57, 16, -4, -1
F8_TAPS 0, -4, 9, 51, 59, 18, -4, -1
F8_TAPS 0, -4, 7, 49, 60, 21, -3, -2
F8_TAPS 0, -4, 5, 46, 62, 24, -3, -2
F8_TAPS 0, -4, 4, 43, 63, 26, -2, -2
F8_TAPS 0, -3, 2, 41, 63, 29, -2, -2
F8_TAPS 0, -3, 1, 38, 64, 32, -1, -3
; regular
F8_TAPS 0, 1, -5, 126, 8, -3, 1, 0
F8_TAPS -1, 3, -10, 122, 18, -6, 2, 0
F8_TAPS -1, 4, -13, 118, 27, -9, 3, -1
F8_TAPS -1, 4, -16, 112, 37, -11, 4, -1
F8_TAPS -1, 5, -18, 105, 48, -14, 4, -1
F8_TAPS -1, 5, -19, 97, 58, -16, 5, -1
F8_TAPS -1, 6, -19, 88, 68, -18, 5, -1
F8_TAPS -1, 6, -19, 78, 78, -19, 6, -1
F8_TAPS -1, 5, -18, 68, 88, -19, 6, -1
F8_TAPS -1, 5, -16, 58, 97, -19, 5, -1
F8_TAPS -1, 4, -14, 48, 105, -18, 5, -1
F8_TAPS -1, 4, -11, 37, 112, -16, 4, -1
F8_TAPS -1, 3, -9, 27, 118, -13, 4, -1
F8_TAPS 0, 2, -6, 18, 122, -10, 3, -1
F8_TAPS 0, 1, -3, 8, 126, -5, 1, 0
; sharp
F8_TAPS -1, 3, -7, 127, 8, -3, 1, 0
F8_TAPS -2, 5, -13, 125, 17, -6, 3, -1
F8_TAPS -3, 7, -17, 121, 27, -10, 5, -2
F8_TAPS -4, 9, -20, 115, 37, -13, 6, -2
F8_TAPS -4, 10, -23, 108, 48, -16, 8, -3
F8_TAPS -4, 10, -24, 100, 59, -19, 9, -3
F8_TAPS -4, 11, -24, 90, 70, -21, 10, -4
F8_TAPS -4, 11, -23, 80, 80, -23, 11, -4
F8_TAPS -4, 10, -21, 70, 90, -24, 11, -4
F8_TAPS -3, 9, -19, 59, 100, -24, 10, -4
F8_TAPS -3, 8, -16, 48, 108, -23, 10, -4
F8_TAPS -2, 6, -13, 37, 115, -20, 9, -4
F8_TAPS -2, 5, -10, 27, 121, -17, 7, -3
F8_TAPS -1, 3, -6, 17, 125, -13, 5, -2
F8_TAPS 0, 1, -3, 8, 127, -7, 3, -1
SECTION .text
%macro filter_h_fn 1
%assign %%px mmsize/2
cglobal %1_8tap_1d_h_ %+ %%px, 6, 6, 11, dst, src, dstride, sstride, h, filtery
mova m6, [pw_256]
mova m7, [filteryq+ 0]
%if ARCH_X86_64 && mmsize > 8
mova m8, [filteryq+16]
mova m9, [filteryq+32]
mova m10, [filteryq+48]
%endif
.loop:
movh m0, [srcq-3]
movh m1, [srcq-2]
movh m2, [srcq-1]
movh m3, [srcq+0]
movh m4, [srcq+1]
movh m5, [srcq+2]
punpcklbw m0, m1
punpcklbw m2, m3
movh m1, [srcq+3]
movh m3, [srcq+4]
add srcq, sstrideq
punpcklbw m4, m5
punpcklbw m1, m3
pmaddubsw m0, m7
%if ARCH_X86_64 && mmsize > 8
pmaddubsw m2, m8
pmaddubsw m4, m9
pmaddubsw m1, m10
%else
pmaddubsw m2, [filteryq+16]
pmaddubsw m4, [filteryq+32]
pmaddubsw m1, [filteryq+48]
%endif
paddw m0, m2
paddw m4, m1
paddsw m0, m4
pmulhrsw m0, m6
%ifidn %1, avg
movh m1, [dstq]
%endif
packuswb m0, m0
%ifidn %1, avg
pavgb m0, m1
%endif
movh [dstq], m0
add dstq, dstrideq
dec hd
jg .loop
RET
%endmacro
INIT_MMX ssse3
filter_h_fn put
filter_h_fn avg
INIT_XMM ssse3
filter_h_fn put
filter_h_fn avg
%macro filter_v_fn 1
%assign %%px mmsize/2
%if ARCH_X86_64
cglobal %1_8tap_1d_v_ %+ %%px, 6, 8, 11, dst, src, dstride, sstride, h, filtery, src4, sstride3
%else
cglobal %1_8tap_1d_v_ %+ %%px, 4, 7, 11, dst, src, dstride, sstride, filtery, src4, sstride3
mov filteryq, r5mp
%define hd r4mp
%endif
sub srcq, sstrideq
lea sstride3q, [sstrideq*3]
sub srcq, sstrideq
mova m6, [pw_256]
sub srcq, sstrideq
mova m7, [filteryq+ 0]
lea src4q, [srcq+sstrideq*4]
%if ARCH_X86_64 && mmsize > 8
mova m8, [filteryq+16]
mova m9, [filteryq+32]
mova m10, [filteryq+48]
%endif
.loop:
; FIXME maybe reuse loads from previous rows, or just more generally
; unroll this to prevent multiple loads of the same data?
movh m0, [srcq]
movh m1, [srcq+sstrideq]
movh m2, [srcq+sstrideq*2]
movh m3, [srcq+sstride3q]
movh m4, [src4q]
movh m5, [src4q+sstrideq]
punpcklbw m0, m1
punpcklbw m2, m3
movh m1, [src4q+sstrideq*2]
movh m3, [src4q+sstride3q]
add srcq, sstrideq
add src4q, sstrideq
punpcklbw m4, m5
punpcklbw m1, m3
pmaddubsw m0, m7
%if ARCH_X86_64 && mmsize > 8
pmaddubsw m2, m8
pmaddubsw m4, m9
pmaddubsw m1, m10
%else
pmaddubsw m2, [filteryq+16]
pmaddubsw m4, [filteryq+32]
pmaddubsw m1, [filteryq+48]
%endif
paddw m0, m2
paddw m4, m1
paddsw m0, m4
pmulhrsw m0, m6
%ifidn %1, avg
movh m1, [dstq]
%endif
packuswb m0, m0
%ifidn %1, avg
pavgb m0, m1
%endif
movh [dstq], m0
add dstq, dstrideq
dec hd
jg .loop
RET
%endmacro
INIT_MMX ssse3
filter_v_fn put
filter_v_fn avg
INIT_XMM ssse3
filter_v_fn put
filter_v_fn avg
%macro fpel_fn 6
%if %2 == 4
%define %%srcfn movh
%define %%dstfn movh
%else
%define %%srcfn movu
%define %%dstfn mova
%endif
%if %2 <= 16
cglobal %1%2, 5, 7, 4, dst, src, dstride, sstride, h, dstride3, sstride3
lea sstride3q, [sstrideq*3]
lea dstride3q, [dstrideq*3]
%else
cglobal %1%2, 5, 5, 4, dst, src, dstride, sstride, h
%endif
.loop:
%%srcfn m0, [srcq]
%%srcfn m1, [srcq+s%3]
%%srcfn m2, [srcq+s%4]
%%srcfn m3, [srcq+s%5]
lea srcq, [srcq+sstrideq*%6]
%ifidn %1, avg
pavgb m0, [dstq]
pavgb m1, [dstq+d%3]
pavgb m2, [dstq+d%4]
pavgb m3, [dstq+d%5]
%endif
%%dstfn [dstq], m0
%%dstfn [dstq+d%3], m1
%%dstfn [dstq+d%4], m2
%%dstfn [dstq+d%5], m3
lea dstq, [dstq+dstrideq*%6]
sub hd, %6
jnz .loop
RET
%endmacro
%define d16 16
%define s16 16
INIT_MMX mmx
fpel_fn put, 4, strideq, strideq*2, stride3q, 4
fpel_fn put, 8, strideq, strideq*2, stride3q, 4
INIT_MMX sse
fpel_fn avg, 4, strideq, strideq*2, stride3q, 4
fpel_fn avg, 8, strideq, strideq*2, stride3q, 4
INIT_XMM sse
fpel_fn put, 16, strideq, strideq*2, stride3q, 4
fpel_fn put, 32, mmsize, strideq, strideq+mmsize, 2
fpel_fn put, 64, mmsize, mmsize*2, mmsize*3, 1
INIT_XMM sse2
fpel_fn avg, 16, strideq, strideq*2, stride3q, 4
fpel_fn avg, 32, mmsize, strideq, strideq+mmsize, 2
fpel_fn avg, 64, mmsize, mmsize*2, mmsize*3, 1
%undef s16
%undef d16
/*
* VP9 SIMD optimizations
*
* Copyright (c) 2013 Ronald S. Bultje <rsbultje@gmail.com>
*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/cpu.h"
#include "libavutil/internal.h"
#include "libavutil/mem.h"
#include "libavutil/x86/asm.h"
#include "libavutil/x86/cpu.h"
#include "libavcodec/vp9.h"
#if HAVE_YASM
#define fpel_func(avg, sz, opt) \
void ff_ ## avg ## sz ## _ ## opt(uint8_t *dst, const uint8_t *src, \
ptrdiff_t dst_stride, \
ptrdiff_t src_stride, \
int h, int mx, int my)
fpel_func(put, 4, mmx);
fpel_func(put, 8, mmx);
fpel_func(put, 16, sse);
fpel_func(put, 32, sse);
fpel_func(put, 64, sse);
fpel_func(avg, 4, sse);
fpel_func(avg, 8, sse);
fpel_func(avg, 16, sse2);
fpel_func(avg, 32, sse2);
fpel_func(avg, 64, sse2);
#undef fpel_func
#define mc_func(avg, sz, dir, opt) \
void \
ff_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t dst_stride, \
ptrdiff_t src_stride, \
int h, \
const int8_t (*filter)[16])
#define mc_funcs(sz) \
mc_func(put, sz, h, ssse3); \
mc_func(avg, sz, h, ssse3); \
mc_func(put, sz, v, ssse3); \
mc_func(avg, sz, v, ssse3)
mc_funcs(4);
mc_funcs(8);
#undef mc_funcs
#undef mc_func
#define mc_rep_func(avg, sz, hsz, dir, opt) \
static av_always_inline void \
ff_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t dst_stride, \
ptrdiff_t src_stride, \
int h, \
const int8_t (*filter)[16]) \
{ \
ff_ ## avg ## _8tap_1d_ ## dir ## _ ## hsz ## _ ## opt(dst, src, \
dst_stride, \
src_stride, \
h, \
filter); \
ff_ ## avg ## _8tap_1d_ ## dir ## _ ## hsz ## _ ## opt(dst + hsz, \
src + hsz, \
dst_stride, \
src_stride, \
h, filter); \
}
#define mc_rep_funcs(sz, hsz) \
mc_rep_func(put, sz, hsz, h, ssse3); \
mc_rep_func(avg, sz, hsz, h, ssse3); \
mc_rep_func(put, sz, hsz, v, ssse3); \
mc_rep_func(avg, sz, hsz, v, ssse3)
mc_rep_funcs(16, 8);
mc_rep_funcs(32, 16);
mc_rep_funcs(64, 32);
#undef mc_rep_funcs
#undef mc_rep_func
extern const int8_t ff_filters_ssse3[3][15][4][16];
#define filter_8tap_2d_fn(op, sz, f, fname) \
static void \
op ## _8tap_ ## fname ## _ ## sz ## hv_ssse3(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t dst_stride, \
ptrdiff_t src_stride, \
int h, int mx, int my) \
{ \
LOCAL_ALIGNED_16(uint8_t, temp, [71 * 64]); \
ff_put_8tap_1d_h_ ## sz ## _ssse3(temp, src - 3 * src_stride, \
64, src_stride, \
h + 7, \
ff_filters_ssse3[f][mx - 1]); \
ff_ ## op ## _8tap_1d_v_ ## sz ## _ssse3(dst, temp + 3 * 64, \
dst_stride, 64, \
h, \
ff_filters_ssse3[f][my - 1]); \
}
#define filters_8tap_2d_fn(op, sz) \
filter_8tap_2d_fn(op, sz, FILTER_8TAP_REGULAR, regular) \
filter_8tap_2d_fn(op, sz, FILTER_8TAP_SHARP, sharp) \
filter_8tap_2d_fn(op, sz, FILTER_8TAP_SMOOTH, smooth)
#define filters_8tap_2d_fn2(op) \
filters_8tap_2d_fn(op, 64) \
filters_8tap_2d_fn(op, 32) \
filters_8tap_2d_fn(op, 16) \
filters_8tap_2d_fn(op, 8) \
filters_8tap_2d_fn(op, 4)
filters_8tap_2d_fn2(put)
filters_8tap_2d_fn2(avg)
#undef filters_8tap_2d_fn2
#undef filters_8tap_2d_fn
#undef filter_8tap_2d_fn
#define filter_8tap_1d_fn(op, sz, f, fname, dir, dvar) \
static void \
op ## _8tap_ ## fname ## _ ## sz ## dir ## _ssse3(uint8_t *dst, \
const uint8_t *src, \
ptrdiff_t dst_stride, \
ptrdiff_t src_stride, \
int h, int mx, \
int my) \
{ \
ff_ ## op ## _8tap_1d_ ## dir ## _ ## sz ## _ssse3(dst, src, \
dst_stride, \
src_stride, h, \
ff_filters_ssse3[f][dvar - 1]); \
}
#define filters_8tap_1d_fn(op, sz, dir, dvar) \
filter_8tap_1d_fn(op, sz, FILTER_8TAP_REGULAR, regular, dir, dvar) \
filter_8tap_1d_fn(op, sz, FILTER_8TAP_SHARP, sharp, dir, dvar) \
filter_8tap_1d_fn(op, sz, FILTER_8TAP_SMOOTH, smooth, dir, dvar)
#define filters_8tap_1d_fn2(op, sz) \
filters_8tap_1d_fn(op, sz, h, mx) \
filters_8tap_1d_fn(op, sz, v, my)
#define filters_8tap_1d_fn3(op) \
filters_8tap_1d_fn2(op, 64) \
filters_8tap_1d_fn2(op, 32) \
filters_8tap_1d_fn2(op, 16) \
filters_8tap_1d_fn2(op, 8) \
filters_8tap_1d_fn2(op, 4)
filters_8tap_1d_fn3(put)
filters_8tap_1d_fn3(avg)
#undef filters_8tap_1d_fn
#undef filters_8tap_1d_fn2
#undef filters_8tap_1d_fn3
#undef filter_8tap_1d_fn
#endif /* HAVE_YASM */
av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp)
{
#if HAVE_YASM
int cpu_flags = av_get_cpu_flags();
#define init_fpel(idx1, idx2, sz, type, opt) \
dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][0][0] = \
dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][0][0] = \
dsp->mc[idx1][FILTER_8TAP_SHARP ][idx2][0][0] = \
dsp->mc[idx1][FILTER_BILINEAR ][idx2][0][0] = ff_ ## type ## sz ## _ ## opt
#define init_subpel1(idx1, idx2, idxh, idxv, sz, dir, type, opt) \
dsp->mc[idx1][FILTER_8TAP_SMOOTH][idx2][idxh][idxv] = type ## _8tap_smooth_ ## sz ## dir ## _ ## opt; \
dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][idxh][idxv] = type ## _8tap_regular_ ## sz ## dir ## _ ## opt; \
dsp->mc[idx1][FILTER_8TAP_SHARP][idx2][idxh][idxv] = type ## _8tap_sharp_ ## sz ## dir ## _ ## opt
#define init_subpel2(idx, idxh, idxv, dir, type, opt) \
init_subpel1(0, idx, idxh, idxv, 64, dir, type, opt); \
init_subpel1(1, idx, idxh, idxv, 32, dir, type, opt); \
init_subpel1(2, idx, idxh, idxv, 16, dir, type, opt); \
init_subpel1(3, idx, idxh, idxv, 8, dir, type, opt); \
init_subpel1(4, idx, idxh, idxv, 4, dir, type, opt)
#define init_subpel3(idx, type, opt) \
init_subpel2(idx, 1, 1, hv, type, opt); \
init_subpel2(idx, 0, 1, v, type, opt); \
init_subpel2(idx, 1, 0, h, type, opt)
if (EXTERNAL_MMX(cpu_flags)) {
init_fpel(4, 0, 4, put, mmx);
init_fpel(3, 0, 8, put, mmx);
}
if (EXTERNAL_SSE(cpu_flags)) {
init_fpel(2, 0, 16, put, sse);
init_fpel(1, 0, 32, put, sse);
init_fpel(0, 0, 64, put, sse);
init_fpel(4, 1, 4, avg, sse);
init_fpel(3, 1, 8, avg, sse);
}
if (EXTERNAL_SSE2(cpu_flags)) {
init_fpel(2, 1, 16, avg, sse2);
init_fpel(1, 1, 32, avg, sse2);
init_fpel(0, 1, 64, avg, sse2);
}
if (EXTERNAL_SSSE3(cpu_flags)) {
init_subpel3(0, put, ssse3);
init_subpel3(1, avg, ssse3);
}
#undef init_fpel
#undef init_subpel1
#undef init_subpel2
#undef init_subpel3
#endif /* HAVE_YASM */
}
......@@ -52,3 +52,34 @@ $(call FATE_VP8_FULL,-emu-edge,-flags +emu_edge)
FATE_SAMPLES_AVCONV-$(CONFIG_VP8_DECODER) += $(FATE_VP8-yes)
fate-vp8: $(FATE_VP8-yes)
define FATE_VP9_SUITE
FATE_VP9-$(CONFIG_MATROSKA_DEMUXER) += fate-vp9$(2)-$(1)
fate-vp9$(2)-$(1): CMD = framemd5 $(3) -i $(TARGET_SAMPLES)/vp9-test-vectors/vp90-2-$(1).webm
fate-vp9$(2)-$(1): REF = $(SRC_PATH)/tests/ref/fate/vp9-$(1)
endef
VP9_Q = 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 \
16 17 18 19 20 21 22 23 24 25 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
VP9_SHARP = 1 2 3 4 5 6 7
VP9_SIZE_A = 08 10 16 18 32 34 64 66
VP9_SIZE_B = 196 198 200 202 208 210 224 226
define FATE_VP9_FULL
$(foreach Q,$(VP9_Q),$(eval $(call FATE_VP9_SUITE,00-quantizer-$(Q),$(1),$(2))))
$(foreach SHARP,$(VP9_SHARP),$(eval $(call FATE_VP9_SUITE,01-sharpness-$(SHARP),$(1),$(2))))
$(foreach W,$(VP9_SIZE_A),$(eval $(foreach H,$(VP9_SIZE_A),$(eval $(call FATE_VP9_SUITE,02-size-$(W)x$(H),$(1),$(2))))))
$(foreach W,$(VP9_SIZE_B),$(eval $(foreach H,$(VP9_SIZE_B),$(eval $(call FATE_VP9_SUITE,03-size-$(W)x$(H),$(1),$(2))))))
$(eval $(call FATE_VP9_SUITE,03-deltaq,$(1),$(2)))
$(eval $(call FATE_VP9_SUITE,2pass-akiyo,$(1),$(2)))
$(eval $(call FATE_VP9_SUITE,segmentation-akiyo,$(1),$(2)))
$(eval $(call FATE_VP9_SUITE,tiling-pedestrian,$(1),$(2)))
endef
$(eval $(call FATE_VP9_FULL))
$(eval $(call FATE_VP9_FULL,-emu-edge,-flags +emu_edge))
FATE_SAMPLES_AVCONV-$(CONFIG_VP9_DECODER) += $(FATE_VP9-yes)
fate-vp9: $(FATE_VP9-yes)
#tb 0: 1/1000
0, 0, 0, 0, 152064, c3fbb7abbdb5bd4ed4a7e34768c17df1
0, 33, 33, 0, 152064, 08203c2595bdb2d58ead6f921345d699
#tb 0: 1/1000
0, 0, 0, 0, 152064, f041b870cf9236d5f22e2b08a77d5958
0, 33, 33, 0, 152064, cbdb7526986ae15592891488c9afc84c
#tb 0: 1/1000
0, 0, 0, 0, 152064, 98048cfdb4af5059f4085c5acc94ef8f
0, 33, 33, 0, 152064, 8160183e1eed1d0af4427be216b8b9f7
#tb 0: 1/1000
0, 0, 0, 0, 152064, 15c548208f5eda243a151a42f4d64855
0, 33, 33, 0, 152064, e96d463dc8e9b27b1c2ec40f77eee6ef
#tb 0: 1/1000
0, 0, 0, 0, 152064, 928c64a0747ac57ab50c1520d694fea7
0, 33, 33, 0, 152064, a6f6daa293231e95ef30ed168f582c84
#tb 0: 1/1000
0, 0, 0, 0, 152064, 082460718b7d7046c8fb23184b7f71ca
0, 33, 33, 0, 152064, 4a41aad51c40a92df72333e13f47d3fe
#tb 0: 1/1000
0, 0, 0, 0, 152064, cfca1bed96ff62a69b2d841fda01c6b9
0, 33, 33, 0, 152064, 9b4d61f1b998745c108f8eb67925e03d
#tb 0: 1/1000
0, 0, 0, 0, 152064, 6f5122064bead9d9882bec2698a6ed9c
0, 33, 33, 0, 152064, 50dae67d2f57a76eece210dee8b6df9e
#tb 0: 1/1000
0, 0, 0, 0, 152064, eb3d6985fcda5d93dd62d53354e8a093
0, 33, 33, 0, 152064, 5b1f5b7780b4cafe1f75e56a0b526643
#tb 0: 1/1000
0, 0, 0, 0, 152064, d7ccaf28c59875fe91983def5490d2b1
0, 33, 33, 0, 152064, bd98fe9492054826748de840b4495309
#tb 0: 1/1000
0, 0, 0, 0, 152064, 20dda6231f9801c9c237c6d09d9939b6
0, 33, 33, 0, 152064, 23c91e93807fb9a4ed5bd5bdd449d99f
#tb 0: 1/1000
0, 0, 0, 0, 152064, 960833315ebcdee97f46c4d98d0f3fef
0, 33, 33, 0, 152064, eec40507d17b64b7895a61cb87b2096a
#tb 0: 1/1000
0, 0, 0, 0, 152064, 6533224d3b6ba1ec0dd973bbe56c6349
0, 33, 33, 0, 152064, 12ceadc6d28327a24a75f8c40b6084d1
#tb 0: 1/1000
0, 0, 0, 0, 152064, 7268de6756014f79a56dcf010c52a97f
0, 33, 33, 0, 152064, 9e39e9b0e2295b8460dfa05f44762771
#tb 0: 1/1000
0, 0, 0, 0, 152064, 57e9e333c641fa952f7485b788df225a
0, 33, 33, 0, 152064, 551f0cea83dcdf4540c3983736757874
#tb 0: 1/1000
0, 0, 0, 0, 152064, 17a0a2842856b9e89aede237648d5dda
0, 33, 33, 0, 152064, c9fcade888a38621bebe3d4b41664245
#tb 0: 1/1000
0, 0, 0, 0, 152064, 6cc2089e9a3d352fe10b59ccd935c677
0, 33, 33, 0, 152064, d165bf7b9cb901e121a65038758d8613
#tb 0: 1/1000
0, 0, 0, 0, 152064, bc80511c83162c09661f155cd29f6dd8
0, 33, 33, 0, 152064, a62f1cbdb3f86d2fb4c880cfd917def5
#tb 0: 1/1000
0, 0, 0, 0, 152064, b2d350f6faa41cb50c2e8a9907d0f4a5
0, 33, 33, 0, 152064, 39b4380d16bc8e093dd4dba475175fb3
#tb 0: 1/1000
0, 0, 0, 0, 152064, 441e09be3c15fcb240afd74bb7a10a72
0, 33, 33, 0, 152064, 32ae5dac876ca5d5ae6ab7c74f4dc25d
#tb 0: 1/1000
0, 0, 0, 0, 152064, 7786eb9944dba0553e129133523a98c1
0, 33, 33, 0, 152064, 206d888f8453427f10a40aa8bf5f6df0
#tb 0: 1/1000
0, 0, 0, 0, 152064, aab95e195be71feca050a839d7b3154d
0, 33, 33, 0, 152064, 02a05d699bbbdc477e34bb0dad9f0391
#tb 0: 1/1000
0, 0, 0, 0, 152064, 41f853c3ee2d4611b645cc643d82e287
0, 33, 33, 0, 152064, 1c240c653110ff8609ca0f0287a6496d
#tb 0: 1/1000
0, 0, 0, 0, 152064, bc5b07369df50c8f97ce1a377fe513cf
0, 33, 33, 0, 152064, ce62ddb4f3e305d0f8587ae8bb44cc79
#tb 0: 1/1000
0, 0, 0, 0, 152064, 982d54041221c977b6f0e37a9236cc76
0, 33, 33, 0, 152064, 57631e7f13f645c834e2944ebfd6d40e
#tb 0: 1/1000
0, 0, 0, 0, 152064, b0fb55f3f2f56b3d27038e83c10123ce
0, 33, 33, 0, 152064, 9fcac3becdcc2d30d778a55eca4c2018
#tb 0: 1/1000
0, 0, 0, 0, 152064, 4f645e0f354da77b9e2f2a6753c361da
0, 33, 33, 0, 152064, b7542998ec298273ca662bc9b658d10e
#tb 0: 1/1000
0, 0, 0, 0, 152064, 6edc96a3747cad43828397045764206e
0, 33, 33, 0, 152064, 5fbc65d20fdca1abd69079851ce676d3
#tb 0: 1/1000
0, 0, 0, 0, 152064, 5db3e910e70da38bb91d01d73acc33dd
0, 33, 33, 0, 152064, b920ee7f7e61b7fdf9f44b1f738d0292
#tb 0: 1/1000
0, 0, 0, 0, 152064, 3cb3e310be5305077efa6216f6f10654
0, 33, 33, 0, 152064, 692d3e098af5978fe1a898ebc1a66a7a
#tb 0: 1/1000
0, 0, 0, 0, 152064, e3b3cea66ea38c5dfba1aa73bb4c611d
0, 33, 33, 0, 152064, 42bb3e54b19c3f4c4f7ee3a6ba012e19
#tb 0: 1/1000
0, 0, 0, 0, 152064, 2523e9ecfd3781eafcd7da192dc105e9
0, 33, 33, 0, 152064, 6d5feea012b9a1f51fc643633e728764
#tb 0: 1/1000
0, 0, 0, 0, 152064, 0a0305eba36500ebf6cc6cc0f01f5a3b
0, 33, 33, 0, 152064, 2c76bcd6763467f9057a726fbcf50ab1
#tb 0: 1/1000
0, 0, 0, 0, 152064, c68433e0e94047c220be9b629334f744
0, 33, 33, 0, 152064, fcfa4dff7a39bc9c5e315849ecbb46ea
#tb 0: 1/1000
0, 0, 0, 0, 152064, ad9dc2f912c137b014a33e2792c88a25
0, 33, 33, 0, 152064, 11221ee4ea5c776f43af68756682cd5a
#tb 0: 1/1000
0, 0, 0, 0, 152064, 75031f898cccf303a64ab46b1f815389
0, 33, 33, 0, 152064, a4fc864e7fbc470dfcab6207e0eea152
#tb 0: 1/1000
0, 0, 0, 0, 152064, c7824af009fde6cafdd8d39fae6bb6cf
0, 33, 33, 0, 152064, 516a82d5fc4dfa3daf713ed2ec36041b
#tb 0: 1/1000
0, 0, 0, 0, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 33, 33, 0, 152064, fb23e0bc64728a492a33d985032f21b8
#tb 0: 1/1000
0, 0, 0, 0, 152064, 8347bfb891317e89ef66781d6c28e24f
0, 33, 33, 0, 152064, a5722f824d32deac042513a1a7dcdcd0
#tb 0: 1/1000
0, 0, 0, 0, 152064, 018968f97fac3bdff146cf22c1da5ef0
0, 33, 33, 0, 152064, ca8b09b01e5132183395e238f1c7901e
#tb 0: 1/1000
0, 0, 0, 0, 152064, 792660f6589ad5340be4bd0554435866
0, 33, 33, 0, 152064, 68c84c8a15d679e0a73678b93215c62c
#tb 0: 1/1000
0, 0, 0, 0, 152064, a456bdfc6c1c07b4cb3a3848843743b9
0, 33, 33, 0, 152064, fe41a12b8cb6bc5667ba2179e076f3b0
#tb 0: 1/1000
0, 0, 0, 0, 152064, f016dd8431694d989700fb1ba71a5b2d
0, 33, 33, 0, 152064, e89c3c5b935157b40f2fb0ab92415828
#tb 0: 1/1000
0, 0, 0, 0, 152064, 7b8ab82625f3006bac89d4fb5197e71c
0, 33, 33, 0, 152064, 18bd3716045563dfba2c72b640b3274b
#tb 0: 1/1000
0, 0, 0, 0, 152064, 66fde04d8320c750e56406feefd29979
0, 33, 33, 0, 152064, f9d01d8fc1722ec345e624e14b404215
#tb 0: 1/1000
0, 0, 0, 0, 152064, cc97597b015896d73f3e60e7ae44c4da
0, 33, 33, 0, 152064, fea98bc508f92135641ab99762444b14
#tb 0: 1/1000
0, 0, 0, 0, 152064, 79ed95c741178bb3c0954f1f6f8e21a3
0, 33, 33, 0, 152064, f02a06a5e2b5b7619c9a52c5bea0564d
#tb 0: 1/1000
0, 0, 0, 0, 152064, 9b98e948b8c2a822f21bd8419e6f4410
0, 33, 33, 0, 152064, 491382d68c16c2a3c6f1746598bc4a97
#tb 0: 1/1000
0, 0, 0, 0, 152064, f0f095b0edae7262f44d7ed7ef84ded4
0, 33, 33, 0, 152064, 0e833889ccac81d60251007d1baf6500
#tb 0: 1/1000
0, 0, 0, 0, 152064, 6c1b7b7827617fb9b8417aca2cfdbcaa
0, 33, 33, 0, 152064, 4c1fc8a89297fdcf79f0faabd42b8684
#tb 0: 1/1000
0, 0, 0, 0, 152064, ca6142db68463487bc28c888ab38476c
0, 33, 33, 0, 152064, 02a71153ec70f569524c3d814cb62f86
#tb 0: 1/1000
0, 0, 0, 0, 152064, eece2627df1ddf0872256eb92352e179
0, 33, 33, 0, 152064, 0ee9f221246ad747250e4b5e8ba586e2
#tb 0: 1/1000
0, 0, 0, 0, 152064, 7290039d974c4e50db9d69f9864bcdbe
0, 33, 33, 0, 152064, 264765de9d02503038a4da54133b9f85
#tb 0: 1/1000
0, 0, 0, 0, 152064, 917af24da66f143a56a01eb2c2254285
0, 33, 33, 0, 152064, 45a05d3bc644420519619e4115662a70
#tb 0: 1/1000
0, 0, 0, 0, 152064, 6fea2820bb10a9dec9add4d2452b01f5
0, 33, 33, 0, 152064, 74675169a4bfc2ff5463c4db5d85a79f
#tb 0: 1/1000
0, 0, 0, 0, 152064, 11e5d196f6537fb7d85988d90195e556
0, 33, 33, 0, 152064, 8536106795f7c93c5a43a11493527469
#tb 0: 1/1000
0, 0, 0, 0, 152064, 40839b7a3a40ec10f96b8a75224f646d
0, 33, 33, 0, 152064, 11408dd73e8c45ddaab99f5c9650102b
#tb 0: 1/1000
0, 0, 0, 0, 152064, d0e9fa03dd48da4592ebaadb4e3794e0
0, 33, 33, 0, 152064, 5172e29b1e04cd543833d6a68aab297c
#tb 0: 1/1000
0, 0, 0, 0, 152064, bef4a27d460e7697e038fe6f1c8bd597
0, 33, 33, 0, 152064, 124674686cafc5f2ff5bc7ea412b8f3b
#tb 0: 1/1000
0, 0, 0, 0, 152064, ae9d99e9d16ef20073300559566844ae
0, 33, 33, 0, 152064, da9405e5a6bfe4ed18d927ba2004008e
#tb 0: 1/1000
0, 0, 0, 0, 152064, 9e66bb8e1b5e206ea4afe4bf2d335ac5
0, 33, 33, 0, 152064, 092b74c905c12c1e87e90f5a79857736
#tb 0: 1/1000
0, 0, 0, 0, 152064, d062dc6be246c8042744018765ef50a8
0, 33, 33, 0, 152064, 45fd9cbacb6a91060a7e49a58a85869d
#tb 0: 1/1000
0, 0, 0, 0, 152064, 62f7e42fe653e81c5a65a25389e045b5
0, 33, 33, 0, 152064, cb0cdd0b25689e0a43328550011d960d
#tb 0: 1/1000
0, 0, 0, 0, 152064, 8467643dceff827e04acd82eeff1d1b0
0, 33, 33, 0, 152064, c786f49d66f4dfd685dea9605821a19f
#tb 0: 1/1000
0, 0, 0, 0, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 33, 33, 0, 152064, aa20a75be3a316193496706c9f760d08
0, 66, 66, 0, 152064, 95567be97a64d3c9efe45f2524116a2e
0, 100, 100, 0, 152064, 219e86cd6b3cca312856eead21776b1c
0, 133, 133, 0, 152064, 4a67fd359ca362398e97c15eb018a2bb
0, 166, 166, 0, 152064, 9916d4e359274d690827f0eb22547423
0, 200, 200, 0, 152064, a07785b52561150c48f1a8eff89d5d75
0, 233, 233, 0, 152064, a3382a92982953dfa20018e5ac975b51
0, 266, 266, 0, 152064, 911836989ca7b148438aa3ec7fc7e303
0, 300, 300, 0, 152064, 5627b981e3fc9e4401d35d3a5ab25917
#tb 0: 1/1000
0, 0, 0, 0, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 33, 33, 0, 152064, cd94572239817ae7c9b07de739c3272b
0, 66, 66, 0, 152064, 383cf752d457e122b5ff49d08960208e
0, 100, 100, 0, 152064, 1c0a6ec9cd3ce29b8b004e7526f1b07e
0, 133, 133, 0, 152064, 91c42a8a108d67947cabfc2a5a80df66
0, 166, 166, 0, 152064, 08c57fc1f3fec0305883315a66c714d1
0, 200, 200, 0, 152064, 70cb8d8dc83eac82f2d3c4b0376bb1aa
0, 233, 233, 0, 152064, ffd62a9ef829ec81f0f74f740488a41f
0, 266, 266, 0, 152064, bab0aa23b5854e2a70926046e4618710
0, 300, 300, 0, 152064, fec456f38f2a43661e786a8d5f67ed15
#tb 0: 1/1000
0, 0, 0, 0, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 33, 33, 0, 152064, 0d487a146393a0b8b84b4be1b371b507
0, 66, 66, 0, 152064, 68372e191eba620a431cfff226026ac3
0, 100, 100, 0, 152064, de7fd274460e36b983fe93acc208d72f
0, 133, 133, 0, 152064, afbd36c61bab65b98ff9acf08e215721
0, 166, 166, 0, 152064, e1e9fc2ab4e7a187a8d8d84aae48d6b9
0, 200, 200, 0, 152064, 11d95de6a9cc5e00511e99534779faac
0, 233, 233, 0, 152064, cd2f5539fdfc2d8eefe6b6da28c13398
0, 266, 266, 0, 152064, a8b3aeed41da7aeb8d5b962ee4a4af93
0, 300, 300, 0, 152064, 4283670bd1c1c506ef18d3dafca22035
#tb 0: 1/1000
0, 0, 0, 0, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 33, 33, 0, 152064, 8bad76c55b5149169d64ce6512521de6
0, 66, 66, 0, 152064, c1d986e1f9bf46382e598ba289b9bd7c
0, 100, 100, 0, 152064, 86c097ac6069c786023d3561dae68bac
0, 133, 133, 0, 152064, 8c238a2831b8c7c49736b6de6ff76ed8
0, 166, 166, 0, 152064, cb5a038ed0a74a317ee72dae93a7ee3e
0, 200, 200, 0, 152064, f8fe330a257e3e4e4c39c1c12820a654
0, 233, 233, 0, 152064, a73e2fcdcbb9334c0c123f8276a2c881
0, 266, 266, 0, 152064, 24fccece8ee639e4d0e00e4060e1db0c
0, 300, 300, 0, 152064, 46d6e9aad69a39c718c5fd1e41e86e6e
#tb 0: 1/1000
0, 0, 0, 0, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 33, 33, 0, 152064, f1ce0a5d57a46c9ff1331804b7b03fdb
0, 66, 66, 0, 152064, 0364a085b06bee6b980189cf5378eda9
0, 100, 100, 0, 152064, 4b5358698d734b0ae210909a913d4c1e
0, 133, 133, 0, 152064, dc22565aaceee77b15fd8ab3c84bd5e0
0, 166, 166, 0, 152064, 5f6340b656536292b46ba9a647aeb6e4
0, 200, 200, 0, 152064, b7d4bce9a04b2a6caa45801be15e331e
0, 233, 233, 0, 152064, 534c851cfe59ffc047815ece98d8cede
0, 266, 266, 0, 152064, 786b0e1564d5c71aabfc2dd528cff4e7
0, 300, 300, 0, 152064, cac0366209cf471bb7cc3e64966cbbd4
#tb 0: 1/1000
0, 0, 0, 0, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 33, 33, 0, 152064, 45d9ca07ed04210b1ebc743169bc8ec4
0, 66, 66, 0, 152064, 5b646cc309a711f1d8814f925002d8c4
0, 100, 100, 0, 152064, 34db8db727fa1ded0a55cc7cf85be249
0, 133, 133, 0, 152064, 54173d08afe6369b16a9c0c9cc6ce04d
0, 166, 166, 0, 152064, 76275b0a478cdb3c1fb527ebbce023c3
0, 200, 200, 0, 152064, e7643cdf0c42f2af700d8730bfc1a453
0, 233, 233, 0, 152064, 6e53097e56f680cb658d63100e7736f7
0, 266, 266, 0, 152064, 1a407c3c8ea1d5245ae68c5ce7de70e1
0, 300, 300, 0, 152064, 6cbca24912cadf09b20be74f14e359c9
#tb 0: 1/1000
0, 0, 0, 0, 152064, a2e5c820fd9733e18f9349fb658ca281
0, 33, 33, 0, 152064, f719d0be18d16a448b4e7da3e2d9bf28
0, 66, 66, 0, 152064, 83ee8ebc0ca796782a2376a76f2ffc26
0, 100, 100, 0, 152064, 7cf5afdbc229e1af50a5377cfc23d831
0, 133, 133, 0, 152064, 44244e896e0362f6376ba5afa563ba8b
0, 166, 166, 0, 152064, df5f518d44eb6cb91b2df5a30d27ef82
0, 200, 200, 0, 152064, 43cc3f151b8337aca7ee659c8abeb783
0, 233, 233, 0, 152064, 4e89573470d9b97464e10806fc81aa8b
0, 266, 266, 0, 152064, 62e0ba70f07ece8d85372f0a42e83a9a
0, 300, 300, 0, 152064, 45ac2928acb11326f6c4a21401f3609c
#tb 0: 1/1000
0, 0, 0, 0, 96, 52def242c36123e5a8f5f53d6a971399
0, 33, 33, 0, 96, 79c93360fbd47179400414bbfee0901c
0, 66, 66, 0, 96, c3b1947c79537baa7838905276276a91
0, 100, 100, 0, 96, 20f35e501bdee0bc63e87b9240265c25
0, 133, 133, 0, 96, 5e8f1c464bafd54833c51860906b5368
0, 166, 166, 0, 96, f57b592600dfc99e634a083278af769a
0, 200, 200, 0, 96, 7b02191f85590cbad3f148c7b92d6436
0, 233, 233, 0, 96, b0a1c9870447a1744f64cd4087ef55ee
0, 266, 266, 0, 96, c82712b1ba7a95efb67cbdde0ad708b6
0, 300, 300, 0, 96, 89f4539f8d7a7b45a91fd2f46335988e
#tb 0: 1/1000
0, 0, 0, 0, 120, ea3e0f807304b0eb2d3e329b0124f75c
0, 33, 33, 0, 120, 8d13cf682d63e7eb13094f55d67fc458
0, 66, 66, 0, 120, e729cc6c3684c94a8f6118c618efc3ea
0, 100, 100, 0, 120, ac43a0ace8e4112e877c2491ecc14fb5
0, 133, 133, 0, 120, 53695f90b88d8e8cb838f0faec3238d3
0, 166, 166, 0, 120, 40afd1c4dfd4a2e3b31631c46d252bcc
0, 200, 200, 0, 120, 2b656f76f2e84d2f82d9bda2b5be94d3
0, 233, 233, 0, 120, b22f004d678d047bc401be5e040cf883
0, 266, 266, 0, 120, 57c840319abfb9c31013fbde54de3fb0
0, 300, 300, 0, 120, 0f3dfc156216d7cfb6fd1d8c77dadab9
#tb 0: 1/1000
0, 0, 0, 0, 192, 0553e56a9d89aea496421885aab491f5
0, 33, 33, 0, 192, b2a14cf676f7ebf3c50450050f76ad16
0, 66, 66, 0, 192, a308d981e09b50571fb0c8ebdcefe505
0, 100, 100, 0, 192, d592ec625a0ac0373e82610c3eed9864
0, 133, 133, 0, 192, acd19642455e643023b4fb882c3891ba
0, 166, 166, 0, 192, 5af5390fd8c29b795e0ddf83f3f34284
0, 200, 200, 0, 192, 473505aa2a76231725cf2107d6c9dbef
0, 233, 233, 0, 192, 84860db6887e320f2d64f80cf0032e57
0, 266, 266, 0, 192, 408e9cf60e99ae99d204ff08f3196d1a
0, 300, 300, 0, 192, d8af96b79258f9382e911ed38340bdf5
#tb 0: 1/1000
0, 0, 0, 0, 216, 4c41f93b1b280b37bc77d7047435eaa4
0, 33, 33, 0, 216, c9c80fdba2ebc2b8c3490ae35e34f84f
0, 66, 66, 0, 216, 089d86acb3263fa5ef4f591a7f44556d
0, 100, 100, 0, 216, 938fca6d93b83484144f5054e4838a41
0, 133, 133, 0, 216, e0592e2ac9f5e09525ce0d3904cadf47
0, 166, 166, 0, 216, ea43ff5d1330986e60c08567262ea764
0, 200, 200, 0, 216, 08b40fe109ee90188f1cba9bbb1b376e
0, 233, 233, 0, 216, b067068a2a7e36d5c5b5b405a1e73a18
0, 266, 266, 0, 216, 9cf2d350296288803434b7451bd2be85
0, 300, 300, 0, 216, 3c785e21dc228d6396738fbfcb470289
#tb 0: 1/1000
0, 0, 0, 0, 384, f92a7777fd69aa2f2914d9a41c4828ba
0, 33, 33, 0, 384, 62e1cc73487d2249a88a60e35a22d9c7
0, 66, 66, 0, 384, aa2619b605cb65eda15fdd99d5775550
0, 100, 100, 0, 384, e6f0a491c543b835d0cefe5ca62c3dbe
0, 133, 133, 0, 384, 361be1a06913c398f09494ca1b2d288f
0, 166, 166, 0, 384, 0497bf849a973357c0ccb8d43f5bd8b4
0, 200, 200, 0, 384, 5ac6ac523147c409dd00820622161dd7
0, 233, 233, 0, 384, 7d07245574a46c524360f09be29a5f19
0, 266, 266, 0, 384, fcfa7fbcaf42f81e4e34a4ee5a029ca1
0, 300, 300, 0, 384, 336e3fe4f15d3d6c82d82b1855dcfeb4
#tb 0: 1/1000
0, 0, 0, 0, 408, f3f2cd8f157466ff23dace85d77367ce
0, 33, 33, 0, 408, 639d9b70a14062e95559c12d2b597f91
0, 66, 66, 0, 408, b2ee07a6656af583f19593229fa11848
0, 100, 100, 0, 408, 74e3b5ab4c798a0afe745694e871bbd5
0, 133, 133, 0, 408, 35f1c30d0f8678f319a392a6c53b5989
0, 166, 166, 0, 408, 07e2b4c0b92a394bfb11124fe80476f0
0, 200, 200, 0, 408, 7864bd20dfc5280e5f027d67ea22bf30
0, 233, 233, 0, 408, 10a2925a7b91dfa9b82de76069388fd4
0, 266, 266, 0, 408, 79cc7f7a149e8d6e04e065f75e63733c
0, 300, 300, 0, 408, 6453d10d97532d9bb03f7c06cba9fca0
#tb 0: 1/1000
0, 0, 0, 0, 768, 764bd02b781a38c621a109c12f3d9393
0, 33, 33, 0, 768, 79496bd2b9212026af816b3b7a0587d5
0, 66, 66, 0, 768, 2a3afd47ba3d075033fd94d5c3746c45
0, 100, 100, 0, 768, fca00cad8d37a6646337baebadd0ca31
0, 133, 133, 0, 768, aca376fb3f8a5ef670ecc2430037262a
0, 166, 166, 0, 768, 7e6c8d96d1e24855c3e380f1bf2ce02c
0, 200, 200, 0, 768, 09e051241972969d439f27f324d78490
0, 233, 233, 0, 768, 2566b2a425caaba41305bf04ff10ea01
0, 266, 266, 0, 768, db3995bedee42ada1b4ee63c339daf1b
0, 300, 300, 0, 768, b00b8f1bf4fd907f0487738f5b5442c6
#tb 0: 1/1000
0, 0, 0, 0, 792, df20e8df89449fe50bb610e95a449a95
0, 33, 33, 0, 792, 18f1a66d463274d1b0489f3a50e86857
0, 66, 66, 0, 792, b0cc102875a94c9a92e53826617adbe9
0, 100, 100, 0, 792, dfece7c17b4b149283ef51bdc1bd440e
0, 133, 133, 0, 792, 6e346884f67be259fcabe493109cb63c
0, 166, 166, 0, 792, 6d282127311eb2d958377490d7cb77f0
0, 200, 200, 0, 792, 637ac8b14ca5ddbaf7b8910406c3cd08
0, 233, 233, 0, 792, e7980f3fcb36969da0d218c4389fa9e8
0, 266, 266, 0, 792, 730a1c95b9fb165f6e1a2f33a0d25de0
0, 300, 300, 0, 792, 7bd8424d0783b1c8ad617e17408371bb
#tb 0: 1/1000
0, 0, 0, 0, 120, e1e66a88615da98523ef887f1463fc42
0, 33, 33, 0, 120, 549842fa98c8faf572882d38b0aae390
0, 66, 66, 0, 120, 17ee85785517705fdc78c6122a4b2548
0, 100, 100, 0, 120, 1143391d419dac30a6c11f366157c974
0, 133, 133, 0, 120, b62d2a962c4c36809ef75a610106715c
0, 166, 166, 0, 120, e6f143ca33fbc0e776bb149950cdedff
0, 200, 200, 0, 120, 01716a1077ec66df00474fd4510d2789
0, 233, 233, 0, 120, 8cb5b6a865fa2cbb15f0d7736fda88a6
0, 266, 266, 0, 120, 0fb9fd883e895a540fe1704dddbbab04
0, 300, 300, 0, 120, 150a3b99aa24ef102c92f87c8adb4386
#tb 0: 1/1000
0, 0, 0, 0, 150, 083d638f2e147295d817bb14fff5e4f4
0, 33, 33, 0, 150, 6dbdc445b6fd6bb99f2025cc2a40977e
0, 66, 66, 0, 150, 41714089383b181d64fbfa7de5904608
0, 100, 100, 0, 150, 11fdb8465e1599f7a9227706646d2cba
0, 133, 133, 0, 150, 907876b3342a10040db0851a936af4e3
0, 166, 166, 0, 150, e7b18d47d06b25de205d873d3d941640
0, 200, 200, 0, 150, 523ce7413c8da7f6a657a9b661f36c44
0, 233, 233, 0, 150, 23caff863af875c66c903662a3e1e6a1
0, 266, 266, 0, 150, ed4cc5557203e5b7a119112ee9ceb00b
0, 300, 300, 0, 150, 4bb78a996be3188888d1c60e11a08e1b
#tb 0: 1/1000
0, 0, 0, 0, 240, fab07d6209d2413e0a434e1aaaa12154
0, 33, 33, 0, 240, f9ffffdb96f98527ba2e553d1265edbb
0, 66, 66, 0, 240, 56a992264cf7da2b23dd97435e9d0365
0, 100, 100, 0, 240, b1db980423d8004bd45a789b02b92a65
0, 133, 133, 0, 240, b29496aedc7026566367b634f55ebb28
0, 166, 166, 0, 240, 2bc9def672da4a2fc17cbd669e2b8081
0, 200, 200, 0, 240, 8c54721514cdf577a52a8668b9135f13
0, 233, 233, 0, 240, 2efab81d5e039d82b3bc7b0303b022c4
0, 266, 266, 0, 240, bd0f42b91b5d126fd0baec765b1096ad
0, 300, 300, 0, 240, c6bfea2735a629167bc6a7a7c76eb7f3
#tb 0: 1/1000
0, 0, 0, 0, 270, 0e9182e214aae732d94d007e5fe44888
0, 33, 33, 0, 270, 2630e2674b5611d68218fddac08815e2
0, 66, 66, 0, 270, d5cdd7d6a3de17939f60bb60ef6877da
0, 100, 100, 0, 270, 29d1961096061029e78963fa82581eca
0, 133, 133, 0, 270, 5c2629f8aa59757f6b4aafa9f6cbcba1
0, 166, 166, 0, 270, 1f1a8b61e4fbd6222ddf42e9d0a07032
0, 200, 200, 0, 270, cfb9771190ac2d0129907102d6abb63f
0, 233, 233, 0, 270, cd98dd856ba573a26a943cbe53221f26
0, 266, 266, 0, 270, ca13c161f067c4a4ce22bd58a2aca55b
0, 300, 300, 0, 270, de4bd1a474a76a35b796a5fc45b4f893
#tb 0: 1/1000
0, 0, 0, 0, 480, 622e6407a051ea08706394d03330ffbf
0, 33, 33, 0, 480, 1841a0daf7c3ef7be94e01fdb1d3968a
0, 66, 66, 0, 480, 37790e6cb2415f7add0ac5d3ab354755
0, 100, 100, 0, 480, 91485880e17c292096a7335566d3648f
0, 133, 133, 0, 480, eb6f74983d5fd13d6bd90afbce8836e1
0, 166, 166, 0, 480, 0069ab5ff7f0d4d601f7d0f9b7a08338
0, 200, 200, 0, 480, dbf04254765f7497070387e8c34895c6
0, 233, 233, 0, 480, 410a9b2d9855b2c29618070994adae96
0, 266, 266, 0, 480, 7e7f34effd90209f29f1b9ae01488b3b
0, 300, 300, 0, 480, 471530f74082c01c9b0f1fcf3d240d77
#tb 0: 1/1000
0, 0, 0, 0, 510, bfeeaf51f972fd0dfe9ee757083cbb54
0, 33, 33, 0, 510, 10cd4ed6d762004846412d9cd0caa407
0, 66, 66, 0, 510, 04cca4008d656ed180de88dd2ddb4f21
0, 100, 100, 0, 510, ec777e377836895748c06849fa35ed2d
0, 133, 133, 0, 510, b55633d0f9239dff3e45a4abce4a35a7
0, 166, 166, 0, 510, 063c3ab4b4c599942c3a8a5b7bfe5029
0, 200, 200, 0, 510, 07b920169d32b5fc51d5b9ae16fef5bf
0, 233, 233, 0, 510, 8d49e727db9d3072b5ab7bab2133d9be
0, 266, 266, 0, 510, 17441437203447e946a57d2f96966332
0, 300, 300, 0, 510, 5d3f14af0e5cd81d0c7d2059f13efa5a
#tb 0: 1/1000
0, 0, 0, 0, 960, 835254d0eecb17bed1f2b0f3a1638165
0, 33, 33, 0, 960, c0c95ce9890eab339a0e0f8b26cb095c
0, 66, 66, 0, 960, f0337d645ade07cb716952b0d19352e8
0, 100, 100, 0, 960, 7e3deb21cb3f0ead90c8af94464cde14
0, 133, 133, 0, 960, c6b1ca6cfce358c411c0637c581157c8
0, 166, 166, 0, 960, 10fce3f11f1ce90286ff4d74fe44fcfd
0, 200, 200, 0, 960, ee0565a1f121bc905a35550619127a50
0, 233, 233, 0, 960, 0624b601d379616eb792c94be60b6c91
0, 266, 266, 0, 960, a1bb79cdf347548f1103f580f2b6930f
0, 300, 300, 0, 960, 40e96e16c7e065aa7932e5aa57f32398
#tb 0: 1/1000
0, 0, 0, 0, 990, 1bd8b2d3bf679c4b925780bf82e12fae
0, 33, 33, 0, 990, a0254b4cd4928fe1080cd6f8828288a9
0, 66, 66, 0, 990, e416e99644cca481dc2806708d716ecb
0, 100, 100, 0, 990, b1ed3203ffc77ed814f1cda7bfe721d2
0, 133, 133, 0, 990, 0ff7b9d84765f7b0b0650775ba72b334
0, 166, 166, 0, 990, 8b6cd91e035bad19b46b132bd411231d
0, 200, 200, 0, 990, c714759a9a64402043ad00e5677c954c
0, 233, 233, 0, 990, 8e4738010b724ce66bcd0a5d5afcfbc1
0, 266, 266, 0, 990, 998a7aab8ed94f4b69bed39fb487f8d5
0, 300, 300, 0, 990, 9964683a15a65c032631a4f608e6009b
#tb 0: 1/1000
0, 0, 0, 0, 192, 68dccd167f9aa18df0840ebb8715eb68
0, 33, 33, 0, 192, 65c90bb99fdbee7abf21031d34cb18dc
0, 66, 66, 0, 192, 9ef1feb2dcbd4d73f3ee84e9e1cd2668
0, 100, 100, 0, 192, b6281f7c88e9aa132d3902046f8cde5a
0, 133, 133, 0, 192, 4b439b716a294bddf9f56a229705907b
0, 166, 166, 0, 192, d42c0a6f0d24522c90bc2233bc1df2c7
0, 200, 200, 0, 192, 74b763a5a12c4c4a581efb1818a92970
0, 233, 233, 0, 192, 0c3a0916ddfda5abdd3ac382f036e71f
0, 266, 266, 0, 192, 26ff590e8ae726f70e8b36f5eaee7a19
0, 300, 300, 0, 192, 30fa5810995d7132387ea585c4a1cc3a
#tb 0: 1/1000
0, 0, 0, 0, 240, fb3cad61d7d9eb511758dbf87dd8abe1
0, 33, 33, 0, 240, 4fbc1aa5559c8db2930803893bd6ba75
0, 66, 66, 0, 240, 2d8e2ee04dcc6097ca9e3f27070cdcc8
0, 100, 100, 0, 240, 05d419f1322855ba3620665b68ce9910
0, 133, 133, 0, 240, b004f8d88cb2c94f4e9a13cfa5bd480a
0, 166, 166, 0, 240, 9d9dec90e2213c0411939131aa9adf7f
0, 200, 200, 0, 240, a00874356ff1b1e9da1a400424661f8d
0, 233, 233, 0, 240, fda587eb6323cd98c773f05905ac1794
0, 266, 266, 0, 240, 781c63d221a04d8130806c799d16753a
0, 300, 300, 0, 240, f346e311829f3789dc5a94da48ada5f4
#tb 0: 1/1000
0, 0, 0, 0, 384, b5c9daafa548e54a8e33e9881fda33f4
0, 33, 33, 0, 384, 1193acd7ea4b7aac968e35ef83c64378
0, 66, 66, 0, 384, cd0e42c0b5a8b3be6f0e1d224062bf99
0, 100, 100, 0, 384, ed79c71d17f68f86cbfa75ea2bfe97f3
0, 133, 133, 0, 384, 1502a859c7e07b31faad5b80e3e27cf7
0, 166, 166, 0, 384, df3f093da914ea947db93c3baa188ecb
0, 200, 200, 0, 384, 480f86eb183b99277c1b38fdaafe2970
0, 233, 233, 0, 384, 023e0114282e04963f0f52e00e65ac61
0, 266, 266, 0, 384, e67f29cf0acc7f9b553458e1e5c59ebf
0, 300, 300, 0, 384, a779a14ba718f0c1df8a7edc9467d12e
#tb 0: 1/1000
0, 0, 0, 0, 432, 5156b11cd9995d0c1638c9b0d2b0786c
0, 33, 33, 0, 432, ef78557f93fb3ea770c7d49ab60edf21
0, 66, 66, 0, 432, f31fb9bb14566e4538a45ac7bf398b2a
0, 100, 100, 0, 432, 97633875537f76ade183e975fa91b0fb
0, 133, 133, 0, 432, 602cf54f9af852175173c21abd63796f
0, 166, 166, 0, 432, 0b3741a6842cb65d6d21eda891882033
0, 200, 200, 0, 432, 44240a27a6b6d36c9661d499fb965f87
0, 233, 233, 0, 432, 9050f263f9a4767f9323ec8aa42cf7e6
0, 266, 266, 0, 432, 57fa3a8494375f588a95376bc0c3cb28
0, 300, 300, 0, 432, 084595f2a65aa10e7d3845044a0e7213
#tb 0: 1/1000
0, 0, 0, 0, 768, c73d611490a5ddec6c690589deaf5e86
0, 33, 33, 0, 768, 5d8eaeb222aa64abda59ce7b09b2f6d9
0, 66, 66, 0, 768, 34321856b8dd5bbb9b63db04d3532289
0, 100, 100, 0, 768, 947337d2fec8a09242f60e31e99f4065
0, 133, 133, 0, 768, bb7d92f6fc055f0cf0e97bd2be56cc9e
0, 166, 166, 0, 768, 5d343c82bcdd0e9d08581043cddfd0ca
0, 200, 200, 0, 768, 612ded93207712e4916d584cc4a7b87c
0, 233, 233, 0, 768, 6ba5e0d19893e1b96f5ca86e0bfd7e18
0, 266, 266, 0, 768, 336572e1dcb110b1eb87bea81e0752f4
0, 300, 300, 0, 768, 705f73d0a39afce59ea571e68bfe25df
#tb 0: 1/1000
0, 0, 0, 0, 816, b8bf711d9a1ce49180ed56407c8a4b0a
0, 33, 33, 0, 816, 0457929b06ce46aec63d66bd38586e3f
0, 66, 66, 0, 816, 3b5f417ee5a936797a6f0d138b8ed73b
0, 100, 100, 0, 816, 5d1a42aeecfd5c8513cb2df94c206c8b
0, 133, 133, 0, 816, a0ab2dddbc810a1667d779f6ed69d010
0, 166, 166, 0, 816, b150cd7c4ec83e6f9d948e99d7465350
0, 200, 200, 0, 816, ea39622ad21312bd8bcecdaf09aa18fb
0, 233, 233, 0, 816, 467a42e1226a01c8ba244f312f588bab
0, 266, 266, 0, 816, f2311e15228ffc7fd377b89c203d0fbf
0, 300, 300, 0, 816, 5df58b3ac0a7856796a46f27be7dcf4c
#tb 0: 1/1000
0, 0, 0, 0, 1536, 925fdc485f3baa1ed145ae391519d7fd
0, 33, 33, 0, 1536, d37af656da2d7a727c8451773495d5ed
0, 66, 66, 0, 1536, 8a0f207a99e46f3d3b2aaa3f1b061981
0, 100, 100, 0, 1536, a3914c7b739d3af2641fd6aae35428ef
0, 133, 133, 0, 1536, 0ba3b49970d7b029f2dfa991fdfc6e61
0, 166, 166, 0, 1536, 55838d1d787dc5a4fa4da2994f04587f
0, 200, 200, 0, 1536, c089f7ba2b2983df2a4dc2e07798af31
0, 233, 233, 0, 1536, c23dcb3b109543a61ccfa404a726caae
0, 266, 266, 0, 1536, 01aaf09960f5ca599ca32768f017d0c9
0, 300, 300, 0, 1536, 79fe955692ecba8bbb00b20a42ca8104
#tb 0: 1/1000
0, 0, 0, 0, 1584, c7b0d91f362dff0a581434af6e902d43
0, 33, 33, 0, 1584, d8b016ef59c6bc193b29d1c714f342c1
0, 66, 66, 0, 1584, c520bd8d4b81aafc7687befff66c7396
0, 100, 100, 0, 1584, 92e81bbd3af675c9cdb1cb00d03dabe1
0, 133, 133, 0, 1584, a271db3defe5daa6d9e0a73a580f4f88
0, 166, 166, 0, 1584, 4077e857321e241bb98dfd89c0aca46f
0, 200, 200, 0, 1584, 0466e1453a94baf876e9f64b60235300
0, 233, 233, 0, 1584, 9d2cb9c7b180d44841e0e4d8a595d912
0, 266, 266, 0, 1584, 500f443eeb0ecef47c34d1e91f0df6ce
0, 300, 300, 0, 1584, 83354487982915c33b1c6243d80adaeb
#tb 0: 1/1000
0, 0, 0, 0, 216, 3219af4ef540636b0f67a989e9966059
0, 33, 33, 0, 216, 1a3655c2cfd2ee332bc89da5b3faf778
0, 66, 66, 0, 216, d638d5b361a6d81440e26993ed86c97d
0, 100, 100, 0, 216, d9bc2e7cffd66db4ba9dcbce99448d4d
0, 133, 133, 0, 216, 399f962e0a0573915bc4da4a9f1effcf
0, 166, 166, 0, 216, 69d917e19b903e4f07f848e9e557bbe7
0, 200, 200, 0, 216, d6311488a58acf6eb0cc45bc4fe3c2da
0, 233, 233, 0, 216, 0ce360a84d5755307f98d65c83f190e1
0, 266, 266, 0, 216, 2554828e6dbf94424ccac30fb153872e
0, 300, 300, 0, 216, 598a55f9735e85b8d45105dd6be7f97b
#tb 0: 1/1000
0, 0, 0, 0, 270, bf574489e9360b6475aa012c747e7924
0, 33, 33, 0, 270, 851100301c2937312a6fd32f5aab5a09
0, 66, 66, 0, 270, 0f7c1209e44ea7cd4df12d82f9224684
0, 100, 100, 0, 270, 28d121f9c40de5280435bfdeaec0c072
0, 133, 133, 0, 270, bb00898d03ce4dff5f7bee719dd3f5b5
0, 166, 166, 0, 270, a098cc66bc25b81f84b0e930b0915cdb
0, 200, 200, 0, 270, 81e25f19bfcbfce17bd7138eedae04ee
0, 233, 233, 0, 270, 69c36c5ce555a461f16a1733450f7258
0, 266, 266, 0, 270, c95236d9e7c624bb664310bd9ef47fb4
0, 300, 300, 0, 270, 7ab0942e686939951037314e9402d2c1
#tb 0: 1/1000
0, 0, 0, 0, 432, 9535aaa2ea26fbdc16e7fe9cba3fc9b4
0, 33, 33, 0, 432, 7f6e7ca33c0b27ff052dc2ab6721e37d
0, 66, 66, 0, 432, d37e3f169457a9c7f2a197353e39d3d6
0, 100, 100, 0, 432, f26d7d81dd81d051680ea2485e812705
0, 133, 133, 0, 432, 704b01955ced6d101b9e9315d3327f28
0, 166, 166, 0, 432, 30d46d6a0f6be383dede451cacf465f4
0, 200, 200, 0, 432, 83c7ed04f0af61ec665041967cbce05d
0, 233, 233, 0, 432, 152daf37dd37607886c50dd4c7796357
0, 266, 266, 0, 432, 609d807351ba74b1c432e3d0516add91
0, 300, 300, 0, 432, 67953f0c735984232cb6782217cdcdf6
#tb 0: 1/1000
0, 0, 0, 0, 486, 83790b0e7004d8d89b7134ee1a88d885
0, 33, 33, 0, 486, 0baf0bf556ae56d2f4b04567e6ac7ed9
0, 66, 66, 0, 486, c648854a4d49f7e407a2450cf4ba292a
0, 100, 100, 0, 486, 510c3aca23339841ffc72ed5c75d184e
0, 133, 133, 0, 486, 1c1f3116ec4d4ee1ad790652e49233ad
0, 166, 166, 0, 486, f94891f4e16fd32d638a2c696f5922e6
0, 200, 200, 0, 486, e164814c22e38cbe45312dfd48d987fc
0, 233, 233, 0, 486, f582515fcc6c4308ad931d2f6cf371a0
0, 266, 266, 0, 486, 0a446974bd227ee34a1621a2b7852abb
0, 300, 300, 0, 486, beca28bdae8d1fe20036b3646f3109cd
#tb 0: 1/1000
0, 0, 0, 0, 864, 62eabc8819ded6ddba2c3a5029497cf0
0, 33, 33, 0, 864, b760182fddf8bc05f149e80bbcb2c281
0, 66, 66, 0, 864, 0c44be0472ebd2653ce9fb174c6180ab
0, 100, 100, 0, 864, bbb033c3bfeeb6f59cb43013597b9d92
0, 133, 133, 0, 864, a769975cdbc6529525f7cac8a0d9299a
0, 166, 166, 0, 864, 15b02059bbced62f19c0626efea1ecb9
0, 200, 200, 0, 864, 47f4b50322ed31649bdcfffb05c70fa2
0, 233, 233, 0, 864, 8649cdd0a958047839f5b6e7bbf6f288
0, 266, 266, 0, 864, 2c766e3fd3882a9a5aff52ffe9d1d341
0, 300, 300, 0, 864, 184a62b7332a1c24acbf03f670fb7ac1
#tb 0: 1/1000
0, 0, 0, 0, 918, 612cc424eaae924cb25c7732c422f752
0, 33, 33, 0, 918, 010e8c2a814862529fcf8d7771ba2d7f
0, 66, 66, 0, 918, 7d791b7a5916738998f77586339d5840
0, 100, 100, 0, 918, aeada5f59f3dda9ab3e898f305428cb2
0, 133, 133, 0, 918, 06af894d38a1f0d3665c0081f5397ddf
0, 166, 166, 0, 918, 24bf31323c568e652550e9d35de9c96c
0, 200, 200, 0, 918, a9681ec47d3e6a19321b9ea47221dc3f
0, 233, 233, 0, 918, 73ae7268df79c4012952bd3e8011e894
0, 266, 266, 0, 918, 67aa4145398ca17036959251cb4ce17b
0, 300, 300, 0, 918, de247b80114c722da849f5aa23adbb38
#tb 0: 1/1000
0, 0, 0, 0, 1728, 72c74de547d9ed1b17bc962dbd5e0bb1
0, 33, 33, 0, 1728, 462849f9e2204738e9f08b40e682a6ae
0, 66, 66, 0, 1728, f0ee17692fd816747b11d5737b511cda
0, 100, 100, 0, 1728, 0234d23406660ede76dd22b35a708390
0, 133, 133, 0, 1728, 6544fdb9dc225d155820d3c7dfc909eb
0, 166, 166, 0, 1728, 1c073544794389596177512fb4dcffce
0, 200, 200, 0, 1728, 864709daac7b091d33afa2210c145084
0, 233, 233, 0, 1728, b049c4ac941743613ede9a41b16acde5
0, 266, 266, 0, 1728, ad0c4adb0efec03729a79f42eec66267
0, 300, 300, 0, 1728, 146057d941f5a47eb8b2c9eefeaf3100
#tb 0: 1/1000
0, 0, 0, 0, 1782, c3fc4a1593b9cc2f3752106af8539386
0, 33, 33, 0, 1782, 7f2ffe6bc1750f6749bb5ad12cbaf34b
0, 66, 66, 0, 1782, 2539b10a981d59ef54efd77cd7276aaa
0, 100, 100, 0, 1782, 0bff22b4dfb7485fbedd6ff5b99673d1
0, 133, 133, 0, 1782, 6a2b38f4abee785260a61bc60f16e7fa
0, 166, 166, 0, 1782, 2fbb69b5519b51548bf1ee425ff79c55
0, 200, 200, 0, 1782, dbd267028be2256111b2411b91fcc117
0, 233, 233, 0, 1782, 12b2f1003633c9e19cae3d0fda06102d
0, 266, 266, 0, 1782, d419a756c492867523af5185fd57d989
0, 300, 300, 0, 1782, 8a7d36760bf5db32baef349b97316b47
#tb 0: 1/1000
0, 0, 0, 0, 384, c7b30cde5664387b0f7a80d9b01e4fe2
0, 33, 33, 0, 384, 2228a2a4e54ab5145525e5803c314dcd
0, 66, 66, 0, 384, 8c048469eba24f3163c36b7461b3b42a
0, 100, 100, 0, 384, f6b8e8e701dea09dcf1158e9a52921c6
0, 133, 133, 0, 384, b3a5fde0daf2eef8fc08521f88f79692
0, 166, 166, 0, 384, 653ae11cc1380ae7f39b2e007f896d81
0, 200, 200, 0, 384, 6e66fe002a7dff95e13cc9d3d13d9686
0, 233, 233, 0, 384, 13308c917a1e22c2f702afc32b8a23c2
0, 266, 266, 0, 384, 4fee1e63f9452dc3f81c1d634bd7f41d
0, 300, 300, 0, 384, 666b43ead5c7c99ae5b7637da5aa4d62
#tb 0: 1/1000
0, 0, 0, 0, 480, 7c5b5df373ebfd31d210ff910e02213b
0, 33, 33, 0, 480, c5b0a5e3eceb792b15818324a43aa2a8
0, 66, 66, 0, 480, 1d9c0eafd4638dfe4fe308174fde2faf
0, 100, 100, 0, 480, 47301d12055944b35008028761cf5e7b
0, 133, 133, 0, 480, 9586ac1087423dcd3b0ff96d43ae475e
0, 166, 166, 0, 480, 26bfe1afea96c7ef2084fffd1fa99a33
0, 200, 200, 0, 480, 0995c8a1935266159a7ef3f95d7f4697
0, 233, 233, 0, 480, 8cfcc0ea67507ab7f3551d8ac50f93a5
0, 266, 266, 0, 480, 658cf3cb887b055d9de7d50db4eb78a9
0, 300, 300, 0, 480, 856bd5189688f7ccfe9995752bc0f1f6
#tb 0: 1/1000
0, 0, 0, 0, 768, 7c2818db2632e5c5beee17e7105d9209
0, 33, 33, 0, 768, cead72bd22995e98b54a91c7b4a20975
0, 66, 66, 0, 768, eb6baee5d65d778052c88ba5db2f9174
0, 100, 100, 0, 768, 1f5f38e89e985e9e4172446de05e91fd
0, 133, 133, 0, 768, 57b57ffcb03627942fc5868324a10feb
0, 166, 166, 0, 768, 4b4066a452d8e9cd687cd611f5d9cb88
0, 200, 200, 0, 768, 113e5069b2a4d2c2e802b72649eb435d
0, 233, 233, 0, 768, e176bb233f76f9fd4c55d62d53487b60
0, 266, 266, 0, 768, f2ff3def712a846ea7b678bd9078e32b
0, 300, 300, 0, 768, 21007ed1c727c5ccc5955188a2cec276
#tb 0: 1/1000
0, 0, 0, 0, 864, 9da5409d344e7b8380688569e54803a5
0, 33, 33, 0, 864, 9b51e14e2e624ee2b430e9eaf1a48798
0, 66, 66, 0, 864, b8811779f363b9a595e3a92737771ea9
0, 100, 100, 0, 864, e5a0c335e5e713a3e77fff0b65127fb9
0, 133, 133, 0, 864, 1bffa3283b463a356794c8f7a73f8c54
0, 166, 166, 0, 864, 97c13270621a583eb9e13c05f9d792f0
0, 200, 200, 0, 864, a6f81a4dde1ffc352ebe9d8ab8782f35
0, 233, 233, 0, 864, 91a955a86ce9378ff3442794ce0934c6
0, 266, 266, 0, 864, 2e4f8938e9c88b328a258a0b99366ea6
0, 300, 300, 0, 864, adbbbc192cf36e1fc7c308824765d482
#tb 0: 1/1000
0, 0, 0, 0, 1536, 117915db1856cee26f05a609c8c8de2e
0, 33, 33, 0, 1536, 943771a98b26b174e88ed1f4e872e504
0, 66, 66, 0, 1536, 3e0d2585e1f1cb540998d107aca5c395
0, 100, 100, 0, 1536, e64a9e1e0232983a69ab48453025b23d
0, 133, 133, 0, 1536, 2c6ef6637fb7b9425f7d7ea28cd84087
0, 166, 166, 0, 1536, 419a5a31a43955d408c13ee8a5ddce9c
0, 200, 200, 0, 1536, 2ab13e1c236553d42d59498ca350b190
0, 233, 233, 0, 1536, b8068beb037f3232d4da38fe33a8a885
0, 266, 266, 0, 1536, 160df68b9e3f75e9b1f8ed7cce327bc2
0, 300, 300, 0, 1536, 1ccafa8c7babdce0983aeb20d298b0ee
#tb 0: 1/1000
0, 0, 0, 0, 1632, 770582911fd0095ebbeae384e87665ac
0, 33, 33, 0, 1632, f99d7e3131f04413cba2f9de6818976d
0, 66, 66, 0, 1632, 3bfbb8c9c48f24cd596973a6deb33a3f
0, 100, 100, 0, 1632, 0b8166afdd357f20c76f77d228bb7171
0, 133, 133, 0, 1632, 3a3d7f2a03e19a82250d6ca0238f9791
0, 166, 166, 0, 1632, 9b558f9b8744b016059f69f3fca90d2c
0, 200, 200, 0, 1632, c857736342f1145d919cb77732120006
0, 233, 233, 0, 1632, 11dc5dda4c883a3146db060dd50343d0
0, 266, 266, 0, 1632, 7526a62ae87de174be86eac7bb36c7f3
0, 300, 300, 0, 1632, 9ef38f47cfc461710ff0dd75690473c0
#tb 0: 1/1000
0, 0, 0, 0, 3072, caa8471a8b381d53c3e8fc627946a871
0, 33, 33, 0, 3072, 2cba86ea14c0f28e242625b08f5e9b88
0, 66, 66, 0, 3072, cea0440ff6569fc82c3030e0340fb649
0, 100, 100, 0, 3072, c18ef37f1356ade96a2f40af954b31c8
0, 133, 133, 0, 3072, 21e6e549378bcff47913ef292e74dc37
0, 166, 166, 0, 3072, a9d3d483f74a5afe5d80725ce696fd20
0, 200, 200, 0, 3072, a436e2586b0963747deaf5e450e2b230
0, 233, 233, 0, 3072, 9daaadf265df56974cb0950843d9fd8c
0, 266, 266, 0, 3072, e0b84714bad2519e62b7d16705fb09d5
0, 300, 300, 0, 3072, 8cdfce574edbe548da7f6cd9a7076b9e
#tb 0: 1/1000
0, 0, 0, 0, 3168, 920ea4b8a00d41489d122d641d6e4fe5
0, 33, 33, 0, 3168, 8bfc8d452a79f2978b8e973b77cbf8a8
0, 66, 66, 0, 3168, 09f3f0d31d3377a844fa5385d9b36b9f
0, 100, 100, 0, 3168, df43fae763da9360c8062bb92ee091a8
0, 133, 133, 0, 3168, 445d8c675bb865d1814fcfa6b8a9afd3
0, 166, 166, 0, 3168, dc7d43db86aac6636724de8790eda555
0, 200, 200, 0, 3168, d3a9fc272424449ffc5b7e69f8f9948b
0, 233, 233, 0, 3168, 11ef33b9bccca54b3703bf24ab55e2d6
0, 266, 266, 0, 3168, ce31b8bf9b00b427ca956abb800d8034
0, 300, 300, 0, 3168, e707f824d6e95d482bf3a0b4d52ea069
#tb 0: 1/1000
0, 0, 0, 0, 408, c14f2ba5b4582c9d3a488976814691b3
0, 33, 33, 0, 408, 4387a4dce19007b7efb810b5a4069749
0, 66, 66, 0, 408, ecfe868d28f4861a5612edfd57447a02
0, 100, 100, 0, 408, 5cba54f568534d29169ac31c8fa505e0
0, 133, 133, 0, 408, fe9aab7b3378b9fc3e373ee626b887db
0, 166, 166, 0, 408, fce72dfc7f9c0cb50ff73761b4d82c1f
0, 200, 200, 0, 408, d4d98f42b1377e0f0ffaa66aa81d40c3
0, 233, 233, 0, 408, 65c027646dc95a749ce2d7ad0a6beccc
0, 266, 266, 0, 408, 317b283a0d907270f671272771022e69
0, 300, 300, 0, 408, d3e2c008584608502f3e24c5c5f64028
#tb 0: 1/1000
0, 0, 0, 0, 510, fd7212b519783cf4831ce4bff91f2312
0, 33, 33, 0, 510, 9768722ee939d80a6716865fdebca33d
0, 66, 66, 0, 510, 328ee0f774eeafde00dcc4b9a8f4e9af
0, 100, 100, 0, 510, f882fa6015fcb042094eadab5fa952cf
0, 133, 133, 0, 510, 4331a3dabeae27d2bf3590eb96ce914a
0, 166, 166, 0, 510, 0e15106bd8e90377f6ed8b464d17159c
0, 200, 200, 0, 510, 8f062653ac2b83f7e541393e838d0e0f
0, 233, 233, 0, 510, eeb98c1728c1a74510f8bfaf10fc0002
0, 266, 266, 0, 510, 30bb058a67d6a5ee3693b21cbca5349a
0, 300, 300, 0, 510, 7ce4b79983b3abc37b141a3bea56e0b7
#tb 0: 1/1000
0, 0, 0, 0, 816, e443c43101be00470c6a61c1a2995b5a
0, 33, 33, 0, 816, 1e79b1b46ec704d360b5fb725913b0f1
0, 66, 66, 0, 816, 6d5e77cafab6bc43498980c515d299d3
0, 100, 100, 0, 816, 91c3bba5fd2aa29ee54c8f3783cfe5a2
0, 133, 133, 0, 816, 9548d07c2a6204694d34e973e8339077
0, 166, 166, 0, 816, 6819a34c7e3c13bee3ea2b18e12e92fd
0, 200, 200, 0, 816, f75920457f01f65bf30ba1ec41076d4e
0, 233, 233, 0, 816, 3a04f6cc0c348c21464b173ac6005043
0, 266, 266, 0, 816, 93a3336374e8cc4dfb2c0b4716ab60ec
0, 300, 300, 0, 816, 148af188b8a2ee93de406a01c2af180d
#tb 0: 1/1000
0, 0, 0, 0, 918, ab7eabb355e5163e7451945018fadebd
0, 33, 33, 0, 918, b9a77cc0c769535808996a6de7b374ff
0, 66, 66, 0, 918, bd773f11d89091b3c9ebc22d8291dd49
0, 100, 100, 0, 918, 278c215d6c188752818f07f4d317c0e0
0, 133, 133, 0, 918, b59856932c675c1ba587644c23cdb002
0, 166, 166, 0, 918, 2bcaef04f89326a56025269a68742043
0, 200, 200, 0, 918, 5abb4a1b96b4bc003cd19a146347c54e
0, 233, 233, 0, 918, 26e36058f451ff80d498ac1c0343489f
0, 266, 266, 0, 918, 57ac43fcc6f1a2c863188aca68d52524
0, 300, 300, 0, 918, 282467118b5b7a986ccd28d16dab3ea7
#tb 0: 1/1000
0, 0, 0, 0, 1632, 7e334867e27046fabf0f39365311c38c
0, 33, 33, 0, 1632, d2a49216ecedea62f546e54c1552f163
0, 66, 66, 0, 1632, f66e10d1779533e5b6e2b98369134833
0, 100, 100, 0, 1632, 0054b8d4393df58eee87784862a29901
0, 133, 133, 0, 1632, b9cdf3ebea0d1e3f1e0c42db2e11a3c2
0, 166, 166, 0, 1632, c08a728d955a559457c82e44c3296148
0, 200, 200, 0, 1632, d05f4c4a8b0e606525c3d388d26a9351
0, 233, 233, 0, 1632, 78fc2544da88a1a21d6626b0f7bbcf8c
0, 266, 266, 0, 1632, 90832c4fed05390377551359bb9a91f7
0, 300, 300, 0, 1632, 5290a0e77081863398f36c7ae192710b
#tb 0: 1/1000
0, 0, 0, 0, 1734, 1bb98ba89abf6b86f47a851f8126e1ff
0, 33, 33, 0, 1734, b960cc795c179afe7eec360c57fddd7f
0, 66, 66, 0, 1734, a93cd094a80c542ecb7b6ac7720c5eff
0, 100, 100, 0, 1734, f1cd34e4f0bf9b1238769f028708b742
0, 133, 133, 0, 1734, f01437ad14450d2136a8fc971f180eb7
0, 166, 166, 0, 1734, 8778230f1182c2227bf1e253bd85df4c
0, 200, 200, 0, 1734, 1d1d5cf6c5cc9e73a1fa5b882e441d74
0, 233, 233, 0, 1734, 2f7a1867487c56c252e35225f71adb55
0, 266, 266, 0, 1734, 1d1aea21f70ceed596f22ec32d8712ee
0, 300, 300, 0, 1734, 260e66df92f32bc853f4cd4ede692ea4
#tb 0: 1/1000
0, 0, 0, 0, 3264, 3856635223f578e1e7f7e7250a53cb8d
0, 33, 33, 0, 3264, ee8d7c3a0ea165420d7e733b9e59219a
0, 66, 66, 0, 3264, 3d33f06bac22131f04e3411fc216dc02
0, 100, 100, 0, 3264, 7aea667775077de32250dac25fd24bb3
0, 133, 133, 0, 3264, 43fb534551f153c5e9e60240df0bf3b4
0, 166, 166, 0, 3264, d42b721aa2242d4258d97f840fdcc901
0, 200, 200, 0, 3264, e876200d720cbe6e36e0ffb775c5ad6c
0, 233, 233, 0, 3264, 453078449d8701270564086e58a1d69e
0, 266, 266, 0, 3264, 22cb799a817d45a7591489e6faa31cb9
0, 300, 300, 0, 3264, 628dc3f03bf5dd5cae135ad1e4b9ebf7
#tb 0: 1/1000
0, 0, 0, 0, 3366, bf4e568217906ee4b58dc4707bee8ef6
0, 33, 33, 0, 3366, f823f8c7b6e47ba43215f3becd35208e
0, 66, 66, 0, 3366, 1d986d65b502e77764428e21e77503a6
0, 100, 100, 0, 3366, 73520382bc54d6aee165402518dd7b5d
0, 133, 133, 0, 3366, c84e943758f2d7e37126172728838640
0, 166, 166, 0, 3366, 1d4b298da98e4b66b31ad6874f726aa6
0, 200, 200, 0, 3366, e67748eeb3c818deb8b51d321cd16a9c
0, 233, 233, 0, 3366, 4d1514c63e669261beef9e35b04c241e
0, 266, 266, 0, 3366, 57705e2131e2129efbc68b74a1e0459c
0, 300, 300, 0, 3366, 681acf1b384856d6e544d8e7a79fc628
#tb 0: 1/1000
0, 0, 0, 0, 768, d801797c94039b0a166d46e151ec912c
0, 33, 33, 0, 768, 161ec22caa3689b214d9ab993424584b
0, 66, 66, 0, 768, 499b589ecf1873e388c256ce948eabb9
0, 100, 100, 0, 768, 22bc77650e3df70e3e36f2a1b8d8aa71
0, 133, 133, 0, 768, 750e40530257a68211596a60de18bffa
0, 166, 166, 0, 768, 4f812a92157e7186642656b59bc28a3d
0, 200, 200, 0, 768, a3f141cec127a2c2e16740b8dd4ce56a
0, 233, 233, 0, 768, a5ba9959bf65ab6e254e5b359a3d59b5
0, 266, 266, 0, 768, baa72b8a57277d9e9ad4b92aab04f5d1
0, 300, 300, 0, 768, 4cb9aebb6c9d5bd164461726de201549
#tb 0: 1/1000
0, 0, 0, 0, 960, 97eb5fd0599d482662eb0a1def5c5ef2
0, 33, 33, 0, 960, dfdc1b61b478dcca8d411021486aa2ec
0, 66, 66, 0, 960, 2cf560f068bdcb9e345951739091808e
0, 100, 100, 0, 960, 33cacb04c0797fc7bd774251e04b7fb9
0, 133, 133, 0, 960, 7fca126c0542c0dcdcf769b156bd85f5
0, 166, 166, 0, 960, 8a46c5a48cb5bd34be8e647c127f8d61
0, 200, 200, 0, 960, 1ddf07562c0b7dc68ed61b8e1a09fcf0
0, 233, 233, 0, 960, d75911d5eb7fc75ffc3ee40344fc7ed2
0, 266, 266, 0, 960, 498329c8a01d950286af11e1fcf3ac07
0, 300, 300, 0, 960, 7a6ec019df5f3e419d389699094f87c3
#tb 0: 1/1000
0, 0, 0, 0, 1536, a43068a364cc42619e62406dcf17ddfc
0, 33, 33, 0, 1536, 94691f93299bbf5b6ba3022b02b3e069
0, 66, 66, 0, 1536, 3c8fc275490b4daf63ef6d8f9b7f81f6
0, 100, 100, 0, 1536, 96c06031f0fcad49dfed256c5c737d07
0, 133, 133, 0, 1536, f722d3a51790b55d070d57d3b9a53d0d
0, 166, 166, 0, 1536, a753b3dfe13f5778f9f054e73e512ef1
0, 200, 200, 0, 1536, fa12cbe6cbc38fa8a38ecbcf1af8833c
0, 233, 233, 0, 1536, cb42303391ef6f76f77d14d2600cce12
0, 266, 266, 0, 1536, e0c18bb1d4dcc8168b5fdd7c7963987e
0, 300, 300, 0, 1536, 581b5291cb60e50326c0dfa6a2d09d8a
#tb 0: 1/1000
0, 0, 0, 0, 1728, adf7e84a351847683f6a8dd177019e29
0, 33, 33, 0, 1728, 8227cf283a27277fbab3d7826e340337
0, 66, 66, 0, 1728, a5551b16db948e395537310d12128e76
0, 100, 100, 0, 1728, 4b57ed07dbc15de9ab6143656b2a7e8e
0, 133, 133, 0, 1728, a15489495f0acc41f446e9689e4142d6
0, 166, 166, 0, 1728, b0a0d5d3ff756e8ae19797455432755c
0, 200, 200, 0, 1728, 094a440243d36edcdd3e9d0d070de011
0, 233, 233, 0, 1728, a780bd61e1abbfbb28581784531608bd
0, 266, 266, 0, 1728, 55886a8c7aad65683aa9366a38382512
0, 300, 300, 0, 1728, 5ae5b24383f66720a62ed1001664051f
#tb 0: 1/1000
0, 0, 0, 0, 3072, 931ab6a2482c3e84bc7ef8dfbc251307
0, 33, 33, 0, 3072, 3552a9d8470a64ed627a6dbb799b7811
0, 66, 66, 0, 3072, cae1863fc606a0e3df3e708b7eefdf99
0, 100, 100, 0, 3072, 4b825a07e235c4708b12a726da8e4cdf
0, 133, 133, 0, 3072, 0dac578ef616a13be2b9db3c0d775524
0, 166, 166, 0, 3072, bfd47cbab8285f301777351c8bc5553c
0, 200, 200, 0, 3072, f29f9a0cfeaaae3bdeb26933bc7c17dc
0, 233, 233, 0, 3072, c7f3a4d24dcf72ef195a402eff77d8f6
0, 266, 266, 0, 3072, 88ede6207441a7953cf893032c353663
0, 300, 300, 0, 3072, 258f4e86541813e3edb1fe5332ff4ab1
#tb 0: 1/1000
0, 0, 0, 0, 3264, 68d00958a78e6252dd75d632806e2022
0, 33, 33, 0, 3264, f7b6266e74200a669eecd241db787ee2
0, 66, 66, 0, 3264, c8b88d43aee037857310edeb74bc66f4
0, 100, 100, 0, 3264, c6d9a52baf3ca962574bff1364fcb8dc
0, 133, 133, 0, 3264, b384fbf3ceef0affa69f5e81681edc6e
0, 166, 166, 0, 3264, cd473f0c8d1cde98153402123a3ee7cf
0, 200, 200, 0, 3264, c0f320a23c3e39719a3b3590fe3c2ab5
0, 233, 233, 0, 3264, 751207d15a791728c1022f711a25cd68
0, 266, 266, 0, 3264, 7396df89a0d88044cf7527420d193636
0, 300, 300, 0, 3264, b772dd247838b0c3ed12713447894323
#tb 0: 1/1000
0, 0, 0, 0, 6144, 35f17db9076fa20368fddfa01543c746
0, 33, 33, 0, 6144, 61cd775dfc177262da9a91d3912e6718
0, 66, 66, 0, 6144, 8b8cf175f91425d703332b22b46c1c0e
0, 100, 100, 0, 6144, 6041afbdd81e228f8f16384d3f9e988e
0, 133, 133, 0, 6144, d30bd08897b50f518920014c7fa55df9
0, 166, 166, 0, 6144, fb67222a183876b502f93e48bb779b70
0, 200, 200, 0, 6144, 60830425ca1dcf3df4ee9c6cd75f066a
0, 233, 233, 0, 6144, 3e178df858f7fcaa2552a1c5c719b5cc
0, 266, 266, 0, 6144, 66718eb0c3981beb7c1119df8a2cd27e
0, 300, 300, 0, 6144, 7c1912448c7756f7451888050760d73d
#tb 0: 1/1000
0, 0, 0, 0, 6336, 88587de65acfc85ff56daac8ef5d12e6
0, 33, 33, 0, 6336, be41f6c788b929b5b6b27c5674f40abd
0, 66, 66, 0, 6336, 04ab3f88ca062a6911405fd84c7e9de4
0, 100, 100, 0, 6336, 231436e0a68d19d3882f285d38aca3fb
0, 133, 133, 0, 6336, 1a067e147a6740bb4ce57c4184437eea
0, 166, 166, 0, 6336, be0c47e06c7e9439570473adf4713f5f
0, 200, 200, 0, 6336, a213b0611247eafab0711748c25e88a0
0, 233, 233, 0, 6336, b1df495aa3afb74399f91c74b527b93c
0, 266, 266, 0, 6336, 46319f21069541e1ee1652621b957860
0, 300, 300, 0, 6336, 313517a5721b2b14683e7eefc83e51b1
#tb 0: 1/1000
0, 0, 0, 0, 792, 3b16847e60786706fc339abc452746ff
0, 33, 33, 0, 792, 365a5951cb127d6df183fe5d5000f493
0, 66, 66, 0, 792, 6d4bceb815ca7717c4a3f86a6670703a
0, 100, 100, 0, 792, 5a0a03d4788934285448c85788ae8d71
0, 133, 133, 0, 792, 8712f9a82d07447e7a0d0a37ddc3858d
0, 166, 166, 0, 792, cff32e6c183c16962207a86d7c6cf0a0
0, 200, 200, 0, 792, dc933d90f87110651d7efb39854d3d46
0, 233, 233, 0, 792, d1299562a022521f0c3cb30668f83b6d
0, 266, 266, 0, 792, 5054254ca125d7c7e6df4001397170cd
0, 300, 300, 0, 792, a6bd7c7c0b02afa8d25f911ec847c61a
#tb 0: 1/1000
0, 0, 0, 0, 990, 7cbd8c6b2fb35c0c3063cb7a379944c9
0, 33, 33, 0, 990, 14062e74b98bed1ca982f408bc14326c
0, 66, 66, 0, 990, f6d6868d849aa74b27df1c5f40c7096e
0, 100, 100, 0, 990, 719c8d7e3769466ee8e3dca3f4747a0e
0, 133, 133, 0, 990, a72e1a7a4c82ec09ea77f87b0e6f25aa
0, 166, 166, 0, 990, a5163d142b429afa155cc2f1401a0b8a
0, 200, 200, 0, 990, 27762d813dd1f80d6aaed5f197124fa5
0, 233, 233, 0, 990, 02e94454660f3528abbde8f50e94288f
0, 266, 266, 0, 990, 1d57dcfa57a55d96f14cfe471aac2e0b
0, 300, 300, 0, 990, 7804477923c0cd067bd09ebca3529775
#tb 0: 1/1000
0, 0, 0, 0, 1584, fa2f292d273c37dc2804a70d1cae1e9d
0, 33, 33, 0, 1584, ba75d90652c021bc7ca061352e6e94ce
0, 66, 66, 0, 1584, e65d9a205bd17d100e50c7b6a7ea772d
0, 100, 100, 0, 1584, 46f9e9ff891576b9462f21d48b7b9e2b
0, 133, 133, 0, 1584, d23cedacf3a37cf6b2774e0b18b6b9d7
0, 166, 166, 0, 1584, 84329f7716a6db5a7e64a68a1155bfc6
0, 200, 200, 0, 1584, ad62286b0e13f4e54df4445cdd4fd4e3
0, 233, 233, 0, 1584, 4511529eb24b21eb63e280070f888642
0, 266, 266, 0, 1584, 4e1c122df1785e0e9134c43c85082e05
0, 300, 300, 0, 1584, ac3a3747a00be3f9f58155648fcf9b24
#tb 0: 1/1000
0, 0, 0, 0, 1782, fda5ad9bf70a51b3a41bdcabf2cce32a
0, 33, 33, 0, 1782, 91916fb20ad542a7a3ad276e6505f9b0
0, 66, 66, 0, 1782, e18e5d11aec483c76afd68f7e64415a4
0, 100, 100, 0, 1782, c13da01c2b6c09101bda7af93ad5fd07
0, 133, 133, 0, 1782, ed8d2568b2ad9c7bd980cba0d3b95cff
0, 166, 166, 0, 1782, e6f3cf312b69d37579e77f2e52cc936b
0, 200, 200, 0, 1782, e509f3682e9c4bcdb0889e044b1979b7
0, 233, 233, 0, 1782, acc3945e557cd7a9642f08a656444976
0, 266, 266, 0, 1782, 44ddd03aa8f03ba393f12fc6a1b3fc17
0, 300, 300, 0, 1782, fdd3e68132c742d9f0cf0ea6fff2a074
#tb 0: 1/1000
0, 0, 0, 0, 3168, 013cd22aea6bfeccc8ec809abd52be5c
0, 33, 33, 0, 3168, 0980adfb0ef879b3c960797272f025ad
0, 66, 66, 0, 3168, d1411ffa0429befb8c71d3ab45acee92
0, 100, 100, 0, 3168, 6c6f825379eaf21709a45be77def7a63
0, 133, 133, 0, 3168, bab632ef00a080739a41c692f2b21c3a
0, 166, 166, 0, 3168, fc0f6045aca252f2e904730227b8f337
0, 200, 200, 0, 3168, c8dbea209329463bfd9238a11b8d5b17
0, 233, 233, 0, 3168, 457247bf4186ed8459e0a1564f0e68f2
0, 266, 266, 0, 3168, baa55e20bd7c73960b080d8a0c8db4d5
0, 300, 300, 0, 3168, dc8933e8edc98cd0cfca44ae22997c62
#tb 0: 1/1000
0, 0, 0, 0, 3366, 6821eb3fcd1d10db32eff70468dcf9c1
0, 33, 33, 0, 3366, ed0094d347d9f250d46b4903cbc14801
0, 66, 66, 0, 3366, fd018555dc9a62b8074d46e7c0fd0b40
0, 100, 100, 0, 3366, 05d5baf9f2e62bbeeb3809a099e84147
0, 133, 133, 0, 3366, 7a150c265214269c08e05fe4f296122d
0, 166, 166, 0, 3366, 9a7ae61d4bb125ee4c4ccce9cc1c3664
0, 200, 200, 0, 3366, 5a88fd6d96dcbc4255e98dfe19ff96b8
0, 233, 233, 0, 3366, 4192c273a46b2b196c871ead0e61ec71
0, 266, 266, 0, 3366, e79ebfc47e755f5db221f392c3216278
0, 300, 300, 0, 3366, b995c5f483a2e553baf4f66d1a47fc57
#tb 0: 1/1000
0, 0, 0, 0, 6336, 929086fbb3e117bd53110b64c1ee915b
0, 33, 33, 0, 6336, 9ed45f5e40dd2393434e14a0c0160c63
0, 66, 66, 0, 6336, 5cdade692b1baf23e61896da18e3e44f
0, 100, 100, 0, 6336, 11a2ebac61a3f826ec41c8031899e55c
0, 133, 133, 0, 6336, 621a1e0142b94d14db9c2121553a11fb
0, 166, 166, 0, 6336, 029a29590f7255f1bc9ff9b7a000ca25
0, 200, 200, 0, 6336, 5fde42becf6bf054d04e2a0fa1b2d55e
0, 233, 233, 0, 6336, 5b8ba552cef1931e1412fb4f3420748b
0, 266, 266, 0, 6336, d41cd7d418f6ec1db802a01a90cfee1e
0, 300, 300, 0, 6336, cea99c93a84a82edff8c6069d131453f
#tb 0: 1/1000
0, 0, 0, 0, 6534, 69f9028d52f95d2e7f986c57b19fc018
0, 33, 33, 0, 6534, 068e611f62b3f6222f6b1699748c8fbf
0, 66, 66, 0, 6534, 3d3fec78ff2274241a7958f17a773a19
0, 100, 100, 0, 6534, 93d71ef1a2d00c7e70e76ccc1859143d
0, 133, 133, 0, 6534, 5a35a640d52bc0930825b963b0b9e830
0, 166, 166, 0, 6534, 782223239e6b1ca1bedbd25d9652a07c
0, 200, 200, 0, 6534, a4b5e8a319cbc9a12d3e36127c7f0fbb
0, 233, 233, 0, 6534, a3e2d9a78fa42b3c817aadfd31fd2d16
0, 266, 266, 0, 6534, e9fc6b83535735f46006f3e4b376755f
0, 300, 300, 0, 6534, 80223f600dfe86021bd0e83fecdc4b2b
#tb 0: 1/1000
0, 0, 0, 0, 126720, 2f90d606edc511c8c960530dd915cb98
0, 33, 33, 0, 126720, 7fd451a057d6341b2b0d116f59e41a13
#tb 0: 1/1000
0, 0, 0, 0, 57624, 14cc1c34b8106e35238d4650a9123852
0, 33, 33, 0, 57624, 66e0bb9136ea24e30b781a4610b428a1
0, 66, 66, 0, 57624, 8e36679c20a3a3e974fdacf7a9343817
0, 100, 100, 0, 57624, 2669fd03ce7ce01f4fc9db23e06fffdb
0, 133, 133, 0, 57624, 46ced29eb6edf2136c8ee19e9a87380f
0, 166, 166, 0, 57624, 4e4138b65a30bc56cd18663a1799f98f
0, 200, 200, 0, 57624, 580b0431b5f808c67e50ed34e62f39ad
0, 233, 233, 0, 57624, 1339bbe256d8499ab17d6a550f7dac70
0, 266, 266, 0, 57624, 89b9dac29a4c4136249c40a3763dc114
0, 300, 300, 0, 57624, a735d341d7df9dcd0b6e51a82b813f61
#tb 0: 1/1000
0, 0, 0, 0, 58212, d2bd2dfaf2ac22b3f2499844f228d89a
0, 33, 33, 0, 58212, e066448baeb39da04b22d4d2ebd27b0a
0, 66, 66, 0, 58212, aace53c0ecca2596c51dd5e70da7abc4
0, 100, 100, 0, 58212, 077256d024ab101918d10ae61142f203
0, 133, 133, 0, 58212, e2bfdad36b0365d41dc6813a371111ee
0, 166, 166, 0, 58212, 17495af68b0a2c075899849382f3b046
0, 200, 200, 0, 58212, 7853db163344798e5c37672adaac92d8
0, 233, 233, 0, 58212, 7b2ee2e1ca709c58457c7d818e47c95c
0, 266, 266, 0, 58212, f7eb3ce10561628f932861358a30b414
0, 300, 300, 0, 58212, 3182374f5aa539fd0faa44ed4a7492e5
#tb 0: 1/1000
0, 0, 0, 0, 58800, b2f2ac3e3833ae1b4dd075fe00210373
0, 33, 33, 0, 58800, c0cce05e56a07111fe62553fa3a87074
0, 66, 66, 0, 58800, 626aab3de03242073e03504e166b4697
0, 100, 100, 0, 58800, 574d2c810f0bbfac57f1f06c2b97445c
0, 133, 133, 0, 58800, 7d5bc5860bd1422d08396fe080452099
0, 166, 166, 0, 58800, 5d47bbfb0f5cdecfe8415ca2caddc206
0, 200, 200, 0, 58800, fbef6a0fa51029d0475975945ccf4b36
0, 233, 233, 0, 58800, c9179c153bcb2a8e9d17ed04e5e2c39c
0, 266, 266, 0, 58800, 107d796592cf2140d4d492beadba2d68
0, 300, 300, 0, 58800, eee46f9ee67fc1121bffb63aeb7c768f
#tb 0: 1/1000
0, 0, 0, 0, 59388, 7109d2ef160828ece26337f36fcfc092
0, 33, 33, 0, 59388, bdaa6612f81a956d9b20d55a04df8346
0, 66, 66, 0, 59388, 15eb75495d2713a64415b990b058d5ca
0, 100, 100, 0, 59388, b997c84553475ba84e8ba3d7ee19ae4e
0, 133, 133, 0, 59388, 63a8badd691bcf643cf676d029ce8a6c
0, 166, 166, 0, 59388, b8ca23d9b3418c4c36040a215b2b7917
0, 200, 200, 0, 59388, 1be0da18386c35e4a5e5d5d32d9a4468
0, 233, 233, 0, 59388, e75a03fa70fe7e6b3a8d8ce7dc8305f1
0, 266, 266, 0, 59388, cbd2b60df9209025c8e890771a05321d
0, 300, 300, 0, 59388, c655d6fcc3333917b66358a9ac2b1357
#tb 0: 1/1000
0, 0, 0, 0, 61152, efa2a2a76a0fe709a78e491346cfcf29
0, 33, 33, 0, 61152, 97de85e21b408878853fa870104707d7
0, 66, 66, 0, 61152, 419bd1157e156d3059190d6b561c57dd
0, 100, 100, 0, 61152, fbb6e01c524fc7c8007c6cfe2c64f467
0, 133, 133, 0, 61152, 7453994c2e9901fa23f295ec0b556f9c
0, 166, 166, 0, 61152, ba39dc984789fa2c4b833cd88013cc97
0, 200, 200, 0, 61152, cea5061cac1be18d5f9a9301a5460491
0, 233, 233, 0, 61152, 1c583018c425b1a91949e0c3eb0a4152
0, 266, 266, 0, 61152, b48be02280ac6f97731af69bcf18de25
0, 300, 300, 0, 61152, 6f8ab465214d8374c9ff77b939da333e
#tb 0: 1/1000
0, 0, 0, 0, 61740, fccc18714a9ed3840bd6e9c6ca4858e5
0, 33, 33, 0, 61740, a8f6eb43cf6ed670eb180c5051de06f7
0, 66, 66, 0, 61740, 6a9baf9eae6e799deaefd6e801f7ace3
0, 100, 100, 0, 61740, 3bb44c8a45aab088c9887c11bc6a4acf
0, 133, 133, 0, 61740, 0907a7e926be9e54bbb087251b4715d9
0, 166, 166, 0, 61740, 10fef2876c20eb3f9570c0c23e5acc69
0, 200, 200, 0, 61740, ffe5d2b6d874af0f878075c97940ccfb
0, 233, 233, 0, 61740, d10fae10144ff88075048827203f7e9c
0, 266, 266, 0, 61740, bdf35736ac625f2178902c1f24d513c0
0, 300, 300, 0, 61740, 30882bf2c21785be6234b637c4b16b28
#tb 0: 1/1000
0, 0, 0, 0, 65856, 13263674ea5aa619250dfd139bda872f
0, 33, 33, 0, 65856, 39f5cbd8917f2b3a1df8cf2b786266de
0, 66, 66, 0, 65856, f9aade31f9e3065f3d5b8645ef099ac6
0, 100, 100, 0, 65856, 124f9664380f092e692b5e881f5a8fcc
0, 133, 133, 0, 65856, e8e040e417830f5e911537828ace21b7
0, 166, 166, 0, 65856, 84ce09882b9c184a787e8022e6d8c8de
0, 200, 200, 0, 65856, b1397fd91814e4fdc4f75c89161ced26
0, 233, 233, 0, 65856, d64f39d64d248f0223ed359e092d46cb
0, 266, 266, 0, 65856, e04ee663dcc52eebd74255671c6f4ec9
0, 300, 300, 0, 65856, 955303cb73bf072c693f37d9778ca2b6
#tb 0: 1/1000
0, 0, 0, 0, 66444, 5cb240f10761f59687612ed589759800
0, 33, 33, 0, 66444, 9d8d5b57336ddfa5c9c5100a0302197d
0, 66, 66, 0, 66444, 9db74997d23b16f527c63e88795331dc
0, 100, 100, 0, 66444, 52758cd901533e790334d464bee516da
0, 133, 133, 0, 66444, 40e671b9b85d07b13acba85eb64bbbaa
0, 166, 166, 0, 66444, 8524b2cd2c9bb3e41c6167f8269e75d2
0, 200, 200, 0, 66444, ff194ad6fa180fde86cc05a99c0580ec
0, 233, 233, 0, 66444, 22ab303cb37745a73c227cd7d1c70003
0, 266, 266, 0, 66444, 01986c58e82e0b5194418f5b75a8599c
0, 300, 300, 0, 66444, eedfc9c14cbf3fa10402dbed52103848
#tb 0: 1/1000
0, 0, 0, 0, 58212, c980866a6f17d4107ce128ee112d74cf
0, 33, 33, 0, 58212, d4d5d2a10e73f1d09919355dc4d63d48
0, 66, 66, 0, 58212, 82c76ed020acb68ff9d8bd81899aa6f8
0, 100, 100, 0, 58212, 8330705fa354fb5838af56dcf9cc0980
0, 133, 133, 0, 58212, e47b63d839a592e6372d18249bf5bc0c
0, 166, 166, 0, 58212, b6095b6f752a50e96cab52e7c3fd52f3
0, 200, 200, 0, 58212, fc4786f48b6ee31043d94f79c5c8a54f
0, 233, 233, 0, 58212, 7d3d06c96496bd5ab44fe5489877771d
0, 266, 266, 0, 58212, 5b96de089a9faa2dc01697fe9dd97f7f
0, 300, 300, 0, 58212, d7361203b4c264067dcb7bf6912e8df2
#tb 0: 1/1000
0, 0, 0, 0, 58806, ee0760611da9938e72f551d219671c76
0, 33, 33, 0, 58806, c512cb8a864c25318254438c7170f373
0, 66, 66, 0, 58806, aaea10aeb7dfd1f9f6dc77adccfcd56f
0, 100, 100, 0, 58806, fb4e68ce202d9c6ecbddc6fe50b1cd7b
0, 133, 133, 0, 58806, 57a803d02f0d71ec4c3c17a112574525
0, 166, 166, 0, 58806, 526d0beaf7ef721c3a6ae8bf3505fd78
0, 200, 200, 0, 58806, 972ab31f81dbb79c2273bcfc98569e8b
0, 233, 233, 0, 58806, e1f05d62691bd1a9494d57449417415c
0, 266, 266, 0, 58806, bc39a559b25e5a1ac698e0101bd6bf29
0, 300, 300, 0, 58806, 04caed04ac21c76af873e21899860fb2
#tb 0: 1/1000
0, 0, 0, 0, 59400, fb0e8171b0f91d9b2ceb5430db27a67b
0, 33, 33, 0, 59400, 73f121e6aa0e6290cfd06ac9b033c772
0, 66, 66, 0, 59400, 4113897efc44f49f5169a579bee03596
0, 100, 100, 0, 59400, aec1d4cf1a15e12b689980cfe136d5d6
0, 133, 133, 0, 59400, 1322af65f647254330120e67ddae38bd
0, 166, 166, 0, 59400, 5d28c1684451812c9db41433e6286d85
0, 200, 200, 0, 59400, 33843fc49d1d8655520c2f42332222ca
0, 233, 233, 0, 59400, 92a8125d8c75eaf6159d5f431c5c71bf
0, 266, 266, 0, 59400, 5bc96553842f65a3e37f012b72b580f5
0, 300, 300, 0, 59400, de5eb6299ee5034dc3b01cdc94bf810a
#tb 0: 1/1000
0, 0, 0, 0, 59994, f5e1cf4cc56742fadddf42189a3f65e3
0, 33, 33, 0, 59994, f3e8ca2c8deb29a6b5bfe415b39c901e
0, 66, 66, 0, 59994, 89c513049e41e145bca46a7f7119567c
0, 100, 100, 0, 59994, 419089035739e84f1aa14ccdf34edcb1
0, 133, 133, 0, 59994, 4962c98c23b16b9257869a8ad5138731
0, 166, 166, 0, 59994, fde9e858ec895c36c2d8071e69f68db6
0, 200, 200, 0, 59994, 42e1271915f31a00be3627fa866ce3ee
0, 233, 233, 0, 59994, c15f794933f913861a6d0041ff2fccdb
0, 266, 266, 0, 59994, 35dab245ba952dc6fddc1a9668c30b28
0, 300, 300, 0, 59994, 30bb4ef77cdde9cf5aea0f1287183b23
#tb 0: 1/1000
0, 0, 0, 0, 61776, d45b561f81cbfcca8a1dddbc2bf8ca31
0, 33, 33, 0, 61776, 3664f63b2e59e380622caadb7a05545e
0, 66, 66, 0, 61776, 0662fa199512320704efecc10af1aaa4
0, 100, 100, 0, 61776, d8dc00882e73be89d0585663892cbcff
0, 133, 133, 0, 61776, ff64b8d50b7c5b484a06dab09a26147c
0, 166, 166, 0, 61776, 1771b6a55112eb7ea10885d1390339cc
0, 200, 200, 0, 61776, 0d5944e8a13e3c2faffb562bbe2671a8
0, 233, 233, 0, 61776, 744bed3a88407b75a8ff27a1b0cec64e
0, 266, 266, 0, 61776, 3887415f2ab10d2a265c4a413e7060b9
0, 300, 300, 0, 61776, 7dd683019b19b464bc0436f41e0b7c87
#tb 0: 1/1000
0, 0, 0, 0, 62370, 8525a27170982c059d5904c1af3b43fb
0, 33, 33, 0, 62370, c4eb329733913360384d3917a58f6f36
0, 66, 66, 0, 62370, ec118b87c9cba0e4bd89fd43567cca4e
0, 100, 100, 0, 62370, 7e57c6caba7924823977e2c9bc11f7fa
0, 133, 133, 0, 62370, f77ffb7228a5eda848acc40ff636ecad
0, 166, 166, 0, 62370, c5dddafbe3badcbbcaaebe97076e0394
0, 200, 200, 0, 62370, 34d69ae2e5b4c4fbcc51627237c9abc5
0, 233, 233, 0, 62370, d9c63fa8b18d6c54e5fa31db866c06cc
0, 266, 266, 0, 62370, 7ab392764a399328bf35977539e3148a
0, 300, 300, 0, 62370, 7fbb7bae3ec775298aaa49a286dfb9d1
#tb 0: 1/1000
0, 0, 0, 0, 66528, 5f69230bfd8bb485bd85552b18339fc0
0, 33, 33, 0, 66528, f5c365774fc1d0bffd5025ce2e931aaf
0, 66, 66, 0, 66528, 2898234103c3624e6470ae82c916e000
0, 100, 100, 0, 66528, d82a7fa705180b68a8ee8cb7de0cdd2d
0, 133, 133, 0, 66528, 144a162d418deae62883a2cc4c341b4c
0, 166, 166, 0, 66528, b3419a48385e42ca15717289ff2daa1c
0, 200, 200, 0, 66528, d6306b5737f88f989bf2e6a1084a94fe
0, 233, 233, 0, 66528, 5669761d7417b52b3cf81d44a13e3fb7
0, 266, 266, 0, 66528, 3f730b8658d7a6657d1af38c75357512
0, 300, 300, 0, 66528, 27df68d515148f732325bf821037d59f
#tb 0: 1/1000
0, 0, 0, 0, 67122, 412c33a8fd71c99e68e6701b050b107c
0, 33, 33, 0, 67122, 8e69483ff8a094096dd550b30be20dde
0, 66, 66, 0, 67122, b8df87ab3d2613be31a3743e34d7e794
0, 100, 100, 0, 67122, ec4b08a4014950f1fe04e83f8a790af0
0, 133, 133, 0, 67122, 030da2b60627d879730108826ce6632c
0, 166, 166, 0, 67122, 03aab0c9b4d75bc0b47fa5237e9efe3d
0, 200, 200, 0, 67122, fd01e369df258f340eb8e486c07ae136
0, 233, 233, 0, 67122, 1c301f0e60c96008fd7b6e8de1ebaa29
0, 266, 266, 0, 67122, 912723f43b2b36366c3e6ab122d31801
0, 300, 300, 0, 67122, b2774a66f7aa0fb7dd7e64b0d67818cd
#tb 0: 1/1000
0, 0, 0, 0, 58800, 651a0627c6cdaee8b46e1f8c4121a368
0, 33, 33, 0, 58800, 3e63075148df16f69c933cf6c63e078c
0, 66, 66, 0, 58800, edf18e52b7d52af2bb7594ed358542d8
0, 100, 100, 0, 58800, 30284124756d00d10f4f8428206ceab8
0, 133, 133, 0, 58800, 6f6ecde53cd0ea5298f4529d396460c6
0, 166, 166, 0, 58800, 0431d389278957fbef3e72f69f3ce008
0, 200, 200, 0, 58800, a047c60c4c60d2ea1f79c86dc98cdf8e
0, 233, 233, 0, 58800, dceda8bf128a8cdcadfa6c5db49cde51
0, 266, 266, 0, 58800, d8a6283637f5abda17e0bf150eac2983
0, 300, 300, 0, 58800, 33dca31ef26fdd0daf9971c8de685d01
#tb 0: 1/1000
0, 0, 0, 0, 59400, d4b3578d800c747bcabaa484a140ffb0
0, 33, 33, 0, 59400, a40f6f8c384c5dc3d5546d960bb6d9e5
0, 66, 66, 0, 59400, e270ae8754d9906dd88b1c7d05280801
0, 100, 100, 0, 59400, bde7fde5012840c5e188f3b29f4f0003
0, 133, 133, 0, 59400, 8f8510c1130615b64fb8469af66ff678
0, 166, 166, 0, 59400, 79b9d4e0c64f82a6e9540394222a593d
0, 200, 200, 0, 59400, 34852ac9ca5c6bfa51736296784343c7
0, 233, 233, 0, 59400, b055218509dbed644113642f8f0ac8a8
0, 266, 266, 0, 59400, 1628866b436f1c4b892474025226e545
0, 300, 300, 0, 59400, 3fdec760c04e30c90e74afb38dbf757c
#tb 0: 1/1000
0, 0, 0, 0, 60000, b339f4e563afadb25f43b8c05b12dc03
0, 33, 33, 0, 60000, 3bd5280e7fb42400085b0b1dbba1905e
0, 66, 66, 0, 60000, acf1c84cabff763fe2073d2c1f183bfc
0, 100, 100, 0, 60000, eaa4983b6baf907efb11d137644569d2
0, 133, 133, 0, 60000, 8a1871c8dc38a19dfd4ac571ad7f39be
0, 166, 166, 0, 60000, 0be539bd51f5f364828dd0abc70360be
0, 200, 200, 0, 60000, df60622d2c9f294f61d738be9e3bd16c
0, 233, 233, 0, 60000, 22b3f1d51ddf92c7d2add305ba0ef405
0, 266, 266, 0, 60000, 01ba29be721e64a5a50526de0797c7d3
0, 300, 300, 0, 60000, 7b7aa7fa0e58202b3104671375762587
#tb 0: 1/1000
0, 0, 0, 0, 60600, c4a13df44e66f06961dd72fc990439e9
0, 33, 33, 0, 60600, 81c73b8d3806ad96af8f422914a253f8
0, 66, 66, 0, 60600, 05f77526125e802be9cb306e375ded6e
0, 100, 100, 0, 60600, ab2e224840ff89abec2c675a23a73094
0, 133, 133, 0, 60600, c30f58f88819eb57102678b169e15188
0, 166, 166, 0, 60600, 33e5e2799eb4a9c548c8372fd6769db9
0, 200, 200, 0, 60600, fa53c1c7e60bd1d00335af542ec69ed7
0, 233, 233, 0, 60600, 534cafe658af10a314d6d084e55b3620
0, 266, 266, 0, 60600, 502529e4fbecc8b890abf665fa21f53c
0, 300, 300, 0, 60600, bf1f73c6e77370bc51a770c8ae87bd12
#tb 0: 1/1000
0, 0, 0, 0, 62400, 702748bec18c500dd41d93ae74b11d56
0, 33, 33, 0, 62400, 4fb542190dab2fd673724d47451ff6ee
0, 66, 66, 0, 62400, dbb4d27d52797dab67e39d32092c9d44
0, 100, 100, 0, 62400, e4a0ed1572207b7ba433896bba711148
0, 133, 133, 0, 62400, 28ec32bc165f4f9d455efec8a7aa8737
0, 166, 166, 0, 62400, a95910575a6423abffb28ca38c384b34
0, 200, 200, 0, 62400, 791f1c558c5467725f4614a75a8a687e
0, 233, 233, 0, 62400, cfd3e12f84f7a811966721e890228313
0, 266, 266, 0, 62400, 824c5fdf938551c28ac1c996645ae52f
0, 300, 300, 0, 62400, 7465917fdd0206e393968232a0ec5193
#tb 0: 1/1000
0, 0, 0, 0, 63000, 31ef44bd12ae702f306c55eba10d2ba7
0, 33, 33, 0, 63000, 83e9d913f5aa058d79a81047ca45e4a2
0, 66, 66, 0, 63000, b5e21313b859f1e2c67aaac5fefc9f68
0, 100, 100, 0, 63000, 959d63c1b219c3479af673a9a8b8d82c
0, 133, 133, 0, 63000, ffcfaf42b69c7cd92f6e3c21987ff7df
0, 166, 166, 0, 63000, e9667d3ee4d8179da44de4fbffcb7df2
0, 200, 200, 0, 63000, 5e2c841bcf4ec6f3a05020d36986fe5b
0, 233, 233, 0, 63000, 19fe287c30bd4c90b00a9631409568c0
0, 266, 266, 0, 63000, 58a8843e50b19860a0a91e1e1bb63bfd
0, 300, 300, 0, 63000, 0ebd31e18597a567f96645acbb2500cf
#tb 0: 1/1000
0, 0, 0, 0, 67200, 315d69847bf752a84231a368278eb0b6
0, 33, 33, 0, 67200, d245738f8627fc345ab38a547bc7d352
0, 66, 66, 0, 67200, 982681cdca448919c2eead94435772ad
0, 100, 100, 0, 67200, 7b67b2d96476e17cd407bbccb19fd070
0, 133, 133, 0, 67200, c38dde73ca097049d1fc689e18a49b5d
0, 166, 166, 0, 67200, 525f323b81d780c669a03655bb0d0b56
0, 200, 200, 0, 67200, 5dbeb96f65e383771c1c877ec559044a
0, 233, 233, 0, 67200, 7d96e976265ef0f9faf173376caaa9e9
0, 266, 266, 0, 67200, 6047c805a724701b80a133486aae0e65
0, 300, 300, 0, 67200, eb8895dd994076a52aa3a0c1758ccbb7
#tb 0: 1/1000
0, 0, 0, 0, 67800, e45b6b9dce4a8509b7d26bc3cfdf7c86
0, 33, 33, 0, 67800, ddb9d5033ecfa2d6e9a5505dce374bda
0, 66, 66, 0, 67800, 52c495d3137143e0bce9382fe5506057
0, 100, 100, 0, 67800, d09f3d6ad084f2966196acd48246f951
0, 133, 133, 0, 67800, 1556d006d0119a3172b98a500b27f8d0
0, 166, 166, 0, 67800, 904f86cfbcc3fa683d3d7744a286cd88
0, 200, 200, 0, 67800, b35907456b8ccab0ae8efc8405b04c89
0, 233, 233, 0, 67800, b7f2648fe0f873f7e9ea4a6d913e45ec
0, 266, 266, 0, 67800, 2da76544bc7e295486c335e17047e12e
0, 300, 300, 0, 67800, 10fd6424caf837d37564ef15f1c6f93d
#tb 0: 1/1000
0, 0, 0, 0, 59388, 1261466179df96099e598e46c50fa7c1
0, 33, 33, 0, 59388, cc0fe373cd0399cf0c95edf92d9ab01f
0, 66, 66, 0, 59388, 7a2dc0afd06ecfcf54321fb759f57601
0, 100, 100, 0, 59388, db9c138503d27f87449f870ab07cab03
0, 133, 133, 0, 59388, ddea2e5e2659e97132a537566d5ed989
0, 166, 166, 0, 59388, c31e90b5eee032526c4e0603332fd160
0, 200, 200, 0, 59388, 7e5b40f03b905d9ee749d3097a484ea0
0, 233, 233, 0, 59388, 93e9f7defa94ff03c041448ae1e55cea
0, 266, 266, 0, 59388, aef8e03f0146699faa16ec28dea49dbe
0, 300, 300, 0, 59388, a651d949b4c8f0e455c6592dc98385f7
#tb 0: 1/1000
0, 0, 0, 0, 59994, 181edc4ebeeff7f0527b93b84d5d8efb
0, 33, 33, 0, 59994, 132c71b634fb67eed51fcdef1775b6b2
0, 66, 66, 0, 59994, fd41144770765fc893adc5843ebe32e4
0, 100, 100, 0, 59994, 77dcbaea101142940b6a78a271842829
0, 133, 133, 0, 59994, 01737c38c1ac711a9744256788211177
0, 166, 166, 0, 59994, 31cd0b5f621daac309c6f249f4c26cd8
0, 200, 200, 0, 59994, e06d34e570dc46904fdb9eeb55811464
0, 233, 233, 0, 59994, 71bf55030373bde1eaeb52d1e97bfa4a
0, 266, 266, 0, 59994, e96063ff02e8a23a666222b59391de9c
0, 300, 300, 0, 59994, 5aa0079168ab5069e8a3064f9e2a6d8b
#tb 0: 1/1000
0, 0, 0, 0, 60600, 20c41d4a1271183dbbc7a44e6b90ea80
0, 33, 33, 0, 60600, bd8c1fba8d8742f4d98b7d5097c8c828
0, 66, 66, 0, 60600, 55cbe06a925009c1b1f9b609b60b4c1d
0, 100, 100, 0, 60600, 78e80c7cf1f142e2dda1bc269b5b3e00
0, 133, 133, 0, 60600, 42ee8157a4c8af6670b81e9324b251e9
0, 166, 166, 0, 60600, 022bdf5a2e1ea5f98503cd25b383ae53
0, 200, 200, 0, 60600, c2073865386a991da01966878ce1ce6d
0, 233, 233, 0, 60600, 6a5b95cd4eff0836b9180a25f663d36a
0, 266, 266, 0, 60600, 5e5498c357340d4755dc98eb0669f103
0, 300, 300, 0, 60600, 0907d5e4020111b1ecfe707df71bcd8a
#tb 0: 1/1000
0, 0, 0, 0, 61206, 610cef52d35e9c641f2b8c10489c3d12
0, 33, 33, 0, 61206, 1f84062e607d4798b0544739fe0da99c
0, 66, 66, 0, 61206, ea379947b5c52ea3989dfc3f47c729d9
0, 100, 100, 0, 61206, 1d06b72f06178cbb6bb5d188d22bff43
0, 133, 133, 0, 61206, 25bd41bd7607f88a01aa0cdc336c9975
0, 166, 166, 0, 61206, 86836a95a7a9fb1eefb20f7c5a15a9ab
0, 200, 200, 0, 61206, d8eb3fecce1b646b9877cd4fcca9f9bf
0, 233, 233, 0, 61206, a057e0b29e4ac9717452cc478c418c12
0, 266, 266, 0, 61206, 9a3bab91b4f0fff174536b1609c9632c
0, 300, 300, 0, 61206, d1cd93975f746b6cae490aae31f89e7e
#tb 0: 1/1000
0, 0, 0, 0, 63024, d2128e290be81bb0700ebe19e3faed4f
0, 33, 33, 0, 63024, dccaecb7e4ddb7e4224221a659af2a43
0, 66, 66, 0, 63024, be8e0966aaf3a9fe9164f63695dc3b62
0, 100, 100, 0, 63024, da944fadc3a239c2254678cadb4cf7fa
0, 133, 133, 0, 63024, 3c270f3c02fcbd192b7f896f3f9ee6d9
0, 166, 166, 0, 63024, 0b3ccda0a87c37e40104ae2f1060e8e9
0, 200, 200, 0, 63024, 254253aba91758f302e7177e614596be
0, 233, 233, 0, 63024, b1501a4e372a5249e74aab77e57a28f1
0, 266, 266, 0, 63024, c4497fea1cefed5cf2b2908620153d26
0, 300, 300, 0, 63024, 5ba20dfa2400b15b5394f315c5c3707d
#tb 0: 1/1000
0, 0, 0, 0, 63630, e4663a28cabbfdd3815efda2d38debcc
0, 33, 33, 0, 63630, 3cc7dbec64e9f697f40d740a72c09fc7
0, 66, 66, 0, 63630, f108981e0ce9c6c501b9ac61d0f1ba44
0, 100, 100, 0, 63630, 63191c7aceb8ac6b030cc1a4b3cda18c
0, 133, 133, 0, 63630, b0a527ae3aafe94d13573199c6f4944f
0, 166, 166, 0, 63630, 1be14b213ebf1d653468b8c16bae03fb
0, 200, 200, 0, 63630, 44e5a8333a043cd93b9d1cc78e5f188f
0, 233, 233, 0, 63630, bfd7619f990f20e23b47d0738a6a8449
0, 266, 266, 0, 63630, 800405f45ca5198014ef8d8521b044fa
0, 300, 300, 0, 63630, dca4eda872349708f54486433efc8225
#tb 0: 1/1000
0, 0, 0, 0, 67872, 1d318f05310f6d40646f23c62c7eafe4
0, 33, 33, 0, 67872, 42870bd73e1a0c5d84b986db3d24f0f0
0, 66, 66, 0, 67872, afaac676150286143c6fec7992a81467
0, 100, 100, 0, 67872, 128f84400c272628e802c2369b6bf548
0, 133, 133, 0, 67872, 9adc24d69f12349d8b17c84f5c111767
0, 166, 166, 0, 67872, b33d2f7a1955248652701f2ade8ab55d
0, 200, 200, 0, 67872, b8acc23721097fce6c8835f5fcfaa6ee
0, 233, 233, 0, 67872, b63bf9a08e4dc5879bbd91efaec95960
0, 266, 266, 0, 67872, 96e8fe29935266f6bd486b99f917eabc
0, 300, 300, 0, 67872, 54be14f8dde6857867cd4581f8557044
#tb 0: 1/1000
0, 0, 0, 0, 68478, 5aa0f439c58c6335cd86d4238a8c4b68
0, 33, 33, 0, 68478, 3616cc306ec05f89d9b0db63200e4abf
0, 66, 66, 0, 68478, 424e98f8ec0ebf2a326a917ee0159bbe
0, 100, 100, 0, 68478, ed5710e412f056fa8c1a277d86dd45d7
0, 133, 133, 0, 68478, 760b850feab485f0bda6cde9943102bc
0, 166, 166, 0, 68478, f4bd90ca72aa707f9b68e6192ac230fd
0, 200, 200, 0, 68478, 58e4aad0bc2a9f3fc279df10208bd6f6
0, 233, 233, 0, 68478, b42f84723dd167d5c544d539275ad537
0, 266, 266, 0, 68478, 5f54feca21331646e68797380260932a
0, 300, 300, 0, 68478, 8e787dd318024aff25af8b4d85040f3c
#tb 0: 1/1000
0, 0, 0, 0, 61152, 6195975181969789e101a83a555d13f7
0, 33, 33, 0, 61152, 2aca5e3307d68a5e969564a943b8e723
0, 66, 66, 0, 61152, aee4b00472ee0b6b7a13e31069181db4
0, 100, 100, 0, 61152, 7808595b650a7c14d8a4800db7c014e0
0, 133, 133, 0, 61152, 746eb763b176286aa875ae06b81118c4
0, 166, 166, 0, 61152, 0e8a78ec061319e27d49ca25e333e017
0, 200, 200, 0, 61152, ac4432db2bb0971d5f70a7dda1210c19
0, 233, 233, 0, 61152, 78870f4bd767f8ab65d369a5b322735d
0, 266, 266, 0, 61152, eee9ddd91209348a64259db6a4a3f80c
0, 300, 300, 0, 61152, c48d21e36a9c0d0d1c64db3f776b3002
#tb 0: 1/1000
0, 0, 0, 0, 61776, 1f1fa3cdf865d8c75183f4ba6203b675
0, 33, 33, 0, 61776, ead33ead8fea5bd5d831a79f4c75a590
0, 66, 66, 0, 61776, 9a406b4464989fd4bb7cbcb1b18aeaa7
0, 100, 100, 0, 61776, fab3d228e7032f2cdc440dbfcb17c4c1
0, 133, 133, 0, 61776, f2f3f8b8d9ece21c359c89245157c613
0, 166, 166, 0, 61776, 321f5a8ecb2cec1780013fe72c237bde
0, 200, 200, 0, 61776, 6f025b1f4ef61d261f05ca149a9470e6
0, 233, 233, 0, 61776, 85abcc8d8e6b5f286ed6aa6c588cf416
0, 266, 266, 0, 61776, b28d710dd44389f774aa02edd6327d5c
0, 300, 300, 0, 61776, 79374bef9819eecafa7396d70c80be7f
#tb 0: 1/1000
0, 0, 0, 0, 62400, ff2dda3ddbe8b461d960baba0ad132bf
0, 33, 33, 0, 62400, d6935ac8f2250316f498e8f01afa04fd
0, 66, 66, 0, 62400, 57173ebaef7b21698c62fa959cb40ead
0, 100, 100, 0, 62400, f354c76d7cf45e9f3adfdde0f6b3b5c9
0, 133, 133, 0, 62400, fbc968ecd214b01509a76996e45dd09a
0, 166, 166, 0, 62400, 9c314b51a80f2a081adf9b9cc26f5f8a
0, 200, 200, 0, 62400, f22883a6a5b74ffa4bb16f22d496b5a5
0, 233, 233, 0, 62400, eb4fa914fc5658d43e32c48a0c39bab3
0, 266, 266, 0, 62400, d763c0c2f44b68e1e3fe9e165334eb0b
0, 300, 300, 0, 62400, 344e1075a48cd61e79b0550809b4c91f
#tb 0: 1/1000
0, 0, 0, 0, 63024, e5164f87feadf4b65257f578affc3e04
0, 33, 33, 0, 63024, 6aee5a3b6c3a096dfc1594762b2b248f
0, 66, 66, 0, 63024, cb1c9dce6fdf7372e0eb2397251f0ade
0, 100, 100, 0, 63024, 4fe5f24c08690c966b6a14ac3422510b
0, 133, 133, 0, 63024, b22a273814523251b365f3278d8a3a9c
0, 166, 166, 0, 63024, 190d9dff373023a25427fc859545ea24
0, 200, 200, 0, 63024, a6307f38718ed686cb195e3833ab27ab
0, 233, 233, 0, 63024, 79630bec5a91d69aca42a910413c2800
0, 266, 266, 0, 63024, 2231cec9c03714b8671e5e1456b148c9
0, 300, 300, 0, 63024, 278458f6734a24f2eb9bc877a6e9d7df
#tb 0: 1/1000
0, 0, 0, 0, 64896, 6bff7c1f4c5ef8412ebf669852c70de6
0, 33, 33, 0, 64896, fdfd7a2308de9509a41fed2880a8f0f5
0, 66, 66, 0, 64896, d8b464811e9c3b8a6db9cc277ac88c59
0, 100, 100, 0, 64896, b8fa29e79be3126dd74310d6dd09c747
0, 133, 133, 0, 64896, dad29803fed686887a0873eb78a469c6
0, 166, 166, 0, 64896, 684de29bbf800f52aea4af9850bcc5b3
0, 200, 200, 0, 64896, 06862dbce7571b4487766b179a596e1d
0, 233, 233, 0, 64896, 99582a966bc7070112e214ce7912e485
0, 266, 266, 0, 64896, a61158581a5719cb0cf13fb3301cb8c4
0, 300, 300, 0, 64896, 9c2295332f34fee3a249262c8ba843bc
#tb 0: 1/1000
0, 0, 0, 0, 65520, b15c7e98ddd137237b062cb51667522f
0, 33, 33, 0, 65520, 00c594c68b19ef39a79a38e86853dc64
0, 66, 66, 0, 65520, e6742abe3d2c178af4298e121391c299
0, 100, 100, 0, 65520, efe5387b38c32f1c25c0fc9836921074
0, 133, 133, 0, 65520, e0e696f4c18af09a74e052903db1468c
0, 166, 166, 0, 65520, f1960270c6704ca47caed63161716025
0, 200, 200, 0, 65520, a1542d7749cfa447481acd7835db838a
0, 233, 233, 0, 65520, a91fb10a17d1d056667860cc43c81dae
0, 266, 266, 0, 65520, b673bfbb722522b4e7b5e9c5b85cc31f
0, 300, 300, 0, 65520, 8b4bb57d3cf609cbf9564a96a6ca6ade
#tb 0: 1/1000
0, 0, 0, 0, 69888, 479d07bb96905ad7d5f0ec3ee12b41ba
0, 33, 33, 0, 69888, 4b6555aaed8e5a45879773f1bf87962e
0, 66, 66, 0, 69888, c5f42cb796dd7b6622957016ca6b502f
0, 100, 100, 0, 69888, f06c954483560866fbff10bae7ba0785
0, 133, 133, 0, 69888, af83aff39999852310395fe241ccb49b
0, 166, 166, 0, 69888, 108377d6f30ceba6f2377330af2da38f
0, 200, 200, 0, 69888, e81e6e0b37a7b92368ede9cab124567c
0, 233, 233, 0, 69888, 59dbe51caaed8e6e825c78c5901fb22c
0, 266, 266, 0, 69888, 24686123ea14c8d1a9b447733df0aaab
0, 300, 300, 0, 69888, ce2035c49237c8076f8dac0d3f61848e
#tb 0: 1/1000
0, 0, 0, 0, 70512, 33aa4af6153570518c59960a0c959053
0, 33, 33, 0, 70512, 024fa27dee80ad199528052aaa8d42c7
0, 66, 66, 0, 70512, b949ef118c7e7e62a8b88e2308219ef9
0, 100, 100, 0, 70512, 3061ee13696ced5e10a646fdd5ca6c34
0, 133, 133, 0, 70512, c4984bd53dcb7b9e2570f2965d077b2f
0, 166, 166, 0, 70512, d564c35c5caadcfd9f80377fa414af72
0, 200, 200, 0, 70512, 9b7d7b10ee2f3eb7a9ffddcebff45b97
0, 233, 233, 0, 70512, a0ede7085b04cbb3519d56b2e4347d14
0, 266, 266, 0, 70512, 63d7af745f9e6a34b618db28fe878ffd
0, 300, 300, 0, 70512, 85077809087e7bdfb9215bfcd1f1bbc0
#tb 0: 1/1000
0, 0, 0, 0, 61740, 5c69f80da667bfd20394995e93e4cd2b
0, 33, 33, 0, 61740, 13363cd8e52ca8c1053db1c84c111bc9
0, 66, 66, 0, 61740, 108976afdf99f59276d6f89879e3bdc3
0, 100, 100, 0, 61740, 770ce25985e6b479d52a9185876cfe83
0, 133, 133, 0, 61740, eba7cbb3c91989aa4c13487ed01675b5
0, 166, 166, 0, 61740, f391c30a47c33a250dd20cb12f0a6e01
0, 200, 200, 0, 61740, c38e12de302177d19dd744a3ea227e90
0, 233, 233, 0, 61740, 8c9370439a0b7289919c6ee68e00570f
0, 266, 266, 0, 61740, ac3748c4b99c4f1aba7430ae12c19cfd
0, 300, 300, 0, 61740, e5228dc84f7933ccc9306907d737ad3c
#tb 0: 1/1000
0, 0, 0, 0, 62370, d83ee2413e701ae405a2b74863d4c5a9
0, 33, 33, 0, 62370, f2ebc0f7dc171e0e5d2911c7ee2df5e1
0, 66, 66, 0, 62370, e189ef4d8add227352a0d6ee62748ee7
0, 100, 100, 0, 62370, 6dcb1dca1a0e2ba85034aba9f021427e
0, 133, 133, 0, 62370, e98c633ba8912f6d65374055ec9af543
0, 166, 166, 0, 62370, 82111cb7d5addce16d9bcba9e0a99503
0, 200, 200, 0, 62370, bbbc73002f794ab0261fe384b2524226
0, 233, 233, 0, 62370, 0bcdc427df47123959f7de9c44fe291e
0, 266, 266, 0, 62370, 505776b3d82e38612393d60b6aa55c1d
0, 300, 300, 0, 62370, feb93758242b847f3d53bb4c97b0ad9c
#tb 0: 1/1000
0, 0, 0, 0, 63000, 2465560246c1ee24d937cb9cbc1422f1
0, 33, 33, 0, 63000, 8926b628dcdf2182516822c7d0d778ec
0, 66, 66, 0, 63000, 9bd14d3ebc7fe81c4223116de1b9c2ec
0, 100, 100, 0, 63000, 2d029d8461c20236066c0786950540fb
0, 133, 133, 0, 63000, 39412b6e62de43bd40c58d4e2e38daf8
0, 166, 166, 0, 63000, 3ea211c24f606b29582147bf872994dd
0, 200, 200, 0, 63000, 261c37f88bf7f40549642578d9464aeb
0, 233, 233, 0, 63000, 98551d44de1e23165e05975babb72446
0, 266, 266, 0, 63000, 1d85ad052dd27e7e6bfea5d2babf5176
0, 300, 300, 0, 63000, ad18b6a3698a3674c2488f927810eb0d
#tb 0: 1/1000
0, 0, 0, 0, 63630, 5d01848aee2b324f2e356627f9c39532
0, 33, 33, 0, 63630, b671fe34bc0e5a682baff929d26ea627
0, 66, 66, 0, 63630, e9a40f87ca5aaa5af9772e286feb9063
0, 100, 100, 0, 63630, 4730f60d4c856e8ad877c0d8b1729ec4
0, 133, 133, 0, 63630, 317fc01349e0984c23d15f97a3a0f442
0, 166, 166, 0, 63630, aea89116ffe48340d1752d1ad5195529
0, 200, 200, 0, 63630, 14694ba65b6308e5f5571486b62ca1cc
0, 233, 233, 0, 63630, 53c6102d877c9a30eaa20ddc45207ea0
0, 266, 266, 0, 63630, 7d1e898b1bead878224e8ff15d624bd9
0, 300, 300, 0, 63630, 37b684bfae5dbd33e8dbb8332b94ce8a
#tb 0: 1/1000
0, 0, 0, 0, 65520, 1156d318c00d299cf5bdc7e485966dab
0, 33, 33, 0, 65520, a8094f8f1e7e04e54251bee8c4c800ce
0, 66, 66, 0, 65520, e2a07d99ffe1cfe6b9fce36e93677fe1
0, 100, 100, 0, 65520, 63d179b00816dbad75b778d2c23955c6
0, 133, 133, 0, 65520, 407de5fb2dfdd52e6173905b09ff22f2
0, 166, 166, 0, 65520, 36900199c56310e651723de4e3ad2f2c
0, 200, 200, 0, 65520, 908db56e975b5db07af17fdc51b12be8
0, 233, 233, 0, 65520, 400e32490b1262009a481cc331a00e44
0, 266, 266, 0, 65520, dc43b786cba033cc92b9921d12f7b3d7
0, 300, 300, 0, 65520, e8c94c5965c729f5d1ef3ba4509c97c8
#tb 0: 1/1000
0, 0, 0, 0, 66150, b65725c68978bdaaafdf735dfbafa9e3
0, 33, 33, 0, 66150, 35be2f16bd5dedc9d3f7a016f0d71701
0, 66, 66, 0, 66150, 8c2873a97b51510d7449869e24a348f5
0, 100, 100, 0, 66150, 724a30e8ae539e797db8889dc08aec5e
0, 133, 133, 0, 66150, e3ae1246a63ea22afd026bfb859fe165
0, 166, 166, 0, 66150, 7e1fa363cf3f44c7a3019f29c14a6da4
0, 200, 200, 0, 66150, c6f26619ab5687a2a698c8766b79f2eb
0, 233, 233, 0, 66150, be5b8c50a772afe95d72bf3cc7c4fd2f
0, 266, 266, 0, 66150, 9eab1417ac249ce31c79750143d52084
0, 300, 300, 0, 66150, 9d2455048dbc3cdc2343a818c5a2bcb1
#tb 0: 1/1000
0, 0, 0, 0, 70560, bb903b926c4b34ae336e21d65ad8fd25
0, 33, 33, 0, 70560, c4c0bc3b112487e994d22176817ace3c
0, 66, 66, 0, 70560, 24e699f7a92ab1b0fe12e0b747470b5b
0, 100, 100, 0, 70560, 200f403694d3acfda63f52e8373f1420
0, 133, 133, 0, 70560, 6df417a8ec1810562301c89724b739d1
0, 166, 166, 0, 70560, 55757b633d8fe669fc0f507dab4fa9f7
0, 200, 200, 0, 70560, 45bc82bee02cb45422be3ac1019896d0
0, 233, 233, 0, 70560, 4aaf5d07d2796910767d5084556c9cf9
0, 266, 266, 0, 70560, f100fa26da47250b98d95a18915f521d
0, 300, 300, 0, 70560, f5a8def53b4638b6ce7c8588d595d0ad
#tb 0: 1/1000
0, 0, 0, 0, 71190, 03707b2f5c392933f7336f380423a0a1
0, 33, 33, 0, 71190, b388553c79573555a3b660f5e36d4e36
0, 66, 66, 0, 71190, a1a7fd8ba7fb0fe7733cdf5440c7c1f3
0, 100, 100, 0, 71190, 9daff7ef71dd54951f0b75a902065259
0, 133, 133, 0, 71190, 60218a4b8bc0a5b0b40fa560a40fb4c0
0, 166, 166, 0, 71190, 21229bfed833468fafc27ce93db1450c
0, 200, 200, 0, 71190, 7aa290c6e503315d7aa3517258d5f63a
0, 233, 233, 0, 71190, 63fd08ae2e859ff3d874ab2c2ce41a42
0, 266, 266, 0, 71190, 725b371247fae28ef4b912368738df64
0, 300, 300, 0, 71190, 7cf2d8d9e464307311b499ff0c3ea05e
#tb 0: 1/1000
0, 0, 0, 0, 65856, 3ffc096f1b42b4d319d4a9efbefc7625
0, 33, 33, 0, 65856, 78b3655d5cad30fa6b2c2d8fd29463de
0, 66, 66, 0, 65856, ab197553d9599b2a03aff62d1d694848
0, 100, 100, 0, 65856, be368d1f3d3fcc710565b5433940f0df
0, 133, 133, 0, 65856, 374c5db60ea9c110b871bb45be0efff1
0, 166, 166, 0, 65856, ec50085400d626de5833bc0a94d9941f
0, 200, 200, 0, 65856, d4ae69937e2a8d9bf2023d4215749635
0, 233, 233, 0, 65856, 9b0b81eb6d62b8014e0639932fe35bc0
0, 266, 266, 0, 65856, cd02d0cc268e6b6df0b2dbd3f3b137e6
0, 300, 300, 0, 65856, 5322ba1085c114f93534e1761a0d8aa1
#tb 0: 1/1000
0, 0, 0, 0, 66528, cf35dffc80946e87bb9d3e18aab9d320
0, 33, 33, 0, 66528, a76ac92f05e9b097f8ac5882e1ffe656
0, 66, 66, 0, 66528, faa1e8a11c9df3e9c9a9dafbebea6d04
0, 100, 100, 0, 66528, 905a28289c8ac793b335096ca7f84e1d
0, 133, 133, 0, 66528, cb480fa6977baf98a74bddf213ecba82
0, 166, 166, 0, 66528, 35224d3708e3ba1dafcc58b803d5ea77
0, 200, 200, 0, 66528, d166d764e87854bca47ab7a2bc8b1f9b
0, 233, 233, 0, 66528, 562f1e06ae36abba5f1fb53e3d6cd7e8
0, 266, 266, 0, 66528, 1599cebef060f6464aeef15aacbde446
0, 300, 300, 0, 66528, 3316ebca2864a9dc04db86069efb1dd1
#tb 0: 1/1000
0, 0, 0, 0, 67200, 0819e6d715c9b4d94f05f63a7ca86199
0, 33, 33, 0, 67200, 9b9a4b01ed4c8a93687e45245b3092a3
0, 66, 66, 0, 67200, 3a076f5b8dba60552e84a391ee04d1c7
0, 100, 100, 0, 67200, 7aafc561f5b96e9d286bd8deb5687774
0, 133, 133, 0, 67200, daa43a89ab6b2761eedaa183e33a3465
0, 166, 166, 0, 67200, c14874409872357b11b65f35a283e058
0, 200, 200, 0, 67200, 37d2ef52a9c694b2596d58ed9ca0d90b
0, 233, 233, 0, 67200, c97bc860c006896d80f52ccc0759f472
0, 266, 266, 0, 67200, 5f8618114a723a017e39a1af695996f3
0, 300, 300, 0, 67200, ee8234fc5ccd41d05eb87e1510f9795e
#tb 0: 1/1000
0, 0, 0, 0, 67872, e1e3b4af5910383ff6f66b6ab1a29544
0, 33, 33, 0, 67872, 8668ef92b72f35728ebb456665d48b95
0, 66, 66, 0, 67872, dffc7c28f86f07bf28451292990e9594
0, 100, 100, 0, 67872, aebfb446fa6d48db36dbd9b5cd147f1e
0, 133, 133, 0, 67872, e3c6cb8c5bb3a26928493bfc297ab827
0, 166, 166, 0, 67872, 68dabae76c1d27ab0e1079d99cb6d413
0, 200, 200, 0, 67872, d1f7745eef748688f3871d00a7e67ef8
0, 233, 233, 0, 67872, 36738851cc2af83fd250dea4cd63941b
0, 266, 266, 0, 67872, 16c0315c43427e7e6719806a89551703
0, 300, 300, 0, 67872, c4d589c0ea4cdfc1dd6dff72084c61fd
#tb 0: 1/1000
0, 0, 0, 0, 69888, 85f08afadfd1204d4131b9ee9c8cc10b
0, 33, 33, 0, 69888, f893de5432a082b3dffcf7499827f548
0, 66, 66, 0, 69888, cb81e0d7b657bc5a4a9cf8ad75a76a77
0, 100, 100, 0, 69888, 8a40842123965731c15fc23fb6366d1d
0, 133, 133, 0, 69888, 09c6d92af14a3fcfb12705cd5da57f2a
0, 166, 166, 0, 69888, 6bede4dc8770df534b599021b0425309
0, 200, 200, 0, 69888, 334b0b0448e9e4e6a0cddcd2e3a0af3f
0, 233, 233, 0, 69888, 09f491f0f3870ef96cff0384cd7183d1
0, 266, 266, 0, 69888, c9e5f81186ac947a77b051c8f0e76eac
0, 300, 300, 0, 69888, 917565c3327bff78b53a78ea739472ff
#tb 0: 1/1000
0, 0, 0, 0, 70560, 427421e5fd2087c6ff7b87a27982332f
0, 33, 33, 0, 70560, b68311fd44e189e4174ac357d5415068
0, 66, 66, 0, 70560, 2c822ff45be7a1ea412d21ff82c7bc1d
0, 100, 100, 0, 70560, 34659186d93516eae1dd4d9a391d1c3f
0, 133, 133, 0, 70560, 1990dd822abc3a10f511589db5aa50f4
0, 166, 166, 0, 70560, 4a4dc076172c79d9fde3e17b47109835
0, 200, 200, 0, 70560, 51874c79850120537fa5c405721d0107
0, 233, 233, 0, 70560, 15d7897a128de9be90be17f1679012c9
0, 266, 266, 0, 70560, a8d9480accf8585e94161a5f7c371cef
0, 300, 300, 0, 70560, 8a9d3f09561b895b423ae9428f620b9b
#tb 0: 1/1000
0, 0, 0, 0, 75264, bedd5d2725ffff06a50e23841bc2dfb8
0, 33, 33, 0, 75264, 8c363f68b0b30f507563516aa99e23ac
0, 66, 66, 0, 75264, 9cb7d51ca4439614dc3f5980507a4d32
0, 100, 100, 0, 75264, b393a18de28ab6b8d1c6afd67a7794e0
0, 133, 133, 0, 75264, 81f69ee1e3d89cb78cac192c352f7741
0, 166, 166, 0, 75264, aabb51f029a9a02e71524cf3500931e9
0, 200, 200, 0, 75264, 6581aec620c508d2b42ccceaa2c6044d
0, 233, 233, 0, 75264, 993cde759158c30dcf0f0a9fdcdfb0d8
0, 266, 266, 0, 75264, 85985ae8d35514d601800a06c8226625
0, 300, 300, 0, 75264, 0eba1d7c193e473586e4a5c87d0e0d21
#tb 0: 1/1000
0, 0, 0, 0, 75936, dca556e648a576b3973fbe4b34d0328c
0, 33, 33, 0, 75936, 34a49e4aba4aca5c76ab0f751341c32b
0, 66, 66, 0, 75936, 4b7cc6d500b273efe7e30fc3a3946f74
0, 100, 100, 0, 75936, 1960f0f1edf9196c96b0de742a3cd53c
0, 133, 133, 0, 75936, 3cb7d90178636911c5d53a5f8e75599c
0, 166, 166, 0, 75936, 84b56c60c2282f85102048cc2cf40b88
0, 200, 200, 0, 75936, 3ca34d2978307ec0fca05130d81bcc26
0, 233, 233, 0, 75936, c15560be737e02ea9d1deeca0af9bb77
0, 266, 266, 0, 75936, 391439789a6aa7bb02d7e699795a9559
0, 300, 300, 0, 75936, 9f681e91cbcbe9920f21236b8ff093c7
#tb 0: 1/1000
0, 0, 0, 0, 66444, 4757a31842453f806de2f2256329547e
0, 33, 33, 0, 66444, fe5fb955a4143091c5bfae7c4a4afe0f
0, 66, 66, 0, 66444, 93766c5a03d71f99afb7705add7b63f0
0, 100, 100, 0, 66444, 30c91162aa6fb0ed3e47325146bb6d8a
0, 133, 133, 0, 66444, 501fe67785b970b1b62c2ae0b36b19ad
0, 166, 166, 0, 66444, 836be5e778e3d20e75c4fcd71f765b3d
0, 200, 200, 0, 66444, 21a9fd5e78212fe71719e173844bc6e6
0, 233, 233, 0, 66444, 81b3919208e345d93dde62740b47dd93
0, 266, 266, 0, 66444, df010555a929ba88a2f25c6267e3786e
0, 300, 300, 0, 66444, d2cff8282e5e7a5bbd879c73df0670c3
#tb 0: 1/1000
0, 0, 0, 0, 67122, b97087eb8c53cf56dc44576912654fb2
0, 33, 33, 0, 67122, 219bb68a59dc166806a5b5689a943b66
0, 66, 66, 0, 67122, 67b2ec19dd3b74d828b51912c25249d6
0, 100, 100, 0, 67122, 73dd9625538e10a0f94d31ac9fe3db23
0, 133, 133, 0, 67122, 51e68f201130da18beb0cb27adcf6fa9
0, 166, 166, 0, 67122, 455d9753b3c0ac5ad7d9da022f69acd0
0, 200, 200, 0, 67122, 60a8905a63db4cdd2560583fb6415030
0, 233, 233, 0, 67122, 48c156f4b2c9f936487b43713a4573fd
0, 266, 266, 0, 67122, a5c8f4190cb34b3ecd42ca8e09bf1646
0, 300, 300, 0, 67122, 233a5d5187137e047993532fc2e725d3
#tb 0: 1/1000
0, 0, 0, 0, 67800, 0ae27db338f73f37eaed806b1c789593
0, 33, 33, 0, 67800, 3f69273752f43699a3bc7b22a88cc3aa
0, 66, 66, 0, 67800, ce0dfafb59910241d2b1a2275a2c2143
0, 100, 100, 0, 67800, 8d20f404e25766c819ee728858bcbc76
0, 133, 133, 0, 67800, 67bc5604c5b0f6c3484b605c1f93c83a
0, 166, 166, 0, 67800, 1c82def3a06430d205cce0db7b5714de
0, 200, 200, 0, 67800, 654d7a676e3b8b64541ed8cdefbd7286
0, 233, 233, 0, 67800, 6c80c78c7b652c5b3b117a0960e89951
0, 266, 266, 0, 67800, ae73e3c69ec6747c5234d58c5e1e36eb
0, 300, 300, 0, 67800, e40d716efd8caf2d4004d299fb914328
#tb 0: 1/1000
0, 0, 0, 0, 68478, 0cd2876640e71de3a6df7839bd6f0b51
0, 33, 33, 0, 68478, f887db6839c0cddd1ea9ae6bfd2cc16d
0, 66, 66, 0, 68478, ff2a890cf4c4973bf181ba8424c2eadc
0, 100, 100, 0, 68478, f69f2e4f3036a21deb43a0bf4b95771f
0, 133, 133, 0, 68478, 93f511739c19f1a3b356dda39d945c93
0, 166, 166, 0, 68478, 7f79633c93765b504fef0324bd10fdba
0, 200, 200, 0, 68478, d6c53d3937c9a40b227b4486452e0b33
0, 233, 233, 0, 68478, 4e26625e8997ad6fe08ae68fbdfdbfd7
0, 266, 266, 0, 68478, 3bf4c8ac0279351bf904cf57b0fc13c1
0, 300, 300, 0, 68478, 12d64d856025185fa9e610dfa62b05af
#tb 0: 1/1000
0, 0, 0, 0, 70512, 6006cac6628cf9e7cea58aec07471b06
0, 33, 33, 0, 70512, f7e994921248b6933920c984880ec96c
0, 66, 66, 0, 70512, c0aeeb9d2009538d8d5e837f45e1542d
0, 100, 100, 0, 70512, 7dacf9d00e85bd52045eb47bae5225b3
0, 133, 133, 0, 70512, 024fd008a099ae954e38a3f0a8ebb6c9
0, 166, 166, 0, 70512, fb6c368a1b3578ab59aa30e0b5cc4853
0, 200, 200, 0, 70512, 07815251f7020b627c365a7a7be694c7
0, 233, 233, 0, 70512, db8b8f48f3693867d2bd8208cf4f929a
0, 266, 266, 0, 70512, 88b42d943c0978d832333a8a3f7b6bbc
0, 300, 300, 0, 70512, 7aa760190f9328ba4f6fa87d1d9e8d3e
#tb 0: 1/1000
0, 0, 0, 0, 71190, a6c1b7686202f5cc64335f92be595309
0, 33, 33, 0, 71190, 3e573d4c693a39c5d6cd46b8873e99bb
0, 66, 66, 0, 71190, d2388f6f641c8ddec98f11493f1a1390
0, 100, 100, 0, 71190, 16473e33532ebc8de2f02077c406346b
0, 133, 133, 0, 71190, 6c75d1c01276838fce40837e373f49db
0, 166, 166, 0, 71190, b718e7445e2b08dde78fa7f30be01346
0, 200, 200, 0, 71190, 2f556ed5afd60b1bbae76984ce073107
0, 233, 233, 0, 71190, 4e5d59daed044c39a14c35f18cb4fb7a
0, 266, 266, 0, 71190, c14901a9906ffcd0eb1efc068ce32941
0, 300, 300, 0, 71190, 3d73b7f87bcd16c1ec565b5cc8d0fe93
#tb 0: 1/1000
0, 0, 0, 0, 75936, 80fb3a643384386beadc0991f171669d
0, 33, 33, 0, 75936, 65a4a51163f49a75f8eeecd94cb2ba47
0, 66, 66, 0, 75936, d5b2aac9889d2991b83fd4360ada0258
0, 100, 100, 0, 75936, 7958ff5535358567ea7df351d78256a7
0, 133, 133, 0, 75936, 7e7413b9a61967d0ade07b81944e9a15
0, 166, 166, 0, 75936, 40a008016adbf9673adbbc4c0edb4454
0, 200, 200, 0, 75936, fef7b5e2809ef79917ab394a067ef4be
0, 233, 233, 0, 75936, 91ee2360faf46a25b95927c55eea603f
0, 266, 266, 0, 75936, a47f14a80a529f79f97accbe23188046
0, 300, 300, 0, 75936, 3613bcd41ff13006fbba3bd0087c44f4
#tb 0: 1/1000
0, 0, 0, 0, 76614, f2370fc802dafdf5082beffc1907a9c6
0, 33, 33, 0, 76614, aad6de7b986234a1d621935b272501c9
0, 66, 66, 0, 76614, 8a6d3784e22e3b4f735e78916fbc3821
0, 100, 100, 0, 76614, 0c4afce19c43fdf3bb1b972810cc9126
0, 133, 133, 0, 76614, 814a68dd76a3135221131988910f51ba
0, 166, 166, 0, 76614, b2379c4b28dca10e67ac58631f9731c0
0, 200, 200, 0, 76614, b16fd651884340a428cea3fe0ac18ba6
0, 233, 233, 0, 76614, cb65cd4c421cfd6a19fb123ec27abbe6
0, 266, 266, 0, 76614, 7f1d2686b9808de8ecc723b18136d57d
0, 300, 300, 0, 76614, da7fd4bff4b6db0221c42492876c5c4d
#tb 0: 1/1000
0, 0, 0, 0, 152064, 043ce065a309514e1e8ebdcbb3c2458b
0, 33, 33, 0, 152064, 8579c9cffd95b11db86158e518b2e34a
0, 66, 66, 0, 152064, ebbba105e499604f5e69b8aa48fe86f4
0, 100, 100, 0, 152064, b08526fab7e106021f9fb9b1e2d4b725
0, 133, 133, 0, 152064, 92afa561d06f41ccc6d2e2bcc3ab2ee4
0, 166, 166, 0, 152064, 50de8ec2db66c783289a3982dd1c4f97
0, 200, 200, 0, 152064, c2ab55d114b8822adef06ccb093b5ac7
0, 233, 233, 0, 152064, e3ee4edbe8a1f0b5486bbd8a52e7cbcb
0, 266, 266, 0, 152064, fc33fd50566cd64e5b13911ee06c6e24
0, 300, 300, 0, 152064, 05297e847f983a19fe2ba5e05932a110
0, 333, 333, 0, 152064, d21db9adb27be89ab3b7f75d89175e24
0, 367, 367, 0, 152064, 29bb87bdebd078f8dd953a70def6c4dc
0, 400, 400, 0, 152064, c57f7bc772f6143a22edaf926f92de5f
0, 433, 433, 0, 152064, 39f2fc755d4bc2cc5ec077035382be22
0, 467, 467, 0, 152064, 000ec9c75374f6d74a5e61189e6fd782
0, 500, 500, 0, 152064, 3027187c9bdb2a755d14513b7e597bb1
0, 533, 533, 0, 152064, 2b3129659df2b3aa10b9398c50301e00
0, 567, 567, 0, 152064, e23bcacf1cafca9a7959508b33e63907
0, 600, 600, 0, 152064, fe0382dd155284998a0d7eb7effb5adf
0, 633, 633, 0, 152064, e0a487860dd0df3d865971b483fab3e9
0, 667, 667, 0, 152064, 7ca757c55b0ea4779cdfa3a535f8f234
0, 700, 700, 0, 152064, 1a276d27f4ce0e2720e25dbed2e524ae
0, 734, 734, 0, 152064, dd39bc322c8bdce196a9c2129bcb5d6e
0, 767, 767, 0, 152064, 63e295427977d645462e0fb3277ccb53
0, 800, 800, 0, 152064, e9a35655c71da22fb0c7865e0bbc91b8
0, 834, 834, 0, 152064, 5903bcbccabb3366382b37bf08119dde
0, 867, 867, 0, 152064, 3b6ce09353b07b193914a71ca2334d8c
0, 900, 900, 0, 152064, cb3731eb5dbe338125c0a7d6b4bf2868
0, 934, 934, 0, 152064, 0837c62b54912ed06f7f755894ad3f6b
0, 967, 967, 0, 152064, 7f215dc14d8e280fc18ad3fb3122fa58
0, 1001, 1001, 0, 152064, 6dafaf5adc45fead74f0153e3764b17d
0, 1034, 1034, 0, 152064, e19c8274ee6377dbf005f6516a81c413
0, 1067, 1067, 0, 152064, 358cbf29bd136d2f9dcb60ab82a2e9e5
0, 1101, 1101, 0, 152064, 2276d4670ff35c3a76c27c3a5810eea3
0, 1134, 1134, 0, 152064, 636dd3390d4011c377915d7d3acc9ee1
0, 1167, 1167, 0, 152064, 5e7a1ed17d80168567d61987425f4e60
0, 1201, 1201, 0, 152064, c10a4830c5f268888789fccd16c0cc0e
0, 1234, 1234, 0, 152064, 298ef49418d730a031ff23311031c969
0, 1267, 1267, 0, 152064, 4dd2249e13cda0f99fa46786d345c96a
0, 1301, 1301, 0, 152064, 24232dbc6e35a069c60422c4c23dfa51
0, 1334, 1334, 0, 152064, ae8751c5ac168d6aa4499fe69f018ae2
0, 1368, 1368, 0, 152064, 6a3a7e60a569e7415f2c3a1453e4dc38
0, 1401, 1401, 0, 152064, 5475af1c118d1b7cc0a357bc434241a8
0, 1434, 1434, 0, 152064, c6b5ab39e630e66e8f09698fd1dfa160
0, 1468, 1468, 0, 152064, f1c0310adf115456167e3fa790e43dde
0, 1501, 1501, 0, 152064, 3028296307b47d10156fc9657693edc3
0, 1534, 1534, 0, 152064, 0903dabcb8ac707b423b222ac5bb4898
0, 1568, 1568, 0, 152064, 713cf71b994e2c85ed577062814c5732
0, 1601, 1601, 0, 152064, 674f56b9cccf5c9d1f88f68c3996a671
0, 1634, 1634, 0, 152064, f63732c2ff823960d8b62d866dfb5e6a
#tb 0: 1/1000
0, 0, 0, 0, 152064, 20cf714300c5e28ffb77bf9c682129bc
0, 33, 33, 0, 152064, 2f271e4de29f87d6b90511fbafdf9fbb
0, 66, 66, 0, 152064, 2f271e4de29f87d6b90511fbafdf9fbb
0, 100, 100, 0, 152064, a88532a043f5f2c6bce729a8e20ee5af
0, 133, 133, 0, 152064, 8d7b5482ed8072a7c95d722783773436
0, 166, 166, 0, 152064, 04872d8619b163b5e0c20123ccddf7dc
0, 200, 200, 0, 152064, ed6d9677782aa6e87b6576541391557f
0, 233, 233, 0, 152064, 689f71108e9bf024cd9ccf48800dcdc7
0, 266, 266, 0, 152064, f7c555792884499bb62a8e739b201739
0, 300, 300, 0, 152064, 7fed82c38ce428a178c56f6131eff5ec
0, 333, 333, 0, 152064, fb638e587ade05baa027bb63edc7ec7c
0, 367, 367, 0, 152064, 319295f5aa44661a80570e844050156a
0, 400, 400, 0, 152064, de2d8635966a1cd57290eac449a5fb4b
0, 433, 433, 0, 152064, 9ac3d711a00aac6b17004bb6451e4cab
0, 467, 467, 0, 152064, d12eced084e72b5230493e2dc2de0f0a
0, 500, 500, 0, 152064, 197761d11407fed723a63b8e28cb8e19
0, 533, 533, 0, 152064, 28d8e807bc142b74f1eaf30dbbf1b7bd
0, 567, 567, 0, 152064, abe88f1f7490d13ba3def9511beaceec
0, 600, 600, 0, 152064, 7d297b9c989ebc0408fd41b14900242a
0, 633, 633, 0, 152064, d5e7adfa2b207d860feff5c894585fd1
0, 667, 667, 0, 152064, aea3e9de9de237f8379785f3467dc9c9
0, 700, 700, 0, 152064, 211967cd949c1d83a8cc4c8267aa6034
0, 734, 734, 0, 152064, 3f49bf8e0434114c15b867be2d53d283
0, 767, 767, 0, 152064, 8d5e629c0e941ca6f049ed2bb59d09a8
0, 800, 800, 0, 152064, d359620957877534bc94cd137dc652fe
0, 834, 834, 0, 152064, 83610fc1969fdfa267e7e462a83ea40c
0, 867, 867, 0, 152064, b2d20dcc3f77a238ce7210991eebe1a7
0, 900, 900, 0, 152064, a42ad37808f30e1d968882bf42e9c641
0, 934, 934, 0, 152064, 55084cded938266a2c3c658dcc162781
0, 967, 967, 0, 152064, e392a3a7d33e10e95fc9cdf0a2080eac
0, 1001, 1001, 0, 152064, 73977c4827463c17e63c0769bb90722f
0, 1034, 1034, 0, 152064, cb5dd87344af7d6fd4ed0e06cb90d9c2
0, 1067, 1067, 0, 152064, 533338860124e392cef2039468c22f75
0, 1101, 1101, 0, 152064, da30f077490042367502a6fe11a46e0f
0, 1134, 1134, 0, 152064, 860ab1bfbd3fe6a27bee5ef8c4e0b600
0, 1167, 1167, 0, 152064, 339ec3863eaed689d46289ffe47bc45d
0, 1201, 1201, 0, 152064, ffa6c990577093106796ed0dee56c483
0, 1234, 1234, 0, 152064, 3fcdc2bc064c79f35ea81a715ff089d0
0, 1267, 1267, 0, 152064, adaef9ec97e23a542db22bcd23c740bd
0, 1301, 1301, 0, 152064, ddcff4bd2c9579181182eb49add0ce3c
0, 1334, 1334, 0, 152064, b3b039c84cffb9272c8ddf9086748696
0, 1368, 1368, 0, 152064, 70939a961ec1e4697031b79e7ebb7919
0, 1401, 1401, 0, 152064, 6b3ff2e003749c6ffeb2d71edecf884c
0, 1434, 1434, 0, 152064, 5e4efc96971f81218c472482b5a79374
0, 1468, 1468, 0, 152064, 279132c87d81a5747824b06423bf6785
0, 1501, 1501, 0, 152064, 1da48caa08007523aab41a56e21dd99b
0, 1534, 1534, 0, 152064, 36ecffb2bfcb587d2556fddcbbd3448b
0, 1568, 1568, 0, 152064, 7823e3c86cd5a05c2959c7ef4d1cfa89
0, 1601, 1601, 0, 152064, b53f78afbad1a43f7aea58814eacd824
0, 1634, 1634, 0, 152064, b9b127b4bc54123bec19b2f4a3fa157c
#tb 0: 1/1000
0, 0, 0, 0, 3110400, 1e6c2e768a5107e57e6d626f0511193a
0, 40, 40, 0, 3110400, 972d3e2b5ee2e3b0907218a243e4cb7d
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment