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