92 #define GET_MODE_BUFFER_SIZE 500
93 #define OPTIONS_ARRAY_SIZE 10
98 #if ARCH_X86 && HAVE_INLINE_ASM
122 {
"dr",
"dering", 1, 5, 6,
DERING},
123 {
"al",
"autolevels", 0, 1, 2,
LEVEL_FIX},
132 {
"be",
"bitexact", 1, 0, 0,
BITEXACT},
139 "default",
"hb:a,vb:a,dr:a",
140 "de",
"hb:a,vb:a,dr:a",
141 "fast",
"h1:a,v1:a,dr:a",
142 "fa",
"h1:a,v1:a,dr:a",
143 "ac",
"ha:a:128:7,va:a,dr:a",
157 const int dcOffset= ((
c->nonBQP*
c->ppMode.baseDcDiff)>>8) + 1;
158 const int dcThreshold= dcOffset*2 + 1;
161 numEq += ((unsigned)(
src[0] -
src[1] + dcOffset)) < dcThreshold;
162 numEq += ((unsigned)(
src[1] -
src[2] + dcOffset)) < dcThreshold;
163 numEq += ((unsigned)(
src[2] -
src[3] + dcOffset)) < dcThreshold;
164 numEq += ((unsigned)(
src[3] -
src[4] + dcOffset)) < dcThreshold;
165 numEq += ((unsigned)(
src[4] -
src[5] + dcOffset)) < dcThreshold;
166 numEq += ((unsigned)(
src[5] -
src[6] + dcOffset)) < dcThreshold;
167 numEq += ((unsigned)(
src[6] -
src[7] + dcOffset)) < dcThreshold;
170 return numEq >
c->ppMode.flatnessThreshold;
180 const int dcOffset= ((
c->nonBQP*
c->ppMode.baseDcDiff)>>8) + 1;
181 const int dcThreshold= dcOffset*2 + 1;
185 numEq += ((unsigned)(
src[0] -
src[0+
stride] + dcOffset)) < dcThreshold;
186 numEq += ((unsigned)(
src[1] -
src[1+
stride] + dcOffset)) < dcThreshold;
187 numEq += ((unsigned)(
src[2] -
src[2+
stride] + dcOffset)) < dcThreshold;
188 numEq += ((unsigned)(
src[3] -
src[3+
stride] + dcOffset)) < dcThreshold;
189 numEq += ((unsigned)(
src[4] -
src[4+
stride] + dcOffset)) < dcThreshold;
190 numEq += ((unsigned)(
src[5] -
src[5+
stride] + dcOffset)) < dcThreshold;
191 numEq += ((unsigned)(
src[6] -
src[6+
stride] + dcOffset)) < dcThreshold;
192 numEq += ((unsigned)(
src[7] -
src[7+
stride] + dcOffset)) < dcThreshold;
195 return numEq >
c->ppMode.flatnessThreshold;
202 if((
unsigned)(
src[0] -
src[5] + 2*
QP) > 4*
QP)
return 0;
204 if((
unsigned)(
src[2] -
src[7] + 2*
QP) > 4*
QP)
return 0;
206 if((
unsigned)(
src[4] -
src[1] + 2*
QP) > 4*
QP)
return 0;
208 if((
unsigned)(
src[6] -
src[3] + 2*
QP) > 4*
QP)
return 0;
249 const int middleEnergy= 5*(dst[4] - dst[3]) + 2*(dst[2] - dst[5]);
251 if(
FFABS(middleEnergy) < 8*
c->QP){
252 const int q=(dst[3] - dst[4])/2;
253 const int leftEnergy= 5*(dst[2] - dst[1]) + 2*(dst[0] - dst[3]);
254 const int rightEnergy= 5*(dst[6] - dst[5]) + 2*(dst[4] - dst[7]);
260 d*=
FFSIGN(-middleEnergy);
288 const int first=
FFABS(dst[-1] - dst[0]) <
c->QP ? dst[-1] : dst[0];
289 const int last=
FFABS(dst[8] - dst[7]) <
c->QP ? dst[8] : dst[7];
292 sums[0] = 4*
first + dst[0] + dst[1] + dst[2] + 4;
293 sums[1] = sums[0] -
first + dst[3];
294 sums[2] = sums[1] -
first + dst[4];
295 sums[3] = sums[2] -
first + dst[5];
296 sums[4] = sums[3] -
first + dst[6];
297 sums[5] = sums[4] - dst[0] + dst[7];
298 sums[6] = sums[5] - dst[1] + last;
299 sums[7] = sums[6] - dst[2] + last;
300 sums[8] = sums[7] - dst[3] + last;
301 sums[9] = sums[8] - dst[4] + last;
303 dst[0]= (sums[0] + sums[2] + 2*dst[0])>>4;
304 dst[1]= (sums[1] + sums[3] + 2*dst[1])>>4;
305 dst[2]= (sums[2] + sums[4] + 2*dst[2])>>4;
306 dst[3]= (sums[3] + sums[5] + 2*dst[3])>>4;
307 dst[4]= (sums[4] + sums[6] + 2*dst[4])>>4;
308 dst[5]= (sums[5] + sums[7] + 2*dst[5])>>4;
309 dst[6]= (sums[6] + sums[8] + 2*dst[6])>>4;
310 dst[7]= (sums[7] + sums[9] + 2*dst[7])>>4;
327 static uint64_t lut[256];
333 int v=
i < 128 ? 2*
i : 2*(
i-256);
342 uint64_t
a= (v/16) & 0xFF;
343 uint64_t
b= (v*3/16) & 0xFF;
344 uint64_t
c= (v*5/16) & 0xFF;
345 uint64_t d= (7*v/16) & 0xFF;
346 uint64_t
A= (0x100 -
a)&0xFF;
347 uint64_t
B= (0x100 -
b)&0xFF;
348 uint64_t
C= (0x100 -
c)&0xFF;
349 uint64_t
D= (0x100 -
c)&0xFF;
351 lut[
i] = (
a<<56) | (
b<<48) | (
c<<40) | (d<<32) |
352 (
D<<24) | (
C<<16) | (
B<<8) | (
A);
386 const int dcOffset= ((
c->nonBQP*
c->ppMode.baseDcDiff)>>8) + 1;
387 const int dcThreshold= dcOffset*2 + 1;
393 numEq += ((unsigned)(
src[-1*
step] -
src[0*
step] + dcOffset)) < dcThreshold;
394 numEq += ((unsigned)(
src[ 0*
step] -
src[1*
step] + dcOffset)) < dcThreshold;
395 numEq += ((unsigned)(
src[ 1*
step] -
src[2*
step] + dcOffset)) < dcThreshold;
396 numEq += ((unsigned)(
src[ 2*
step] -
src[3*
step] + dcOffset)) < dcThreshold;
397 numEq += ((unsigned)(
src[ 3*
step] -
src[4*
step] + dcOffset)) < dcThreshold;
398 numEq += ((unsigned)(
src[ 4*
step] -
src[5*
step] + dcOffset)) < dcThreshold;
399 numEq += ((unsigned)(
src[ 5*
step] -
src[6*
step] + dcOffset)) < dcThreshold;
400 numEq += ((unsigned)(
src[ 6*
step] -
src[7*
step] + dcOffset)) < dcThreshold;
401 numEq += ((unsigned)(
src[ 7*
step] -
src[8*
step] + dcOffset)) < dcThreshold;
402 if(numEq >
c->ppMode.flatnessThreshold){
432 sums[6] = sums[5] -
src[1*
step] + last;
433 sums[7] = sums[6] -
src[2*
step] + last;
434 sums[8] = sums[7] -
src[3*
step] + last;
435 sums[9] = sums[8] -
src[4*
step] + last;
459 if(
FFABS(middleEnergy) < 8*
QP){
468 d*=
FFSIGN(-middleEnergy);
479 d= (d < 0) ? 32 : -32;
497 #define TEMPLATE_PP_C 1
503 # define TEMPLATE_PP_ALTIVEC 1
508 #if ARCH_X86 && HAVE_INLINE_ASM
509 # if CONFIG_RUNTIME_CPUDETECT
510 # define TEMPLATE_PP_SSE2 1
513 # if HAVE_SSE2_INLINE
514 # define TEMPLATE_PP_SSE2 1
520 typedef void (*
pp_fn)(
const uint8_t
src[],
int srcStride, uint8_t dst[],
int dstStride,
int width,
int height,
521 const int8_t QPs[],
int QPStride,
int isColor,
PPContext *
c2);
526 pp_fn pp = postProcess_C;
532 #if CONFIG_RUNTIME_CPUDETECT
533 #if ARCH_X86 && HAVE_INLINE_ASM
541 pp = postProcess_SSE2;
543 pp = postProcess_altivec;
548 pp(
src, srcStride, dst, dstStride,
width,
height, QPs, QPStride, isColor,
c);
554 "Available postprocessing filters:\n"
556 "short long name short long option Description\n"
557 "* * a autoq CPU power dependent enabler\n"
558 " c chrom chrominance filtering enabled\n"
559 " y nochrom chrominance filtering disabled\n"
560 " n noluma luma filtering disabled\n"
561 "hb hdeblock (2 threshold) horizontal deblocking filter\n"
562 " 1. difference factor: default=32, higher -> more deblocking\n"
563 " 2. flatness threshold: default=39, lower -> more deblocking\n"
564 " the h & v deblocking filters share these\n"
565 " so you can't set different thresholds for h / v\n"
566 "vb vdeblock (2 threshold) vertical deblocking filter\n"
567 "ha hadeblock (2 threshold) horizontal deblocking filter\n"
568 "va vadeblock (2 threshold) vertical deblocking filter\n"
569 "h1 x1hdeblock experimental h deblock filter 1\n"
570 "v1 x1vdeblock experimental v deblock filter 1\n"
571 "dr dering deringing filter\n"
572 "al autolevels automatic brightness / contrast\n"
573 " f fullyrange stretch luminance to (0..255)\n"
574 "lb linblenddeint linear blend deinterlacer\n"
575 "li linipoldeint linear interpolating deinterlace\n"
576 "ci cubicipoldeint cubic interpolating deinterlacer\n"
577 "md mediandeint median deinterlacer\n"
578 "fd ffmpegdeint ffmpeg deinterlacer\n"
579 "l5 lowpass5 FIR lowpass deinterlacer\n"
580 "de default hb:a,vb:a,dr:a\n"
581 "fa fast h1:a,v1:a,dr:a\n"
582 "ac ha:a:128:7,va:a,dr:a\n"
583 "tn tmpnoise (3 threshold) temporal noise reducer\n"
584 " 1. <= 2. <= 3. larger -> stronger filtering\n"
585 "fq forceQuant <quantizer> force quantizer\n"
587 "<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]...\n"
588 "long form example:\n"
589 "vdeblock:autoq/hdeblock:autoq/linblenddeint default,-vdeblock\n"
590 "short form example:\n"
591 "vb:a/hb:a/lb de,-vb\n"
601 static const char filterDelimiters[] =
",/";
602 static const char optionDelimiters[] =
":|";
611 if (!strcmp(
name,
"help")) {
613 for (p =
pp_help; strchr(p,
'\n'); p = strchr(p,
'\n') + 1) {
642 const char *filterName;
650 int numOfUnknownOptions=0;
654 filterToken=
av_strtok(p, filterDelimiters, &tokstate);
655 if(!filterToken)
break;
656 p+= strlen(filterToken) + 1;
657 filterName=
av_strtok(filterToken, optionDelimiters, &tokstate);
664 if(*filterName ==
'-'){
675 else if(!strcmp(
"nochrom",
option) || !strcmp(
"y",
option)) chrom=0;
676 else if(!strcmp(
"chrom",
option) || !strcmp(
"c",
option)) chrom=1;
677 else if(!strcmp(
"noluma",
option) || !strcmp(
"n",
option)) luma=0;
680 numOfUnknownOptions++;
696 spaceLeft= p -
temp + plen;
701 memmove(p + newlen, p, plen+1);
708 if( !strcmp(
filters[
i].longName, filterName)
709 || !strcmp(
filters[
i].shortName, filterName)){
716 if(q >=
filters[
i].minLumQuality && luma)
718 if(chrom==1 || (chrom==-1 &&
filters[
i].chromDefault))
727 if( !strcmp(
options[o],
"fullyrange")
731 numOfUnknownOptions--;
746 numOfUnknownOptions--;
747 if(numOfNoises >= 3)
break;
755 for(o=0;
options[o] && o<2; o++){
760 numOfUnknownOptions--;
769 for(o=0;
options[o] && o<1; o++){
774 numOfUnknownOptions--;
780 if(!filterNameOk) ppMode->
error++;
781 ppMode->
error += numOfUnknownOptions;
803 int mbWidth = (
width+15)>>4;
804 int mbHeight= (
height+15)>>4;
808 c->qpStride= qpStride;
824 reallocAlign((
void **)&
c->nonBQPTable, qpStride*mbHeight*
sizeof(int8_t));
825 reallocAlign((
void **)&
c->stdQPTable, qpStride*mbHeight*
sizeof(int8_t));
826 reallocAlign((
void **)&
c->forcedQPTable, mbWidth*
sizeof(int8_t));
838 int qpStride= (
width+15)/16 + 2;
845 c->hChromaSubSample= cpuCaps&0x3;
846 c->vChromaSubSample= (cpuCaps>>4)&0x3;
848 c->hChromaSubSample= 1;
849 c->vChromaSubSample= 1;
889 uint8_t * dst[3],
const int dstStride[3],
891 const int8_t *QP_store,
int QPStride,
892 pp_mode *vm,
void *vc,
int pict_type)
894 int mbWidth = (
width+15)>>4;
895 int mbHeight= (
height+15)>>4;
899 int absQPStride =
FFABS(QPStride);
902 if(
c->stride < minStride ||
c->qpStride < absQPStride)
904 FFMAX(minStride,
c->stride),
905 FFMAX(
c->qpStride, absQPStride));
909 QP_store=
c->forcedQPTable;
910 absQPStride = QPStride = 0;
912 for(
i=0;
i<mbWidth;
i++)
c->forcedQPTable[
i]=
mode->forcedQuant;
914 for(
i=0;
i<mbWidth;
i++)
c->forcedQPTable[
i]= 1;
919 const int count=
FFMAX(mbHeight * absQPStride, mbWidth);
920 for(
i=0;
i<(count>>2);
i++){
923 for(
i<<=2;
i<count;
i++){
924 c->stdQPTable[
i] = QP_store[
i]>>1;
926 QP_store=
c->stdQPTable;
927 QPStride= absQPStride;
932 for(y=0; y<mbHeight; y++){
933 for(x=0; x<mbWidth; x++){
941 if((pict_type&7)!=3){
944 const int count=
FFMAX(mbHeight * QPStride, mbWidth);
945 for(
i=0;
i<(count>>2);
i++){
948 for(
i<<=2;
i<count;
i++){
949 c->nonBQPTable[
i] = QP_store[
i] & 0x3F;
953 for(
i=0;
i<mbHeight;
i++) {
954 for(j=0; j<absQPStride; j++) {
955 c->nonBQPTable[
i*absQPStride+j] = QP_store[
i*QPStride+j] & 0x3F;
967 if (!(
src[1] &&
src[2] && dst[1] && dst[2]))
979 else if(srcStride[1] == dstStride[1] && srcStride[2] == dstStride[2]){
985 memcpy(&(dst[1][y*dstStride[1]]), &(
src[1][y*srcStride[1]]),
width);
986 memcpy(&(dst[2][y*dstStride[2]]), &(
src[2][y*srcStride[2]]),
width);