[SCM] libav/experimental: accurate/slow (per line instead of per block) deblock filter spport which is identical to what is recommanded in the mpeg4 spec
siretart at users.alioth.debian.org
siretart at users.alioth.debian.org
Sun Jun 30 15:40:29 UTC 2013
The following commit has been merged in the experimental branch:
commit 12eebd26ae209fe8eec06011f06b1f8a21f4ba11
Author: Michael Niedermayer <michaelni at gmx.at>
Date: Thu May 27 15:57:20 2004 +0000
accurate/slow (per line instead of per block) deblock filter spport which is identical to what is recommanded in the mpeg4 spec
Originally committed as revision 3163 to svn://svn.ffmpeg.org/ffmpeg/trunk
diff --git a/libavcodec/libpostproc/postprocess.c b/libavcodec/libpostproc/postprocess.c
index a03ff13..b7ffadb 100644
--- a/libavcodec/libpostproc/postprocess.c
+++ b/libavcodec/libpostproc/postprocess.c
@@ -108,8 +108,10 @@ try to unroll inner for(x=0 ... loop to avoid these damn if(x ... checks
#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
# define attribute_used __attribute__((used))
+# define always_inline __attribute__((always_inline)) inline
#else
# define attribute_used
+# define always_inline inline
#endif
#ifdef ARCH_X86
@@ -122,7 +124,6 @@ static uint64_t __attribute__((aligned(8))) attribute_used b08= 0x080808080808
static uint64_t __attribute__((aligned(8))) attribute_used b80= 0x8080808080808080LL;
#endif
-
static uint8_t clip_table[3*256];
static uint8_t * const clip_tab= clip_table + 256;
@@ -139,6 +140,8 @@ static struct PPFilter filters[]=
{"vr", "rkvdeblock", 1, 2, 4, V_RK1_FILTER},*/
{"h1", "x1hdeblock", 1, 1, 3, H_X1_FILTER},
{"v1", "x1vdeblock", 1, 2, 4, V_X1_FILTER},
+ {"ha", "ahdeblock", 1, 1, 3, H_A_DEBLOCK},
+ {"va", "avdeblock", 1, 2, 4, V_A_DEBLOCK},
{"dr", "dering", 1, 5, 6, DERING},
{"al", "autolevels", 0, 1, 2, LEVEL_FIX},
{"lb", "linblenddeint", 1, 1, 4, LINEAR_BLEND_DEINT_FILTER},
@@ -154,10 +157,11 @@ static struct PPFilter filters[]=
static char *replaceTable[]=
{
- "default", "hdeblock:a,vdeblock:a,dering:a,autolevels,tmpnoise:a:150:200:400",
- "de", "hdeblock:a,vdeblock:a,dering:a,autolevels,tmpnoise:a:150:200:400",
- "fast", "x1hdeblock:a,x1vdeblock:a,dering:a,autolevels,tmpnoise:a:150:200:400",
- "fa", "x1hdeblock:a,x1vdeblock:a,dering:a,autolevels,tmpnoise:a:150:200:400",
+ "default", "hdeblock:a,vdeblock:a,dering:a",
+ "de", "hdeblock:a,vdeblock:a,dering:a",
+ "fast", "x1hdeblock:a,x1vdeblock:a,dering:a",
+ "fa", "x1hdeblock:a,x1vdeblock:a,dering:a",
+ "ac", "ha:a:128:7,va:a,dering:a",
NULL //End Marker
};
@@ -469,6 +473,111 @@ static inline void horizX1Filter(uint8_t *src, int stride, int QP)
}
}
+/**
+ * accurate deblock filter
+ */
+static always_inline void do_a_deblock(uint8_t *src, int step, int stride, PPContext *c){
+ int y;
+ const int QP= c->QP;
+ const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1;
+ const int dcThreshold= dcOffset*2 + 1;
+//START_TIMER
+ src+= step*4; // src points to begin of the 8x8 Block
+ for(y=0; y<8; y++){
+ int numEq= 0;
+
+ if(((unsigned)(src[-1*step] - src[0*step] + dcOffset)) < dcThreshold) numEq++;
+ if(((unsigned)(src[ 0*step] - src[1*step] + dcOffset)) < dcThreshold) numEq++;
+ if(((unsigned)(src[ 1*step] - src[2*step] + dcOffset)) < dcThreshold) numEq++;
+ if(((unsigned)(src[ 2*step] - src[3*step] + dcOffset)) < dcThreshold) numEq++;
+ if(((unsigned)(src[ 3*step] - src[4*step] + dcOffset)) < dcThreshold) numEq++;
+ if(((unsigned)(src[ 4*step] - src[5*step] + dcOffset)) < dcThreshold) numEq++;
+ if(((unsigned)(src[ 5*step] - src[6*step] + dcOffset)) < dcThreshold) numEq++;
+ if(((unsigned)(src[ 6*step] - src[7*step] + dcOffset)) < dcThreshold) numEq++;
+ if(((unsigned)(src[ 7*step] - src[8*step] + dcOffset)) < dcThreshold) numEq++;
+ if(numEq > c->ppMode.flatnessThreshold){
+ int min, max, x;
+
+ if(src[0] > src[step]){
+ max= src[0];
+ min= src[step];
+ }else{
+ max= src[step];
+ min= src[0];
+ }
+ for(x=2; x<8; x+=2){
+ if(src[x*step] > src[(x+1)*step]){
+ if(src[x *step] > max) max= src[ x *step];
+ if(src[(x+1)*step] < min) min= src[(x+1)*step];
+ }else{
+ if(src[(x+1)*step] > max) max= src[(x+1)*step];
+ if(src[ x *step] < min) min= src[ x *step];
+ }
+ }
+ if(max-min < 2*QP){
+ const int first= ABS(src[-1*step] - src[0]) < QP ? src[-1*step] : src[0];
+ const int last= ABS(src[8*step] - src[7*step]) < QP ? src[8*step] : src[7*step];
+
+ int sums[10];
+ sums[0] = 4*first + src[0*step] + src[1*step] + src[2*step] + 4;
+ sums[1] = sums[0] - first + src[3*step];
+ sums[2] = sums[1] - first + src[4*step];
+ sums[3] = sums[2] - first + src[5*step];
+ sums[4] = sums[3] - first + src[6*step];
+ sums[5] = sums[4] - src[0*step] + src[7*step];
+ sums[6] = sums[5] - src[1*step] + last;
+ sums[7] = sums[6] - src[2*step] + last;
+ sums[8] = sums[7] - src[3*step] + last;
+ sums[9] = sums[8] - src[4*step] + last;
+
+ src[0*step]= (sums[0] + sums[2] + 2*src[0*step])>>4;
+ src[1*step]= (sums[1] + sums[3] + 2*src[1*step])>>4;
+ src[2*step]= (sums[2] + sums[4] + 2*src[2*step])>>4;
+ src[3*step]= (sums[3] + sums[5] + 2*src[3*step])>>4;
+ src[4*step]= (sums[4] + sums[6] + 2*src[4*step])>>4;
+ src[5*step]= (sums[5] + sums[7] + 2*src[5*step])>>4;
+ src[6*step]= (sums[6] + sums[8] + 2*src[6*step])>>4;
+ src[7*step]= (sums[7] + sums[9] + 2*src[7*step])>>4;
+ }
+ }else{
+ const int middleEnergy= 5*(src[4*step] - src[3*step]) + 2*(src[2*step] - src[5*step]);
+
+ if(ABS(middleEnergy) < 8*QP)
+ {
+ const int q=(src[3*step] - src[4*step])/2;
+ const int leftEnergy= 5*(src[2*step] - src[1*step]) + 2*(src[0*step] - src[3*step]);
+ const int rightEnergy= 5*(src[6*step] - src[5*step]) + 2*(src[4*step] - src[7*step]);
+
+ int d= ABS(middleEnergy) - MIN( ABS(leftEnergy), ABS(rightEnergy) );
+ d= MAX(d, 0);
+
+ d= (5*d + 32) >> 6;
+ d*= SIGN(-middleEnergy);
+
+ if(q>0)
+ {
+ d= d<0 ? 0 : d;
+ d= d>q ? q : d;
+ }
+ else
+ {
+ d= d>0 ? 0 : d;
+ d= d<q ? q : d;
+ }
+
+ src[3*step]-= d;
+ src[4*step]+= d;
+ }
+ }
+
+ src += stride;
+ }
+/*if(step==16){
+ STOP_TIMER("step16")
+}else{
+ STOP_TIMER("stepX")
+}*/
+}
//Note: we have C, MMX, MMX2, 3DNOW version there is no 3DNOW+MMX2 one
//Plain C versions
@@ -632,6 +741,8 @@ char *pp_help=
" the h & v deblocking filters share these\n"
" so you can't set different thresholds for h / v\n"
"vb vdeblock (2 threshold) vertical deblocking filter\n"
+"ha hadeblock (2 threshold) horizontal deblocking filter\n"
+"va vadeblock (2 threshold) vertical deblocking filter\n"
"h1 x1hdeblock experimental h deblock filter 1\n"
"v1 x1vdeblock experimental v deblock filter 1\n"
"dr dering deringing filter\n"
@@ -642,8 +753,8 @@ char *pp_help=
"ci cubicipoldeint cubic interpolating deinterlacer\n"
"md mediandeint median deinterlacer\n"
"fd ffmpegdeint ffmpeg deinterlacer\n"
-"de default hb:a,vb:a,dr:a,al\n"
-"fa fast h1:a,v1:a,dr:a,al\n"
+"de default hb:a,vb:a,dr:a\n"
+"fa fast h1:a,v1:a,dr:a\n"
"tn tmpnoise (3 threshold) temporal noise reducer\n"
" 1. <= 2. <= 3. larger -> stronger filtering\n"
"fq forceQuant <quantizer> force quantizer\n"
@@ -793,7 +904,8 @@ pp_mode_t *pp_get_mode_by_name_and_quality(char *name, int quality)
}
}
}
- else if(filters[i].mask == V_DEBLOCK || filters[i].mask == H_DEBLOCK)
+ else if(filters[i].mask == V_DEBLOCK || filters[i].mask == H_DEBLOCK
+ || filters[i].mask == V_A_DEBLOCK || filters[i].mask == H_A_DEBLOCK)
{
int o;
diff --git a/libavcodec/libpostproc/postprocess_internal.h b/libavcodec/libpostproc/postprocess_internal.h
index db50fa3..3d6728e 100644
--- a/libavcodec/libpostproc/postprocess_internal.h
+++ b/libavcodec/libpostproc/postprocess_internal.h
@@ -37,9 +37,11 @@
// Experimental vertical filters
#define V_X1_FILTER 0x0200 // 512
+#define V_A_DEBLOCK 0x0400
// Experimental horizontal filters
#define H_X1_FILTER 0x2000 // 8192
+#define H_A_DEBLOCK 0x4000
/// select between full y range (255-0) or standart one (234-16)
#define FULL_Y_RANGE 0x8000 // 32768
diff --git a/libavcodec/libpostproc/postprocess_template.c b/libavcodec/libpostproc/postprocess_template.c
index 4e81bd5..0a8d8e2 100644
--- a/libavcodec/libpostproc/postprocess_template.c
+++ b/libavcodec/libpostproc/postprocess_template.c
@@ -2814,7 +2814,8 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int
|| (mode & LOWPASS5_DEINT_FILTER)) copyAhead=14;
else if( (mode & V_DEBLOCK)
|| (mode & LINEAR_IPOL_DEINT_FILTER)
- || (mode & MEDIAN_DEINT_FILTER)) copyAhead=13;
+ || (mode & MEDIAN_DEINT_FILTER)
+ || (mode & V_A_DEBLOCK)) copyAhead=13;
else if(mode & V_X1_FILTER) copyAhead=11;
// else if(mode & V_RK1_FILTER) copyAhead=10;
else if(mode & DERING) copyAhead=9;
@@ -3110,6 +3111,8 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int
RENAME(doVertLowPass)(dstBlock, stride, &c);
else if(t==2)
RENAME(doVertDefFilter)(dstBlock, stride, &c);
+ }else if(mode & V_A_DEBLOCK){
+ do_a_deblock(dstBlock, stride, 1, &c);
}
}
@@ -3131,6 +3134,8 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int
RENAME(doVertLowPass)(tempBlock1, 16, &c);
else if(t==2)
RENAME(doVertDefFilter)(tempBlock1, 16, &c);
+ }else if(mode & H_A_DEBLOCK){
+ do_a_deblock(tempBlock1, 16, 1, &c);
}
RENAME(transpose2)(dstBlock-4, dstStride, tempBlock1 + 4*16);
@@ -3146,6 +3151,8 @@ static void RENAME(postProcess)(uint8_t src[], int srcStride, uint8_t dst[], int
RENAME(doHorizLowPass)(dstBlock-4, stride, &c);
else if(t==2)
RENAME(doHorizDefFilter)(dstBlock-4, stride, &c);
+ }else if(mode & H_A_DEBLOCK){
+ do_a_deblock(dstBlock-8, 1, stride, &c);
}
#endif
if(mode & DERING)
--
Libav/FFmpeg packaging
More information about the pkg-multimedia-commits
mailing list