Go to the documentation of this file.
24 #ifndef AVCODEC_VVC_DSP_H
25 #define AVCODEC_VVC_DSP_H
48 void (*
put[2 ][7 ][2 ][2 ])(
49 int16_t *
dst,
const uint8_t *
src, ptrdiff_t src_stride,
int height,
50 const int8_t *
hf,
const int8_t *
vf,
int width);
53 uint8_t *
dst, ptrdiff_t dst_stride,
const uint8_t *
src, ptrdiff_t src_stride,
int height,
54 const int8_t *
hf,
const int8_t *
vf,
int width);
57 uint8_t *
dst, ptrdiff_t dst_stride,
const uint8_t *
src, ptrdiff_t src_stride,
int height,
58 int denom,
int wx,
int ox,
const int8_t *
hf,
const int8_t *
vf,
int width);
61 int16_t *
dst,
const uint8_t *
src, ptrdiff_t src_stride,
int src_height,
62 int x,
int y,
int dx,
int dy,
int height,
const int8_t *
hf,
const int8_t *
vf,
int width);
65 uint8_t *
dst,
const ptrdiff_t dst_stride,
const uint8_t *
src, ptrdiff_t src_stride,
int src_height,
66 int x,
int y,
int dx,
int dy,
int height,
const int8_t *
hf,
const int8_t *
vf,
int width);
69 uint8_t *
dst,
const ptrdiff_t dst_stride,
const uint8_t *
src, ptrdiff_t src_stride,
int src_height,
70 int x,
int y,
int dx,
int dy,
int height,
int denom,
int wx,
int ox,
const int8_t *
hf,
const int8_t *
vf,
73 void (*
avg)(uint8_t *
dst, ptrdiff_t dst_stride,
76 void (*
w_avg)(uint8_t *
_dst,
const ptrdiff_t _dst_stride,
78 int denom,
int w0,
int w1,
int o0,
int o1);
81 const uint8_t *inter, ptrdiff_t inter_stride,
int inter_weight);
84 const int16_t *
src0,
const int16_t *
src1,
85 const uint8_t *
weights,
int step_x,
int step_y);
87 void (*
fetch_samples)(int16_t *
dst,
const uint8_t *
src, ptrdiff_t src_stride,
int x_frac,
int y_frac);
91 void (*
apply_prof)(int16_t *
dst,
const int16_t *
src,
const int16_t *diff_mv_x,
const int16_t *diff_mv_y);
94 const int16_t *diff_mv_x,
const int16_t *diff_mv_y);
96 const int16_t *diff_mv_x,
const int16_t *diff_mv_y,
int denom,
int wx,
int ox);
98 void (*
apply_bdof)(uint8_t *
dst, ptrdiff_t dst_stride,
const int16_t *
src0,
const int16_t *
src1,
int block_w,
int block_h);
100 int (*
sad)(
const int16_t *
src0,
const int16_t *
src1,
int dx,
int dy,
int block_w,
int block_h);
113 int mode_id,
int is_transpose);
118 int w,
int h, ptrdiff_t
stride,
int c_idx,
int mode,
int ref_idx,
int filter_flag,
int need_pdpc);
120 int c_idx,
int mode,
int ref_idx,
int filter_flag,
int need_pdpc);
140 const uint8_t *no_p,
const uint8_t *no_q,
const uint8_t *max_len_p,
const uint8_t *max_len_q,
int hor_ctu_edge);
142 const uint8_t *no_p,
const uint8_t *no_q,
const uint8_t *max_len_p,
const uint8_t *max_len_q,
int shift);
147 void (*
band_filter[9])(uint8_t *
dst,
const uint8_t *
src, ptrdiff_t dst_stride, ptrdiff_t src_stride,
148 const int16_t *sao_offset_val,
int sao_left_class,
int width,
int height);
151 const int16_t *sao_offset_val,
int sao_eo_class,
int width,
int height);
152 void (*
edge_restore[2])(uint8_t *
dst,
const uint8_t *
src, ptrdiff_t dst_stride, ptrdiff_t src_stride,
154 const uint8_t *vert_edge,
const uint8_t *horiz_edge,
const uint8_t *diag_edge);
158 void (*
filter[2 ])(uint8_t *
dst, ptrdiff_t dst_stride,
const uint8_t *
src, ptrdiff_t src_stride,
160 void (*
filter_cc)(uint8_t *
dst, ptrdiff_t dst_stride,
const uint8_t *luma, ptrdiff_t luma_stride,
164 int vb_pos,
int *gradient_tmp);
166 const int16_t *coeff_set,
const uint8_t *clip_idx_set,
const uint8_t *class_to_filt);
void(* recon_coeff_and_clip)(int16_t *coeff, int16_t *clip, const int *class_idx, const int *transpose_idx, int size, const int16_t *coeff_set, const uint8_t *clip_idx_set, const uint8_t *class_to_filt)
void(* filter)(uint8_t *dst, ptrdiff_t dst_stride, int width, int height, const void *lut)
void(* pred_v)(uint8_t *src, const uint8_t *_top, int w, int h, ptrdiff_t stride)
void(* pred_dc)(uint8_t *src, const uint8_t *top, const uint8_t *left, int w, int h, ptrdiff_t stride)
void(* put_scaled[2/*luma, chroma */][7/*log2(width) - 1 */])(int16_t *dst, const uint8_t *src, ptrdiff_t src_stride, int src_height, int x, int y, int dx, int dy, int height, const int8_t *hf, const int8_t *vf, int width)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t const uint8_t * src
void(* put_uni_w[2/*luma, chroma */][7/*log2(width) - 1 */][2/*int, frac */][2/*int, frac */])(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src, ptrdiff_t src_stride, int height, int denom, int wx, int ox, const int8_t *hf, const int8_t *vf, int width)
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
void(* dmvr[2][2])(int16_t *dst, const uint8_t *src, ptrdiff_t src_stride, int height, intptr_t mx, intptr_t my, int width)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int height
void(* add_residual)(uint8_t *dst, const int *res, int width, int height, ptrdiff_t stride)
int(* sad)(const int16_t *src0, const int16_t *src1, int dx, int dy, int block_w, int block_h)
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
void(* intra_cclm_pred)(const struct VVCLocalContext *lc, int x0, int y0, int w, int h)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t mx
void(* w_avg)(uint8_t *_dst, const ptrdiff_t _dst_stride, const int16_t *src0, const int16_t *src1, int width, int height, int denom, int w0, int w1, int o0, int o1)
void(* apply_prof_uni)(uint8_t *dst, ptrdiff_t dst_stride, const int16_t *src, const int16_t *diff_mv_x, const int16_t *diff_mv_y)
void ff_vvc_dsp_init(VVCDSPContext *hpc, int bit_depth)
void(* band_filter[9])(uint8_t *dst, const uint8_t *src, ptrdiff_t dst_stride, ptrdiff_t src_stride, const int16_t *sao_offset_val, int sao_left_class, int width, int height)
void(* filter_luma[2/*h, v */])(uint8_t *pix, ptrdiff_t stride, const int32_t *beta, const int32_t *tc, const uint8_t *no_p, const uint8_t *no_q, const uint8_t *max_len_p, const uint8_t *max_len_q, int hor_ctu_edge)
void ff_vvc_dsp_init_riscv(VVCDSPContext *hpc, const int bit_depth)
void(* filter_cc)(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *luma, ptrdiff_t luma_stride, int width, int height, int hs, int vs, const int16_t *filter, int vb_pos)
void(* pred_planar)(uint8_t *src, const uint8_t *top, const uint8_t *left, int w, int h, ptrdiff_t stride)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t my
void(* lmcs_scale_chroma)(struct VVCLocalContext *lc, int *dst, const int *coeff, int w, int h, int x0_cu, int y0_cu)
void(* avg)(uint8_t *dst, ptrdiff_t dst_stride, const int16_t *src0, const int16_t *src1, int width, int height)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int width
void(* add_residual_joint)(uint8_t *dst, const int *res, int width, int height, ptrdiff_t stride, int c_sign, int shift)
void(* bdof_fetch_samples)(int16_t *dst, const uint8_t *src, ptrdiff_t src_stride, int x_frac, int y_frac, int width, int height)
void(* apply_bdof)(uint8_t *dst, ptrdiff_t dst_stride, const int16_t *src0, const int16_t *src1, int block_w, int block_h)
void ff_vvc_dsp_init_x86(VVCDSPContext *hpc, const int bit_depth)
void(* transform_bdpcm)(int *coeffs, int width, int height, int vertical, int log2_transform_range)
void(* edge_restore[2])(uint8_t *dst, const uint8_t *src, ptrdiff_t dst_stride, ptrdiff_t src_stride, const struct SAOParams *sao, const int *borders, int width, int height, int c_idx, const uint8_t *vert_edge, const uint8_t *horiz_edge, const uint8_t *diag_edge)
void(* pred_angular_h)(uint8_t *src, const uint8_t *_top, const uint8_t *_left, int w, int h, ptrdiff_t stride, int c_idx, int mode, int ref_idx, int filter_flag, int need_pdpc)
void(* filter[2/*luma, chroma */])(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src, ptrdiff_t src_stride, int width, int height, const int16_t *filter, const int16_t *clip, int vb_pos)
void(* filter_chroma[2/*h, v */])(uint8_t *pix, ptrdiff_t stride, const int32_t *beta, const int32_t *tc, const uint8_t *no_p, const uint8_t *no_q, const uint8_t *max_len_p, const uint8_t *max_len_q, int shift)
void(* apply_prof)(int16_t *dst, const int16_t *src, const int16_t *diff_mv_x, const int16_t *diff_mv_y)
static int shift(int a, int b)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
void(* edge_filter[9])(uint8_t *dst, const uint8_t *src, ptrdiff_t dst_stride, const int16_t *sao_offset_val, int sao_eo_class, int width, int height)
void(* intra_pred)(const struct VVCLocalContext *lc, int x0, int y0, int w, int h, int c_idx)
void(* pred_mip)(uint8_t *src, const uint8_t *top, const uint8_t *left, int w, int h, ptrdiff_t stride, int mode_id, int is_transpose)
void(* apply_prof_uni_w)(uint8_t *dst, const ptrdiff_t dst_stride, const int16_t *src, const int16_t *diff_mv_x, const int16_t *diff_mv_y, int denom, int wx, int ox)
static const int weights[]
uint8_t ptrdiff_t const uint8_t ptrdiff_t int const int8_t * hf
void(* classify)(int *class_idx, int *transpose_idx, const uint8_t *src, ptrdiff_t src_stride, int width, int height, int vb_pos, int *gradient_tmp)
void(* itx[VVC_N_TX_TYPE][VVC_N_TX_SIZE])(int *coeffs, ptrdiff_t step, size_t nz)
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
void(* put_uni[2/*luma, chroma */][7/*log2(width) - 1 */][2/*int, frac */][2/*int, frac */])(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src, ptrdiff_t src_stride, int height, const int8_t *hf, const int8_t *vf, int width)
void ff_vvc_dsp_init_aarch64(VVCDSPContext *hpc, const int bit_depth)
void(* put_gpm)(uint8_t *dst, ptrdiff_t dst_stride, int width, int height, const int16_t *src0, const int16_t *src1, const uint8_t *weights, int step_x, int step_y)
int(* ladf_level[2/*h, v */])(const uint8_t *pix, ptrdiff_t stride)
void(* pred_angular_v)(uint8_t *src, const uint8_t *_top, const uint8_t *_left, int w, int h, ptrdiff_t stride, int c_idx, int mode, int ref_idx, int filter_flag, int need_pdpc)
void(* put_uni_w_scaled[2/*luma, chroma */][7/*log2(width) - 1 */])(uint8_t *dst, const ptrdiff_t dst_stride, const uint8_t *src, ptrdiff_t src_stride, int src_height, int x, int y, int dx, int dy, int height, int denom, int wx, int ox, const int8_t *hf, const int8_t *vf, int width)
void(* put_ciip)(uint8_t *dst, ptrdiff_t dst_stride, int width, int height, const uint8_t *inter, ptrdiff_t inter_stride, int inter_weight)
void(* pred_residual_joint)(int *buf, int width, int height, int c_sign, int shift)
static const double coeff[2][5]
void(* pred_h)(uint8_t *src, const uint8_t *_left, int w, int h, ptrdiff_t stride)
void(* fetch_samples)(int16_t *dst, const uint8_t *src, ptrdiff_t src_stride, int x_frac, int y_frac)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int const int8_t const int8_t * vf
void(* put[2/*luma, chroma */][7/*log2(width) - 1 */][2/*int, frac */][2/*int, frac */])(int16_t *dst, const uint8_t *src, ptrdiff_t src_stride, int height, const int8_t *hf, const int8_t *vf, int width)
void(* put_uni_scaled[2/*luma, chroma */][7/*log2(width) - 1 */])(uint8_t *dst, const ptrdiff_t dst_stride, const uint8_t *src, ptrdiff_t src_stride, int src_height, int x, int y, int dx, int dy, int height, const int8_t *hf, const int8_t *vf, int width)