95 #define GET_MODE_BUFFER_SIZE 500
96 #define OPTIONS_ARRAY_SIZE 10
101 #if ARCH_X86 && HAVE_INLINE_ASM
125 {
"dr",
"dering", 1, 5, 6,
DERING},
126 {
"al",
"autolevels", 0, 1, 2,
LEVEL_FIX},
135 {
"be",
"bitexact", 1, 0, 0,
BITEXACT},
142 "default",
"hb:a,vb:a,dr:a",
143 "de",
"hb:a,vb:a,dr:a",
144 "fast",
"h1:a,v1:a,dr:a",
145 "fa",
"h1:a,v1:a,dr:a",
146 "ac",
"ha:a:128:7,va:a,dr:a",
160 const int dcOffset= ((
c->nonBQP*
c->ppMode.baseDcDiff)>>8) + 1;
161 const int dcThreshold= dcOffset*2 + 1;
164 numEq += ((unsigned)(
src[0] -
src[1] + dcOffset)) < dcThreshold;
165 numEq += ((unsigned)(
src[1] -
src[2] + dcOffset)) < dcThreshold;
166 numEq += ((unsigned)(
src[2] -
src[3] + dcOffset)) < dcThreshold;
167 numEq += ((unsigned)(
src[3] -
src[4] + dcOffset)) < dcThreshold;
168 numEq += ((unsigned)(
src[4] -
src[5] + dcOffset)) < dcThreshold;
169 numEq += ((unsigned)(
src[5] -
src[6] + dcOffset)) < dcThreshold;
170 numEq += ((unsigned)(
src[6] -
src[7] + dcOffset)) < dcThreshold;
173 return numEq >
c->ppMode.flatnessThreshold;
183 const int dcOffset= ((
c->nonBQP*
c->ppMode.baseDcDiff)>>8) + 1;
184 const int dcThreshold= dcOffset*2 + 1;
188 numEq += ((unsigned)(
src[0] -
src[0+
stride] + dcOffset)) < dcThreshold;
189 numEq += ((unsigned)(
src[1] -
src[1+
stride] + dcOffset)) < dcThreshold;
190 numEq += ((unsigned)(
src[2] -
src[2+
stride] + dcOffset)) < dcThreshold;
191 numEq += ((unsigned)(
src[3] -
src[3+
stride] + dcOffset)) < dcThreshold;
192 numEq += ((unsigned)(
src[4] -
src[4+
stride] + dcOffset)) < dcThreshold;
193 numEq += ((unsigned)(
src[5] -
src[5+
stride] + dcOffset)) < dcThreshold;
194 numEq += ((unsigned)(
src[6] -
src[6+
stride] + dcOffset)) < dcThreshold;
195 numEq += ((unsigned)(
src[7] -
src[7+
stride] + dcOffset)) < dcThreshold;
198 return numEq >
c->ppMode.flatnessThreshold;
205 if((
unsigned)(
src[0] -
src[5] + 2*
QP) > 4*
QP)
return 0;
207 if((
unsigned)(
src[2] -
src[7] + 2*
QP) > 4*
QP)
return 0;
209 if((
unsigned)(
src[4] -
src[1] + 2*
QP) > 4*
QP)
return 0;
211 if((
unsigned)(
src[6] -
src[3] + 2*
QP) > 4*
QP)
return 0;
252 const int middleEnergy= 5*(dst[4] - dst[3]) + 2*(dst[2] - dst[5]);
254 if(
FFABS(middleEnergy) < 8*
c->QP){
255 const int q=(dst[3] - dst[4])/2;
256 const int leftEnergy= 5*(dst[2] - dst[1]) + 2*(dst[0] - dst[3]);
257 const int rightEnergy= 5*(dst[6] - dst[5]) + 2*(dst[4] - dst[7]);
291 const int first=
FFABS(dst[-1] - dst[0]) <
c->QP ? dst[-1] : dst[0];
292 const int last=
FFABS(dst[8] - dst[7]) <
c->QP ? dst[8] : dst[7];
295 sums[0] = 4*
first + dst[0] + dst[1] + dst[2] + 4;
296 sums[1] = sums[0] -
first + dst[3];
297 sums[2] = sums[1] -
first + dst[4];
298 sums[3] = sums[2] -
first + dst[5];
299 sums[4] = sums[3] -
first + dst[6];
300 sums[5] = sums[4] - dst[0] + dst[7];
301 sums[6] = sums[5] - dst[1] + last;
302 sums[7] = sums[6] - dst[2] + last;
303 sums[8] = sums[7] - dst[3] + last;
304 sums[9] = sums[8] - dst[4] + last;
306 dst[0]= (sums[0] + sums[2] + 2*dst[0])>>4;
307 dst[1]= (sums[1] + sums[3] + 2*dst[1])>>4;
308 dst[2]= (sums[2] + sums[4] + 2*dst[2])>>4;
309 dst[3]= (sums[3] + sums[5] + 2*dst[3])>>4;
310 dst[4]= (sums[4] + sums[6] + 2*dst[4])>>4;
311 dst[5]= (sums[5] + sums[7] + 2*dst[5])>>4;
312 dst[6]= (sums[6] + sums[8] + 2*dst[6])>>4;
313 dst[7]= (sums[7] + sums[9] + 2*dst[7])>>4;
330 static uint64_t lut[256];
336 int v=
i < 128 ? 2*
i : 2*(
i-256);
345 uint64_t
a= (v/16) & 0xFF;
346 uint64_t
b= (v*3/16) & 0xFF;
347 uint64_t
c= (v*5/16) & 0xFF;
348 uint64_t
d= (7*v/16) & 0xFF;
349 uint64_t
A= (0x100 -
a)&0xFF;
350 uint64_t
B= (0x100 -
b)&0xFF;
351 uint64_t
C= (0x100 -
c)&0xFF;
352 uint64_t
D= (0x100 -
c)&0xFF;
354 lut[
i] = (
a<<56) | (
b<<48) | (
c<<40) | (
d<<32) |
355 (
D<<24) | (
C<<16) | (
B<<8) | (
A);
389 const int dcOffset= ((
c->nonBQP*
c->ppMode.baseDcDiff)>>8) + 1;
390 const int dcThreshold= dcOffset*2 + 1;
396 numEq += ((unsigned)(
src[-1*
step] -
src[0*
step] + dcOffset)) < dcThreshold;
397 numEq += ((unsigned)(
src[ 0*
step] -
src[1*
step] + dcOffset)) < dcThreshold;
398 numEq += ((unsigned)(
src[ 1*
step] -
src[2*
step] + dcOffset)) < dcThreshold;
399 numEq += ((unsigned)(
src[ 2*
step] -
src[3*
step] + dcOffset)) < dcThreshold;
400 numEq += ((unsigned)(
src[ 3*
step] -
src[4*
step] + dcOffset)) < dcThreshold;
401 numEq += ((unsigned)(
src[ 4*
step] -
src[5*
step] + dcOffset)) < dcThreshold;
402 numEq += ((unsigned)(
src[ 5*
step] -
src[6*
step] + dcOffset)) < dcThreshold;
403 numEq += ((unsigned)(
src[ 6*
step] -
src[7*
step] + dcOffset)) < dcThreshold;
404 numEq += ((unsigned)(
src[ 7*
step] -
src[8*
step] + dcOffset)) < dcThreshold;
405 if(numEq >
c->ppMode.flatnessThreshold){
435 sums[6] = sums[5] -
src[1*
step] + last;
436 sums[7] = sums[6] -
src[2*
step] + last;
437 sums[8] = sums[7] -
src[3*
step] + last;
438 sums[9] = sums[8] -
src[4*
step] + last;
462 if(
FFABS(middleEnergy) < 8*
QP){
482 d= (
d < 0) ? 32 : -32;
500 #define TEMPLATE_PP_C 1
504 # define TEMPLATE_PP_ALTIVEC 1
509 #if ARCH_X86 && HAVE_INLINE_ASM
510 # if CONFIG_RUNTIME_CPUDETECT
511 # define TEMPLATE_PP_MMX 1
513 # define TEMPLATE_PP_MMXEXT 1
515 # define TEMPLATE_PP_3DNOW 1
517 # define TEMPLATE_PP_SSE2 1
520 # if HAVE_SSE2_INLINE
521 # define TEMPLATE_PP_SSE2 1
523 # elif HAVE_MMXEXT_INLINE
524 # define TEMPLATE_PP_MMXEXT 1
526 # elif HAVE_AMD3DNOW_INLINE
527 # define TEMPLATE_PP_3DNOW 1
529 # elif HAVE_MMX_INLINE
530 # define TEMPLATE_PP_MMX 1
536 typedef void (*
pp_fn)(
const uint8_t
src[],
int srcStride, uint8_t dst[],
int dstStride,
int width,
int height,
537 const int8_t QPs[],
int QPStride,
int isColor,
PPContext *
c2);
542 pp_fn pp = postProcess_C;
548 #if CONFIG_RUNTIME_CPUDETECT
549 #if ARCH_X86 && HAVE_INLINE_ASM
560 pp = postProcess_SSE2;
561 #elif HAVE_MMXEXT_INLINE
562 pp = postProcess_MMX2;
563 #elif HAVE_AMD3DNOW_INLINE
564 pp = postProcess_3DNow;
565 #elif HAVE_MMX_INLINE
566 pp = postProcess_MMX;
568 pp = postProcess_altivec;
573 pp(
src, srcStride, dst, dstStride,
width,
height, QPs, QPStride, isColor,
c);
579 "Available postprocessing filters:\n"
581 "short long name short long option Description\n"
582 "* * a autoq CPU power dependent enabler\n"
583 " c chrom chrominance filtering enabled\n"
584 " y nochrom chrominance filtering disabled\n"
585 " n noluma luma filtering disabled\n"
586 "hb hdeblock (2 threshold) horizontal deblocking filter\n"
587 " 1. difference factor: default=32, higher -> more deblocking\n"
588 " 2. flatness threshold: default=39, lower -> more deblocking\n"
589 " the h & v deblocking filters share these\n"
590 " so you can't set different thresholds for h / v\n"
591 "vb vdeblock (2 threshold) vertical deblocking filter\n"
592 "ha hadeblock (2 threshold) horizontal deblocking filter\n"
593 "va vadeblock (2 threshold) vertical deblocking filter\n"
594 "h1 x1hdeblock experimental h deblock filter 1\n"
595 "v1 x1vdeblock experimental v deblock filter 1\n"
596 "dr dering deringing filter\n"
597 "al autolevels automatic brightness / contrast\n"
598 " f fullyrange stretch luminance to (0..255)\n"
599 "lb linblenddeint linear blend deinterlacer\n"
600 "li linipoldeint linear interpolating deinterlace\n"
601 "ci cubicipoldeint cubic interpolating deinterlacer\n"
602 "md mediandeint median deinterlacer\n"
603 "fd ffmpegdeint ffmpeg deinterlacer\n"
604 "l5 lowpass5 FIR lowpass deinterlacer\n"
605 "de default hb:a,vb:a,dr:a\n"
606 "fa fast h1:a,v1:a,dr:a\n"
607 "ac ha:a:128:7,va:a,dr:a\n"
608 "tn tmpnoise (3 threshold) temporal noise reducer\n"
609 " 1. <= 2. <= 3. larger -> stronger filtering\n"
610 "fq forceQuant <quantizer> force quantizer\n"
612 "<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]...\n"
613 "long form example:\n"
614 "vdeblock:autoq/hdeblock:autoq/linblenddeint default,-vdeblock\n"
615 "short form example:\n"
616 "vb:a/hb:a/lb de,-vb\n"
626 static const char filterDelimiters[] =
",/";
627 static const char optionDelimiters[] =
":|";
636 if (!strcmp(
name,
"help")) {
638 for (p =
pp_help; strchr(p,
'\n'); p = strchr(p,
'\n') + 1) {
667 const char *filterName;
675 int numOfUnknownOptions=0;
679 filterToken=
av_strtok(p, filterDelimiters, &tokstate);
680 if(!filterToken)
break;
681 p+= strlen(filterToken) + 1;
682 filterName=
av_strtok(filterToken, optionDelimiters, &tokstate);
689 if(*filterName ==
'-'){
700 else if(!strcmp(
"nochrom",
option) || !strcmp(
"y",
option)) chrom=0;
701 else if(!strcmp(
"chrom",
option) || !strcmp(
"c",
option)) chrom=1;
702 else if(!strcmp(
"noluma",
option) || !strcmp(
"n",
option)) luma=0;
705 numOfUnknownOptions++;
721 spaceLeft= p -
temp + plen;
726 memmove(p + newlen, p, plen+1);
733 if( !strcmp(
filters[
i].longName, filterName)
734 || !strcmp(
filters[
i].shortName, filterName)){
741 if(q >=
filters[
i].minLumQuality && luma)
743 if(chrom==1 || (chrom==-1 &&
filters[
i].chromDefault))
752 if( !strcmp(
options[o],
"fullyrange")
756 numOfUnknownOptions--;
771 numOfUnknownOptions--;
772 if(numOfNoises >= 3)
break;
780 for(o=0;
options[o] && o<2; o++){
785 numOfUnknownOptions--;
794 for(o=0;
options[o] && o<1; o++){
799 numOfUnknownOptions--;
805 if(!filterNameOk) ppMode->
error++;
806 ppMode->
error += numOfUnknownOptions;
828 int mbWidth = (
width+15)>>4;
829 int mbHeight= (
height+15)>>4;
833 c->qpStride= qpStride;
849 reallocAlign((
void **)&
c->nonBQPTable, qpStride*mbHeight*
sizeof(int8_t));
850 reallocAlign((
void **)&
c->stdQPTable, qpStride*mbHeight*
sizeof(int8_t));
851 reallocAlign((
void **)&
c->forcedQPTable, mbWidth*
sizeof(int8_t));
863 int qpStride= (
width+15)/16 + 2;
870 c->hChromaSubSample= cpuCaps&0x3;
871 c->vChromaSubSample= (cpuCaps>>4)&0x3;
873 c->hChromaSubSample= 1;
874 c->vChromaSubSample= 1;
917 uint8_t * dst[3],
const int dstStride[3],
919 const int8_t *QP_store,
int QPStride,
920 pp_mode *vm,
void *vc,
int pict_type)
922 int mbWidth = (
width+15)>>4;
923 int mbHeight= (
height+15)>>4;
927 int absQPStride =
FFABS(QPStride);
930 if(
c->stride < minStride ||
c->qpStride < absQPStride)
932 FFMAX(minStride,
c->stride),
933 FFMAX(
c->qpStride, absQPStride));
937 QP_store=
c->forcedQPTable;
938 absQPStride = QPStride = 0;
940 for(
i=0;
i<mbWidth;
i++)
c->forcedQPTable[
i]=
mode->forcedQuant;
942 for(
i=0;
i<mbWidth;
i++)
c->forcedQPTable[
i]= 1;
947 const int count=
FFMAX(mbHeight * absQPStride, mbWidth);
948 for(
i=0;
i<(count>>2);
i++){
951 for(
i<<=2;
i<count;
i++){
952 c->stdQPTable[
i] = QP_store[
i]>>1;
954 QP_store=
c->stdQPTable;
955 QPStride= absQPStride;
960 for(y=0; y<mbHeight; y++){
961 for(x=0; x<mbWidth; x++){
969 if((pict_type&7)!=3){
972 const int count=
FFMAX(mbHeight * QPStride, mbWidth);
973 for(
i=0;
i<(count>>2);
i++){
976 for(
i<<=2;
i<count;
i++){
977 c->nonBQPTable[
i] = QP_store[
i] & 0x3F;
981 for(
i=0;
i<mbHeight;
i++) {
982 for(j=0; j<absQPStride; j++) {
983 c->nonBQPTable[
i*absQPStride+j] = QP_store[
i*QPStride+j] & 0x3F;
995 if (!(
src[1] &&
src[2] && dst[1] && dst[2]))
1001 if(
mode->chromMode){
1007 else if(srcStride[1] == dstStride[1] && srcStride[2] == dstStride[2]){
1013 memcpy(&(dst[1][y*dstStride[1]]), &(
src[1][y*srcStride[1]]),
width);
1014 memcpy(&(dst[2][y*dstStride[2]]), &(
src[2][y*srcStride[2]]),
width);