100 return FFMPEG_CONFIGURATION;
105 #define LICENSE_PREFIX "libpostproc license: "
113 #define GET_MODE_BUFFER_SIZE 500
114 #define OPTIONS_ARRAY_SIZE 10
116 #define TEMP_STRIDE 8
119 #if ARCH_X86 && HAVE_INLINE_ASM
143 {
"dr",
"dering", 1, 5, 6,
DERING},
144 {
"al",
"autolevels", 0, 1, 2,
LEVEL_FIX},
153 {
"be",
"bitexact", 1, 0, 0,
BITEXACT},
160 "default",
"hb:a,vb:a,dr:a",
161 "de",
"hb:a,vb:a,dr:a",
162 "fast",
"h1:a,v1:a,dr:a",
163 "fa",
"h1:a,v1:a,dr:a",
164 "ac",
"ha:a:128:7,va:a,dr:a",
169 #if ARCH_X86 && HAVE_INLINE_ASM
170 static inline void prefetchnta(
const void *p)
172 __asm__
volatile(
"prefetchnta (%0)\n\t"
177 static inline void prefetcht0(
const void *p)
179 __asm__
volatile(
"prefetcht0 (%0)\n\t"
184 static inline void prefetcht1(
const void *p)
186 __asm__
volatile(
"prefetcht1 (%0)\n\t"
191 static inline void prefetcht2(
const void *p)
193 __asm__
volatile(
"prefetcht2 (%0)\n\t"
210 const int dcThreshold= dcOffset*2 + 1;
213 numEq += ((unsigned)(src[0] - src[1] + dcOffset)) < dcThreshold;
214 numEq += ((unsigned)(src[1] - src[2] + dcOffset)) < dcThreshold;
215 numEq += ((unsigned)(src[2] - src[3] + dcOffset)) < dcThreshold;
216 numEq += ((unsigned)(src[3] - src[4] + dcOffset)) < dcThreshold;
217 numEq += ((unsigned)(src[4] - src[5] + dcOffset)) < dcThreshold;
218 numEq += ((unsigned)(src[5] - src[6] + dcOffset)) < dcThreshold;
219 numEq += ((unsigned)(src[6] - src[7] + dcOffset)) < dcThreshold;
233 const int dcThreshold= dcOffset*2 + 1;
237 numEq += ((unsigned)(src[0] - src[0+stride] + dcOffset)) < dcThreshold;
238 numEq += ((unsigned)(src[1] - src[1+stride] + dcOffset)) < dcThreshold;
239 numEq += ((unsigned)(src[2] - src[2+stride] + dcOffset)) < dcThreshold;
240 numEq += ((unsigned)(src[3] - src[3+stride] + dcOffset)) < dcThreshold;
241 numEq += ((unsigned)(src[4] - src[4+stride] + dcOffset)) < dcThreshold;
242 numEq += ((unsigned)(src[5] - src[5+stride] + dcOffset)) < dcThreshold;
243 numEq += ((unsigned)(src[6] - src[6+stride] + dcOffset)) < dcThreshold;
244 numEq += ((unsigned)(src[7] - src[7+stride] + dcOffset)) < dcThreshold;
254 if((
unsigned)(src[0] - src[5] + 2*QP) > 4*QP)
return 0;
256 if((
unsigned)(src[2] - src[7] + 2*QP) > 4*QP)
return 0;
258 if((
unsigned)(src[4] - src[1] + 2*QP) > 4*QP)
return 0;
260 if((
unsigned)(src[6] - src[3] + 2*QP) > 4*QP)
return 0;
271 if((
unsigned)(src[ x + 0*stride] - src[ x + 5*stride] + 2*QP) > 4*QP)
return 0;
272 if((
unsigned)(src[1+x + 2*stride] - src[1+x + 7*stride] + 2*QP) > 4*QP)
return 0;
273 if((
unsigned)(src[2+x + 4*stride] - src[2+x + 1*stride] + 2*QP) > 4*QP)
return 0;
274 if((
unsigned)(src[3+x + 6*stride] - src[3+x + 3*stride] + 2*QP) > 4*QP)
return 0;
301 const int middleEnergy= 5*(dst[4] - dst[3]) + 2*(dst[2] - dst[5]);
303 if(
FFABS(middleEnergy) < 8*c->
QP){
304 const int q=(dst[3] - dst[4])/2;
305 const int leftEnergy= 5*(dst[2] - dst[1]) + 2*(dst[0] - dst[3]);
306 const int rightEnergy= 5*(dst[6] - dst[5]) + 2*(dst[4] - dst[7]);
312 d*=
FFSIGN(-middleEnergy);
340 const int first=
FFABS(dst[-1] - dst[0]) < c->
QP ? dst[-1] : dst[0];
341 const int last=
FFABS(dst[8] - dst[7]) < c->
QP ? dst[8] : dst[7];
344 sums[0] = 4*first + dst[0] + dst[1] + dst[2] + 4;
345 sums[1] = sums[0] - first + dst[3];
346 sums[2] = sums[1] - first + dst[4];
347 sums[3] = sums[2] - first + dst[5];
348 sums[4] = sums[3] - first + dst[6];
349 sums[5] = sums[4] - dst[0] + dst[7];
350 sums[6] = sums[5] - dst[1] + last;
351 sums[7] = sums[6] - dst[2] + last;
352 sums[8] = sums[7] - dst[3] + last;
353 sums[9] = sums[8] - dst[4] + last;
355 dst[0]= (sums[0] + sums[2] + 2*dst[0])>>4;
356 dst[1]= (sums[1] + sums[3] + 2*dst[1])>>4;
357 dst[2]= (sums[2] + sums[4] + 2*dst[2])>>4;
358 dst[3]= (sums[3] + sums[5] + 2*dst[3])>>4;
359 dst[4]= (sums[4] + sums[6] + 2*dst[4])>>4;
360 dst[5]= (sums[5] + sums[7] + 2*dst[5])>>4;
361 dst[6]= (sums[6] + sums[8] + 2*dst[6])>>4;
362 dst[7]= (sums[7] + sums[9] + 2*dst[7])>>4;
379 static uint64_t lut[256];
385 int v= i < 128 ? 2*i : 2*(i-256);
394 uint64_t
a= (v/16) & 0xFF;
395 uint64_t
b= (v*3/16) & 0xFF;
396 uint64_t
c= (v*5/16) & 0xFF;
397 uint64_t d= (7*v/16) & 0xFF;
398 uint64_t
A= (0x100 -
a)&0xFF;
399 uint64_t
B= (0x100 -
b)&0xFF;
400 uint64_t
C= (0x100 -
c)&0xFF;
401 uint64_t
D= (0x100 -
c)&0xFF;
403 lut[i] = (a<<56) | (b<<48) | (c<<40) | (d<<32) |
404 (D<<24) | (C<<16) | (B<<8) | (A);
410 int a= src[1] - src[2];
411 int b= src[3] - src[4];
412 int c= src[5] - src[6];
439 const int dcThreshold= dcOffset*2 + 1;
445 numEq += ((unsigned)(src[-1*step] - src[0*step] + dcOffset)) < dcThreshold;
446 numEq += ((unsigned)(src[ 0*step] - src[1*step] + dcOffset)) < dcThreshold;
447 numEq += ((unsigned)(src[ 1*step] - src[2*step] + dcOffset)) < dcThreshold;
448 numEq += ((unsigned)(src[ 2*step] - src[3*step] + dcOffset)) < dcThreshold;
449 numEq += ((unsigned)(src[ 3*step] - src[4*step] + dcOffset)) < dcThreshold;
450 numEq += ((unsigned)(src[ 4*step] - src[5*step] + dcOffset)) < dcThreshold;
451 numEq += ((unsigned)(src[ 5*step] - src[6*step] + dcOffset)) < dcThreshold;
452 numEq += ((unsigned)(src[ 6*step] - src[7*step] + dcOffset)) < dcThreshold;
453 numEq += ((unsigned)(src[ 7*step] - src[8*step] + dcOffset)) < dcThreshold;
457 if(src[0] > src[step]){
465 if(src[x*step] > src[(x+1)*step]){
466 if(src[x *step] > max) max= src[ x *step];
467 if(src[(x+1)*step] <
min) min= src[(x+1)*step];
469 if(src[(x+1)*step] > max) max= src[(x+1)*step];
470 if(src[ x *step] < min) min= src[ x *step];
474 const int first=
FFABS(src[-1*step] - src[0]) < QP ? src[-1*step] : src[0];
475 const int last=
FFABS(src[8*step] - src[7*step]) < QP ? src[8*step] : src[7*step];
478 sums[0] = 4*first + src[0*step] + src[1*step] + src[2*step] + 4;
479 sums[1] = sums[0] - first + src[3*step];
480 sums[2] = sums[1] - first + src[4*step];
481 sums[3] = sums[2] - first + src[5*step];
482 sums[4] = sums[3] - first + src[6*step];
483 sums[5] = sums[4] - src[0*step] + src[7*step];
484 sums[6] = sums[5] - src[1*step] + last;
485 sums[7] = sums[6] - src[2*step] + last;
486 sums[8] = sums[7] - src[3*step] + last;
487 sums[9] = sums[8] - src[4*step] + last;
499 src[0*step]= (sums[0] + sums[2] + 2*src[0*step])>>4;
500 src[1*step]= (sums[1] + sums[3] + 2*src[1*step])>>4;
501 src[2*step]= (sums[2] + sums[4] + 2*src[2*step])>>4;
502 src[3*step]= (sums[3] + sums[5] + 2*src[3*step])>>4;
503 src[4*step]= (sums[4] + sums[6] + 2*src[4*step])>>4;
504 src[5*step]= (sums[5] + sums[7] + 2*src[5*step])>>4;
505 src[6*step]= (sums[6] + sums[8] + 2*src[6*step])>>4;
506 src[7*step]= (sums[7] + sums[9] + 2*src[7*step])>>4;
509 const int middleEnergy= 5*(src[4*step] - src[3*step]) + 2*(src[2*step] - src[5*step]);
511 if(
FFABS(middleEnergy) < 8*
QP){
512 const int q=(src[3*step] - src[4*step])/2;
513 const int leftEnergy= 5*(src[2*step] - src[1*step]) + 2*(src[0*step] - src[3*step]);
514 const int rightEnergy= 5*(src[6*step] - src[5*step]) + 2*(src[4*step] - src[7*step]);
520 d*=
FFSIGN(-middleEnergy);
531 d= (d < 0) ? 32 : -32;
532 src[3*step]= av_clip_uint8(src[3*step] - d);
533 src[4*step]= av_clip_uint8(src[4*step] + d);
554 #define TEMPLATE_PP_C 1
558 # define TEMPLATE_PP_ALTIVEC 1
563 #if ARCH_X86 && HAVE_INLINE_ASM
564 # if CONFIG_RUNTIME_CPUDETECT
565 # define TEMPLATE_PP_MMX 1
567 # define TEMPLATE_PP_MMXEXT 1
569 # define TEMPLATE_PP_3DNOW 1
571 # define TEMPLATE_PP_SSE2 1
574 # if HAVE_SSE2_INLINE
575 # define TEMPLATE_PP_SSE2 1
577 # elif HAVE_MMXEXT_INLINE
578 # define TEMPLATE_PP_MMXEXT 1
580 # elif HAVE_AMD3DNOW_INLINE
581 # define TEMPLATE_PP_3DNOW 1
583 # elif HAVE_MMX_INLINE
584 # define TEMPLATE_PP_MMX 1
596 pp_fn pp = postProcess_C;
602 #if CONFIG_RUNTIME_CPUDETECT
603 #if ARCH_X86 && HAVE_INLINE_ASM
614 pp = postProcess_SSE2;
615 #elif HAVE_MMXEXT_INLINE
616 pp = postProcess_MMX2;
617 #elif HAVE_AMD3DNOW_INLINE
618 pp = postProcess_3DNow;
619 #elif HAVE_MMX_INLINE
620 pp = postProcess_MMX;
622 pp = postProcess_altivec;
627 pp(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
633 "Available postprocessing filters:\n"
635 "short long name short long option Description\n"
636 "* * a autoq CPU power dependent enabler\n"
637 " c chrom chrominance filtering enabled\n"
638 " y nochrom chrominance filtering disabled\n"
639 " n noluma luma filtering disabled\n"
640 "hb hdeblock (2 threshold) horizontal deblocking filter\n"
641 " 1. difference factor: default=32, higher -> more deblocking\n"
642 " 2. flatness threshold: default=39, lower -> more deblocking\n"
643 " the h & v deblocking filters share these\n"
644 " so you can't set different thresholds for h / v\n"
645 "vb vdeblock (2 threshold) vertical deblocking filter\n"
646 "ha hadeblock (2 threshold) horizontal deblocking filter\n"
647 "va vadeblock (2 threshold) vertical deblocking filter\n"
648 "h1 x1hdeblock experimental h deblock filter 1\n"
649 "v1 x1vdeblock experimental v deblock filter 1\n"
650 "dr dering deringing filter\n"
651 "al autolevels automatic brightness / contrast\n"
652 " f fullyrange stretch luminance to (0..255)\n"
653 "lb linblenddeint linear blend deinterlacer\n"
654 "li linipoldeint linear interpolating deinterlace\n"
655 "ci cubicipoldeint cubic interpolating deinterlacer\n"
656 "md mediandeint median deinterlacer\n"
657 "fd ffmpegdeint ffmpeg deinterlacer\n"
658 "l5 lowpass5 FIR lowpass deinterlacer\n"
659 "de default hb:a,vb:a,dr:a\n"
660 "fa fast h1:a,v1:a,dr:a\n"
661 "ac ha:a:128:7,va:a,dr:a\n"
662 "tn tmpnoise (3 threshold) temporal noise reducer\n"
663 " 1. <= 2. <= 3. larger -> stronger filtering\n"
664 "fq forceQuant <quantizer> force quantizer\n"
666 "<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]...\n"
667 "long form example:\n"
668 "vdeblock:autoq/hdeblock:autoq/linblenddeint default,-vdeblock\n"
669 "short form example:\n"
670 "vb:a/hb:a/lb de,-vb\n"
680 static const char filterDelimiters[] =
",/";
681 static const char optionDelimiters[] =
":|";
690 if (!strcmp(name,
"help")) {
692 for (p =
pp_help; strchr(p,
'\n'); p = strchr(p,
'\n') + 1) {
719 const char *filterName;
727 int numOfUnknownOptions=0;
731 filterToken=
av_strtok(p, filterDelimiters, &tokstate);
732 if(!filterToken)
break;
733 p+= strlen(filterToken) + 1;
734 filterName=
av_strtok(filterToken, optionDelimiters, &tokstate);
741 if(*filterName ==
'-'){
747 option=
av_strtok(NULL, optionDelimiters, &tokstate);
751 if(!strcmp(
"autoq", option) || !strcmp(
"a", option)) q= quality;
752 else if(!strcmp(
"nochrom", option) || !strcmp(
"y", option)) chrom=0;
753 else if(!strcmp(
"chrom", option) || !strcmp(
"c", option)) chrom=1;
754 else if(!strcmp(
"noluma", option) || !strcmp(
"n", option)) luma=0;
756 options[numOfUnknownOptions] =
option;
757 numOfUnknownOptions++;
761 options[numOfUnknownOptions] = NULL;
773 spaceLeft= p - temp + plen;
778 memmove(p + newlen, p, plen+1);
785 if( !strcmp(filters[i].longName, filterName)
786 || !strcmp(filters[i].shortName, filterName)){
793 if(q >= filters[i].minLumQuality && luma)
795 if(chrom==1 || (chrom==-1 && filters[i].chromDefault))
796 if(q >= filters[i].minChromQuality)
803 for(o=0; options[o]; o++){
804 if( !strcmp(options[o],
"fullyrange")
805 ||!strcmp(options[o],
"f")){
808 numOfUnknownOptions--;
817 for(o=0; options[o]; o++){
820 strtol(options[o], &tail, 0);
821 if(tail!=options[o]){
823 numOfUnknownOptions--;
824 if(numOfNoises >= 3)
break;
832 for(o=0; options[o] && o<2; o++){
834 int val= strtol(options[o], &tail, 0);
835 if(tail==options[o])
break;
837 numOfUnknownOptions--;
846 for(o=0; options[o] && o<1; o++){
848 int val= strtol(options[o], &tail, 0);
849 if(tail==options[o])
break;
851 numOfUnknownOptions--;
857 if(!filterNameOk) ppMode->
error++;
858 ppMode->
error += numOfUnknownOptions;
880 int mbWidth = (width+15)>>4;
881 int mbHeight= (height+15)>>4;
915 int qpStride= (width+15)/16 + 2;
967 uint8_t * dst[3],
const int dstStride[3],
970 pp_mode *vm,
void *vc,
int pict_type)
972 int mbWidth = (width+15)>>4;
973 int mbHeight= (height+15)>>4;
977 int absQPStride =
FFABS(QPStride);
988 absQPStride = QPStride = 0;
997 const int count=
FFMAX(mbHeight * absQPStride, mbWidth);
998 for(i=0; i<(count>>2); i++){
999 ((uint32_t*)c->
stdQPTable)[i] = (((
const uint32_t*)QP_store)[i]>>1) & 0x7F7F7F7F;
1001 for(i<<=2; i<
count; i++){
1005 QPStride= absQPStride;
1010 for(y=0; y<mbHeight; y++){
1011 for(x=0; x<mbWidth; x++){
1019 if((pict_type&7)!=3){
1022 const int count=
FFMAX(mbHeight * QPStride, mbWidth);
1023 for(i=0; i<(count>>2); i++){
1024 ((uint32_t*)c->
nonBQPTable)[i] = ((
const uint32_t*)QP_store)[i] & 0x3F3F3F3F;
1026 for(i<<=2; i<
count; i++){
1031 for(i=0; i<mbHeight; i++) {
1032 for(j=0; j<absQPStride; j++) {
1033 c->
nonBQPTable[i*absQPStride+j] = QP_store[i*QPStride+j] & 0x3F;
1042 postProcess(src[0], srcStride[0], dst[0], dstStride[0],
1043 width, height, QP_store, QPStride, 0, mode, c);
1045 if (!(src[1] && src[2] && dst[1] && dst[2]))
1052 postProcess(src[1], srcStride[1], dst[1], dstStride[1],
1053 width, height, QP_store, QPStride, 1, mode, c);
1054 postProcess(src[2], srcStride[2], dst[2], dstStride[2],
1055 width, height, QP_store, QPStride, 2, mode, c);
1057 else if(srcStride[1] == dstStride[1] && srcStride[2] == dstStride[2]){
1058 linecpy(dst[1], src[1], height, srcStride[1]);
1059 linecpy(dst[2], src[2], height, srcStride[2]);
1063 memcpy(&(dst[1][y*dstStride[1]]), &(src[1][y*srcStride[1]]), width);
1064 memcpy(&(dst[2][y*dstStride[2]]), &(src[2][y*srcStride[2]]), width);