Fixed intra filtering process for future use-cases

This commit is contained in:
Marko Viitanen 2013-03-19 17:12:43 +02:00
parent 73d6ed2ff3
commit ff5652609e
4 changed files with 41 additions and 103 deletions

View file

@ -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);

View file

@ -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

View file

@ -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)
{ {

View file

@ -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