On Sun, 26 Jul 2020 at 16:16, Jernej Škrabec <jernej.skrabec@xxxxxxxx> wrote: > > Hi Ezequiel! > > Dne sobota, 25. julij 2020 ob 15:08:37 CEST je Ezequiel Garcia napisal(a): > > Hi Jernej, > > > > As you know, I'm not familiar with this hardware, > > but I've tried to take a detailed look anyway. > > > > Thanks, any review is welcome. > > > The driver looks mostly good to me, I just have > > some minor comments. > > > > More importantly, seems the current uAPI > > control is supporting this platform nicely, > > which gives us some confidence to mark it > > as stable. > > Yes, it looks pretty good in that regard. > > > > > Comments below. > > > > On Wed, 22 Jul 2020 at 17:35, Jernej Skrabec <jernej.skrabec@xxxxxxxx> > wrote: > > > VP8 in Cedrus shares same engine as H264. > > > > > > Note that it seems necessary to call bitstream parsing functions, > > > to parse frame header, otherwise decoded image is garbage. This is > > > contrary to what is driver supposed to do. However, values are not > > > really used, so this might be acceptable. It's possible that bitstream > > > parsing functions set some internal VPU state, which is later necessary > > > for proper decoding. Biggest suspect is "VP8 probs update" trigger. > > > > I suggest that you also put this explanation here, as a comment > > in the cedrus_vp8.c > > Ok. > > > > > > Signed-off-by: Jernej Skrabec <jernej.skrabec@xxxxxxxx> > > > --- > > > Changes in v2: > > > - rebased on top of current linux-media master branch > > > > > > drivers/staging/media/sunxi/cedrus/Makefile | 3 +- > > > drivers/staging/media/sunxi/cedrus/cedrus.c | 8 + > > > drivers/staging/media/sunxi/cedrus/cedrus.h | 15 + > > > .../staging/media/sunxi/cedrus/cedrus_dec.c | 5 + > > > .../staging/media/sunxi/cedrus/cedrus_hw.c | 1 + > > > .../staging/media/sunxi/cedrus/cedrus_regs.h | 80 ++ > > > .../staging/media/sunxi/cedrus/cedrus_video.c | 9 + > > > .../staging/media/sunxi/cedrus/cedrus_vp8.c | 699 ++++++++++++++++++ > > > 8 files changed, 819 insertions(+), 1 deletion(-) > > > create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus_vp8.c > > > > > > diff --git a/drivers/staging/media/sunxi/cedrus/Makefile > > > b/drivers/staging/media/sunxi/cedrus/Makefile index > > > 1bce49d3e7e2..a647b3690bf8 100644 > > > --- a/drivers/staging/media/sunxi/cedrus/Makefile > > > +++ b/drivers/staging/media/sunxi/cedrus/Makefile > > > @@ -2,4 +2,5 @@ > > > > > > obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += sunxi-cedrus.o > > > > > > sunxi-cedrus-y = cedrus.o cedrus_video.o cedrus_hw.o cedrus_dec.o \ > > > > > > - cedrus_mpeg2.o cedrus_h264.o cedrus_h265.o > > > + cedrus_mpeg2.o cedrus_h264.o cedrus_h265.o \ > > > + cedrus_vp8.o > > > diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c > > > b/drivers/staging/media/sunxi/cedrus/cedrus.c index > > > bc27f9430eeb..b2f5f03ad4a3 100644 > > > --- a/drivers/staging/media/sunxi/cedrus/cedrus.c > > > +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c > > > @@ -135,6 +135,13 @@ static const struct cedrus_control cedrus_controls[] > > > = {> > > > .codec = CEDRUS_CODEC_H265, > > > .required = false, > > > > > > }, > > > > > > + { > > > + .cfg = { > > > + .id = > > > V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER, + }, > > > + .codec = CEDRUS_CODEC_VP8, > > > + .required = true, > > > + }, > > > > > > }; > > > > > > #define CEDRUS_CONTROLS_COUNT ARRAY_SIZE(cedrus_controls) > > > > > > @@ -381,6 +388,7 @@ static int cedrus_probe(struct platform_device *pdev) > > > > > > dev->dec_ops[CEDRUS_CODEC_MPEG2] = &cedrus_dec_ops_mpeg2; > > > dev->dec_ops[CEDRUS_CODEC_H264] = &cedrus_dec_ops_h264; > > > dev->dec_ops[CEDRUS_CODEC_H265] = &cedrus_dec_ops_h265; > > > > > > + dev->dec_ops[CEDRUS_CODEC_VP8] = &cedrus_dec_ops_vp8; > > > > > > mutex_init(&dev->dev_mutex); > > > > > > diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h > > > b/drivers/staging/media/sunxi/cedrus/cedrus.h index > > > 96765555ab8a..9f4605afa0f4 100644 > > > --- a/drivers/staging/media/sunxi/cedrus/cedrus.h > > > +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h > > > @@ -35,6 +35,7 @@ enum cedrus_codec { > > > > > > CEDRUS_CODEC_MPEG2, > > > CEDRUS_CODEC_H264, > > > CEDRUS_CODEC_H265, > > > > > > + CEDRUS_CODEC_VP8, > > > > > > CEDRUS_CODEC_LAST, > > > > > > }; > > > > > > @@ -75,6 +76,10 @@ struct cedrus_h265_run { > > > > > > const struct v4l2_ctrl_hevc_slice_params *slice_params; > > > > > > }; > > > > > > +struct cedrus_vp8_run { > > > + const struct v4l2_ctrl_vp8_frame_header *slice_params; > > > > I don't think VP8 has any concept of slice, as H264 does. > > I think it's misleading to call this parameter as slice_params. > > > > frame_info perhaps? Or frame_params? > Either works for me. > > > +}; > > > + > > > > > > struct cedrus_run { > > > > > > struct vb2_v4l2_buffer *src; > > > struct vb2_v4l2_buffer *dst; > > > > > > @@ -83,6 +88,7 @@ struct cedrus_run { > > > > > > struct cedrus_h264_run h264; > > > struct cedrus_mpeg2_run mpeg2; > > > struct cedrus_h265_run h265; > > > > > > + struct cedrus_vp8_run vp8; > > > > > > }; > > > > > > }; > > > > > > @@ -134,6 +140,14 @@ struct cedrus_ctx { > > > > > > void *neighbor_info_buf; > > > dma_addr_t neighbor_info_buf_addr; > > > > > > } h265; > > > > > > + struct { > > > + unsigned int last_frame_p_type; > > > + unsigned int last_filter_type; > > > + unsigned int last_sharpness_level; > > > + > > > + u8 *entropy_probs_buf; > > > + dma_addr_t entropy_probs_buf_dma; > > > + } vp8; > > > > > > } codec; > > > > > > }; > > > > > > @@ -180,6 +194,7 @@ struct cedrus_dev { > > > > > > extern struct cedrus_dec_ops cedrus_dec_ops_mpeg2; > > > extern struct cedrus_dec_ops cedrus_dec_ops_h264; > > > extern struct cedrus_dec_ops cedrus_dec_ops_h265; > > > > > > +extern struct cedrus_dec_ops cedrus_dec_ops_vp8; > > > > > > static inline void cedrus_write(struct cedrus_dev *dev, u32 reg, u32 val) > > > { > > > > > > diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c > > > b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c index > > > 58c48e4fdfe9..47c079f14c74 100644 > > > --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c > > > +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c > > > @@ -68,6 +68,11 @@ void cedrus_device_run(void *priv) > > > > > > V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS); > > > > > > break; > > > > > > + case V4L2_PIX_FMT_VP8_FRAME: > > > + run.vp8.slice_params = cedrus_find_control_data(ctx, > > > + V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER); > > > + break; > > > + > > > > > > default: > > > break; > > > > > > } > > > > > > diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c > > > b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c index > > > 1744e6fcc999..cb8cabfc7cee 100644 > > > --- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c > > > +++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c > > > @@ -48,6 +48,7 @@ int cedrus_engine_enable(struct cedrus_ctx *ctx, enum > > > cedrus_codec codec)> > > > break; > > > > > > case CEDRUS_CODEC_H264: > > > + case CEDRUS_CODEC_VP8: > > I would add a comment here mentioning > > both codecs use the same decoding mode bit. > > Ok. > > > > > > reg |= VE_MODE_DEC_H264; > > > break; > > > > > > diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h > > > b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h index > > > 66b152f18d17..7718c561823f 100644 > > > --- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h > > > +++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h > > > @@ -546,6 +546,7 @@ > > > > > > #define VE_H264_SHS_QP_SCALING_MATRIX_DEFAULT BIT(24) > > > > > > #define VE_H264_CTRL 0x220 > > > > > > +#define VE_H264_CTRL_VP8 BIT(29) > > > > > > #define VE_H264_CTRL_VLD_DATA_REQ_INT BIT(2) > > > #define VE_H264_CTRL_DECODE_ERR_INT BIT(1) > > > #define VE_H264_CTRL_SLICE_DECODE_INT BIT(0) > > > > > > @@ -555,7 +556,12 @@ > > > > > > VE_H264_CTRL_SLICE_DECODE_INT) > > > > > > #define VE_H264_TRIGGER_TYPE 0x224 > > > > > > +#define VE_H264_TRIGGER_TYPE_PROBABILITY(x) SHIFT_AND_MASK_BITS(x, 31, > > > 24) +#define VE_H264_TRIGGER_TYPE_BIN_LENS(x) > > > SHIFT_AND_MASK_BITS((x) - 1, 18, 16)> > > > #define VE_H264_TRIGGER_TYPE_N_BITS(x) (((x) & 0x3f) << 8) > > > > > > +#define VE_H264_TRIGGER_TYPE_VP8_GET_BITS (15 << 0) > > > +#define VE_H264_TRIGGER_TYPE_VP8_UPDATE_COEF (14 << 0) > > > +#define VE_H264_TRIGGER_TYPE_VP8_SLICE_DECODE (10 << 0) > > > > > > #define VE_H264_TRIGGER_TYPE_AVC_SLICE_DECODE (8 << 0) > > > #define VE_H264_TRIGGER_TYPE_INIT_SWDEC (7 << 0) > > > #define VE_H264_TRIGGER_TYPE_FLUSH_BITS (3 << 0) > > > > > > @@ -565,6 +571,7 @@ > > > > > > #define VE_H264_STATUS_DECODE_ERR_INT > > > VE_H264_CTRL_DECODE_ERR_INT > > > #define VE_H264_STATUS_SLICE_DECODE_INT > > > VE_H264_CTRL_SLICE_DECODE_INT #define VE_H264_STATUS_VLD_BUSY > > > BIT(8) > > > > > > +#define VE_H264_STATUS_VP8_UPPROB_BUSY BIT(17) > > > > > > #define VE_H264_STATUS_INT_MASK > > > VE_H264_CTRL_INT_MASK > > Why not just using VE_H264_CTRL_INT_MASK? > > > > Having an alias looks confusing. > > This is not my change so I suggest to address it later. > > > > > > @@ -583,10 +590,83 @@ > > > > > > #define VE_H264_OUTPUT_FRAME_IDX 0x24c > > > #define VE_H264_EXTRA_BUFFER1 0x250 > > > #define VE_H264_EXTRA_BUFFER2 0x254 > > > > > > +#define VE_H264_MB_ADDR 0x260 > > > +#define VE_H264_ERROR_CASE 0x2b8 > > > > > > #define VE_H264_BASIC_BITS 0x2dc > > > #define VE_AVC_SRAM_PORT_OFFSET 0x2e0 > > > #define VE_AVC_SRAM_PORT_DATA 0x2e4 > > > > > > +#define VE_VP8_PPS 0x214 > > > +#define VE_VP8_PPS_PIC_TYPE_P_FRAME BIT(31) > > > +#define VE_VP8_PPS_LAST_SHARPNESS_LEVEL(v) SHIFT_AND_MASK_BITS(v, 30, > > > 28) +#define VE_VP8_PPS_LAST_PIC_TYPE_P_FRAME BIT(27) > > > +#define VE_VP8_PPS_ALTREF_SIGN_BIAS BIT(26) > > > +#define VE_VP8_PPS_GOLDEN_SIGN_BIAS BIT(25) > > > +#define VE_VP8_PPS_RELOAD_ENTROPY_PROBS BIT(24) > > > +#define VE_VP8_PPS_REFRESH_ENTROPY_PROBS BIT(23) > > > +#define VE_VP8_PPS_MB_NO_COEFF_SKIP BIT(22) > > > +#define VE_VP8_PPS_TOKEN_PARTITION(v) SHIFT_AND_MASK_BITS(v, 21, > > > 20) +#define VE_VP8_PPS_MODE_REF_LF_DELTA_UPDATE BIT(19) > > > +#define VE_VP8_PPS_MODE_REF_LF_DELTA_ENABLE BIT(18) > > > +#define VE_VP8_PPS_LOOP_FILTER_LEVEL(v) > > > SHIFT_AND_MASK_BITS(v, 17, 12) +#define VE_VP8_PPS_LOOP_FILTER_SIMPLE > > > BIT(11) > > > +#define VE_VP8_PPS_SHARPNESS_LEVEL(v) SHIFT_AND_MASK_BITS(v, 10, > > > 8) +#define VE_VP8_PPS_LAST_LOOP_FILTER_SIMPLE BIT(7) > > > +#define VE_VP8_PPS_SEGMENTATION_ENABLE BIT(6) > > > +#define VE_VP8_PPS_MB_SEGMENT_ABS_DELTA BIT(5) > > > +#define VE_VP8_PPS_UPDATE_MB_SEGMENTATION_MAP BIT(4) > > > +#define VE_VP8_PPS_FULL_PIXEL BIT(3) > > > +#define VE_VP8_PPS_BILINEAR_MC_FILTER BIT(2) > > > +#define VE_VP8_PPS_FILTER_TYPE_SIMPLE BIT(1) > > > +#define VE_VP8_PPS_LPF_DISABLE BIT(0) > > > + > > > +#define VE_VP8_QP_INDEX_DELTA 0x218 > > > +#define VE_VP8_QP_INDEX_DELTA_UVAC(v) SHIFT_AND_MASK_BITS(v, 31, > > > 27) +#define VE_VP8_QP_INDEX_DELTA_UVDC(v) > > > SHIFT_AND_MASK_BITS(v, 26, 22) +#define VE_VP8_QP_INDEX_DELTA_Y2AC(v) > > > SHIFT_AND_MASK_BITS(v, 21, 17) +#define > > > VE_VP8_QP_INDEX_DELTA_Y2DC(v) SHIFT_AND_MASK_BITS(v, 16, 12) > > > +#define VE_VP8_QP_INDEX_DELTA_Y1DC(v) SHIFT_AND_MASK_BITS(v, > > > 11, 7) +#define VE_VP8_QP_INDEX_DELTA_BASE_QINDEX(v) > > > SHIFT_AND_MASK_BITS(v, 6, 0) + > > > +#define VE_VP8_PART_SIZE_OFFSET 0x21c > > > +#define VE_VP8_ENTROPY_PROBS_ADDR 0x250 > > > +#define VE_VP8_FIRST_DATA_PART_LEN 0x254 > > > + > > > +#define VE_VP8_FSIZE 0x258 > > > +#define VE_VP8_FSIZE_WIDTH(w) \ > > > + SHIFT_AND_MASK_BITS(DIV_ROUND_UP(w, 16), 15, 8) > > > +#define VE_VP8_FSIZE_HEIGHT(h) \ > > > + SHIFT_AND_MASK_BITS(DIV_ROUND_UP(h, 16), 7, 0) > > > + > > > +#define VE_VP8_PICSIZE 0x25c > > > +#define VE_VP8_PICSIZE_WIDTH(w) > > > SHIFT_AND_MASK_BITS(w, 27, 16) +#define VE_VP8_PICSIZE_HEIGHT(h) > > > SHIFT_AND_MASK_BITS(h, 11, 0) + > > > +#define VE_VP8_REC_LUMA 0x2ac > > > +#define VE_VP8_FWD_LUMA 0x2b0 > > > +#define VE_VP8_BWD_LUMA 0x2b4 > > > +#define VE_VP8_REC_CHROMA 0x2d0 > > > +#define VE_VP8_FWD_CHROMA 0x2d4 > > > +#define VE_VP8_BWD_CHROMA 0x2d8 > > > +#define VE_VP8_ALT_LUMA 0x2e8 > > > +#define VE_VP8_ALT_CHROMA 0x2ec > > > + > > > +#define VE_VP8_SEGMENT_FEAT_MB_LV0 0x2f0 > > > +#define VE_VP8_SEGMENT_FEAT_MB_LV1 0x2f4 > > > + > > > +#define VE_VP8_SEGMENT3(v) SHIFT_AND_MASK_BITS(v, 31, > > > 24) +#define VE_VP8_SEGMENT2(v) > > > SHIFT_AND_MASK_BITS(v, 23, 16) +#define VE_VP8_SEGMENT1(v) > > > SHIFT_AND_MASK_BITS(v, 15, 8) +#define VE_VP8_SEGMENT0(v) > > > SHIFT_AND_MASK_BITS(v, 7, 0) + > > > +#define VE_VP8_REF_LF_DELTA 0x2f8 > > > +#define VE_VP8_MODE_LF_DELTA 0x2fc > > > + > > > +#define VE_VP8_LF_DELTA3(v) SHIFT_AND_MASK_BITS(v, 30, > > > 24) +#define VE_VP8_LF_DELTA2(v) > > > SHIFT_AND_MASK_BITS(v, 22, 16) +#define VE_VP8_LF_DELTA1(v) > > > SHIFT_AND_MASK_BITS(v, 14, 8) +#define VE_VP8_LF_DELTA0(v) > > > SHIFT_AND_MASK_BITS(v, 6, 0) + > > > > > > #define VE_ISP_INPUT_SIZE 0xa00 > > > #define VE_ISP_INPUT_STRIDE 0xa04 > > > #define VE_ISP_CTRL 0xa08 > > > > > > diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c > > > b/drivers/staging/media/sunxi/cedrus/cedrus_video.c index > > > 16d82309e7b6..0212054484dd 100644 > > > --- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c > > > +++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c > > > @@ -48,6 +48,10 @@ static struct cedrus_format cedrus_formats[] = { > > > > > > .directions = CEDRUS_DECODE_SRC, > > > .capabilities = CEDRUS_CAPABILITY_H265_DEC, > > > > > > }, > > > > > > + { > > > + .pixelformat = V4L2_PIX_FMT_VP8_FRAME, > > > + .directions = CEDRUS_DECODE_SRC, > > > + }, > > > > > > { > > > > > > .pixelformat = V4L2_PIX_FMT_SUNXI_TILED_NV12, > > > .directions = CEDRUS_DECODE_DST, > > > > > > @@ -110,6 +114,7 @@ void cedrus_prepare_format(struct v4l2_pix_format > > > *pix_fmt)> > > > case V4L2_PIX_FMT_MPEG2_SLICE: > > > case V4L2_PIX_FMT_H264_SLICE: > > > > > > case V4L2_PIX_FMT_HEVC_SLICE: > > > + case V4L2_PIX_FMT_VP8_FRAME: > > > /* Zero bytes per line for encoded source. */ > > > bytesperline = 0; > > > /* Choose some minimum size since this can't be 0 */ > > > > > > @@ -448,6 +453,10 @@ static int cedrus_start_streaming(struct vb2_queue > > > *vq, unsigned int count)> > > > ctx->current_codec = CEDRUS_CODEC_H265; > > > break; > > > > > > + case V4L2_PIX_FMT_VP8_FRAME: > > > + ctx->current_codec = CEDRUS_CODEC_VP8; > > > + break; > > > + > > > > > > default: > > > return -EINVAL; > > > > > > } > > > > > > diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_vp8.c > > > b/drivers/staging/media/sunxi/cedrus/cedrus_vp8.c new file mode 100644 > > > index 000000000000..93beffd07c35 > > > --- /dev/null > > > +++ b/drivers/staging/media/sunxi/cedrus/cedrus_vp8.c > > > @@ -0,0 +1,699 @@ > > > +// SPDX-License-Identifier: GPL-2.0-or-later > > > +/* > > > + * Cedrus VPU driver > > > + * > > > + * Copyright (c) 2019 Jernej Skrabec <jernej.skrabec@xxxxxxxx> > > > + */ > > > + > > > +#include <linux/delay.h> > > > +#include <linux/types.h> > > > + > > > +#include <media/videobuf2-dma-contig.h> > > > + > > > +#include "cedrus.h" > > > +#include "cedrus_hw.h" > > > +#include "cedrus_regs.h" > > > + > > > +#define CEDRUS_ENTROPY_PROBS_SIZE 0x2400 > > > +#define VP8_PROB_HALF 128 > > > + > > > +static const u8 prob_table_init[] = { > > > > What's this prob_table_init and where > > are the values coming from? > > > > Doesn't seem like coming from the spec. > > Well, that's good question. Actually, this structure consists from several > arrays defined in VP8. See https://bitbucket.org/paullo612/cedarx-vp8-test/src/ > default/src/vp8.c function fill_probs_table(). It's my understanding that this > was reverse engineered from CedarX binary library. Instead of building array > every time codec is started, I just precomputed it. I agree that it needs some > explanation. > I wonder if we can at least point out that it comes from a reverse engineering effort. > > > > > + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, > > > 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xB0, 0xF6, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0xDF, 0xF1, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF9, 0xFD, 0xFD, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF4, 0xFC, 0xFF, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0xEA, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xF6, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xEF, 0xFD, > > > 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFE, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0xFF, 0xF8, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, > > > 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, 0xFF, 0xFE, 0xFF, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, > > > 0xFD, 0xFE, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0xFB, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, > > > 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFE, 0xFD, > > > 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0xFA, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, + 0xFF, > > > 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, > > > 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0xD9, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE1, 0xFC, 0xF1, > > > 0xFD, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0xEA, 0xFA, 0xF1, 0xFA, 0xFD, 0xFF, 0xFD, 0xFE, + 0xFF, > > > 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0xDF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, > > > 0xFD, 0xFE, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF8, > > > 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0xF9, 0xFE, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFD, 0xFF, 0xFF, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0xF7, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFD, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, > > > 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xFF, 0xFF, 0xFF, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, > > > 0xFE, 0xFD, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, > > > 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0xBA, 0xFB, 0xFA, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, > > > 0xFB, 0xF4, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0xFB, 0xFB, 0xF3, 0xFD, 0xFE, 0xFF, 0xFE, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0xFF, 0xFD, 0xFE, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEC, 0xFD, 0xFE, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0xFB, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, + 0xFF, > > > 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, > > > 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFE, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, > > > 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, > > > 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF8, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0xFA, 0xFE, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, > > > 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFE, 0xF9, 0xFD, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFD, 0xFD, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF6, > > > 0xFD, 0xFD, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0xFC, 0xFE, 0xFB, 0xFE, 0xFE, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF8, 0xFE, 0xFD, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0xFD, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, > > > 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0xFF, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0xF5, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, > > > 0xFD, 0xFE, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFB, > > > 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0xFC, 0xFD, 0xFE, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFE, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFF, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0xF9, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFA, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, > > > 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, > > > 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, > > > 0x9C, 0xA3, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x6F, 0x96, 0x00, + > > > 0x00, 0x00, 0x00, 0x00, 0x78, 0x5A, 0x4F, 0x85, 0x57, 0x55, 0x50, 0x6F, + > > > 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, + 0x93, 0x88, 0x12, 0x00, 0x6A, 0x91, 0x01, 0x00, 0xB3, > > > 0x79, 0x01, 0x00, + 0xDF, 0x01, 0x22, 0x00, 0xD0, 0x01, 0x01, 0x00, > > > 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x07, 0x01, 0x01, 0x8F, + 0x0E, 0x12, 0x0E, 0x6B, 0x87, 0x40, > > > 0x39, 0x44, 0x3C, 0x38, 0x80, 0x41, + 0x9F, 0x86, 0x80, 0x22, 0xEA, > > > 0xBC, 0x80, 0x1C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0x84, 0x02, 0x04, 0x06, 0x80, 0x81, 0x82, 0x83, 0x80, 0x02, 0x04, > > > 0x06, + 0x81, 0x82, 0x83, 0x84, 0x80, 0x02, 0x81, 0x04, 0x82, 0x83, > > > 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x02, 0x08, + 0x04, 0x06, 0x80, 0x81, 0x82, 0x83, 0x0A, 0x0C, > > > 0x84, 0x85, 0x86, 0x87, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x02, 0x08, 0x04, 0x06, 0x80, 0x81, + 0x82, 0x83, 0x0A, 0x0C, 0x84, > > > 0x85, 0x86, 0x87, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x02, 0x82, > > > 0x04, 0x80, 0x81, 0x00, 0x00, 0x80, 0x02, 0x81, 0x04, + 0x82, 0x06, > > > 0x08, 0x0C, 0x83, 0x0A, 0x85, 0x86, 0x84, 0x0E, 0x87, 0x10, + 0x88, > > > 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + > > > 0x00, 0x00, 0x00, 0x00, 0x8A, 0x02, 0x8B, 0x04, 0x8C, 0x8D, 0x00, 0x00, + > > > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > > 0x00, 0x00, + 0x87, 0x02, 0x85, 0x04, 0x86, 0x06, 0x88, 0x89, > > > +}; > > > + > > > +static const u8 vp8_mv_update_prob[2][19] = { > > > > Seems like the V4L2 VP8 uapi header should > > #define MV_PROB_CNT 19 so you could use it through > > the driver. > > Ok. > > > > > Also, these look like k_mv_entropy_update_probs, > > could you add a comment here about this? > > Well, this table can even go in common header... I'm not sure how many future > codecs would need it. For now, it can stay here but maybe renaming it to > vp8_k_mv_entropy_update_probs would be enough (instead of comment)? > How about both? Comments are free :-) > > > > > + { 237, 246, 253, 253, 254, 254, 254, 254, 254, > > > + 254, 254, 254, 254, 254, 250, 250, 252, 254, 254 }, > > > + { 231, 243, 245, 253, 254, 254, 254, 254, 254, > > > + 254, 254, 254, 254, 254, 251, 251, 254, 254, 254 } > > > +}; > > > + > > > +static uint8_t read_bits(struct cedrus_dev *dev, unsigned int bits_count, > > > + unsigned int probability) > > > +{ > > > + cedrus_write(dev, VE_H264_TRIGGER_TYPE, > > > + VE_H264_TRIGGER_TYPE_VP8_GET_BITS | > > > + VE_H264_TRIGGER_TYPE_BIN_LENS(bits_count) | > > > + VE_H264_TRIGGER_TYPE_PROBABILITY(probability)); > > > + > > > + while (cedrus_read(dev, VE_H264_STATUS) & VE_H264_STATUS_VLD_BUSY) > > > + ; > > > + > > > > You can abstract this as cedrus_wait_for(flag), > > which should be based on readl_poll_timeout_atomic. > > > > The flag argument would be VE_H264_STATUS_VP8_UPPROB_BUSY > > or VE_H264_STATUS_VLD_BUSY. This way it'll be cleaner > > and you don't risk deadlocks if the hardware goes nuts. > > Good idea. > > > > > > + return cedrus_read(dev, VE_H264_BASIC_BITS); > > > +} > > > + > > > +static void get_delta_q(struct cedrus_dev *dev) > > > +{ > > > + if (read_bits(dev, 1, VP8_PROB_HALF)) { > > > + read_bits(dev, 4, VP8_PROB_HALF); > > > + read_bits(dev, 1, VP8_PROB_HALF); > > > + } > > > +} > > > + > > > +static void process_segmentation_info(struct cedrus_dev *dev) > > > +{ > > > + int update = read_bits(dev, 1, VP8_PROB_HALF); > > > + int i; > > > + > > > + if (read_bits(dev, 1, VP8_PROB_HALF)) { > > > + read_bits(dev, 1, VP8_PROB_HALF); > > > + > > > + for (i = 0; i < 4; i++) > > > + if (read_bits(dev, 1, VP8_PROB_HALF)) { > > > + read_bits(dev, 7, VP8_PROB_HALF); > > > + read_bits(dev, 1, VP8_PROB_HALF); > > > + } > > > + > > > + for (i = 0; i < 4; i++) > > > + if (read_bits(dev, 1, VP8_PROB_HALF)) { > > > + read_bits(dev, 6, VP8_PROB_HALF); > > > + read_bits(dev, 1, VP8_PROB_HALF); > > > + } > > > + } > > > + > > > + if (update) > > > + for (i = 0; i < 3; i++) > > > + if (read_bits(dev, 1, VP8_PROB_HALF)) > > > + read_bits(dev, 8, VP8_PROB_HALF); > > > +} > > > + > > > +static void process_ref_lf_delta_info(struct cedrus_dev *dev) > > > +{ > > > + if (read_bits(dev, 1, VP8_PROB_HALF)) { > > > + int i; > > > + > > > + for (i = 0; i < 4; i++) > > > + if (read_bits(dev, 1, VP8_PROB_HALF)) { > > > + read_bits(dev, 6, VP8_PROB_HALF); > > > + read_bits(dev, 1, VP8_PROB_HALF); > > > + } > > > + > > > + for (i = 0; i < 4; i++) > > > + if (read_bits(dev, 1, VP8_PROB_HALF)) { > > > + read_bits(dev, 6, VP8_PROB_HALF); > > > + read_bits(dev, 1, VP8_PROB_HALF); > > > + } > > > + } > > > +} > > > + > > > +static void process_ref_frame_info(struct cedrus_dev *dev) > > > +{ > > > + u8 refresh_golden_frame = read_bits(dev, 1, VP8_PROB_HALF); > > > + u8 refresh_alt_ref_frame = read_bits(dev, 1, VP8_PROB_HALF); > > > + > > > + if (!refresh_golden_frame) > > > + read_bits(dev, 2, VP8_PROB_HALF); > > > + > > > + if (!refresh_alt_ref_frame) > > > + read_bits(dev, 2, VP8_PROB_HALF); > > > + > > > + read_bits(dev, 1, VP8_PROB_HALF); > > > + read_bits(dev, 1, VP8_PROB_HALF); > > > +} > > > + > > > +static void cedrus_read_header(struct cedrus_dev *dev, > > > + const struct v4l2_ctrl_vp8_frame_header > > > *slice) +{ > > > + int i, j; > > > + > > > + if (VP8_FRAME_IS_KEY_FRAME(slice)) { > > > + read_bits(dev, 1, VP8_PROB_HALF); > > > + read_bits(dev, 1, VP8_PROB_HALF); > > > + } > > > + > > > + if (read_bits(dev, 1, VP8_PROB_HALF)) > > > + process_segmentation_info(dev); > > > + > > > + read_bits(dev, 1, VP8_PROB_HALF); > > > + read_bits(dev, 6, VP8_PROB_HALF); > > > + read_bits(dev, 3, VP8_PROB_HALF); > > > + > > > + if (read_bits(dev, 1, VP8_PROB_HALF)) > > > + process_ref_lf_delta_info(dev); > > > + > > > + read_bits(dev, 2, VP8_PROB_HALF); Answering below's question, I would add a comment here: /* y_ac_qi */ > > > + read_bits(dev, 7, VP8_PROB_HALF); > > > + > > > + get_delta_q(dev); > > > + get_delta_q(dev); > > > + get_delta_q(dev); > > > + get_delta_q(dev); > > > + get_delta_q(dev); > > > + > > > > for loop? > > Ok but would be 5 some macro? If so, what should be it's name? > Well, perhaps QUANT_DELTA_COUNT ? And maybe a small comment (together with the one above) to clarify this is just parsing y_dc_delta, y2_dc_delta, ... and so on. > > > > > + if (!VP8_FRAME_IS_KEY_FRAME(slice)) > > > + process_ref_frame_info(dev); > > > + > > > + read_bits(dev, 1, VP8_PROB_HALF); > > > + > > > + if (!VP8_FRAME_IS_KEY_FRAME(slice)) > > > + read_bits(dev, 1, VP8_PROB_HALF); > > > + > > > + cedrus_write(dev, VE_H264_TRIGGER_TYPE, > > > VE_H264_TRIGGER_TYPE_VP8_UPDATE_COEF); + while (cedrus_read(dev, > > > VE_H264_STATUS) & VE_H264_STATUS_VP8_UPPROB_BUSY) + ; > > > + > > > + cedrus_write(dev, VE_H264_STATUS, VE_H264_CTRL_INT_MASK); > > > + > > > > This one looks like cedrus_vp8_irq_clear function, maybe just > > call that instead. > > Ok. > > > > > > + if (read_bits(dev, 1, VP8_PROB_HALF)) > > > + read_bits(dev, 8, VP8_PROB_HALF); > > > + > > > + if (!VP8_FRAME_IS_KEY_FRAME(slice)) { > > > + read_bits(dev, 8, VP8_PROB_HALF); > > > + read_bits(dev, 8, VP8_PROB_HALF); > > > + read_bits(dev, 8, VP8_PROB_HALF); > > > + > > > + if (read_bits(dev, 1, VP8_PROB_HALF)) { > > > + read_bits(dev, 8, VP8_PROB_HALF); > > > + read_bits(dev, 8, VP8_PROB_HALF); > > > + read_bits(dev, 8, VP8_PROB_HALF); > > > + read_bits(dev, 8, VP8_PROB_HALF); > > > + } > > > + > > > + if (read_bits(dev, 1, VP8_PROB_HALF)) { > > > + read_bits(dev, 8, VP8_PROB_HALF); > > > + read_bits(dev, 8, VP8_PROB_HALF); > > > + read_bits(dev, 8, VP8_PROB_HALF); > > > + } > > > + > > > + for (i = 0; i < 2; i++) > > > + for (j = 0; j < 19; j++) > > > + if (read_bits(dev, 1, > > > vp8_mv_update_prob[i][j])) + > > > read_bits(dev, 7, VP8_PROB_HALF); + } > > > +} > > > + > > > +static void cedrus_vp8_update_probs(const struct > > > v4l2_ctrl_vp8_frame_header *slice, + u8 > > > *prob_table) > > > +{ > > > + int i, j, k; > > > + > > > + memcpy(&prob_table[0x1008], slice->entropy_header.y_mode_probs, > > > 4); > > > + memcpy(&prob_table[0x1010], slice->entropy_header.uv_mode_probs, > > > 3); + > > > > Use sizeof instead of hardcoding the size? > > Ok. > > > > > > + memcpy(&prob_table[0x1018], slice->segment_header.segment_probs, > > > 3); + > > > + prob_table[0x101c] = slice->prob_skip_false; > > > + prob_table[0x101d] = slice->prob_intra; > > > + prob_table[0x101e] = slice->prob_last; > > > + prob_table[0x101f] = slice->prob_gf; > > > + > > > + memcpy(&prob_table[0x1020], slice->entropy_header.mv_probs[0], > > > 19); > > > + memcpy(&prob_table[0x1040], slice->entropy_header.mv_probs[1], > > > 19); > > > + > > > + for (i = 0; i < 4; ++i) > > > + for (j = 0; j < 8; ++j) > > > + for (k = 0; k < 3; ++k) > > > + memcpy(&prob_table[i * 512 + j * 64 + k * > > > 16], + > > > slice->entropy_header.coeff_probs[i][j][k], 11); +} > > > + > > > +static enum cedrus_irq_status > > > +cedrus_vp8_irq_status(struct cedrus_ctx *ctx) > > > +{ > > > + struct cedrus_dev *dev = ctx->dev; > > > + u32 reg = cedrus_read(dev, VE_H264_STATUS); > > > + > > > + if (reg & (VE_H264_STATUS_DECODE_ERR_INT | > > > + VE_H264_STATUS_VLD_DATA_REQ_INT)) > > > + return CEDRUS_IRQ_ERROR; > > > + > > > + if (reg & VE_H264_CTRL_SLICE_DECODE_INT) > > > + return CEDRUS_IRQ_OK; > > > + > > > + return CEDRUS_IRQ_NONE; > > > +} > > > + > > > +static void cedrus_vp8_irq_clear(struct cedrus_ctx *ctx) > > > +{ > > > + struct cedrus_dev *dev = ctx->dev; > > > + > > > + cedrus_write(dev, VE_H264_STATUS, > > > + VE_H264_STATUS_INT_MASK); > > > +} > > > + > > > +static void cedrus_vp8_irq_disable(struct cedrus_ctx *ctx) > > > +{ > > > + struct cedrus_dev *dev = ctx->dev; > > > + u32 reg = cedrus_read(dev, VE_H264_CTRL); > > > + > > > + cedrus_write(dev, VE_H264_CTRL, > > > + reg & ~VE_H264_CTRL_INT_MASK); > > > +} > > > + > > > +static void cedrus_vp8_setup(struct cedrus_ctx *ctx, > > > + struct cedrus_run *run) > > > +{ > > > + const struct v4l2_ctrl_vp8_frame_header *slice = > > > run->vp8.slice_params; + struct vb2_queue *cap_q = > > > &ctx->fh.m2m_ctx->cap_q_ctx.q; > > > + struct vb2_buffer *src_buf = &run->src->vb2_buf; > > > + struct cedrus_dev *dev = ctx->dev; > > > + dma_addr_t luma_addr, chroma_addr; > > > + dma_addr_t src_buf_addr; > > > + int header_size; > > > + int qindex; > > > + u32 reg; > > > + > > > + cedrus_engine_enable(ctx, CEDRUS_CODEC_VP8); > > > + > > > + cedrus_write(dev, VE_H264_CTRL, VE_H264_CTRL_VP8); > > > + > > > + cedrus_vp8_update_probs(slice, ctx->codec.vp8.entropy_probs_buf); > > > + > > > + reg = slice->first_part_size * 8; > > > + cedrus_write(dev, VE_VP8_FIRST_DATA_PART_LEN, reg); > > > + > > > + header_size = VP8_FRAME_IS_KEY_FRAME(slice) ? 10 : 3; > > > + > > > + reg = slice->first_part_size + header_size; > > > + cedrus_write(dev, VE_VP8_PART_SIZE_OFFSET, reg); > > > + > > > + reg = vb2_plane_size(src_buf, 0) * 8; > > > + cedrus_write(dev, VE_H264_VLD_LEN, reg); > > > + > > > + /* > > > + * FIXME: There is a problem if frame header is skipped (adding > > > + * first_part_header_bits to offset). It seems that functions > > > + * for parsing bitstreams change internal state of VPU in some > > > + * way that can't be otherwise set. Maybe this can be bypassed > > > + * by somehow fixing probability table buffer? > > > + */ > > > + reg = header_size * 8; > > > + cedrus_write(dev, VE_H264_VLD_OFFSET, reg); > > > + > > > + src_buf_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0); > > > + cedrus_write(dev, VE_H264_VLD_END, > > > + src_buf_addr + vb2_get_plane_payload(src_buf, 0)); > > > + cedrus_write(dev, VE_H264_VLD_ADDR, > > > + VE_H264_VLD_ADDR_VAL(src_buf_addr) | > > > + VE_H264_VLD_ADDR_FIRST | VE_H264_VLD_ADDR_VALID | > > > + VE_H264_VLD_ADDR_LAST); > > > + > > > + cedrus_write(dev, VE_H264_TRIGGER_TYPE, > > > + VE_H264_TRIGGER_TYPE_INIT_SWDEC); > > > + > > > + cedrus_write(dev, VE_VP8_ENTROPY_PROBS_ADDR, > > > + ctx->codec.vp8.entropy_probs_buf_dma); > > > + > > > + reg = 0; > > > + switch (slice->version) { > > > + case 1: > > > + reg |= VE_VP8_PPS_FILTER_TYPE_SIMPLE; > > > + reg |= VE_VP8_PPS_BILINEAR_MC_FILTER; > > > + break; > > > + case 2: > > > + reg |= VE_VP8_PPS_LPF_DISABLE; > > > + reg |= VE_VP8_PPS_BILINEAR_MC_FILTER; > > > + break; > > > + case 3: > > > + reg |= VE_VP8_PPS_LPF_DISABLE; > > > + reg |= VE_VP8_PPS_FULL_PIXEL; > > > + break; > > > + } > > > + if (slice->segment_header.flags & > > > V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP) + reg |= > > > VE_VP8_PPS_UPDATE_MB_SEGMENTATION_MAP; > > > + if (!(slice->segment_header.flags & > > > V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE)) + reg |= > > > VE_VP8_PPS_MB_SEGMENT_ABS_DELTA; > > > + if (slice->segment_header.flags & > > > V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED) + reg |= > > > VE_VP8_PPS_SEGMENTATION_ENABLE; > > > + if (ctx->codec.vp8.last_filter_type) > > > + reg |= VE_VP8_PPS_LAST_LOOP_FILTER_SIMPLE; > > > + reg |= > > > VE_VP8_PPS_SHARPNESS_LEVEL(slice->lf_header.sharpness_level); + if > > > (slice->lf_header.flags & V4L2_VP8_LF_FILTER_TYPE_SIMPLE) + > > > reg |= VE_VP8_PPS_LOOP_FILTER_SIMPLE; > > > + reg |= VE_VP8_PPS_LOOP_FILTER_LEVEL(slice->lf_header.level); > > > + if (slice->lf_header.flags & V4L2_VP8_LF_HEADER_ADJ_ENABLE) > > > + reg |= VE_VP8_PPS_MODE_REF_LF_DELTA_ENABLE; > > > + if (slice->lf_header.flags & V4L2_VP8_LF_HEADER_DELTA_UPDATE) > > > + reg |= VE_VP8_PPS_MODE_REF_LF_DELTA_UPDATE; > > > + reg |= VE_VP8_PPS_TOKEN_PARTITION(ilog2(slice->num_dct_parts)); > > > + if (slice->flags & V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF) > > > + reg |= VE_VP8_PPS_MB_NO_COEFF_SKIP; > > > + reg |= VE_VP8_PPS_RELOAD_ENTROPY_PROBS; > > > + if (slice->flags & V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN) > > > + reg |= VE_VP8_PPS_GOLDEN_SIGN_BIAS; > > > + if (slice->flags & V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT) > > > + reg |= VE_VP8_PPS_ALTREF_SIGN_BIAS; > > > + if (ctx->codec.vp8.last_frame_p_type) > > > + reg |= VE_VP8_PPS_LAST_PIC_TYPE_P_FRAME; > > > + reg |= > > > VE_VP8_PPS_LAST_SHARPNESS_LEVEL(ctx->codec.vp8.last_sharpness_level); + > > > if (!(slice->flags & V4L2_VP8_FRAME_HEADER_FLAG_KEY_FRAME)) + > > > reg |= VE_VP8_PPS_PIC_TYPE_P_FRAME; > > > + cedrus_write(dev, VE_VP8_PPS, reg); > > > + > > > + cedrus_read_header(dev, slice); > > > + > > > + /* reset registers changed by HW */ > > > + cedrus_write(dev, VE_H264_CUR_MB_NUM, 0); > > > + cedrus_write(dev, VE_H264_MB_ADDR, 0); > > > + cedrus_write(dev, VE_H264_ERROR_CASE, 0); > > > + > > > + reg = 0; > > > + reg |= > > > VE_VP8_QP_INDEX_DELTA_UVAC(slice->quant_header.uv_ac_delta); > > > + reg |= > > > VE_VP8_QP_INDEX_DELTA_UVDC(slice->quant_header.uv_dc_delta); > > > + reg |= > > > VE_VP8_QP_INDEX_DELTA_Y2AC(slice->quant_header.y2_ac_delta); > > > + reg |= > > > VE_VP8_QP_INDEX_DELTA_Y2DC(slice->quant_header.y2_dc_delta); > > > + reg |= VE_VP8_QP_INDEX_DELTA_Y1DC(slice->quant_header.y_dc_delta); > > > + reg |= > > > VE_VP8_QP_INDEX_DELTA_BASE_QINDEX(slice->quant_header.y_ac_qi); + > > > cedrus_write(dev, VE_VP8_QP_INDEX_DELTA, reg); > > > + > > > + reg = 0; > > > + reg |= VE_VP8_FSIZE_WIDTH(slice->width); > > > + reg |= VE_VP8_FSIZE_HEIGHT(slice->height); > > > + cedrus_write(dev, VE_VP8_FSIZE, reg); > > > + > > > + reg = 0; > > > + reg |= VE_VP8_PICSIZE_WIDTH(slice->width); > > > + reg |= VE_VP8_PICSIZE_HEIGHT(slice->height); > > > + cedrus_write(dev, VE_VP8_PICSIZE, reg); > > > + > > > + reg = 0; > > > + reg |= VE_VP8_SEGMENT3(slice->segment_header.quant_update[3]); > > > + reg |= VE_VP8_SEGMENT2(slice->segment_header.quant_update[2]); > > > + reg |= VE_VP8_SEGMENT1(slice->segment_header.quant_update[1]); > > > + reg |= VE_VP8_SEGMENT0(slice->segment_header.quant_update[0]); > > > + cedrus_write(dev, VE_VP8_SEGMENT_FEAT_MB_LV0, reg); > > > + > > > + reg = 0; > > > + reg |= VE_VP8_SEGMENT3(slice->segment_header.lf_update[3]); > > > + reg |= VE_VP8_SEGMENT2(slice->segment_header.lf_update[2]); > > > + reg |= VE_VP8_SEGMENT1(slice->segment_header.lf_update[1]); > > > + reg |= VE_VP8_SEGMENT0(slice->segment_header.lf_update[0]); > > > + cedrus_write(dev, VE_VP8_SEGMENT_FEAT_MB_LV1, reg); > > > + > > > + reg = 0; > > > + reg |= VE_VP8_LF_DELTA3(slice->lf_header.ref_frm_delta[3]); > > > + reg |= VE_VP8_LF_DELTA2(slice->lf_header.ref_frm_delta[2]); > > > + reg |= VE_VP8_LF_DELTA1(slice->lf_header.ref_frm_delta[1]); > > > + reg |= VE_VP8_LF_DELTA0(slice->lf_header.ref_frm_delta[0]); > > > + cedrus_write(dev, VE_VP8_REF_LF_DELTA, reg); > > > + > > > + reg = 0; > > > + reg |= VE_VP8_LF_DELTA3(slice->lf_header.mb_mode_delta[3]); > > > + reg |= VE_VP8_LF_DELTA2(slice->lf_header.mb_mode_delta[2]); > > > + reg |= VE_VP8_LF_DELTA1(slice->lf_header.mb_mode_delta[1]); > > > + reg |= VE_VP8_LF_DELTA0(slice->lf_header.mb_mode_delta[0]); > > > + cedrus_write(dev, VE_VP8_MODE_LF_DELTA, reg); > > > + > > > + luma_addr = cedrus_dst_buf_addr(ctx, run->dst->vb2_buf.index, 0); > > > + chroma_addr = cedrus_dst_buf_addr(ctx, run->dst->vb2_buf.index, > > > 1); > > > + cedrus_write(dev, VE_VP8_REC_LUMA, luma_addr); > > > + cedrus_write(dev, VE_VP8_REC_CHROMA, chroma_addr); > > > + > > > + qindex = vb2_find_timestamp(cap_q, slice->last_frame_ts, 0); > > > + if (qindex >= 0) { > > > + luma_addr = cedrus_dst_buf_addr(ctx, qindex, 0); > > > + chroma_addr = cedrus_dst_buf_addr(ctx, qindex, 1); > > > + cedrus_write(dev, VE_VP8_FWD_LUMA, luma_addr); > > > + cedrus_write(dev, VE_VP8_FWD_CHROMA, chroma_addr); > > > + } else { > > > + cedrus_write(dev, VE_VP8_FWD_LUMA, 0); > > > + cedrus_write(dev, VE_VP8_FWD_CHROMA, 0); > > > + } > > > + > > > + qindex = vb2_find_timestamp(cap_q, slice->golden_frame_ts, 0); > > > + if (qindex >= 0) { > > > + luma_addr = cedrus_dst_buf_addr(ctx, qindex, 0); > > > + chroma_addr = cedrus_dst_buf_addr(ctx, qindex, 1); > > > + cedrus_write(dev, VE_VP8_BWD_LUMA, luma_addr); > > > + cedrus_write(dev, VE_VP8_BWD_CHROMA, chroma_addr); > > > + } else { > > > + cedrus_write(dev, VE_VP8_BWD_LUMA, 0); > > > + cedrus_write(dev, VE_VP8_BWD_CHROMA, 0); > > > + } > > > + > > > + qindex = vb2_find_timestamp(cap_q, slice->alt_frame_ts, 0); > > > + if (qindex >= 0) { > > > + luma_addr = cedrus_dst_buf_addr(ctx, qindex, 0); > > > + chroma_addr = cedrus_dst_buf_addr(ctx, qindex, 1); > > > + cedrus_write(dev, VE_VP8_ALT_LUMA, luma_addr); > > > + cedrus_write(dev, VE_VP8_ALT_CHROMA, chroma_addr); > > > + } else { > > > + cedrus_write(dev, VE_VP8_ALT_LUMA, 0); > > > + cedrus_write(dev, VE_VP8_ALT_CHROMA, 0); > > > + } > > > + > > > + cedrus_write(dev, VE_H264_CTRL, VE_H264_CTRL_VP8 | > > > + VE_H264_CTRL_DECODE_ERR_INT | > > > + VE_H264_CTRL_SLICE_DECODE_INT); > > > + > > > + if (slice->lf_header.level) { > > > + ctx->codec.vp8.last_filter_type = > > > + !!(slice->lf_header.flags & > > > V4L2_VP8_LF_FILTER_TYPE_SIMPLE); + > > > ctx->codec.vp8.last_frame_p_type = > > > + !VP8_FRAME_IS_KEY_FRAME(slice); > > > + ctx->codec.vp8.last_sharpness_level = > > > + slice->lf_header.sharpness_level; > > > + } > > > +} > > > + > > > +static int cedrus_vp8_start(struct cedrus_ctx *ctx) > > > +{ > > > + struct cedrus_dev *dev = ctx->dev; > > > + > > > + ctx->codec.vp8.entropy_probs_buf = > > > + dma_alloc_coherent(dev->dev, CEDRUS_ENTROPY_PROBS_SIZE, > > > + &ctx->codec.vp8.entropy_probs_buf_dma, > > > + GFP_KERNEL); > > > + if (!ctx->codec.vp8.entropy_probs_buf) > > > + return -ENOMEM; > > > + > > > + memcpy(&ctx->codec.vp8.entropy_probs_buf[2048], > > > > I think this 2048 offset, deserves a small comment, if possible. > > Not sure what to put into the comment, really. This part has no documentation > and it was deduced from reverse engineered code. Except maybe "Load default > entropy probabilities"? > Well, even a small comment mentioning this comes from reverse engineering and we have no documentation, would at least clarify we are not being intentionally obscure. > > > > That's it. Looks mostly good! > > Thanks for review. > No problem. Thanks, Ezequiel > Best regards, > Jernej > > > > > Thanks, > > Ezequiel > > > >