mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-12-18 03:04:06 +00:00
Fixed intra filtering process for future use-cases
This commit is contained in:
parent
73d6ed2ff3
commit
ff5652609e
|
@ -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 = 36;
|
encoder->QP = 32;
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -279,13 +279,8 @@ void encode_one_frame(encoder_control* encoder)
|
||||||
}
|
}
|
||||||
else// if(encoder->frame < 10)
|
else// if(encoder->frame < 10)
|
||||||
{
|
{
|
||||||
if(encoder->QP > 20) encoder->QP-=2;
|
//if(encoder->QP > 20) encoder->QP-=2;
|
||||||
/* Picture Parameter Set (PPS) */
|
|
||||||
encode_pic_parameter_set(encoder);
|
|
||||||
bitstream_align(encoder->stream);
|
|
||||||
bitstream_flush(encoder->stream);
|
|
||||||
nal_write(encoder->output, encoder->stream->buffer, encoder->stream->buffer_pos, 0, NAL_PIC_PARAMETER_SET, 0);
|
|
||||||
bitstream_clear_buffer(encoder->stream);
|
|
||||||
|
|
||||||
cabac_start(&cabac);
|
cabac_start(&cabac);
|
||||||
encoder->in.cur_pic.slicetype = SLICE_I;
|
encoder->in.cur_pic.slicetype = SLICE_I;
|
||||||
|
@ -298,41 +293,6 @@ void encode_one_frame(encoder_control* encoder)
|
||||||
bitstream_flush(encoder->stream);
|
bitstream_flush(encoder->stream);
|
||||||
nal_write(encoder->output, encoder->stream->buffer, encoder->stream->buffer_pos, 0, 0, encoder->frame);
|
nal_write(encoder->output, encoder->stream->buffer, encoder->stream->buffer_pos, 0, 0, encoder->frame);
|
||||||
bitstream_clear_buffer(encoder->stream);
|
bitstream_clear_buffer(encoder->stream);
|
||||||
|
|
||||||
/*
|
|
||||||
encoder->in.cur_pic.type = 0;
|
|
||||||
encode_slice_header(encoder);
|
|
||||||
bitstream_align(encoder->stream);
|
|
||||||
bitstream_flush(encoder->stream);
|
|
||||||
nal_write(encoder->output, encoder->stream->buffer, encoder->stream->buffer_pos, 0, 0, 0);
|
|
||||||
bitstream_clear_buffer(encoder->stream);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
cabac_start(&cabac);
|
|
||||||
encoder->in.cur_pic.type = NAL_IDR_SLICE;
|
|
||||||
encode_slice_header(encoder);
|
|
||||||
bitstream_align(encoder->stream);
|
|
||||||
encode_slice_data(encoder);
|
|
||||||
cabac_flush(&cabac);
|
|
||||||
bitstream_align(encoder->stream);
|
|
||||||
bitstream_flush(encoder->stream);
|
|
||||||
nal_write(encoder->output, encoder->stream->buffer, encoder->stream->buffer_pos, 0, NAL_IDR_SLICE, 0);
|
|
||||||
bitstream_clear_buffer(encoder->stream);
|
|
||||||
*/
|
|
||||||
/* Non-IDR slice */
|
|
||||||
/*
|
|
||||||
cabac_start(&cabac);
|
|
||||||
encoder->in.cur_pic.type = NAL_NONIDR_SLICE;
|
|
||||||
encode_slice_header(encoder);
|
|
||||||
bitstream_align(encoder->stream);
|
|
||||||
encode_slice_data(encoder);
|
|
||||||
cabac_flush(&cabac);
|
|
||||||
bitstream_align(encoder->stream);
|
|
||||||
bitstream_flush(encoder->stream);
|
|
||||||
nal_write(encoder->output, encoder->stream->buffer, encoder->stream->buffer_pos, 0, NAL_NONIDR_SLICE, encoder->frame+1);
|
|
||||||
bitstream_clear_buffer(encoder->stream);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
/*
|
/*
|
||||||
|
@ -770,9 +730,9 @@ void encode_coding_tree(encoder_control* encoder,uint16_t xCtb,uint16_t yCtb, ui
|
||||||
/* ToDo: separate chroma prediction */
|
/* ToDo: separate chroma prediction */
|
||||||
//printf("(%d, %d) SAD: %d\n", xCtb,yCtb,bestSAD);
|
//printf("(%d, %d) SAD: %d\n", xCtb,yCtb,bestSAD);
|
||||||
intra_buildReferenceBorder(&encoder->in.cur_pic, xCtb, yCtb,(LCU_WIDTH>>(depth+1))*2+8, rec, (LCU_WIDTH>>(depth+1))*2+8, 1);
|
intra_buildReferenceBorder(&encoder->in.cur_pic, xCtb, yCtb,(LCU_WIDTH>>(depth+1))*2+8, rec, (LCU_WIDTH>>(depth+1))*2+8, 1);
|
||||||
intra_recon(recShiftU,(LCU_WIDTH>>(depth+1))*2+8,xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)),yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)),width>>1,predU,width>>1,intraPredMode);
|
intra_recon(recShiftU,(LCU_WIDTH>>(depth+1))*2+8,xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)),yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)),width>>1,predU,width>>1,intraPredMode,1);
|
||||||
intra_buildReferenceBorder(&encoder->in.cur_pic, xCtb, yCtb,(LCU_WIDTH>>(depth+1))*2+8, rec, (LCU_WIDTH>>(depth+1))*2+8, 2);
|
intra_buildReferenceBorder(&encoder->in.cur_pic, xCtb, yCtb,(LCU_WIDTH>>(depth+1))*2+8, rec, (LCU_WIDTH>>(depth+1))*2+8, 2);
|
||||||
intra_recon(recShiftU,(LCU_WIDTH>>(depth+1))*2+8,xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)),yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)),width>>1,predV,width>>1,intraPredMode);
|
intra_recon(recShiftU,(LCU_WIDTH>>(depth+1))*2+8,xCtb*(LCU_WIDTH>>(MAX_DEPTH+1)),yCtb*(LCU_WIDTH>>(MAX_DEPTH+1)),width>>1,predV,width>>1,intraPredMode,1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
PREDINFO CODING
|
PREDINFO CODING
|
||||||
|
|
85
src/intra.c
85
src/intra.c
|
@ -20,6 +20,9 @@
|
||||||
#include "picture.h"
|
#include "picture.h"
|
||||||
#include "intra.h"
|
#include "intra.h"
|
||||||
|
|
||||||
|
|
||||||
|
const uint8_t intraHorVerDistThres[4] = {0,7,1,0};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Set intrablock mode (and init typedata)
|
\brief Set intrablock mode (and init typedata)
|
||||||
\param pic picture to use
|
\param pic picture to use
|
||||||
|
@ -224,6 +227,7 @@ void intra_filter(int16_t* ref, uint32_t stride,uint32_t width, int8_t mode)
|
||||||
*/
|
*/
|
||||||
int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t recstride, uint32_t xpos, uint32_t ypos,uint32_t width, int16_t* dst,int32_t dststride, uint32_t *sad)
|
int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t recstride, uint32_t xpos, uint32_t ypos,uint32_t width, int16_t* dst,int32_t dststride, uint32_t *sad)
|
||||||
{
|
{
|
||||||
|
typedef uint32_t (*SADfunction)(int16_t *block,uint32_t stride1,int16_t* block2, uint32_t stride2);
|
||||||
uint32_t bestSAD = 0xffffffff;
|
uint32_t bestSAD = 0xffffffff;
|
||||||
uint32_t SAD = 0;
|
uint32_t SAD = 0;
|
||||||
int16_t bestMode = 1;
|
int16_t bestMode = 1;
|
||||||
|
@ -232,6 +236,8 @@ int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t
|
||||||
int16_t pred[LCU_WIDTH*LCU_WIDTH>>2];
|
int16_t pred[LCU_WIDTH*LCU_WIDTH>>2];
|
||||||
int16_t origBlock[LCU_WIDTH*LCU_WIDTH>>2];
|
int16_t origBlock[LCU_WIDTH*LCU_WIDTH>>2];
|
||||||
uint8_t *origShift = &orig[xpos+ypos*origstride];
|
uint8_t *origShift = &orig[xpos+ypos*origstride];
|
||||||
|
SADfunction SADarray[4] = {&SAD4x4,&SAD8x8,&SAD16x16,&SAD32x32};
|
||||||
|
uint8_t threshold = intraHorVerDistThres[g_toBits[width]]; /*!< Intra filtering threshold */
|
||||||
#define COPY_PRED_TO_DST() for(y = 0; y < (int32_t)width; y++) { for(x = 0; x < (int32_t)width; x++) { dst[x+y*dststride] = pred[x+y*width]; } }
|
#define COPY_PRED_TO_DST() for(y = 0; y < (int32_t)width; y++) { for(x = 0; x < (int32_t)width; x++) { dst[x+y*dststride] = pred[x+y*width]; } }
|
||||||
#define CHECK_FOR_BEST(mode) SAD = calcSAD(pred,width,origBlock,width); \
|
#define CHECK_FOR_BEST(mode) SAD = calcSAD(pred,width,origBlock,width); \
|
||||||
if(SAD < bestSAD)\
|
if(SAD < bestSAD)\
|
||||||
|
@ -241,23 +247,9 @@ int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t
|
||||||
COPY_PRED_TO_DST();\
|
COPY_PRED_TO_DST();\
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(width)
|
/* Choose SAD function according to width */
|
||||||
{
|
calcSAD = SADarray[g_toBits[width]];
|
||||||
case 4:
|
|
||||||
calcSAD = &SAD4x4;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
calcSAD = &SAD8x8;
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
calcSAD = &SAD16x16;
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
calcSAD = &SAD32x32;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
;
|
|
||||||
}
|
|
||||||
/* Store original block for SAD computation */
|
/* Store original block for SAD computation */
|
||||||
i = 0;
|
i = 0;
|
||||||
for(y = 0; y < (int32_t)width; y++)
|
for(y = 0; y < (int32_t)width; y++)
|
||||||
|
@ -277,30 +269,19 @@ int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t
|
||||||
}
|
}
|
||||||
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 angular that don't require filtering */
|
||||||
CHECK_FOR_BEST(10);
|
for(i = 2; i < 35; i++)
|
||||||
intra_getAngularPred(rec,recstride,pred, width,width,width,26, xpos?1:0, ypos?1:0, 0);
|
{
|
||||||
CHECK_FOR_BEST(26);
|
if(MIN(abs(i-26),abs(i-10)) <= threshold)
|
||||||
|
{
|
||||||
|
intra_getAngularPred(rec,recstride,pred, width,width,width,i, xpos?1:0, ypos?1:0, 0);
|
||||||
|
CHECK_FOR_BEST(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*Apply filter*/
|
/*Apply filter*/
|
||||||
intra_filter(rec,recstride,width,0);
|
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 */
|
/* Test planar */
|
||||||
intra_getPlanarPred(rec, recstride, xpos, ypos, width, pred, width);
|
intra_getPlanarPred(rec, recstride, xpos, ypos, width, pred, width);
|
||||||
CHECK_FOR_BEST(0);
|
CHECK_FOR_BEST(0);
|
||||||
|
@ -310,30 +291,16 @@ int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t
|
||||||
/* 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
|
/* Test angular predictions which require filtered samples */
|
||||||
|
|
||||||
//if(xpos && ypos)
|
|
||||||
//for(i = 2; 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)
|
if(MIN(abs(i-26),abs(i-10)) > threshold)
|
||||||
{
|
{
|
||||||
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;
|
||||||
#undef COPY_PRED_TO_DST
|
#undef COPY_PRED_TO_DST
|
||||||
#undef CHECK_FOR_BEST
|
#undef CHECK_FOR_BEST
|
||||||
|
@ -341,13 +308,23 @@ int16_t intra_prediction(uint8_t* orig,uint32_t origstride,int16_t* rec,uint32_t
|
||||||
return bestMode;
|
return bestMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void intra_recon(int16_t* rec,uint32_t recstride, uint32_t xpos, uint32_t ypos,uint32_t width, int16_t* dst,int32_t dststride, int8_t mode)
|
void intra_recon(int16_t* rec,uint32_t recstride, uint32_t xpos, uint32_t ypos,uint32_t width, int16_t* dst,int32_t dststride, int8_t mode, int8_t chroma)
|
||||||
{
|
{
|
||||||
int32_t x,y,i;
|
int32_t x,y,i;
|
||||||
int16_t pred[LCU_WIDTH*LCU_WIDTH>>2];
|
int16_t pred[LCU_WIDTH*LCU_WIDTH>>2];
|
||||||
//int16_t* recShift = &rec[xpos+ypos*recstride];
|
//int16_t* recShift = &rec[xpos+ypos*recstride];
|
||||||
#define COPY_PRED_TO_DST() for(y = 0; y < (int32_t)width; y++) { for(x = 0; x < (int32_t)width; x++) { dst[x+y*dststride] = pred[x+y*width]; } }
|
#define COPY_PRED_TO_DST() for(y = 0; y < (int32_t)width; y++) { for(x = 0; x < (int32_t)width; x++) { dst[x+y*dststride] = pred[x+y*width]; } }
|
||||||
|
|
||||||
|
/* Filtering apply if luma and not DC */
|
||||||
|
if(!chroma && mode != 1/*&& width > 4*/)
|
||||||
|
{
|
||||||
|
uint8_t threshold = intraHorVerDistThres[g_toBits[width]];
|
||||||
|
if(MIN(abs(mode-26),abs(mode-10)) > threshold)
|
||||||
|
{
|
||||||
|
intra_filter(rec,recstride,width,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* planar */
|
/* planar */
|
||||||
if(mode == 0)
|
if(mode == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,7 @@ int16_t intra_getDCPred(int16_t* pic, uint16_t picwidth,uint32_t xpos, uint32_t
|
||||||
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);
|
||||||
void intra_getAngularPred(int16_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(int16_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_recon(int16_t* rec,uint32_t recstride, uint32_t xpos, uint32_t ypos,uint32_t width, int16_t* dst,int32_t dststride, int8_t mode);
|
void intra_recon(int16_t* rec,uint32_t recstride, uint32_t xpos, uint32_t ypos,uint32_t width, int16_t* dst,int32_t dststride, int8_t mode, int8_t chroma);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue