mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 19:24: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) */
|
/* input init (ToDo: read from commandline / config) */
|
||||||
encoder->bitdepth = 8;
|
encoder->bitdepth = 8;
|
||||||
encoder->frame = 0;
|
encoder->frame = 0;
|
||||||
encoder->QP = 35;
|
encoder->QP = 36;
|
||||||
encoder->in.video_format = FORMAT_420;
|
encoder->in.video_format = FORMAT_420;
|
||||||
init_encoder_input(&encoder->in, input, cfg->width, cfg->height);
|
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.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.uData, cfg->width*cfg->height>>2,1,input);
|
||||||
fread(encoder->in.cur_pic.vData, 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.yRecData, 0, cfg->width*cfg->height);
|
||||||
memset(encoder->in.cur_pic.uRecData, 128, cfg->width*cfg->height>>2);
|
memset(encoder->in.cur_pic.uRecData, 128, cfg->width*cfg->height>>2);
|
||||||
memset(encoder->in.cur_pic.vRecData, 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);
|
encode_one_frame(encoder);
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
|
|
@ -334,12 +334,29 @@ void encode_one_frame(encoder_control* encoder)
|
||||||
bitstream_clear_buffer(encoder->stream);
|
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 */
|
/* Clear prediction data */
|
||||||
/* ToDo: store */
|
/* ToDo: store */
|
||||||
for(i=0; i < MAX_DEPTH+1; i++)
|
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));
|
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)
|
void encode_pic_parameter_set(encoder_control* encoder)
|
||||||
|
@ -745,7 +762,15 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
||||||
//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);
|
//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 */
|
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 */
|
/* 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);
|
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 */
|
/* 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);
|
quant(encoder,pre_quant_coeff,coeff, width, width, 0);
|
||||||
|
|
||||||
/* Check for non-zero coeffs */
|
/* 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 */
|
/* RECONSTRUCT for predictions */
|
||||||
dequant(encoder,coeff,pre_quant_coeff,width, width,0);
|
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;
|
i = 0;
|
||||||
for(y = 0; y < LCU_WIDTH>>depth; y++)
|
for(y = 0; y < LCU_WIDTH>>depth; y++)
|
||||||
|
|
131
src/intra.c
131
src/intra.c
|
@ -190,6 +190,69 @@ int8_t intra_getDirLumaPredictor(picture* pic,uint32_t xCtb, uint32_t yCtb, uint
|
||||||
return 1;
|
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
|
/*! \brief Function to test best intra prediction
|
||||||
\param orig original picture data
|
\param orig original picture data
|
||||||
\param origstride original picture stride
|
\param origstride original picture stride
|
||||||
|
@ -251,9 +314,7 @@ 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);
|
x = intra_getDCPred(rec, recstride, xpos, ypos, width);
|
||||||
for(i = 0; i < width*width; i++)
|
for(i = 0; i < width*width; i++)
|
||||||
|
@ -261,20 +322,62 @@ int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t
|
||||||
pred[i] = x;
|
pred[i] = x;
|
||||||
}
|
}
|
||||||
CHECK_FOR_BEST(1);
|
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 */
|
/* Test directional predictions */
|
||||||
/* ToDo: add conditions to skip some modes on borders */
|
/* ToDo: add conditions to skip some modes on borders */
|
||||||
|
|
||||||
//chroma can use only 26 and 10
|
//chroma can use only 26 and 10
|
||||||
|
//OK: 26 10
|
||||||
|
|
||||||
/*
|
//if(xpos && ypos)
|
||||||
if(xpos && ypos)
|
|
||||||
//for(i = 2; i < 35; i++)
|
//for(i = 2; i < 35; i++)
|
||||||
//for(i = 26; i < 35; i++)
|
//for(i = 26; i < 35; i++)
|
||||||
|
|
||||||
for(i = 2; i < 35; i++)
|
for(i = 2; i < 35; i++)
|
||||||
|
{
|
||||||
|
if(i != 10 && i != 26)
|
||||||
{
|
{
|
||||||
intra_getAngularPred(rec,recstride,pred, width,width,width,i, xpos?1:0, ypos?1:0, 0);
|
intra_getAngularPred(rec,recstride,pred, width,width,width,i, xpos?1:0, ypos?1:0, 0);
|
||||||
CHECK_FOR_BEST(i);
|
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;
|
*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();
|
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)
|
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 */
|
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 */
|
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 */
|
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 */
|
/* Fill left column */
|
||||||
if(xCtb)
|
if(xCtb)
|
||||||
|
@ -405,7 +516,7 @@ void intra_buildReferenceBorder(picture* pic, int32_t xCtb, int32_t yCtb,int8_t
|
||||||
}
|
}
|
||||||
/* Topleft corner */
|
/* Topleft corner */
|
||||||
dst[0] = (xCtb&&yCtb)?srcShifted[-srcWidth-1]:dst[dststride];
|
dst[0] = (xCtb&&yCtb)?srcShifted[-srcWidth-1]:dst[dststride];
|
||||||
/*
|
|
||||||
{
|
{
|
||||||
FILE* test = fopen("blockout.yuv","wb");
|
FILE* test = fopen("blockout.yuv","wb");
|
||||||
int x,y;
|
int x,y;
|
||||||
|
@ -420,7 +531,7 @@ void intra_buildReferenceBorder(picture* pic, int32_t xCtb, int32_t yCtb,int8_t
|
||||||
}
|
}
|
||||||
fclose(test);
|
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)
|
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)
|
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);
|
int16_t pDcVal = 1<<(g_uiBitDepth-1);
|
||||||
uint32_t k, l, bottomLeft, topRight;
|
int32_t k, l, bottomLeft, topRight;
|
||||||
int32_t horPred;
|
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 blkSize = width;
|
||||||
uint32_t offset2D = width;
|
uint32_t offset2D = width;
|
||||||
uint32_t shift1D = g_aucConvertToBit[ width ] + 2;
|
uint32_t shift1D = g_aucConvertToBit[ width ] + 2;
|
||||||
|
|
Loading…
Reference in a new issue