This source file includes following definitions.
- diff_blk
- has_nonzero_value
- compute_transform_coeffs
- analyze
#include "libde265/encoder/algo/tb-transform.h"
#include "libde265/encoder/encoder-core.h"
#include "libde265/encoder/encoder-context.h"
#include "libde265/encoder/encoder-syntax.h"
#include <assert.h>
#include <limits>
#include <math.h>
#include <iostream>
void diff_blk(int16_t* out,int out_stride,
const uint8_t* a_ptr, int a_stride,
const uint8_t* b_ptr, int b_stride,
int blkSize)
{
for (int by=0;by<blkSize;by++)
for (int bx=0;bx<blkSize;bx++)
{
out[by*out_stride+bx] = a_ptr[by*a_stride+bx] - b_ptr[by*b_stride+bx];
}
}
static bool has_nonzero_value(const int16_t* data, int n)
{
for (int i=0;i<n;i++)
if (data[i]) return true;
return false;
}
void compute_transform_coeffs(encoder_context* ectx,
enc_tb* tb,
const de265_image* input,
int x0,int y0,
int log2TbSize,
const enc_cb* cb,
int cIdx)
{
int xC = x0;
int yC = y0;
int tbSize = 1<<log2TbSize;
if (cIdx>0) { xC>>=1; yC>>=1; }
enum PredMode predMode = cb->PredMode;
int16_t blk[32*32];
int16_t* residual;
if (predMode==MODE_INTRA) {
residual = tb->residual[cIdx]->get_buffer_s16();
}
else {
}
tb->alloc_coeff_memory(cIdx, tbSize);
int trType;
if (cIdx==0 && log2TbSize==2 && predMode==MODE_INTRA) trType=1;
else trType=0;
fwd_transform(&ectx->acceleration, tb->coeff[cIdx], tbSize, log2TbSize, trType, residual, tbSize);
quant_coefficients(tb->coeff[cIdx], tb->coeff[cIdx], log2TbSize, cb->qp, true);
tb->cbf[cIdx] = has_nonzero_value(tb->coeff[cIdx], 1<<(log2TbSize<<1));
}
enc_tb* Algo_TB_Transform::analyze(encoder_context* ectx,
context_model_table& ctxModel,
const de265_image* input,
enc_tb* tb,
int trafoDepth, int MaxTrafoDepth,
int IntraSplitFlag)
{
enter();
const enc_cb* cb = tb->cb;
*tb->downPtr = tb;
de265_image* img = ectx->img;
int stride = ectx->img->get_image_stride(0);
uint8_t* luma_plane = ectx->img->get_image_plane(0);
uint8_t* cb_plane = ectx->img->get_image_plane(1);
uint8_t* cr_plane = ectx->img->get_image_plane(2);
int x0 = tb->x;
int y0 = tb->y;
int xBase = cb->x;
int yBase = cb->y;
int log2TbSize = tb->log2Size;
compute_transform_coeffs(ectx, tb, input, x0,y0, log2TbSize, cb, 0 );
if (ectx->get_sps().chroma_format_idc == CHROMA_444) {
compute_transform_coeffs(ectx, tb, input, x0,y0, log2TbSize, cb, 1 );
compute_transform_coeffs(ectx, tb, input, x0,y0, log2TbSize, cb, 2 );
}
else if (log2TbSize > 2) {
compute_transform_coeffs(ectx, tb, input, x0,y0, log2TbSize-1, cb, 1 );
compute_transform_coeffs(ectx, tb, input, x0,y0, log2TbSize-1, cb, 2 );
}
else if (tb->blkIdx==3) {
compute_transform_coeffs(ectx, tb, input, xBase,yBase, log2TbSize, cb, 1 );
compute_transform_coeffs(ectx, tb, input, xBase,yBase, log2TbSize, cb, 2 );
}
tb->reconstruct(ectx, ectx->img);
CABAC_encoder_estim estim;
estim.set_context_models(&ctxModel);
tb->rate_withoutCbfChroma = 0;
const seq_parameter_set* sps = &ectx->img->get_sps();
if (log2TbSize <= sps->Log2MaxTrafoSize &&
log2TbSize > sps->Log2MinTrafoSize &&
trafoDepth < MaxTrafoDepth &&
!(IntraSplitFlag && trafoDepth==0))
{
encode_split_transform_flag(ectx, &estim, log2TbSize, 0);
tb->rate_withoutCbfChroma += estim.getRDBits();
estim.reset();
}
float luma_cbf_bits = 0;
if (cb->PredMode == MODE_INTRA || trafoDepth != 0 ||
tb->cbf[1] || tb->cbf[2]) {
encode_cbf_luma(&estim, trafoDepth==0, tb->cbf[0]);
luma_cbf_bits = estim.getRDBits();
}
descend(tb,"DCT");
float bits = mAlgo_TB_RateEstimation->encode_transform_unit(ectx,ctxModel,
tb,cb, x0,y0, xBase,yBase,
log2TbSize, trafoDepth, tb->blkIdx);
ascend();
tb->rate_withoutCbfChroma += bits + luma_cbf_bits;
estim.reset();
tb->rate = (tb->rate_withoutCbfChroma +
recursive_cbfChroma_rate(&estim,tb,log2TbSize,trafoDepth));
int tbSize = 1<<log2TbSize;
tb->distortion = SSD(input->get_image_plane_at_pos(0, x0,y0), input->get_image_stride(0),
tb->reconstruction[0]->get_buffer_u8(),
tb->reconstruction[0]->getStride(),
tbSize, tbSize);
return tb;
}