]> git.sesse.net Git - x264/commitdiff
Use TV range algorithm for bit-depth conversions
authorAnton Mitrofanov <BugMaster@narod.ru>
Sun, 22 Jan 2012 18:13:52 +0000 (22:13 +0400)
committerFiona Glaser <fiona@x264.com>
Sat, 4 Feb 2012 15:18:16 +0000 (07:18 -0800)
Such sources are more common, so better to be correct for the common case.
This also produces less error for the case of full range than the previous algorithm produced for the case of TV range.

filters/video/depth.c
input/raw.c

index 43b84db91ce378f143a76c3687c3032e079ab891..e01aaae4f46cdebbaedf2cb2cc92aec95764af41 100644 (file)
@@ -65,12 +65,12 @@ static int csp_num_interleaved( int csp, int plane )
  * depth again is lossless. */
 #define DITHER_PLANE( pitch ) \
 static void dither_plane_##pitch( pixel *dst, int dst_stride, uint16_t *src, int src_stride, \
-                                        int width, int height, int16_t *errors ) \
+                                  int width, int height, int16_t *errors ) \
 { \
     const int lshift = 16-BIT_DEPTH; \
-    const int rshift = 2*BIT_DEPTH-16; \
+    const int rshift = 16-BIT_DEPTH+2; \
+    const int half = 1 << (16-BIT_DEPTH+1); \
     const int pixel_max = (1 << BIT_DEPTH)-1; \
-    const int half = 1 << (16-BIT_DEPTH); \
     memset( errors, 0, (width+1) * sizeof(int16_t) ); \
     for( int y = 0; y < height; y++, src += src_stride, dst += dst_stride ) \
     { \
@@ -78,8 +78,8 @@ static void dither_plane_##pitch( pixel *dst, int dst_stride, uint16_t *src, int
         for( int x = 0; x < width; x++ ) \
         { \
             err = err*2 + errors[x] + errors[x+1]; \
-            dst[x*pitch] = x264_clip3( (((src[x*pitch]+half)<<2)+err)*pixel_max >> 18, 0, pixel_max ); \
-            errors[x] = err = src[x*pitch] - (dst[x*pitch] << lshift) - (dst[x*pitch] >> rshift); \
+            dst[x*pitch] = x264_clip3( ((src[x*pitch]<<2)+err+half) >> rshift, 0, pixel_max ); \
+            errors[x] = err = src[x*pitch] - (dst[x*pitch] << lshift); \
         } \
     } \
 }
@@ -114,13 +114,8 @@ static void dither_image( cli_image_t *out, cli_image_t *img, int16_t *error_buf
 
 static void scale_image( cli_image_t *output, cli_image_t *img )
 {
-    /* this function mimics how swscale does upconversion. 8-bit is converted
-     * to 16-bit through left shifting the orginal value with 8 and then adding
-     * the original value to that. This effectively keeps the full color range
-     * while also being fast. for n-bit we basically do the same thing, but we
-     * discard the lower 16-n bits. */
     int csp_mask = img->csp & X264_CSP_MASK;
-    const int shift = 16-BIT_DEPTH;
+    const int shift = BIT_DEPTH - 8;
     for( int i = 0; i < img->planes; i++ )
     {
         uint8_t *src = img->plane[i];
@@ -131,7 +126,7 @@ static void scale_image( cli_image_t *output, cli_image_t *img )
         for( int j = 0; j < height; j++ )
         {
             for( int k = 0; k < width; k++ )
-                dst[k] = ((src[k] << 8) + src[k]) >> shift;
+                dst[k] = src[k] << shift;
 
             src += img->stride[i];
             dst += output->stride[i]/2;
index 53a9ca2a78d2104be1c2eff1ea99176bc73c5b44..a9b2de1aeef5a9f59251520f5164707428ff23f3 100644 (file)
@@ -113,9 +113,8 @@ static int read_frame_internal( cli_pic_t *pic, raw_hnd_t *h )
             uint16_t *plane = (uint16_t*)pic->img.plane[i];
             uint64_t pixel_count = h->plane_size[i];
             int lshift = 16 - h->bit_depth;
-            int rshift = 2*h->bit_depth - 16;
             for( uint64_t j = 0; j < pixel_count; j++ )
-                plane[j] = (plane[j] << lshift) + (plane[j] >> rshift);
+                plane[j] = plane[j] << lshift;
         }
     }
     return error;