^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: LGPL-2.1+ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2016 Tom aan de Wiel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #ifndef CODEC_FWHT_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define CODEC_FWHT_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * The compressed format consists of a fwht_cframe_hdr struct followed by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * compressed frame data. The header contains the size of that data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Each Y, Cb and Cr plane is compressed separately. If the compressed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * size of each plane becomes larger than the uncompressed size, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * that plane is stored uncompressed and the corresponding bit is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * in the flags field of the header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Each compressed plane consists of macroblocks and each macroblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * is run-length-encoded. Each macroblock starts with a 16 bit value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Bit 15 indicates if this is a P-coded macroblock (1) or not (0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * P-coded macroblocks contain a delta against the previous frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Bits 1-12 contain a number. If non-zero, then this same macroblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * repeats that number of times. This results in a high degree of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * compression for generated images like colorbars.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * Following this macroblock header the MB coefficients are run-length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * encoded: the top 12 bits contain the coefficient, the bottom 4 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * tell how many times this coefficient occurs. The value 0xf indicates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * that the remainder of the macroblock should be filled with zeroes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * All 16 and 32 bit values are stored in big-endian (network) order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * Each fwht_cframe_hdr starts with an 8 byte magic header that is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * guaranteed not to occur in the compressed frame data. This header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * can be used to sync to the next frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * This codec uses the Fast Walsh Hadamard Transform. Tom aan de Wiel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * developed this as part of a university project, specifically for use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * with this driver. His project report can be found here:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * https://hverkuil.home.xs4all.nl/fwht.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * This is a sequence of 8 bytes with the low 4 bits set to 0xf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * This sequence cannot occur in the encoded data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Note that these two magic values are symmetrical so endian issues here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define FWHT_MAGIC1 0x4f4f4f4f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define FWHT_MAGIC2 0xffffffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define FWHT_VERSION 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Set if this is an interlaced format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define FWHT_FL_IS_INTERLACED BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* Set if this is a bottom-first (NTSC) interlaced format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define FWHT_FL_IS_BOTTOM_FIRST BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* Set if each 'frame' contains just one field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define FWHT_FL_IS_ALTERNATE BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * If FWHT_FL_IS_ALTERNATE was set, then this is set if this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * 'frame' is the bottom field, else it is the top field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define FWHT_FL_IS_BOTTOM_FIELD BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* Set if this frame is uncompressed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define FWHT_FL_LUMA_IS_UNCOMPRESSED BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define FWHT_FL_CB_IS_UNCOMPRESSED BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define FWHT_FL_CR_IS_UNCOMPRESSED BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define FWHT_FL_CHROMA_FULL_HEIGHT BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define FWHT_FL_CHROMA_FULL_WIDTH BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define FWHT_FL_ALPHA_IS_UNCOMPRESSED BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define FWHT_FL_I_FRAME BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* A 4-values flag - the number of components - 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define FWHT_FL_COMPONENTS_NUM_MSK GENMASK(18, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define FWHT_FL_COMPONENTS_NUM_OFFSET 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define FWHT_FL_PIXENC_MSK GENMASK(20, 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define FWHT_FL_PIXENC_OFFSET 19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define FWHT_FL_PIXENC_YUV (1 << FWHT_FL_PIXENC_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define FWHT_FL_PIXENC_RGB (2 << FWHT_FL_PIXENC_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define FWHT_FL_PIXENC_HSV (3 << FWHT_FL_PIXENC_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * A macro to calculate the needed padding in order to make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * both luma and chroma components resolutions are rounded up to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * a multiple of 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define vic_round_dim(dim, div) (round_up((dim) / (div), 8) * (div))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct fwht_cframe_hdr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) u32 magic1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) u32 magic2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) __be32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) __be32 width, height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) __be32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) __be32 colorspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) __be32 xfer_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) __be32 ycbcr_enc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) __be32 quantization;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) __be32 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct fwht_cframe {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u16 i_frame_qp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u16 p_frame_qp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) __be16 *rlc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) s16 coeffs[8 * 8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) s16 de_coeffs[8 * 8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) s16 de_fwht[8 * 8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u32 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct fwht_raw_frame {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) unsigned int width_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) unsigned int height_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned int luma_alpha_step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned int chroma_step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned int components_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) u8 *luma, *cb, *cr, *alpha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define FWHT_FRAME_PCODED BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define FWHT_FRAME_UNENCODED BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define FWHT_LUMA_UNENCODED BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define FWHT_CB_UNENCODED BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define FWHT_CR_UNENCODED BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define FWHT_ALPHA_UNENCODED BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) u32 fwht_encode_frame(struct fwht_raw_frame *frm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct fwht_raw_frame *ref_frm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct fwht_cframe *cf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) bool is_intra, bool next_is_intra,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned int width, unsigned int height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) unsigned int stride, unsigned int chroma_stride);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) bool fwht_decode_frame(struct fwht_cframe *cf, u32 hdr_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) unsigned int components_num, unsigned int width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) unsigned int height, const struct fwht_raw_frame *ref,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) unsigned int ref_stride, unsigned int ref_chroma_stride,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct fwht_raw_frame *dst, unsigned int dst_stride,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) unsigned int dst_chroma_stride);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #endif