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},
159 "default",
"hb:a,vb:a,dr:a",
160 "de",
"hb:a,vb:a,dr:a",
161 "fast",
"h1:a,v1:a,dr:a",
162 "fa",
"h1:a,v1:a,dr:a",
163 "ac",
"ha:a:128:7,va:a,dr:a",
168 #if ARCH_X86 && HAVE_INLINE_ASM
169 static inline void prefetchnta(
void *p)
171 __asm__
volatile(
"prefetchnta (%0)\n\t"
176 static inline void prefetcht0(
void *p)
178 __asm__
volatile(
"prefetcht0 (%0)\n\t"
183 static inline void prefetcht1(
void *p)
185 __asm__
volatile(
"prefetcht1 (%0)\n\t"
190 static inline void prefetcht2(
void *p)
192 __asm__
volatile(
"prefetcht2 (%0)\n\t"
209 const int dcThreshold= dcOffset*2 + 1;
212 if(((
unsigned)(src[0] - src[1] + dcOffset)) < dcThreshold) numEq++;
213 if(((
unsigned)(src[1] - src[2] + dcOffset)) < dcThreshold) numEq++;
214 if(((
unsigned)(src[2] - src[3] + dcOffset)) < dcThreshold) numEq++;
215 if(((
unsigned)(src[3] - src[4] + dcOffset)) < dcThreshold) numEq++;
216 if(((
unsigned)(src[4] - src[5] + dcOffset)) < dcThreshold) numEq++;
217 if(((
unsigned)(src[5] - src[6] + dcOffset)) < dcThreshold) numEq++;
218 if(((
unsigned)(src[6] - src[7] + dcOffset)) < dcThreshold) numEq++;
232 const int dcThreshold= dcOffset*2 + 1;
236 if(((
unsigned)(src[0] - src[0+stride] + dcOffset)) < dcThreshold) numEq++;
237 if(((
unsigned)(src[1] - src[1+stride] + dcOffset)) < dcThreshold) numEq++;
238 if(((
unsigned)(src[2] - src[2+stride] + dcOffset)) < dcThreshold) numEq++;
239 if(((
unsigned)(src[3] - src[3+stride] + dcOffset)) < dcThreshold) numEq++;
240 if(((
unsigned)(src[4] - src[4+stride] + dcOffset)) < dcThreshold) numEq++;
241 if(((
unsigned)(src[5] - src[5+stride] + dcOffset)) < dcThreshold) numEq++;
242 if(((
unsigned)(src[6] - src[6+stride] + dcOffset)) < dcThreshold) numEq++;
243 if(((
unsigned)(src[7] - src[7+stride] + dcOffset)) < dcThreshold) numEq++;
253 if((
unsigned)(src[0] - src[5] + 2*QP) > 4*QP)
return 0;
255 if((
unsigned)(src[2] - src[7] + 2*QP) > 4*QP)
return 0;
257 if((
unsigned)(src[4] - src[1] + 2*QP) > 4*QP)
return 0;
259 if((
unsigned)(src[6] - src[3] + 2*QP) > 4*QP)
return 0;
270 if((
unsigned)(src[ x + 0*stride] - src[ x + 5*stride] + 2*QP) > 4*QP)
return 0;
271 if((
unsigned)(src[1+x + 2*stride] - src[1+x + 7*stride] + 2*QP) > 4*QP)
return 0;
272 if((
unsigned)(src[2+x + 4*stride] - src[2+x + 1*stride] + 2*QP) > 4*QP)
return 0;
273 if((
unsigned)(src[3+x + 6*stride] - src[3+x + 3*stride] + 2*QP) > 4*QP)
return 0;
306 const int middleEnergy= 5*(dst[4] - dst[3]) + 2*(dst[2] - dst[5]);
308 if(
FFABS(middleEnergy) < 8*c->
QP){
309 const int q=(dst[3] - dst[4])/2;
310 const int leftEnergy= 5*(dst[2] - dst[1]) + 2*(dst[0] - dst[3]);
311 const int rightEnergy= 5*(dst[6] - dst[5]) + 2*(dst[4] - dst[7]);
317 d*=
FFSIGN(-middleEnergy);
345 const int first=
FFABS(dst[-1] - dst[0]) < c->
QP ? dst[-1] : dst[0];
346 const int last=
FFABS(dst[8] - dst[7]) < c->
QP ? dst[8] : dst[7];
349 sums[0] = 4*first + dst[0] + dst[1] + dst[2] + 4;
350 sums[1] = sums[0] - first + dst[3];
351 sums[2] = sums[1] - first + dst[4];
352 sums[3] = sums[2] - first + dst[5];
353 sums[4] = sums[3] - first + dst[6];
354 sums[5] = sums[4] - dst[0] + dst[7];
355 sums[6] = sums[5] - dst[1] + last;
356 sums[7] = sums[6] - dst[2] + last;
357 sums[8] = sums[7] - dst[3] + last;
358 sums[9] = sums[8] - dst[4] + last;
360 dst[0]= (sums[0] + sums[2] + 2*dst[0])>>4;
361 dst[1]= (sums[1] + sums[3] + 2*dst[1])>>4;
362 dst[2]= (sums[2] + sums[4] + 2*dst[2])>>4;
363 dst[3]= (sums[3] + sums[5] + 2*dst[3])>>4;
364 dst[4]= (sums[4] + sums[6] + 2*dst[4])>>4;
365 dst[5]= (sums[5] + sums[7] + 2*dst[5])>>4;
366 dst[6]= (sums[6] + sums[8] + 2*dst[6])>>4;
367 dst[7]= (sums[7] + sums[9] + 2*dst[7])>>4;
384 static uint64_t lut[256];
390 int v= i < 128 ? 2*i : 2*(i-256);
399 uint64_t
a= (v/16) & 0xFF;
400 uint64_t
b= (v*3/16) & 0xFF;
401 uint64_t
c= (v*5/16) & 0xFF;
402 uint64_t d= (7*v/16) & 0xFF;
403 uint64_t
A= (0x100 -
a)&0xFF;
404 uint64_t
B= (0x100 -
b)&0xFF;
405 uint64_t
C= (0x100 -
c)&0xFF;
406 uint64_t
D= (0x100 -
c)&0xFF;
408 lut[i] = (a<<56) | (b<<48) | (c<<40) | (d<<32) |
409 (D<<24) | (C<<16) | (B<<8) | (A);
415 int a= src[1] - src[2];
416 int b= src[3] - src[4];
417 int c= src[5] - src[6];
444 const int dcThreshold= dcOffset*2 + 1;
450 if(((
unsigned)(src[-1*step] - src[0*step] + dcOffset)) < dcThreshold) numEq++;
451 if(((
unsigned)(src[ 0*step] - src[1*step] + dcOffset)) < dcThreshold) numEq++;
452 if(((
unsigned)(src[ 1*step] - src[2*step] + dcOffset)) < dcThreshold) numEq++;
453 if(((
unsigned)(src[ 2*step] - src[3*step] + dcOffset)) < dcThreshold) numEq++;
454 if(((
unsigned)(src[ 3*step] - src[4*step] + dcOffset)) < dcThreshold) numEq++;
455 if(((
unsigned)(src[ 4*step] - src[5*step] + dcOffset)) < dcThreshold) numEq++;
456 if(((
unsigned)(src[ 5*step] - src[6*step] + dcOffset)) < dcThreshold) numEq++;
457 if(((
unsigned)(src[ 6*step] - src[7*step] + dcOffset)) < dcThreshold) numEq++;
458 if(((
unsigned)(src[ 7*step] - src[8*step] + dcOffset)) < dcThreshold) numEq++;
462 if(src[0] > src[step]){
470 if(src[x*step] > src[(x+1)*step]){
471 if(src[x *step] > max) max= src[ x *step];
472 if(src[(x+1)*step] <
min) min= src[(x+1)*step];
474 if(src[(x+1)*step] > max) max= src[(x+1)*step];
475 if(src[ x *step] < min) min= src[ x *step];
479 const int first=
FFABS(src[-1*step] - src[0]) < QP ? src[-1*step] : src[0];
480 const int last=
FFABS(src[8*step] - src[7*step]) < QP ? src[8*step] : src[7*step];
483 sums[0] = 4*first + src[0*step] + src[1*step] + src[2*step] + 4;
484 sums[1] = sums[0] - first + src[3*step];
485 sums[2] = sums[1] - first + src[4*step];
486 sums[3] = sums[2] - first + src[5*step];
487 sums[4] = sums[3] - first + src[6*step];
488 sums[5] = sums[4] - src[0*step] + src[7*step];
489 sums[6] = sums[5] - src[1*step] + last;
490 sums[7] = sums[6] - src[2*step] + last;
491 sums[8] = sums[7] - src[3*step] + last;
492 sums[9] = sums[8] - src[4*step] + last;
494 src[0*step]= (sums[0] + sums[2] + 2*src[0*step])>>4;
495 src[1*step]= (sums[1] + sums[3] + 2*src[1*step])>>4;
496 src[2*step]= (sums[2] + sums[4] + 2*src[2*step])>>4;
497 src[3*step]= (sums[3] + sums[5] + 2*src[3*step])>>4;
498 src[4*step]= (sums[4] + sums[6] + 2*src[4*step])>>4;
499 src[5*step]= (sums[5] + sums[7] + 2*src[5*step])>>4;
500 src[6*step]= (sums[6] + sums[8] + 2*src[6*step])>>4;
501 src[7*step]= (sums[7] + sums[9] + 2*src[7*step])>>4;
504 const int middleEnergy= 5*(src[4*step] - src[3*step]) + 2*(src[2*step] - src[5*step]);
506 if(
FFABS(middleEnergy) < 8*
QP){
507 const int q=(src[3*step] - src[4*step])/2;
508 const int leftEnergy= 5*(src[2*step] - src[1*step]) + 2*(src[0*step] - src[3*step]);
509 const int rightEnergy= 5*(src[6*step] - src[5*step]) + 2*(src[4*step] - src[7*step]);
515 d*=
FFSIGN(-middleEnergy);
542 #define TEMPLATE_PP_C 1
546 # define TEMPLATE_PP_ALTIVEC 1
551 #if ARCH_X86 && HAVE_INLINE_ASM
552 # if CONFIG_RUNTIME_CPUDETECT
553 # define TEMPLATE_PP_MMX 1
555 # define TEMPLATE_PP_MMXEXT 1
557 # define TEMPLATE_PP_3DNOW 1
559 # define TEMPLATE_PP_SSE2 1
562 # if HAVE_SSE2_INLINE
563 # define TEMPLATE_PP_SSE2 1
565 # elif HAVE_MMXEXT_INLINE
566 # define TEMPLATE_PP_MMXEXT 1
568 # elif HAVE_AMD3DNOW_INLINE
569 # define TEMPLATE_PP_3DNOW 1
571 # elif HAVE_MMX_INLINE
572 # define TEMPLATE_PP_MMX 1
584 pp_fn pp = postProcess_C;
590 #if CONFIG_RUNTIME_CPUDETECT
591 #if ARCH_X86 && HAVE_INLINE_ASM
602 pp = postProcess_SSE2;
603 #elif HAVE_MMXEXT_INLINE
604 pp = postProcess_MMX2;
605 #elif HAVE_AMD3DNOW_INLINE
606 pp = postProcess_3DNow;
607 #elif HAVE_MMX_INLINE
608 pp = postProcess_MMX;
610 pp = postProcess_altivec;
615 pp(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
621 "Available postprocessing filters:\n"
623 "short long name short long option Description\n"
624 "* * a autoq CPU power dependent enabler\n"
625 " c chrom chrominance filtering enabled\n"
626 " y nochrom chrominance filtering disabled\n"
627 " n noluma luma filtering disabled\n"
628 "hb hdeblock (2 threshold) horizontal deblocking filter\n"
629 " 1. difference factor: default=32, higher -> more deblocking\n"
630 " 2. flatness threshold: default=39, lower -> more deblocking\n"
631 " the h & v deblocking filters share these\n"
632 " so you can't set different thresholds for h / v\n"
633 "vb vdeblock (2 threshold) vertical deblocking filter\n"
634 "ha hadeblock (2 threshold) horizontal deblocking filter\n"
635 "va vadeblock (2 threshold) vertical deblocking filter\n"
636 "h1 x1hdeblock experimental h deblock filter 1\n"
637 "v1 x1vdeblock experimental v deblock filter 1\n"
638 "dr dering deringing filter\n"
639 "al autolevels automatic brightness / contrast\n"
640 " f fullyrange stretch luminance to (0..255)\n"
641 "lb linblenddeint linear blend deinterlacer\n"
642 "li linipoldeint linear interpolating deinterlace\n"
643 "ci cubicipoldeint cubic interpolating deinterlacer\n"
644 "md mediandeint median deinterlacer\n"
645 "fd ffmpegdeint ffmpeg deinterlacer\n"
646 "l5 lowpass5 FIR lowpass deinterlacer\n"
647 "de default hb:a,vb:a,dr:a\n"
648 "fa fast h1:a,v1:a,dr:a\n"
649 "ac ha:a:128:7,va:a,dr:a\n"
650 "tn tmpnoise (3 threshold) temporal noise reducer\n"
651 " 1. <= 2. <= 3. larger -> stronger filtering\n"
652 "fq forceQuant <quantizer> force quantizer\n"
654 "<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]...\n"
655 "long form example:\n"
656 "vdeblock:autoq/hdeblock:autoq/linblenddeint default,-vdeblock\n"
657 "short form example:\n"
658 "vb:a/hb:a/lb de,-vb\n"
668 static const char filterDelimiters[] =
",/";
669 static const char optionDelimiters[] =
":|";
678 if (!strcmp(name,
"help")) {
680 for (p =
pp_help; strchr(p,
'\n'); p = strchr(p,
'\n') + 1) {
715 int numOfUnknownOptions=0;
718 filterToken= strtok(p, filterDelimiters);
719 if(filterToken == NULL)
break;
720 p+= strlen(filterToken) + 1;
721 filterName= strtok(filterToken, optionDelimiters);
722 if (filterName == NULL) {
728 if(*filterName ==
'-'){
734 option= strtok(NULL, optionDelimiters);
735 if(option == NULL)
break;
738 if(!strcmp(
"autoq", option) || !strcmp(
"a", option)) q= quality;
739 else if(!strcmp(
"nochrom", option) || !strcmp(
"y", option)) chrom=0;
740 else if(!strcmp(
"chrom", option) || !strcmp(
"c", option)) chrom=1;
741 else if(!strcmp(
"noluma", option) || !strcmp(
"n", option)) luma=0;
743 options[numOfUnknownOptions] =
option;
744 numOfUnknownOptions++;
748 options[numOfUnknownOptions] = NULL;
760 spaceLeft= p - temp + plen;
765 memmove(p + newlen, p, plen+1);
771 for(i=0; filters[i].
shortName!=NULL; i++){
772 if( !strcmp(filters[i].longName, filterName)
773 || !strcmp(filters[i].shortName, filterName)){
780 if(q >= filters[i].minLumQuality && luma)
782 if(chrom==1 || (chrom==-1 && filters[i].chromDefault))
783 if(q >= filters[i].minChromQuality)
790 for(o=0; options[o]!=NULL; o++){
791 if( !strcmp(options[o],
"fullyrange")
792 ||!strcmp(options[o],
"f")){
795 numOfUnknownOptions--;
804 for(o=0; options[o]!=NULL; o++){
807 strtol(options[o], &tail, 0);
808 if(tail!=options[o]){
810 numOfUnknownOptions--;
811 if(numOfNoises >= 3)
break;
819 for(o=0; options[o]!=NULL && o<2; o++){
821 int val= strtol(options[o], &tail, 0);
822 if(tail==options[o])
break;
824 numOfUnknownOptions--;
833 for(o=0; options[o]!=NULL && o<1; o++){
835 int val= strtol(options[o], &tail, 0);
836 if(tail==options[o])
break;
838 numOfUnknownOptions--;
844 if(!filterNameOk) ppMode->
error++;
845 ppMode->
error += numOfUnknownOptions;
867 int mbWidth = (width+15)>>4;
868 int mbHeight= (height+15)>>4;
902 int qpStride= (width+15)/16 + 2;
952 uint8_t * dst[3],
const int dstStride[3],
955 pp_mode *vm,
void *vc,
int pict_type)
957 int mbWidth = (width+15)>>4;
958 int mbHeight= (height+15)>>4;
962 int absQPStride =
FFABS(QPStride);
973 absQPStride = QPStride = 0;
982 const int count= mbHeight * absQPStride;
983 for(i=0; i<(count>>2); i++){
984 ((uint32_t*)c->
stdQPTable)[i] = (((
const uint32_t*)QP_store)[i]>>1) & 0x7F7F7F7F;
986 for(i<<=2; i<
count; i++){
990 QPStride= absQPStride;
995 for(y=0; y<mbHeight; y++){
996 for(x=0; x<mbWidth; x++){
1004 if((pict_type&7)!=3){
1007 const int count= mbHeight * QPStride;
1008 for(i=0; i<(count>>2); i++){
1009 ((uint32_t*)c->
nonBQPTable)[i] = ((
const uint32_t*)QP_store)[i] & 0x3F3F3F3F;
1011 for(i<<=2; i<
count; i++){
1016 for(i=0; i<mbHeight; i++) {
1017 for(j=0; j<absQPStride; j++) {
1018 c->
nonBQPTable[i*absQPStride+j] = QP_store[i*QPStride+j] & 0x3F;
1027 postProcess(src[0], srcStride[0], dst[0], dstStride[0],
1028 width, height, QP_store, QPStride, 0, mode, c);
1034 postProcess(src[1], srcStride[1], dst[1], dstStride[1],
1035 width, height, QP_store, QPStride, 1, mode, c);
1036 postProcess(src[2], srcStride[2], dst[2], dstStride[2],
1037 width, height, QP_store, QPStride, 2, mode, c);
1039 else if(srcStride[1] == dstStride[1] && srcStride[2] == dstStride[2]){
1040 linecpy(dst[1], src[1], height, srcStride[1]);
1041 linecpy(dst[2], src[2], height, srcStride[2]);
1045 memcpy(&(dst[1][y*dstStride[1]]), &(src[1][y*srcStride[1]]), width);
1046 memcpy(&(dst[2][y*dstStride[2]]), &(src[2][y*srcStride[2]]), width);