Imported Debian version 2.5.0~trusty1.1
[deb_ffmpeg.git] / ffmpeg / libpostproc / postprocess.c
index 670908ca9fabb6a6bbb68cc243484ddea210e6aa..f8fb35639194f786592bd40fbefb8935a0f3b73b 100644 (file)
@@ -151,6 +151,7 @@ static const struct PPFilter filters[]=
     {"tn", "tmpnoise",              1, 7, 8, TEMP_NOISE_FILTER},
     {"fq", "forcequant",            1, 0, 0, FORCE_QUANT},
     {"be", "bitexact",              1, 0, 0, BITEXACT},
+    {"vi", "visualize",             1, 0, 0, VISUALIZE},
     {NULL, NULL,0,0,0,0} //End Marker
 };
 
@@ -166,28 +167,28 @@ static const char * const replaceTable[]=
 
 
 #if ARCH_X86 && HAVE_INLINE_ASM
-static inline void prefetchnta(void *p)
+static inline void prefetchnta(const void *p)
 {
     __asm__ volatile(   "prefetchnta (%0)\n\t"
         : : "r" (p)
     );
 }
 
-static inline void prefetcht0(void *p)
+static inline void prefetcht0(const void *p)
 {
     __asm__ volatile(   "prefetcht0 (%0)\n\t"
         : : "r" (p)
     );
 }
 
-static inline void prefetcht1(void *p)
+static inline void prefetcht1(const void *p)
 {
     __asm__ volatile(   "prefetcht1 (%0)\n\t"
         : : "r" (p)
     );
 }
 
-static inline void prefetcht2(void *p)
+static inline void prefetcht2(const void *p)
 {
     __asm__ volatile(   "prefetcht2 (%0)\n\t"
         : : "r" (p)
@@ -209,13 +210,13 @@ static inline int isHorizDC_C(const uint8_t src[], int stride, const PPContext *
     const int dcThreshold= dcOffset*2 + 1;
 
     for(y=0; y<BLOCK_SIZE; y++){
-        if(((unsigned)(src[0] - src[1] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[1] - src[2] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[2] - src[3] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[3] - src[4] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[4] - src[5] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[5] - src[6] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[6] - src[7] + dcOffset)) < dcThreshold) numEq++;
+        numEq += ((unsigned)(src[0] - src[1] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[1] - src[2] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[2] - src[3] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[3] - src[4] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[4] - src[5] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[5] - src[6] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[6] - src[7] + dcOffset)) < dcThreshold;
         src+= stride;
     }
     return numEq > c->ppMode.flatnessThreshold;
@@ -233,14 +234,14 @@ static inline int isVertDC_C(const uint8_t src[], int stride, const PPContext *c
 
     src+= stride*4; // src points to begin of the 8x8 Block
     for(y=0; y<BLOCK_SIZE-1; y++){
-        if(((unsigned)(src[0] - src[0+stride] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[1] - src[1+stride] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[2] - src[2+stride] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[3] - src[3+stride] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[4] - src[4+stride] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[5] - src[5+stride] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[6] - src[6+stride] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[7] - src[7+stride] + dcOffset)) < dcThreshold) numEq++;
+        numEq += ((unsigned)(src[0] - src[0+stride] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[1] - src[1+stride] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[2] - src[2+stride] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[3] - src[3+stride] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[4] - src[4+stride] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[5] - src[5+stride] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[6] - src[6+stride] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[7] - src[7+stride] + dcOffset)) < dcThreshold;
         src+= stride;
     }
     return numEq > c->ppMode.flatnessThreshold;
@@ -278,10 +279,7 @@ static inline int isVertMinMaxOk_C(const uint8_t src[], int stride, int QP)
 static inline int horizClassify_C(const uint8_t src[], int stride, const PPContext *c)
 {
     if( isHorizDC_C(src, stride, c) ){
-        if( isHorizMinMaxOk_C(src, stride, c->QP) )
-            return 1;
-        else
-            return 0;
+        return isHorizMinMaxOk_C(src, stride, c->QP);
     }else{
         return 2;
     }
@@ -290,10 +288,7 @@ static inline int horizClassify_C(const uint8_t src[], int stride, const PPConte
 static inline int vertClassify_C(const uint8_t src[], int stride, const PPContext *c)
 {
     if( isVertDC_C(src, stride, c) ){
-        if( isVertMinMaxOk_C(src, stride, c->QP) )
-            return 1;
-        else
-            return 0;
+        return isVertMinMaxOk_C(src, stride, c->QP);
     }else{
         return 2;
     }
@@ -436,7 +431,7 @@ static inline void horizX1Filter(uint8_t *src, int stride, int QP)
  * accurate deblock filter
  */
 static av_always_inline void do_a_deblock_C(uint8_t *src, int step,
-                                            int stride, const PPContext *c)
+                                            int stride, const PPContext *c, int mode)
 {
     int y;
     const int QP= c->QP;
@@ -447,15 +442,15 @@ static av_always_inline void do_a_deblock_C(uint8_t *src, int step,
     for(y=0; y<8; y++){
         int numEq= 0;
 
-        if(((unsigned)(src[-1*step] - src[0*step] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[ 0*step] - src[1*step] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[ 1*step] - src[2*step] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[ 2*step] - src[3*step] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[ 3*step] - src[4*step] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[ 4*step] - src[5*step] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[ 5*step] - src[6*step] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[ 6*step] - src[7*step] + dcOffset)) < dcThreshold) numEq++;
-        if(((unsigned)(src[ 7*step] - src[8*step] + dcOffset)) < dcThreshold) numEq++;
+        numEq += ((unsigned)(src[-1*step] - src[0*step] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[ 0*step] - src[1*step] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[ 1*step] - src[2*step] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[ 2*step] - src[3*step] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[ 3*step] - src[4*step] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[ 4*step] - src[5*step] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[ 5*step] - src[6*step] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[ 6*step] - src[7*step] + dcOffset)) < dcThreshold;
+        numEq += ((unsigned)(src[ 7*step] - src[8*step] + dcOffset)) < dcThreshold;
         if(numEq > c->ppMode.flatnessThreshold){
             int min, max, x;
 
@@ -491,6 +486,16 @@ static av_always_inline void do_a_deblock_C(uint8_t *src, int step,
                 sums[8] = sums[7] - src[3*step] + last;
                 sums[9] = sums[8] - src[4*step] + last;
 
+                if (mode & VISUALIZE) {
+                    src[0*step] =
+                    src[1*step] =
+                    src[2*step] =
+                    src[3*step] =
+                    src[4*step] =
+                    src[5*step] =
+                    src[6*step] =
+                    src[7*step] = 128;
+                }
                 src[0*step]= (sums[0] + sums[2] + 2*src[0*step])>>4;
                 src[1*step]= (sums[1] + sums[3] + 2*src[1*step])>>4;
                 src[2*step]= (sums[2] + sums[4] + 2*src[2*step])>>4;
@@ -522,6 +527,13 @@ static av_always_inline void do_a_deblock_C(uint8_t *src, int step,
                     d = FFMAX(d, q);
                 }
 
+                if ((mode & VISUALIZE) && d) {
+                    d= (d < 0) ? 32 : -32;
+                    src[3*step]= av_clip_uint8(src[3*step] - d);
+                    src[4*step]= av_clip_uint8(src[4*step] + d);
+                    d = 0;
+                }
+
                 src[3*step]-= d;
                 src[4*step]+= d;
             }
@@ -704,21 +716,22 @@ pp_mode *pp_get_mode_by_name_and_quality(const char *name, int quality)
     av_log(NULL, AV_LOG_DEBUG, "pp: %s\n", name);
 
     for(;;){
-        char *filterName;
+        const char *filterName;
         int q= 1000000; //PP_QUALITY_MAX;
         int chrom=-1;
         int luma=-1;
-        char *option;
-        char *options[OPTIONS_ARRAY_SIZE];
+        const char *option;
+        const char *options[OPTIONS_ARRAY_SIZE];
         int i;
         int filterNameOk=0;
         int numOfUnknownOptions=0;
         int enable=1; //does the user want us to enabled or disabled the filter
+        char *tokstate;
 
-        filterToken= strtok(p, filterDelimiters);
+        filterToken= av_strtok(p, filterDelimiters, &tokstate);
         if(!filterToken) break;
         p+= strlen(filterToken) + 1; // p points to next filterToken
-        filterName= strtok(filterToken, optionDelimiters);
+        filterName= av_strtok(filterToken, optionDelimiters, &tokstate);
         if (!filterName) {
             ppMode->error++;
             break;
@@ -731,7 +744,7 @@ pp_mode *pp_get_mode_by_name_and_quality(const char *name, int quality)
         }
 
         for(;;){ //for all options
-            option= strtok(NULL, optionDelimiters);
+            option= av_strtok(NULL, optionDelimiters, &tokstate);
             if(!option) break;
 
             av_log(NULL, AV_LOG_DEBUG, "pp: option: %s\n", option);
@@ -858,7 +871,7 @@ void pp_free_mode(pp_mode *mode){
     av_free(mode);
 }
 
-static void reallocAlign(void **p, int alignment, int size){
+static void reallocAlign(void **p, int size){
     av_free(*p);
     *p= av_mallocz(size);
 }
@@ -871,23 +884,23 @@ static void reallocBuffers(PPContext *c, int width, int height, int stride, int
     c->stride= stride;
     c->qpStride= qpStride;
 
-    reallocAlign((void **)&c->tempDst, 8, stride*24+32);
-    reallocAlign((void **)&c->tempSrc, 8, stride*24);
-    reallocAlign((void **)&c->tempBlocks, 8, 2*16*8);
-    reallocAlign((void **)&c->yHistogram, 8, 256*sizeof(uint64_t));
+    reallocAlign((void **)&c->tempDst, stride*24+32);
+    reallocAlign((void **)&c->tempSrc, stride*24);
+    reallocAlign((void **)&c->tempBlocks, 2*16*8);
+    reallocAlign((void **)&c->yHistogram, 256*sizeof(uint64_t));
     for(i=0; i<256; i++)
             c->yHistogram[i]= width*height/64*15/256;
 
     for(i=0; i<3; i++){
         //Note: The +17*1024 is just there so I do not have to worry about r/w over the end.
-        reallocAlign((void **)&c->tempBlurred[i], 8, stride*mbHeight*16 + 17*1024);
-        reallocAlign((void **)&c->tempBlurredPast[i], 8, 256*((height+7)&(~7))/2 + 17*1024);//FIXME size
+        reallocAlign((void **)&c->tempBlurred[i], stride*mbHeight*16 + 17*1024);
+        reallocAlign((void **)&c->tempBlurredPast[i], 256*((height+7)&(~7))/2 + 17*1024);//FIXME size
     }
 
-    reallocAlign((void **)&c->deintTemp, 8, 2*width+32);
-    reallocAlign((void **)&c->nonBQPTable, 8, qpStride*mbHeight*sizeof(QP_STORE_T));
-    reallocAlign((void **)&c->stdQPTable, 8, qpStride*mbHeight*sizeof(QP_STORE_T));
-    reallocAlign((void **)&c->forcedQPTable, 8, mbWidth*sizeof(QP_STORE_T));
+    reallocAlign((void **)&c->deintTemp, 2*width+32);
+    reallocAlign((void **)&c->nonBQPTable, qpStride*mbHeight*sizeof(QP_STORE_T));
+    reallocAlign((void **)&c->stdQPTable, qpStride*mbHeight*sizeof(QP_STORE_T));
+    reallocAlign((void **)&c->forcedQPTable, mbWidth*sizeof(QP_STORE_T));
 }
 
 static const char * context_to_name(void * ptr) {
@@ -931,8 +944,10 @@ void pp_free_context(void *vc){
     PPContext *c = (PPContext*)vc;
     int i;
 
-    for(i=0; i<3; i++) av_free(c->tempBlurred[i]);
-    for(i=0; i<3; i++) av_free(c->tempBlurredPast[i]);
+    for(i=0; i<FF_ARRAY_ELEMS(c->tempBlurred); i++)
+        av_free(c->tempBlurred[i]);
+    for(i=0; i<FF_ARRAY_ELEMS(c->tempBlurredPast); i++)
+        av_free(c->tempBlurredPast[i]);
 
     av_free(c->tempBlocks);
     av_free(c->yHistogram);
@@ -956,8 +971,8 @@ void  pp_postprocess(const uint8_t * src[3], const int srcStride[3],
 {
     int mbWidth = (width+15)>>4;
     int mbHeight= (height+15)>>4;
-    PPMode *mode = (PPMode*)vm;
-    PPContext *c = (PPContext*)vc;
+    PPMode *mode = vm;
+    PPContext *c = vc;
     int minStride= FFMAX(FFABS(srcStride[0]), FFABS(dstStride[0]));
     int absQPStride = FFABS(QPStride);
 
@@ -1027,6 +1042,9 @@ void  pp_postprocess(const uint8_t * src[3], const int srcStride[3],
     postProcess(src[0], srcStride[0], dst[0], dstStride[0],
                 width, height, QP_store, QPStride, 0, mode, c);
 
+    if (!(src[1] && src[2] && dst[1] && dst[2]))
+        return;
+
     width  = (width )>>c->hChromaSubSample;
     height = (height)>>c->vChromaSubSample;