95 #include "libavutil/ffversion.h" 
  106     return FFMPEG_CONFIGURATION;
 
  111 #define LICENSE_PREFIX "libpostproc license: " 
  115 #define GET_MODE_BUFFER_SIZE 500 
  116 #define OPTIONS_ARRAY_SIZE 10 
  118 #define TEMP_STRIDE 8 
  121 #if ARCH_X86 && HAVE_INLINE_ASM 
  145     {
"dr", 
"dering",                1, 5, 6, 
DERING},
 
  146     {
"al", 
"autolevels",            0, 1, 2, 
LEVEL_FIX},
 
  155     {
"be", 
"bitexact",              1, 0, 0, 
BITEXACT},
 
  162     "default",      
"hb:a,vb:a,dr:a",
 
  163     "de",           
"hb:a,vb:a,dr:a",
 
  164     "fast",         
"h1:a,v1:a,dr:a",
 
  165     "fa",           
"h1:a,v1:a,dr:a",
 
  166     "ac",           
"ha:a:128:7,va:a,dr:a",
 
  180     const int dcOffset= ((
c->nonBQP*
c->ppMode.baseDcDiff)>>8) + 1;
 
  181     const int dcThreshold= dcOffset*2 + 1;
 
  184         numEq += ((unsigned)(
src[0] - 
src[1] + dcOffset)) < dcThreshold;
 
  185         numEq += ((unsigned)(
src[1] - 
src[2] + dcOffset)) < dcThreshold;
 
  186         numEq += ((unsigned)(
src[2] - 
src[3] + dcOffset)) < dcThreshold;
 
  187         numEq += ((unsigned)(
src[3] - 
src[4] + dcOffset)) < dcThreshold;
 
  188         numEq += ((unsigned)(
src[4] - 
src[5] + dcOffset)) < dcThreshold;
 
  189         numEq += ((unsigned)(
src[5] - 
src[6] + dcOffset)) < dcThreshold;
 
  190         numEq += ((unsigned)(
src[6] - 
src[7] + dcOffset)) < dcThreshold;
 
  193     return numEq > 
c->ppMode.flatnessThreshold;
 
  203     const int dcOffset= ((
c->nonBQP*
c->ppMode.baseDcDiff)>>8) + 1;
 
  204     const int dcThreshold= dcOffset*2 + 1;
 
  208         numEq += ((unsigned)(
src[0] - 
src[0+
stride] + dcOffset)) < dcThreshold;
 
  209         numEq += ((unsigned)(
src[1] - 
src[1+
stride] + dcOffset)) < dcThreshold;
 
  210         numEq += ((unsigned)(
src[2] - 
src[2+
stride] + dcOffset)) < dcThreshold;
 
  211         numEq += ((unsigned)(
src[3] - 
src[3+
stride] + dcOffset)) < dcThreshold;
 
  212         numEq += ((unsigned)(
src[4] - 
src[4+
stride] + dcOffset)) < dcThreshold;
 
  213         numEq += ((unsigned)(
src[5] - 
src[5+
stride] + dcOffset)) < dcThreshold;
 
  214         numEq += ((unsigned)(
src[6] - 
src[6+
stride] + dcOffset)) < dcThreshold;
 
  215         numEq += ((unsigned)(
src[7] - 
src[7+
stride] + dcOffset)) < dcThreshold;
 
  218     return numEq > 
