📄 deblock_ref.c
字号:
y = frame->y + buf_width*(buf_height-img_height)/2 + (buf_width-img_width)/2; u = frame->u + buf_width*(buf_height-img_height)/8 + (buf_width-img_width)/4; v = frame->v + buf_width*(buf_height-img_height)/8 + (buf_width-img_width)/4; // Do edges in both directions (d=0: vertical; d=1: horizontal) for (d = 0; d < 2; d++) { int QPyAv = (QPyCurr + ((d == 0) ? QPyLeft : QPyTop) + 1) >> 1; int QPcAv = (QP_TO_CHROMA_MAPPING[QPyCurr] + ((d == 0) ? QP_TO_CHROMA_MAPPING[QPyLeft] : QP_TO_CHROMA_MAPPING[QPyTop]) + 1) >> 1; unsigned char *SrcY = y + (MBy << 4)*(buf_width) + (MBx << 4); unsigned char *SrcU = u + (MBy << 3)*(buf_width >> 1) + (MBx << 3); unsigned char *SrcV = v + (MBy << 3)*(buf_width >> 1) + (MBx << 3); int PtrIncY = ((d == 0) ? buf_width : 1); int IncY = ((d == 0) ? 1 : buf_width); int PtrIncC = ((d == 0) ? (buf_width >> 1) : 1); int IncC = ((d == 0) ? 1 : (buf_width >> 1));#ifdef DEBUG //Store qp_av for debugging // First entry is external qp_av and second is internal qp_av qp_av_ref[(MBy * (img_width>>4) + MBx) * 8 + d * 2] = QPyAv; qp_av_ref[(MBy * (img_width>>4) + MBx) * 8 + d * 2 + 1] = QPyCurr; qp_av_ref[(MBy * (img_width>>4) + MBx) * 8 + 4 + d * 2] = QPcAv; qp_av_ref[(MBy * (img_width>>4) + MBx) * 8 + 4 + d * 2 + 1] = QP_TO_CHROMA_MAPPING[QPyCurr];#endif // Loop over four edges in a MB for (i = 0; i < 4; i++) { int QPy = (i == 0) ? QPyAv : QPyCurr; int QPc = (i == 0) ? QPcAv : QP_TO_CHROMA_MAPPING[QPyCurr]; // Call actual filtering functions#ifdef DEBUG_OUTPUT if (!dbgfile.is_open()) { dbgfile.open(DEBUG_FILENAME, ofstream::out); } if( *((int*)((*BSRef)[d][i])) ) { dbgfile << "Frame: " << frame->info.frame_num << endl; dbgfile << "Macroblock: (" << MBx << ", " << MBy << ")" << endl; dbgfile << "Edge: " << ((d == 0) ? "Vertical" : "Horizontal") << " edge #" << i << endl; dbgfile << "SrcPtrY: " << (unsigned int)(SrcY - frame->y) << endl; dbgfile << "Strength: " << int((*BSRef)[d][i][0]) << ", " << int((*BSRef)[d][i][1]) << ", " << int((*BSRef)[d][i][2]) << ", " << int((*BSRef)[d][i][3]) << endl; dbgfile << "QPy: " << QPy << endl; dbgfile << "PtrIncY: " << PtrIncY << endl; dbgfile << "IncY: " << IncY << endl; }#endif if ( ! (((d == 0) & DontFilterVertEdges) || ((d == 1) & DontFilterHorzEdges))) { EdgeLoopLuma(SrcY, (*BSRef)[d][i], QPy, alpha_c0_offset, beta_offset, PtrIncY, IncY); } SrcY += (IncY << 2); if ((i & 1) == 0) {#ifdef DEBUG_OUTPUT if( *((int*)BSRef[d][i]) ) { dbgfile << "SrcPtrU: " << (unsigned int)(SrcU - frame->u) << endl; dbgfile << "SrcPtrV: " << (unsigned int)(SrcV - frame->v) << endl; dbgfile << "QPc: " << QPc << endl; dbgfile << "PtrIncC: " << PtrIncC << endl; dbgfile << "IncC: " << IncC << endl; }#endif if ( ! (((d == 0) & DontFilterVertEdges) || ((d == 1) & DontFilterHorzEdges))) { EdgeLoopChroma(SrcU, (*BSRef)[d][i], QPc, alpha_c0_offset, beta_offset, PtrIncC, IncC); EdgeLoopChroma(SrcV, (*BSRef)[d][i], QPc, alpha_c0_offset, beta_offset, PtrIncC, IncC); } SrcU += (IncC << 2); SrcV += (IncC << 2); }#ifdef DEBUG_OUTPUT if( *((int*)BSRef[d][i]) ) { dbgfile << endl; }#endif } }}//====================================================================void EdgeLoopLuma//====================================================================// Filters one edge (16 pixels) of luma //--------------------------------------------------------------------( // pointer to the first pixel of the edge, (right or bottom). unsigned char *SrcPtr, // filtering strength, top to bottom for vert. edges and left to // right for horizontal ones unsigned char Strength[4], // quant step int QP, int AlphaC0Offset, int BetaOffset, // pixel offset along the border int PtrInc, // pixel offset across the border int inc )//--------------------------------------------------------------------{ // TODO: This low-level function is largely VSofts code---need to // comment it. int ap, aq, Strng ; int inc2, inc3, inc4 ; int C0, c0, Delta, dif, AbsDelta ; int L2, L1, L0, R0, R1, R2, RL0 ; const unsigned char *ClipTab; int Alpha, Beta; int small_gap; int indexA, indexB; int i,j; inc2 = inc<<1 ; inc3 = inc + inc2 ; inc4 = inc<<2 ; indexA = IClip(0, MAX_QP, QP + AlphaC0Offset); indexB = IClip(0, MAX_QP, QP + BetaOffset); Alpha=ALPHA_TABLE[indexA]; Beta=BETA_TABLE[indexB]; ClipTab=CLIP_TAB[indexA]; for( j=0 ; j<4 ;j++ ) { Strng = Strength[j]; assert(Strng != 0xFF); if (!Strng) { SrcPtr += PtrInc << 2; continue; } for (i=0; i<4; i++) { L0 = SrcPtr [-inc ] ; R0 = SrcPtr [ 0] ; AbsDelta = abs( Delta = R0 - L0 ) ; if( AbsDelta < Alpha ) { C0 = ClipTab[ Strng ] ; L1 = SrcPtr[-inc2] ; R1 = SrcPtr[ inc ] ; if( ((abs( R0 - R1) - Beta ) & (abs(L0 - L1) - Beta )) < 0 ) { L2 = SrcPtr[-inc3] ; R2 = SrcPtr[ inc2] ; aq = (abs( R0 - R2) - Beta ) < 0 ; ap = (abs( L0 - L2) - Beta ) < 0 ; RL0 = L0 + R0 ; if(Strng == 4 ) { // INTRA strong filtering small_gap = (AbsDelta < ((Alpha >> 2) + 2)); aq &= small_gap; ap &= small_gap; if (aq) { SrcPtr[ 0 ] = (unsigned char)(( L1 + ((R1 + RL0) << 1) + SrcPtr[ inc2] + 4) >> 3); SrcPtr[ inc ] = (unsigned char)(( SrcPtr[ inc2] + R0 + R1 + L0 + 2) >> 2); SrcPtr[ inc2] = (unsigned char)((((SrcPtr[ inc3] + SrcPtr[ inc2]) <<1) + SrcPtr[ inc2] + R1 + RL0 + 4) >> 3); } else { SrcPtr[ 0 ] = (unsigned char)(((R1 << 1) + R0 + L1 + 2) >> 2); } if (ap) { SrcPtr[-inc ] = (unsigned char)(( R1 + ((L1 + RL0) << 1) + SrcPtr[-inc3] + 4) >> 3); SrcPtr[-inc2] = (unsigned char)(( SrcPtr[-inc3] + L1 + L0 + R0 + 2) >> 2); SrcPtr[-inc3] = (unsigned char)((((SrcPtr[-inc4] + SrcPtr[-inc3]) <<1) + SrcPtr[-inc3] + L1 + RL0 + 4) >> 3); } else { SrcPtr[-inc ] = (unsigned char)(((L1 << 1) + L0 + R1 + 2) >> 2); } } else { // normal filtering c0 = C0 + ap + aq ; dif = IClip( -c0, c0, ( (Delta << 2) + (L1 - R1) + 4) >> 3 ) ; SrcPtr[ -inc ] = (unsigned char)(CLIP0_255(L0 + dif)); SrcPtr[ 0 ] = (unsigned char)(CLIP0_255(R0 - dif)); if( ap ) SrcPtr[-inc2] += (unsigned char)(IClip( -C0, C0, ( L2 + ((RL0+1) >> 1) - (L1<<1)) >> 1 )); if( aq ) SrcPtr[ inc] += (unsigned char)(IClip( -C0, C0, ( R2 + ((RL0+1) >> 1) - (R1<<1)) >> 1 )); } } } SrcPtr += PtrInc ; // Increment to next set of pixel } }}//====================================================================void EdgeLoopChroma//====================================================================// Filters one edge (8 pixels) of chroma //--------------------------------------------------------------------( // pointer to the first pixel of the edge, (right or bottom). unsigned char* SrcPtr, // filtering strength, top to bottom for vert. edges and left to // right for horizontal ones unsigned char Strength[4], // quant step int QP, int AlphaC0Offset, int BetaOffset, // pixel offset along the border int PtrInc, // pixel offset across the border int inc)//--------------------------------------------------------------------{ // TODO: This low-level function is largely VSofts code---need to // comment it. int Strng ; int inc2=inc<<1; int C0, c0, Delta, dif, AbsDelta ; int L1, L0, R0, R1; const unsigned char *ClipTab; int Alpha, Beta; int indexA, indexB; int i,j; indexA = IClip(0, MAX_QP, QP + AlphaC0Offset); indexB = IClip(0, MAX_QP, QP + BetaOffset); Alpha=ALPHA_TABLE[indexA]; Beta=BETA_TABLE[indexB]; ClipTab=CLIP_TAB[indexA]; for( j=0 ; j<4 ; j++) { Strng = Strength[j]; assert(Strng != 0xFF); if (Strng) { for (i=0; i<2; i++) { L0 = SrcPtr [-inc ] ; R0 = SrcPtr [ 0] ; AbsDelta = abs( Delta = R0 - L0 ) ; if( AbsDelta < Alpha ) { C0 = ClipTab[ Strng ] ; L1 = SrcPtr[-inc2] ; R1 = SrcPtr[ inc ] ; if( ((abs( R0 - R1) - Beta ) & (abs(L0 - L1) - Beta )) < 0 ) { if(Strng == 4 ) { // INTRA strong filtering SrcPtr[ 0 ] = (unsigned char)(((R1 << 1) + R0 + L1 + 2) >> 2); SrcPtr[-inc ] = (unsigned char)(((L1 << 1) + L0 + R1 + 2) >> 2); } else { // normal filtering c0 = C0+1; dif = IClip( -c0, c0, ( (Delta << 2) + (L1 - R1) + 4) >> 3 ) ; SrcPtr[ -inc ] = (unsigned char)(CLIP0_255(L0 + dif)); SrcPtr[ 0 ] = (unsigned char)(CLIP0_255(R0 - dif)); } } } SrcPtr += PtrInc ; // Increment to next set of pixel } } else SrcPtr += PtrInc << 1 ; }}static void pad_deblock_out_frame(yuv_frame_t *Reference, int PadAmount){ int i, j; bool LeftPad, TopPad, RightPad, BottomPad; int ReadX, ReadY, ReadIdx; int WriteIdx; int buf_width = Reference->width; int buf_height = Reference->height; int img_width = Reference->image_width; int img_height = Reference->image_height; char *frame_y = Reference->y; char *frame_u = Reference->u; char *frame_v = Reference->v; assert(2*PadAmount == buf_width - img_width); assert(2*PadAmount == buf_height - img_height); // Pad Y plane for (j = PadAmount; j < (img_height + PadAmount); j++) { memset(frame_y + j * buf_width, frame_y[j*buf_width + PadAmount], PadAmount); memset(frame_y + j * buf_width + img_width + PadAmount, frame_y[j * buf_width + img_width + PadAmount - 1], PadAmount); } for (j = 0; j < PadAmount; j++) { memcpy(frame_y + j * buf_width, frame_y + PadAmount * buf_width, buf_width); } for (j = img_height + PadAmount; j < (img_height + 2*PadAmount); j++) { memcpy(frame_y + j * buf_width, frame_y + (img_height + PadAmount - 1) * buf_width, buf_width); } img_height /= 2; img_width /= 2; buf_height /= 2; buf_width /= 2; PadAmount /= 2; // Pad UV planes for (j = PadAmount; j < (img_height + PadAmount); j++) { memset(frame_u + j * buf_width, frame_u[j*buf_width + PadAmount], PadAmount); memset(frame_u + j * buf_width + img_width + PadAmount, frame_u[j * buf_width + img_width + PadAmount - 1], PadAmount); memset(frame_v + j * buf_width, frame_v[j*buf_width + PadAmount], PadAmount); memset(frame_v + j * buf_width + img_width + PadAmount, frame_v[j * buf_width + img_width + PadAmount - 1], PadAmount); } for (j = 0; j < PadAmount; j++) { memcpy(frame_u + j * buf_width, frame_u + PadAmount * buf_width, buf_width); memcpy(frame_v + j * buf_width, frame_v + PadAmount * buf_width, buf_width); } for (j = img_height + PadAmount; j < (img_height + 2*PadAmount); j++) { memcpy(frame_u + j * buf_width, frame_u + (img_height + PadAmount - 1) * buf_width, buf_width); memcpy(frame_v + j * buf_width, frame_v + (img_height + PadAmount - 1) * buf_width, buf_width); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -