OSDN Git Service

Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Sat, 13 Aug 2011 20:23:40 +0000 (22:23 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sat, 13 Aug 2011 20:24:47 +0000 (22:24 +0200)
* qatar/master:
  swscale: add dithering to yuv2yuvX_altivec_real
  rv34: free+allocate buffer instead of reallocating it to preserve alignment
  h264: add missing brackets.
  swscale: use 15-bit intermediates for 9/10-bit scaling.

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/h264_refs.c
libavcodec/rv34.c
libswscale/ppc/swscale_altivec.c
libswscale/swscale.c
libswscale/swscale_internal.h
libswscale/utils.c
libswscale/x86/swscale_template.c
tests/ref/lavfi/pixfmts_scale

Simple merge
Simple merge
Simple merge
@@@ -307,20 -211,12 +307,12 @@@ yuv2yuvX16_c_template(const int16_t *lu
  
  #define output_pixel(pos, val) \
      if (big_endian) { \
-         if (output_bits == 16) { \
-             AV_WB16(pos, av_clip_uint16(val >> shift)); \
-         } else { \
-             AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits)); \
-         } \
+         AV_WB16(pos, av_clip_uint16(val >> shift)); \
      } else { \
-         if (output_bits == 16) { \
-             AV_WL16(pos, av_clip_uint16(val >> shift)); \
-         } else { \
-             AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \
-         } \
+         AV_WL16(pos, av_clip_uint16(val >> shift)); \
      }
      for (i = 0; i < dstW; i++) {
 -        int val = 1 << (30-output_bits - 1);
 +        int val = 1 << (26-output_bits + 4*dword - 1);
          int j;
  
          for (j = 0; j < lumFilterSize; j++)
@@@ -1979,11 -1917,8 +2031,11 @@@ static void hScale16To19_c(SwsContext *
      int32_t *dst = (int32_t *) _dst;
      const uint16_t *src = (const uint16_t *) _src;
      int bits = av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
-     int sh = (bits <= 7) ? 11 : (bits - 4);
+     int sh = bits - 4;
  
 +    if((isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8) && av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1<15)
 +        sh= 9;
 +
      for (i = 0; i < dstW; i++) {
          int j;
          int srcPos = filterPos[i];
@@@ -2016,35 -1972,25 +2089,54 @@@ static void hScale8To15_c(SwsContext *c
      }
  }
  
 +static inline void hScale16N_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc,
 +                                    const int16_t *filter, const int16_t *filterPos, long filterSize, int shift)
 +{
 +    int i, j;
 +
 +    for (i=0; i<dstW; i++) {
 +        int srcPos= filterPos[i];
 +        int val=0;
 +        for (j=0; j<filterSize; j++) {
 +            val += ((int)src[srcPos + j])*filter[filterSize*i + j];
 +        }
 +        dst[i] = FFMIN(val>>shift, (1<<15)-1); // the cubic equation does overflow ...
 +    }
 +}
 +
 +static inline void hScale16NX_c(int16_t *dst, int dstW, const uint16_t *src, int srcW, int xInc,
 +                                    const int16_t *filter, const int16_t *filterPos, long filterSize, int shift)
 +{
 +    int i, j;
 +    for (i=0; i<dstW; i++) {
 +        int srcPos= filterPos[i];
 +        int val=0;
 +        for (j=0; j<filterSize; j++) {
 +            val += ((int)av_bswap16(src[srcPos + j]))*filter[filterSize*i + j];
 +        }
 +        dst[i] = FFMIN(val>>shift, (1<<15)-1); // the cubic equation does overflow ...
 +    }
 +}
 +
+ static void hScale8To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *src,
+                           const int16_t *filter, const int16_t *filterPos,
+                           int filterSize)
+ {
+     int i;
+     int32_t *dst = (int32_t *) _dst;
+     for (i=0; i<dstW; i++) {
+         int j;
+         int srcPos= filterPos[i];
+         int val=0;
+         for (j=0; j<filterSize; j++) {
+             val += ((int)src[srcPos + j])*filter[filterSize*i + j];
+         }
+         //filter += hFilterSize;
+         dst[i] = FFMIN(val>>3, (1<<19)-1); // the cubic equation does overflow ...
+         //dst[i] = val>>7;
+     }
+ }
  //FIXME all pal and rgb srcFormats could do this convertion as well
  //FIXME all scalers more complex than bilinear could do half of this transform
  static void chrRangeToJpeg_c(int16_t *dstU, int16_t *dstV, int width)
@@@ -2122,27 -2068,8 +2214,10 @@@ static void hyscale_fast_c(SwsContext *
          dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;
          xpos+=xInc;
      }
 +    for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--)
 +        dst[i] = src[srcW-1]*128;
  }
  
- static void scale8To16Rv_c(uint16_t *_dst, const uint8_t *src, int len)
- {
-     int i;
-     uint8_t *dst = (uint8_t *) _dst;
-     for (i = len - 1; i >= 0; i--) {
-         dst[i * 2] = dst[i * 2 + 1] = src[i];
-     }
- }
- static void scale19To15Fw_c(int16_t *dst, const int32_t *src, int len)
- {
-     int i;
-     for (i = 0; i < len; i++) {
-         dst[i] = src[i] >> 4;
-     }
- }
  // *** horizontal scale Y line to temp buffer
  static av_always_inline void hyscale(SwsContext *c, int16_t *dst, int dstWidth,
                                       const uint8_t *src, int srcW, int xInc,
          src= formatConvBuffer;
      }
  
-     if (av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1 < 8 && c->scalingBpp == 16 && !isAnyRGB(c->srcFormat)) {
-         c->scale8To16Rv((uint16_t *) formatConvBuffer, src, srcW);
-         src = formatConvBuffer;
-     }
 -    if (!c->hyscale_fast) {
 +    if (c->hScale16) {
 +        int shift= isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8 ? 13 : av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
 +        c->hScale16(dst, dstWidth, (const uint16_t*)src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize, shift);
 +    } else if (!c->hyscale_fast) {
          c->hScale(c, dst, dstWidth, src, hLumFilter, hLumFilterPos, hLumFilterSize);
      } else { // fast bilinear upscale / crap downscale
          c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);
@@@ -2213,19 -2124,7 +2279,11 @@@ static av_always_inline void hcscale(Sw
          src2= buf2;
      }
  
-     if (av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1 < 8 && c->scalingBpp == 16 && !isAnyRGB(c->srcFormat)) {
-         uint8_t *buf2 = (formatConvBuffer + FFALIGN(srcW * 2+78, 16));
-         c->scale8To16Rv((uint16_t *) formatConvBuffer, src1, srcW);
-         c->scale8To16Rv((uint16_t *) buf2,             src2, srcW);
-         src1 = formatConvBuffer;
-         src2 = buf2;
-     }
 -    if (!c->hcscale_fast) {
 +    if (c->hScale16) {
 +        int shift= isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8 ? 13 : av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
 +        c->hScale16(dst1, dstWidth, (const uint16_t*)src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, shift);
 +        c->hScale16(dst2, dstWidth, (const uint16_t*)src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize, shift);
 +    } else if (!c->hcscale_fast) {
          c->hScale(c, dst1, dstWidth, src1, hChrFilter, hChrFilterPos, hChrFilterSize);
          c->hScale(c, dst2, dstWidth, src2, hChrFilter, hChrFilterPos, hChrFilterSize);
      } else { // fast bilinear upscale / crap downscale
@@@ -2771,17 -2660,12 +2824,17 @@@ static av_cold void sws_init_swScale_c(
          case PIX_FMT_PAL8     :
          case PIX_FMT_BGR4_BYTE:
          case PIX_FMT_RGB4_BYTE: c->chrToYV12 = palToUV_c; break;
 -#if HAVE_BIGENDIAN
 +        case PIX_FMT_YUV444P9BE:
 +        case PIX_FMT_YUV420P9BE:
 +        case PIX_FMT_YUV444P10BE:
 +        case PIX_FMT_YUV422P10BE:
-         case PIX_FMT_YUV420P10BE: c->hScale16= HAVE_BIGENDIAN ? hScale16N_c : hScale16NX_c; break;
++        case PIX_FMT_YUV420P10BE: c->hScale16= HAVE_BIGENDIAN ? NULL : hScale16NX_c; break;
          case PIX_FMT_YUV444P9LE:
          case PIX_FMT_YUV420P9LE:
          case PIX_FMT_YUV422P10LE:
 -        case PIX_FMT_YUV444P10LE:
          case PIX_FMT_YUV420P10LE:
-         case PIX_FMT_YUV444P10LE: c->hScale16= HAVE_BIGENDIAN ? hScale16NX_c : hScale16N_c; break;
++        case PIX_FMT_YUV444P10LE: c->hScale16= HAVE_BIGENDIAN ? hScale16NX_c : NULL; break;
 +#if HAVE_BIGENDIAN
          case PIX_FMT_YUV420P16LE:
          case PIX_FMT_YUV422P16LE:
          case PIX_FMT_YUV444P16LE: c->chrToYV12 = bswap16UV_c; break;
          }
      }
  
-     if((isAnyRGB(c->srcFormat) && av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1<15)
-        || c->srcFormat == PIX_FMT_PAL8)
-         c->hScale16= hScale16N_c;
-     if (c->scalingBpp == 8) {
-     c->hScale       = hScale_c;
-     if (c->flags & SWS_FAST_BILINEAR) {
-         c->hyscale_fast = hyscale_fast_c;
-         c->hcscale_fast = hcscale_fast_c;
-     }
 +
-     if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
-         if (c->srcRange) {
-             c->lumConvertRange = lumRangeFromJpeg_c;
-             c->chrConvertRange = chrRangeFromJpeg_c;
+     if (c->srcBpc == 8) {
+         if (c->dstBpc <= 10) {
++            if((isAnyRGB(c->srcFormat) && av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1<15)
++            || c->srcFormat == PIX_FMT_PAL8)
++                c->hScale16= hScale16N_c;
+             c->hScale       = hScale8To15_c;
+             if (c->flags & SWS_FAST_BILINEAR) {
+                 c->hyscale_fast = hyscale_fast_c;
+                 c->hcscale_fast = hcscale_fast_c;
+             }
          } else {
-             c->lumConvertRange = lumRangeToJpeg_c;
-             c->chrConvertRange = chrRangeToJpeg_c;
+             c->hScale = hScale8To19_c;
++            av_assert0(c->hScale16 != hScale16N_c && c->hScale16 != hScale16NX_c);
          }
-     }
      } else {
-         if(c->hScale16 == hScale16NX_c && !isAnyRGB(c->srcFormat)){
-             c->chrToYV12 = bswap16UV_c;
-             c->lumToYV12 = bswap16Y_c;
++        if(c->dstBpc > 10){
++            if((isAnyRGB(c->srcFormat) && av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1<15)
++            || c->srcFormat == PIX_FMT_PAL8)
++                c->hScale16= hScale16N_c;
++            if(c->hScale16 == hScale16NX_c && !isAnyRGB(c->srcFormat)){
++                c->chrToYV12 = bswap16UV_c;
++                c->lumToYV12 = bswap16Y_c;
++            }
++            c->hScale16 = NULL;
 +        }
-         c->hScale16 = NULL;
-         c->hScale = hScale16_c;
-         c->scale19To15Fw = scale19To15Fw_c;
-         c->scale8To16Rv  = scale8To16Rv_c;
+         c->hScale = c->dstBpc > 10 ? hScale16To19_c : hScale16To15_c;
+     }
  
-         if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
+     if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
+         if (c->dstBpc <= 10) {
+             if (c->srcRange) {
+                 c->lumConvertRange = lumRangeFromJpeg_c;
+                 c->chrConvertRange = chrRangeFromJpeg_c;
+             } else {
+                 c->lumConvertRange = lumRangeToJpeg_c;
+                 c->chrConvertRange = chrRangeToJpeg_c;
+             }
+         } else {
              if (c->srcRange) {
                  c->lumConvertRange = lumRangeFromJpeg16_c;
                  c->chrConvertRange = chrRangeFromJpeg16_c;
Simple merge
@@@ -842,14 -853,18 +842,18 @@@ int sws_init_context(SwsContext *c, Sws
          }
      }
  
-     c->scalingBpp = FFMAX(av_pix_fmt_descriptors[srcFormat].comp[0].depth_minus1,
-                           av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1) >= 15 ? 16 : 8;
-     if (c->scalingBpp == 16)
+     c->srcBpc = 1 + av_pix_fmt_descriptors[srcFormat].comp[0].depth_minus1;
+     if (c->srcBpc < 8)
+         c->srcBpc = 8;
+     c->dstBpc = 1 + av_pix_fmt_descriptors[dstFormat].comp[0].depth_minus1;
+     if (c->dstBpc < 8)
+         c->dstBpc = 8;
++    if (isAnyRGB(srcFormat) && c->dstBpc == 16)
++        c->srcBpc = 16;
+     if (c->dstBpc == 16)
          dst_stride <<= 1;
-     av_assert0(c->scalingBpp<=16);
 -    FF_ALLOC_OR_GOTO(c, c->formatConvBuffer,
 -                     FFALIGN(srcW, 16) * 2 * FFALIGN(c->srcBpc, 8) >> 3,
 -                     fail);
 +    FF_ALLOC_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail);
-     if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2 && c->scalingBpp == 8) {
+     if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2 && c->srcBpc == 8 && c->dstBpc <= 10) {
          c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0;
          if (!c->canMMX2BeUsed && dstW >=srcW && (srcW&15)==0 && (flags&SWS_FAST_BILINEAR)) {
              if (flags&SWS_PRINT_INFO)
              c->chrXInc+= 20;
          }
          //we don't use the x86 asm scaler if MMX is available
-         else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX && c->scalingBpp == 8) {
 -        else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) {
++        else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX && c->dstBpc <= 10) {
              c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20;
              c->chrXInc = ((c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20;
          }
          FF_ALLOCZ_OR_GOTO(c, c->lumPixBuf[i+c->vLumBufSize], dst_stride+16, fail);
          c->lumPixBuf[i] = c->lumPixBuf[i+c->vLumBufSize];
      }
 -    // 64 / (c->dstBpc & ~7) is the same as 16 / sizeof(scaling_intermediate)
 -    c->uv_off_px   = dst_stride_px + 64 / (c->dstBpc &~ 7);
 -    c->uv_off_byte = dst_stride + 16;
 +    // 64 / c->scalingBpp is the same as 16 / sizeof(scaling_intermediate)
-     c->uv_off   = (dst_stride>>1) + 64 / c->scalingBpp;
++    c->uv_off   = (dst_stride>>1) + 64 / (c->dstBpc &~ 7);
 +    c->uv_offx2 = dst_stride + 16;
      for (i=0; i<c->vChrBufSize; i++) {
          FF_ALLOC_OR_GOTO(c, c->chrUPixBuf[i+c->vChrBufSize], dst_stride*2+32, fail);
          c->chrUPixBuf[i] = c->chrUPixBuf[i+c->vChrBufSize];
  
      //try to avoid drawing green stuff between the right end and the stride end
      for (i=0; i<c->vChrBufSize; i++)
 -        memset(c->chrUPixBuf[i], 64, dst_stride*2+1);
 +        if(av_pix_fmt_descriptors[c->dstFormat].comp[0].depth_minus1 == 15){
-             av_assert0(c->scalingBpp == 16);
++            av_assert0(c->dstBpc > 10);
 +            for(j=0; j<dst_stride/2+1; j++)
 +                ((int32_t*)(c->chrUPixBuf[i]))[j] = 1<<18;
 +        } else
 +            for(j=0; j<dst_stride+1; j++)
 +                ((int16_t*)(c->chrUPixBuf[i]))[j] = 1<<14;
  
      assert(c->chrDstH <= dstH);
  
@@@ -2530,8 -2371,4 +2530,8 @@@ static av_cold void RENAME(sws_init_swS
          }
      }
  #endif /* !COMPILE_TEMPLATE_MMX2 */
-     if(c->scalingBpp != 8)
 +    if(isAnyRGB(c->srcFormat) && av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1<15)
 +        c->hScale16= RENAME(hScale16);
++    if(c->dstBpc > 10)
 +        c->hScale16 = NULL;
  }
@@@ -1,32 -1,32 +1,32 @@@
 -abgr                d894cb97f6c80eb21bdbe8a4eea62d86
 -argb                54346f2b2eef10919e0f247241df3b24
 -bgr24               570f8d6b51a838aed022ef67535f6bdc
 +abgr                cff82561a074874027ac1cc896fd2730
 +argb                756dd1eaa5baca2238ce23dbdc452684
 +bgr24               e44192347a45586c6c157e3059610cd1
- bgr48be             07f7a0cc34feb3646434d47c0cec8cee
- bgr48le             9abd2c3a66088e6c9078232064eba61e
+ bgr48be             390d3058a12a99c2b153ed7922508bea
+ bgr48le             39fe06feb4ec1d9730dccc04a0cfac4c
  bgr4_byte           ee1d35a7baf8e9016891929a2f565c0b
 -bgr555be            de8901c1358834fddea060fcb3a67beb
 -bgr555le            36b745067197f9ca8c1731cac51329c9
 -bgr565be            922a2503767036ae9536f4f7823c04ee
 -bgr565le            3a514a298c6161a071ddf9963c06509d
 +bgr555be            6a2d335856db12e3ea72173d71610e21
 +bgr555le            41e3e0961478dc634bf68a7bbd670cc9
 +bgr565be            21077a3744c889b97032414b11232933
 +bgr565le            614897eaeb422bd9a972f8ee51909be5
  bgr8                7f007fa6c153a16e808a9c51605a4016
 -bgra                a5e7040f9a80cccd65e5acf2ca09ace5
 +bgra                01cfdda1f72fcabb6c46424e27f8c519
  gray                d7786a7d9d99ac74230cc045cab5632c
  gray16be            b554d6c1cc8da23967445be4dd3e4a86
  gray16le            715a33aa1c19cb26b14f5cc000e7a3d1
 -monob               88c4c050758e64d120f50c7eff694381
 -monow               d31772ebaa877fc2a78565937f7f9673
 +monob               cb62f31b701c6e987b574974d1b31e32
 +monow               fd5d417ab7728acddffc06870661df61
  nv12                4676d59db43d657dc12841f6bc3ab452
  nv21                69c699510ff1fb777b118ebee1002f14
 -rgb24               514692e28e8ff6860e415ce4fcf6eb8c
 +rgb24               13ff53ebeab74dc05492836f1cfbd2c1
- rgb48be             f18841c19fc6d9c817a3095f557b9bc5
- rgb48le             819e7b8acd8965ba57ba46198a5cc9bf
+ rgb48be             8fac63787a711886030f8e056872b488
+ rgb48le             ab92f2763a2eb264c3870cc758f97149
  rgb4_byte           d81ffd3add95842a618eec81024f0b5c
 -rgb555be            4607309f9f217d51cbb53d13b84b4537
 -rgb555le            a350ef1dc2c9688ed49e7ba018843795
 -rgb565be            678ce231c4ea13629c1353b1df4ffbef
 -rgb565le            6f4bb711238baa762d73305213f8d035
 +rgb555be            491dc49ff83258ffe415289bdcfb50b2
 +rgb555le            bd698d86c03170c4a16607c0fd1f750f
 +rgb565be            35682c17c85f307147041f23ac8092aa
 +rgb565le            bfa0c639d80c3c03fd0c9e5f34296a5e
  rgb8                091d0170b354ef0e97312b95feb5483f
 -rgba                a3d362f222098a00e63867f612018659
 +rgba                16873e3ac914e76116629a5ff8940ac4
  uyvy422             314bd486277111a95d9369b944fa0400
  yuv410p             7df8f6d69b56a8dcb6c7ee908e5018b5
  yuv411p             1143e7c5cc28fe0922b051b17733bc4c