c->ppMode.flatnessThreshold;
 
  225         if((
unsigned)(
src[0] - 
src[5] + 2*
QP) > 4*
QP) 
return 0;
 
  227         if((
unsigned)(
src[2] - 
src[7] + 2*
QP) > 4*
QP) 
return 0;
 
  229         if((
unsigned)(
src[4] - 
src[1] + 2*
QP) > 4*
QP) 
return 0;
 
  231         if((
unsigned)(
src[6] - 
src[3] + 2*
QP) > 4*
QP) 
return 0;
 
  272         const int middleEnergy= 5*(dst[4] - dst[3]) + 2*(dst[2] - dst[5]);
 
  274         if(
FFABS(middleEnergy) < 8*
c->QP){
 
  275             const int q=(dst[3] - dst[4])/2;
 
  276             const int leftEnergy=  5*(dst[2] - dst[1]) + 2*(dst[0] - dst[3]);
 
  277             const int rightEnergy= 5*(dst[6] - dst[5]) + 2*(dst[4] - dst[7]);
 
  311         const int first= 
FFABS(dst[-1] - dst[0]) < 
c->QP ? dst[-1] : dst[0];
 
  312         const int last= 
FFABS(dst[8] - dst[7]) < 
c->QP ? dst[8] : dst[7];
 
  315         sums[0] = 4*
first + dst[0] + dst[1] + dst[2] + 4;
 
  316         sums[1] = sums[0] - 
first  + dst[3];
 
  317         sums[2] = sums[1] - 
first  + dst[4];
 
  318         sums[3] = sums[2] - 
first  + dst[5];
 
  319         sums[4] = sums[3] - 
first  + dst[6];
 
  320         sums[5] = sums[4] - dst[0] + dst[7];
 
  321         sums[6] = sums[5] - dst[1] + last;
 
  322         sums[7] = sums[6] - dst[2] + last;
 
  323         sums[8] = sums[7] - dst[3] + last;
 
  324         sums[9] = sums[8] - dst[4] + last;
 
  326         dst[0]= (sums[0] + sums[2] + 2*dst[0])>>4;
 
  327         dst[1]= (sums[1] + sums[3] + 2*dst[1])>>4;
 
  328         dst[2]= (sums[2] + sums[4] + 2*dst[2])>>4;
 
  329         dst[3]= (sums[3] + sums[5] + 2*dst[3])>>4;
 
  330         dst[4]= (sums[4] + sums[6] + 2*dst[4])>>4;
 
  331         dst[5]= (sums[5] + sums[7] + 2*dst[5])>>4;
 
  332         dst[6]= (sums[6] + sums[8] + 2*dst[6])>>4;
 
  333         dst[7]= (sums[7] + sums[9] + 2*dst[7])>>4;
 
  350     static uint64_t lut[256];
 
  356             int v= 
i < 128 ? 2*
i : 2*(
i-256);
 
  365             uint64_t 
a= (v/16)   & 0xFF;
 
  366             uint64_t 
b= (v*3/16) & 0xFF;
 
  367             uint64_t 
c= (v*5/16) & 0xFF;
 
  368             uint64_t 
d= (7*v/16) & 0xFF;
 
  369             uint64_t 
A= (0x100 - 
a)&0xFF;
 
  370             uint64_t 
B= (0x100 - 
b)&0xFF;
 
  371             uint64_t 
C= (0x100 - 
c)&0xFF;
 
  372             uint64_t 
D= (0x100 - 
c)&0xFF;
 
  374             lut[
i]   = (
a<<56) | (
b<<48) | (
c<<40) | (
d<<32) |
 
  375                        (
D<<24) | (
C<<16) | (
B<<8)  | (
A);
 
  409     const int dcOffset= ((
c->nonBQP*
c->ppMode.baseDcDiff)>>8) + 1;
 
  410     const int dcThreshold= dcOffset*2 + 1;
 
  416         numEq += ((unsigned)(
src[-1*
step] - 
src[0*
step] + dcOffset)) < dcThreshold;
 
  417         numEq += ((unsigned)(
src[ 0*
step] - 
src[1*
step] + dcOffset)) < dcThreshold;
 
  418         numEq += ((unsigned)(
src[ 1*
step] - 
src[2*
step] + dcOffset)) < dcThreshold;
 
  419         numEq += ((unsigned)(
src[ 2*
step] - 
src[3*
step] + dcOffset)) < dcThreshold;
 
  420         numEq += ((unsigned)(
src[ 3*
step] - 
src[4*
step] + dcOffset)) < dcThreshold;
 
  421         numEq += ((unsigned)(
src[ 4*
step] - 
src[5*
step] + dcOffset)) < dcThreshold;
 
  422         numEq += ((unsigned)(
src[ 5*
step] - 
src[6*
step] + dcOffset)) < dcThreshold;
 
  423         numEq += ((unsigned)(
src[ 6*
step] - 
src[7*
step] + dcOffset)) < dcThreshold;
 
  424         numEq += ((unsigned)(
src[ 7*
step] - 
src[8*
step] + dcOffset)) < dcThreshold;
 
  425         if(numEq > 
c->ppMode.flatnessThreshold){
 
  455                 sums[6] = sums[5] - 
src[1*
step] + last;
 
  456                 sums[7] = sums[6] - 
src[2*
step] + last;
 
  457                 sums[8] = sums[7] - 
src[3*
step] + last;
 
  458                 sums[9] = sums[8] - 
src[4*
step] + last;
 
  482             if(
FFABS(middleEnergy) < 8*
QP){
 
  502                     d= (
d < 0) ? 32 : -32;
 
  520 #define TEMPLATE_PP_C 1 
  524 #   define TEMPLATE_PP_ALTIVEC 1 
  529 #if ARCH_X86 && HAVE_INLINE_ASM 
  530 #    if CONFIG_RUNTIME_CPUDETECT 
  531 #        define TEMPLATE_PP_MMX 1 
  533 #        define TEMPLATE_PP_MMXEXT 1 
  535 #        define TEMPLATE_PP_3DNOW 1 
  537 #        define TEMPLATE_PP_SSE2 1 
  540 #        if HAVE_SSE2_INLINE 
  541 #            define TEMPLATE_PP_SSE2 1 
  543 #        elif HAVE_MMXEXT_INLINE 
  544 #            define TEMPLATE_PP_MMXEXT 1 
  546 #        elif HAVE_AMD3DNOW_INLINE 
  547 #            define TEMPLATE_PP_3DNOW 1 
  549 #        elif HAVE_MMX_INLINE 
  550 #            define TEMPLATE_PP_MMX 1 
  556 typedef void (*
pp_fn)(
const uint8_t 
src[], 
int srcStride, uint8_t dst[], 
int dstStride, 
int width, 
int height,
 
  557                       const int8_t QPs[], 
int QPStride, 
int isColor, 
PPContext *
c2);
 
  562     pp_fn pp = postProcess_C;
 
  568 #if CONFIG_RUNTIME_CPUDETECT 
  569 #if ARCH_X86 && HAVE_INLINE_ASM 
  580         pp = postProcess_SSE2;
 
  581 #elif   HAVE_MMXEXT_INLINE 
  582         pp = postProcess_MMX2;
 
  583 #elif HAVE_AMD3DNOW_INLINE 
  584         pp = postProcess_3DNow;
 
  585 #elif HAVE_MMX_INLINE 
  586         pp = postProcess_MMX;
 
  588         pp = postProcess_altivec;
 
  593     pp(
src, srcStride, dst, dstStride, 
width, 
height, QPs, QPStride, isColor, 
c);
 
  599 "Available postprocessing filters:\n" 
  601 "short  long name       short   long option     Description\n" 
  602 "*      *               a       autoq           CPU power dependent enabler\n" 
  603 "                       c       chrom           chrominance filtering enabled\n" 
  604 "                       y       nochrom         chrominance filtering disabled\n" 
  605 "                       n       noluma          luma filtering disabled\n" 
  606 "hb     hdeblock        (2 threshold)           horizontal deblocking filter\n" 
  607 "       1. difference factor: default=32, higher -> more deblocking\n" 
  608 "       2. flatness threshold: default=39, lower -> more deblocking\n" 
  609 "                       the h & v deblocking filters share these\n" 
  610 "                       so you can't set different thresholds for h / v\n" 
  611 "vb     vdeblock        (2 threshold)           vertical deblocking filter\n" 
  612 "ha     hadeblock       (2 threshold)           horizontal deblocking filter\n" 
  613 "va     vadeblock       (2 threshold)           vertical deblocking filter\n" 
  614 "h1     x1hdeblock                              experimental h deblock filter 1\n" 
  615 "v1     x1vdeblock                              experimental v deblock filter 1\n" 
  616 "dr     dering                                  deringing filter\n" 
  617 "al     autolevels                              automatic brightness / contrast\n" 
  618 "                       f        fullyrange     stretch luminance to (0..255)\n" 
  619 "lb     linblenddeint                           linear blend deinterlacer\n" 
  620 "li     linipoldeint                            linear interpolating deinterlace\n" 
  621 "ci     cubicipoldeint                          cubic interpolating deinterlacer\n" 
  622 "md     mediandeint                             median deinterlacer\n" 
  623 "fd     ffmpegdeint                             ffmpeg deinterlacer\n" 
  624 "l5     lowpass5                                FIR lowpass deinterlacer\n" 
  625 "de     default                                 hb:a,vb:a,dr:a\n" 
  626 "fa     fast                                    h1:a,v1:a,dr:a\n" 
  627 "ac                                             ha:a:128:7,va:a,dr:a\n" 
  628 "tn     tmpnoise        (3 threshold)           temporal noise reducer\n" 
  629 "                     1. <= 2. <= 3.            larger -> stronger filtering\n" 
  630 "fq     forceQuant      <quantizer>             force quantizer\n" 
  632 "<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]...\n" 
  633 "long form example:\n" 
  634 "vdeblock:autoq/hdeblock:autoq/linblenddeint    default,-vdeblock\n" 
  635 "short form example:\n" 
  636 "vb:a/hb:a/lb                                   de,-vb\n" 
  646     static const char filterDelimiters[] = 
",/";
 
  647     static const char optionDelimiters[] = 
":|";
 
  656     if (!strcmp(
name, 
"help")) {
 
  658         for (p = 
pp_help; strchr(p, 
'\n'); p = strchr(p, 
'\n') + 1) {
 
  687         const char *filterName;
 
  695         int numOfUnknownOptions=0;
 
  699         filterToken= 
av_strtok(p, filterDelimiters, &tokstate);
 
  700         if(!filterToken) 
break;
 
  701         p+= strlen(filterToken) + 1; 
 
  702         filterName= 
av_strtok(filterToken, optionDelimiters, &tokstate);
 
  709         if(*filterName == 
'-'){
 
  720             else if(!strcmp(
"nochrom", 
option) || !strcmp(
"y", 
option)) chrom=0;
 
  721             else if(!strcmp(
"chrom", 
option) || !strcmp(
"c", 
option)) chrom=1;
 
  722             else if(!strcmp(
"noluma", 
option) || !strcmp(
"n", 
option)) luma=0;
 
  725                 numOfUnknownOptions++;
 
  741                 spaceLeft= p - 
temp + plen;
 
  746                 memmove(p + newlen, p, plen+1);
 
  753             if(   !strcmp(
filters[
i].longName, filterName)
 
  754                || !strcmp(
filters[
i].shortName, filterName)){
 
  761                 if(q >= 
filters[
i].minLumQuality && luma)
 
  763                 if(chrom==1 || (chrom==-1 && 
filters[
i].chromDefault))
 
  772                         if(  !strcmp(
options[o],
"fullyrange")
 
  776                             numOfUnknownOptions--;
 
  791                             numOfUnknownOptions--;
 
  792                             if(numOfNoises >= 3) 
break;
 
  800                     for(o=0; 
options[o] && o<2; o++){
 
  805                         numOfUnknownOptions--;
 
  814                     for(o=0; 
options[o] && o<1; o++){
 
  819                         numOfUnknownOptions--;
 
  825         if(!filterNameOk) ppMode->
error++;
 
  826         ppMode->
error += numOfUnknownOptions;
 
  848     int mbWidth = (
width+15)>>4;
 
  849     int mbHeight= (
height+15)>>4;
 
  853     c->qpStride= qpStride;
 
  869     reallocAlign((
void **)&
c->nonBQPTable, qpStride*mbHeight*
sizeof(int8_t));
 
  870     reallocAlign((
void **)&
c->stdQPTable, qpStride*mbHeight*
sizeof(int8_t));
 
  871     reallocAlign((
void **)&
c->forcedQPTable, mbWidth*
sizeof(int8_t));
 
  883     int qpStride= (
width+15)/16 + 2; 
 
  890         c->hChromaSubSample= cpuCaps&0x3;
 
  891         c->vChromaSubSample= (cpuCaps>>4)&0x3;
 
  893         c->hChromaSubSample= 1;
 
  894         c->vChromaSubSample= 1;
 
  937                      uint8_t * dst[3], 
const int dstStride[3],
 
  939                      const int8_t *QP_store,  
int QPStride,
 
  940                      pp_mode *vm,  
void *vc, 
int pict_type)
 
  942     int mbWidth = (
width+15)>>4;
 
  943     int mbHeight= (
height+15)>>4;
 
  947     int absQPStride = 
FFABS(QPStride);
 
  950     if(
c->stride < minStride || 
c->qpStride < absQPStride)
 
  952                        FFMAX(minStride, 
c->stride),
 
  953                        FFMAX(
c->qpStride, absQPStride));
 
  957         QP_store= 
c->forcedQPTable;
 
  958         absQPStride = QPStride = 0;
 
  960             for(
i=0; 
i<mbWidth; 
i++) 
c->forcedQPTable[
i]= 
mode->forcedQuant;
 
  962             for(
i=0; 
i<mbWidth; 
i++) 
c->forcedQPTable[
i]= 1;
 
  967         const int count= 
FFMAX(mbHeight * absQPStride, mbWidth);
 
  968         for(
i=0; 
i<(count>>2); 
i++){
 
  971         for(
i<<=2; 
i<count; 
i++){
 
  972             c->stdQPTable[
i] = QP_store[
i]>>1;
 
  974         QP_store= 
c->stdQPTable;
 
  975         QPStride= absQPStride;
 
  980         for(y=0; y<mbHeight; y++){
 
  981             for(x=0; x<mbWidth; x++){
 
  989     if((pict_type&7)!=3){
 
  992             const int count= 
FFMAX(mbHeight * QPStride, mbWidth);
 
  993             for(
i=0; 
i<(count>>2); 
i++){
 
  996             for(
i<<=2; 
i<count; 
i++){
 
  997                 c->nonBQPTable[
i] = QP_store[
i] & 0x3F;
 
 1001             for(
i=0; 
i<mbHeight; 
i++) {
 
 1002                 for(j=0; j<absQPStride; j++) {
 
 1003                     c->nonBQPTable[
i*absQPStride+j] = QP_store[
i*QPStride+j] & 0x3F;
 
 1015     if (!(
src[1] && 
src[2] && dst[1] && dst[2]))
 
 1021     if(
mode->chromMode){
 
 1027     else if(srcStride[1] == dstStride[1] && srcStride[2] == dstStride[2]){
 
 1033             memcpy(&(dst[1][y*dstStride[1]]), &(
src[1][y*srcStride[1]]), 
width);
 
 1034             memcpy(&(dst[2][y*dstStride[2]]), &(
src[2][y*srcStride[2]]), 
width);