mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-23 18:14:06 +00:00
Intra angular fixed, intra filtering. This version produces bit-perfect output.
This commit is contained in:
parent
83b904e34d
commit
08cc0e97ab
|
@ -130,7 +130,7 @@
|
|||
/* input init (ToDo: read from commandline / config) */
|
||||
encoder->bitdepth = 8;
|
||||
encoder->frame = 0;
|
||||
encoder->QP = 35;
|
||||
encoder->QP = 36;
|
||||
encoder->in.video_format = FORMAT_420;
|
||||
init_encoder_input(&encoder->in, input, cfg->width, cfg->height);
|
||||
|
||||
|
@ -141,10 +141,13 @@
|
|||
fread(encoder->in.cur_pic.yData, cfg->width*cfg->height,1,input);
|
||||
fread(encoder->in.cur_pic.uData, cfg->width*cfg->height>>2,1,input);
|
||||
fread(encoder->in.cur_pic.vData, cfg->width*cfg->height>>2,1,input);
|
||||
|
||||
/* Clear reconstruction buffers */
|
||||
memset(encoder->in.cur_pic.yRecData, 0, cfg->width*cfg->height);
|
||||
memset(encoder->in.cur_pic.uRecData, 128, cfg->width*cfg->height>>2);
|
||||
memset(encoder->in.cur_pic.vRecData, 128, cfg->width*cfg->height>>2);
|
||||
|
||||
/* /////////////THE ACTUAL CODING HAPPENDS HERE\\\\\\\\\\\\\\\\\\\ */
|
||||
encode_one_frame(encoder);
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
|
|
@ -334,12 +334,29 @@ void encode_one_frame(encoder_control* encoder)
|
|||
bitstream_clear_buffer(encoder->stream);
|
||||
*/
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
/*
|
||||
{
|
||||
int x,y;
|
||||
for(y = 0; y < encoder->in.height_in_LCU*2;y++)
|
||||
{
|
||||
for(x = 0;x < encoder->in.width_in_LCU*2;x++)
|
||||
{
|
||||
i = (x<<2)+(y<<2)*(encoder->in.width_in_LCU<<MAX_DEPTH);
|
||||
printf("(%d,%d) Intramode: %d\n", x<<2, y<<2,encoder->in.cur_pic.CU[0][i].intra.mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
/* Clear prediction data */
|
||||
/* ToDo: store */
|
||||
for(i=0; i < MAX_DEPTH+1; i++)
|
||||
{
|
||||
memset(encoder->in.cur_pic.CU[i], 0, (encoder->in.height_in_LCU<<MAX_DEPTH)*(encoder->in.width_in_LCU<<MAX_DEPTH)*sizeof(CU_info));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void encode_pic_parameter_set(encoder_control* encoder)
|
||||
|
@ -724,7 +741,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
|||
int i,x,y;
|
||||
uint32_t flag;
|
||||
uint32_t bestSAD;
|
||||
uint8_t *base = &encoder->in.cur_pic.yData[xCtb*(LCU_WIDTH>>(MAX_DEPTH)) + (yCtb*(LCU_WIDTH>>(MAX_DEPTH)))*encoder->in.width];
|
||||
uint8_t *base = &encoder->in.cur_pic.yData[xCtb*(LCU_WIDTH>>(MAX_DEPTH)) + (yCtb*(LCU_WIDTH>>(MAX_DEPTH)))*encoder->in.width];
|
||||
uint8_t *baseU = &encoder->in.cur_pic.uData[xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)];
|
||||
uint8_t *baseV = &encoder->in.cur_pic.vData[xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)];
|
||||
uint32_t width = LCU_WIDTH>>depth;
|
||||
|
@ -736,16 +753,24 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
|||
int16_t predV[16*16];
|
||||
|
||||
int16_t rec[(LCU_WIDTH+8)*(LCU_WIDTH+8)];
|
||||
int16_t *recShift = &rec[(LCU_WIDTH>>(depth))*2+8+1];
|
||||
int16_t *recShift = &rec[(LCU_WIDTH>>(depth))*2+8+1];
|
||||
int16_t *recShiftU = &rec[(LCU_WIDTH>>(depth+1))*2+8+1];
|
||||
uint8_t *recbase = &encoder->in.cur_pic.yRecData[xCtb*(LCU_WIDTH>>(MAX_DEPTH)) + (yCtb*(LCU_WIDTH>>(MAX_DEPTH)))*encoder->in.width];
|
||||
uint8_t *recbaseU = &encoder->in.cur_pic.uRecData[xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)];
|
||||
uint8_t *recbaseV = &encoder->in.cur_pic.vRecData[xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)];
|
||||
uint8_t *recbase = &encoder->in.cur_pic.yRecData[xCtb*(LCU_WIDTH>>(MAX_DEPTH)) + (yCtb*(LCU_WIDTH>>(MAX_DEPTH)))*encoder->in.width];
|
||||
uint8_t *recbaseU = &encoder->in.cur_pic.uRecData[xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)];
|
||||
uint8_t *recbaseV = &encoder->in.cur_pic.vRecData[xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)) + (yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)))*(encoder->in.width>>1)];
|
||||
//int16_t dcpredU = intra_getDCPred(encoder->in.cur_pic.uRecData,encoder->in.width>>1, xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)), yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)), depth+1);
|
||||
//int16_t dcpredV = intra_getDCPred(encoder->in.cur_pic.vRecData,encoder->in.width>>1, xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)), yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)), depth+1);
|
||||
|
||||
cabac_encodeBinTrm(&cabac, 0); /* IPCMFlag == 0 */
|
||||
|
||||
/*
|
||||
{
|
||||
FILE *recout = fopen("blockrec.yuv", "wb");
|
||||
fwrite(encoder->in.cur_pic.yRecData,encoder->cfg->width*encoder->cfg->height,1,recout);
|
||||
fwrite(encoder->in.cur_pic.uRecData,encoder->cfg->width*encoder->cfg->height>>2,1,recout);
|
||||
fwrite(encoder->in.cur_pic.vRecData,encoder->cfg->width*encoder->cfg->height>>2,1,recout);
|
||||
fclose(recout);
|
||||
}
|
||||
*/
|
||||
/* Build reconstructed block to use in prediction with extrapolated borders */
|
||||
intra_buildReferenceBorder(&encoder->in.cur_pic, xCtb, yCtb,(LCU_WIDTH>>(depth))*2+8, rec, (LCU_WIDTH>>(depth))*2+8, 0);
|
||||
|
||||
|
@ -886,7 +911,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
|||
}
|
||||
|
||||
/* Transform and quant residual to coeffs */
|
||||
transform2d(block,pre_quant_coeff,LCU_WIDTH>>depth,0);
|
||||
transform2d(block,pre_quant_coeff,width,0);
|
||||
quant(encoder,pre_quant_coeff,coeff, width, width, 0);
|
||||
|
||||
/* Check for non-zero coeffs */
|
||||
|
@ -906,7 +931,7 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
|||
{
|
||||
/* RECONSTRUCT for predictions */
|
||||
dequant(encoder,coeff,pre_quant_coeff,width, width,0);
|
||||
itransform2d(block,pre_quant_coeff,LCU_WIDTH>>depth,0);
|
||||
itransform2d(block,pre_quant_coeff,width,0);
|
||||
|
||||
i = 0;
|
||||
for(y = 0; y < LCU_WIDTH>>depth; y++)
|
||||
|
|
139
src/intra.c
139
src/intra.c
|
@ -190,6 +190,69 @@ int8_t intra_getDirLumaPredictor(picture* pic,uint32_t xCtb, uint32_t yCtb, uint
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void intra_filter(int16_t* ref, uint32_t stride,uint32_t width, int8_t mode)
|
||||
{
|
||||
#define FWIDTH (LCU_WIDTH+1)
|
||||
int16_t filtered[FWIDTH*FWIDTH];
|
||||
int16_t* filteredShift = &filtered[FWIDTH+1];
|
||||
int x,y;
|
||||
if(!mode)
|
||||
{
|
||||
//pF[ -1 ][ -1 ] = ( p[ -1 ][ 0 ] + 2 * p[ -1 ][ -1 ] + p[ 0 ][ -1 ] + 2 ) >> 2 (8 35)
|
||||
filteredShift[-FWIDTH-1] = (ref[-1]+2*ref[-stride-1]+ref[-stride]+2) >> 2;
|
||||
|
||||
//pF[ -1 ][ y ] = ( p[ -1 ][ y + 1 ] + 2 * p[ -1 ][ y ] + p[ -1 ][ y - 1 ] + 2 ) >> 2 for y = 0..nTbS * 2 - 2 (8 36)
|
||||
for(y = 0; y < width*2-1; y++)
|
||||
{
|
||||
filteredShift[y*FWIDTH-1] = (ref[(y+1)*stride-1] + 2*ref[y*stride-1] + ref[(y-1)*stride-1]+2) >> 2;
|
||||
}
|
||||
|
||||
//pF[ -1 ][ nTbS * 2 - 1 ] = p[ -1 ][ nTbS * 2 - 1 ] (8 37)
|
||||
filteredShift[(width*2-1)*FWIDTH-1] = ref[(width*2-1)*stride-1];
|
||||
|
||||
//pF[ x ][ -1 ] = ( p[ x - 1 ][ -1 ] + 2 * p[ x ][ -1 ] + p[ x + 1 ][ -1 ] + 2 ) >> 2 for x = 0..nTbS * 2 - 2 (8 38)
|
||||
for(x = 0; x < width*2-1; x++)
|
||||
{
|
||||
filteredShift[x-FWIDTH] = (ref[x-1-stride] + 2*ref[x-stride] + ref[x+1-stride]+2) >> 2;
|
||||
}
|
||||
|
||||
//pF[ nTbS * 2 - 1 ][ -1 ] = p[ nTbS * 2 - 1 ][ -1 ]
|
||||
filteredShift[(width*2-1)-FWIDTH] = ref[(width*2-1)-stride];
|
||||
|
||||
for(x = -1; x < (int32_t)width*2; x++)
|
||||
{
|
||||
ref[x-stride] = filtered[x+1];
|
||||
}
|
||||
for(y = 0; y < width*2; y++)
|
||||
{
|
||||
ref[y*stride-1] = filtered[(y+1)*FWIDTH];
|
||||
}
|
||||
/*
|
||||
{
|
||||
FILE* test = fopen("blockoutF2.yuv","wb");
|
||||
|
||||
uint8_t outvalue;
|
||||
for(y = 0; y < 72; y++)
|
||||
{
|
||||
for(x = 0; x < 72; x++)
|
||||
{
|
||||
outvalue = filtered[(x)+(y)*FWIDTH];
|
||||
fwrite(&outvalue,1,1,test);
|
||||
}
|
||||
}
|
||||
fclose(test);
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("UNHANDLED: %s: %d\r\n", __FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
#undef FWIDTH
|
||||
}
|
||||
|
||||
/*! \brief Function to test best intra prediction
|
||||
\param orig original picture data
|
||||
\param origstride original picture stride
|
||||
|
@ -251,30 +314,70 @@ int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t
|
|||
}
|
||||
}
|
||||
|
||||
/* Test planar */
|
||||
intra_getPlanarPred(rec, recstride, xpos, ypos, width, pred, width);
|
||||
CHECK_FOR_BEST(0);
|
||||
/* Test DC */
|
||||
|
||||
/* Test DC */
|
||||
x = intra_getDCPred(rec, recstride, xpos, ypos, width);
|
||||
for(i = 0; i < width*width; i++)
|
||||
{
|
||||
pred[i] = x;
|
||||
}
|
||||
CHECK_FOR_BEST(1);
|
||||
|
||||
intra_getAngularPred(rec,recstride,pred, width,width,width,10, xpos?1:0, ypos?1:0, 0);
|
||||
CHECK_FOR_BEST(10);
|
||||
intra_getAngularPred(rec,recstride,pred, width,width,width,26, xpos?1:0, ypos?1:0, 0);
|
||||
CHECK_FOR_BEST(26);
|
||||
|
||||
/*Apply filter*/
|
||||
intra_filter(rec,recstride,width,0);
|
||||
|
||||
/*
|
||||
{
|
||||
FILE* test = fopen("blockoutF.yuv","wb");
|
||||
|
||||
uint8_t outvalue;
|
||||
for(y = 0; y < recstride; y++)
|
||||
{
|
||||
for(x = 0; x < recstride; x++)
|
||||
{
|
||||
outvalue = rec[(x-1)+(y-1)*recstride];
|
||||
fwrite(&outvalue,1,1,test);
|
||||
}
|
||||
}
|
||||
fclose(test);
|
||||
}
|
||||
*/
|
||||
/* Test planar */
|
||||
intra_getPlanarPred(rec, recstride, xpos, ypos, width, pred, width);
|
||||
CHECK_FOR_BEST(0);
|
||||
|
||||
|
||||
/* Test directional predictions */
|
||||
/* ToDo: add conditions to skip some modes on borders */
|
||||
|
||||
//chroma can use only 26 and 10
|
||||
|
||||
/*
|
||||
if(xpos && ypos)
|
||||
//OK: 26 10
|
||||
|
||||
//if(xpos && ypos)
|
||||
//for(i = 2; i < 35; i++)
|
||||
//for(i = 26; i < 35; i++)
|
||||
|
||||
for(i = 2; i < 35; i++)
|
||||
{
|
||||
intra_getAngularPred(rec,recstride,pred, width,width,width,i, xpos?1:0, ypos?1:0, 0);
|
||||
CHECK_FOR_BEST(i);
|
||||
if(i != 10 && i != 26)
|
||||
{
|
||||
intra_getAngularPred(rec,recstride,pred, width,width,width,i, xpos?1:0, ypos?1:0, 0);
|
||||
CHECK_FOR_BEST(i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
intra_getAngularPred(rec,recstride,pred, width,width,width,2, xpos?1:0, ypos?1:0, 0);
|
||||
CHECK_FOR_BEST(2);
|
||||
*/
|
||||
/*
|
||||
intra_getAngularPred(rec,recstride,pred, width,width,width,3, xpos?1:0, ypos?1:0, 0);
|
||||
CHECK_FOR_BEST(3);
|
||||
*/
|
||||
|
||||
*sad = bestSAD;
|
||||
|
@ -316,6 +419,14 @@ void intra_recon(int16_t* rec,uint32_t recstride, uint32_t xpos, uint32_t ypos,u
|
|||
COPY_PRED_TO_DST();
|
||||
}
|
||||
|
||||
|
||||
/*! \brief this functions build a reference block (only borders) used for intra predictions
|
||||
\param pic picture to use as a source, should contain full CU-data
|
||||
\param outwidth width of the prediction block
|
||||
\param chroma signaling if chroma is used, 0 = luma, 1 = U and 2 = V
|
||||
|
||||
|
||||
*/
|
||||
void intra_buildReferenceBorder(picture* pic, int32_t xCtb, int32_t yCtb,int8_t outwidth, int16_t* dst, int32_t dststride, int8_t chroma)
|
||||
{
|
||||
int32_t leftColumn; /*!< left column iterator */
|
||||
|
@ -330,7 +441,7 @@ void intra_buildReferenceBorder(picture* pic, int32_t xCtb, int32_t yCtb,int8_t
|
|||
uint8_t* srcShifted = &srcPic[xCtb*SCU_width+(yCtb*SCU_width)*srcWidth]; /*!< input picture pointer shifted to start from the left-top corner of the current block */
|
||||
int32_t width_in_SCU = srcWidth/SCU_width; /*!< picture width in SCU */
|
||||
|
||||
memset(dst,0,outwidth*outwidth*sizeof(int16_t));
|
||||
//memset(dst,127,outwidth*outwidth*sizeof(int16_t));
|
||||
|
||||
/* Fill left column */
|
||||
if(xCtb)
|
||||
|
@ -405,7 +516,7 @@ void intra_buildReferenceBorder(picture* pic, int32_t xCtb, int32_t yCtb,int8_t
|
|||
}
|
||||
/* Topleft corner */
|
||||
dst[0] = (xCtb&&yCtb)?srcShifted[-srcWidth-1]:dst[dststride];
|
||||
/*
|
||||
|
||||
{
|
||||
FILE* test = fopen("blockout.yuv","wb");
|
||||
int x,y;
|
||||
|
@ -420,7 +531,7 @@ void intra_buildReferenceBorder(picture* pic, int32_t xCtb, int32_t yCtb,int8_t
|
|||
}
|
||||
fclose(test);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
void intra_getAngularPred(uint16_t* pSrc, int32_t srcStride, int16_t* rpDst, int32_t dstStride, int32_t width, int32_t height, int32_t dirMode, int8_t leftAvail,int8_t topAvail, int8_t filter)
|
||||
|
@ -591,9 +702,9 @@ void intra_DCPredFiltering(uint8_t* pSrc, int32_t iSrcStride, uint8_t* rpDst, in
|
|||
void intra_getPlanarPred(int16_t* src,int32_t srcstride, uint32_t xpos, uint32_t ypos,uint32_t width, int16_t* dst,int32_t dststride)
|
||||
{
|
||||
int16_t pDcVal = 1<<(g_uiBitDepth-1);
|
||||
uint32_t k, l, bottomLeft, topRight;
|
||||
int32_t k, l, bottomLeft, topRight;
|
||||
int32_t horPred;
|
||||
int16_t leftColumn[LCU_WIDTH], topRow[LCU_WIDTH], bottomRow[LCU_WIDTH], rightColumn[LCU_WIDTH];
|
||||
int32_t leftColumn[LCU_WIDTH], topRow[LCU_WIDTH], bottomRow[LCU_WIDTH], rightColumn[LCU_WIDTH];
|
||||
uint32_t blkSize = width;
|
||||
uint32_t offset2D = width;
|
||||
uint32_t shift1D = g_aucConvertToBit[ width ] + 2;
|
||||
|
|
Loading…
Reference in a new issue