Guest User

Untitled

a guest
Oct 21st, 2017
406
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 7.58 KB | None | 0 0
  1. From ea071fec1c4637db5e7cef2bcd1d6334061d775f Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Jan=20Ekstr=C3=B6m?= <jeebjp@gmail.com>
  3. Date: Sat, 27 Aug 2011 23:25:40 +0300
  4. Subject: [PATCH 2/2] Correct the limited-range 8->10 conversion algorithm Now
  5.  follows BT.709 precisely.
  6.  
  7. ---
  8. filters/video/depth.c |   45 ++++++++++++++++++++++++++++++---------------
  9.  input/raw.c           |   13 +++++++++++--
  10.  2 files changed, 41 insertions(+), 17 deletions(-)
  11.  
  12. diff --git a/filters/video/depth.c b/filters/video/depth.c
  13. index 9ea2cbc..dddc889 100644
  14. --- a/filters/video/depth.c
  15. +++ b/filters/video/depth.c
  16. @@ -36,6 +36,7 @@ typedef struct
  17.  
  18.      int bit_depth;
  19.      int dst_csp;
  20. +    int full_range;
  21.      cli_pic_t buffer;
  22.      int16_t *error_buf;
  23.  } depth_hnd_t;
  24. @@ -65,7 +66,7 @@ static int csp_num_interleaved( int csp, int plane )
  25.   * depth again is lossless. */
  26.  #define DITHER_PLANE( pitch ) \
  27.  static void dither_plane_##pitch( pixel *dst, int dst_stride, uint16_t *src, int src_stride, \
  28. -                                        int width, int height, int16_t *errors ) \
  29. +                                        int width, int height, int16_t *errors, int full_range ) \
  30.  { \
  31.      const int lshift = 16-BIT_DEPTH; \
  32.      const int rshift = 2*BIT_DEPTH-16; \
  33. @@ -79,7 +80,7 @@ static void dither_plane_##pitch( pixel *dst, int dst_stride, uint16_t *src, int
  34.          { \
  35.              err = err*2 + errors[x] + errors[x+1]; \
  36.              dst[x*pitch] = x264_clip3( (((src[x*pitch]+half)<<2)+err)*pixel_max >> 18, 0, pixel_max ); \
  37. -            errors[x] = err = src[x*pitch] - (dst[x*pitch] << lshift) - (dst[x*pitch] >> rshift); \
  38. +            errors[x] = err = src[x*pitch] - (dst[x*pitch] << lshift) - (full_range*dst[x*pitch] >> rshift); \
  39.          } \
  40.      } \
  41.  }
  42. @@ -87,7 +88,7 @@ static void dither_plane_##pitch( pixel *dst, int dst_stride, uint16_t *src, int
  43.  DITHER_PLANE( 1 )
  44.  DITHER_PLANE( 2 )
  45.  
  46. -static void dither_image( cli_image_t *out, cli_image_t *img, int16_t *error_buf )
  47. +static void dither_image( cli_image_t *out, cli_image_t *img, int16_t *error_buf, int full_range )
  48.  {
  49.      int csp_mask = img->csp & X264_CSP_MASK;
  50.      for( int i = 0; i < img->planes; i++ )
  51. @@ -98,7 +99,7 @@ static void dither_image( cli_image_t *out, cli_image_t *img, int16_t *error_buf
  52.  
  53.  #define CALL_DITHER_PLANE( pitch, off ) \
  54.          dither_plane_##pitch( ((pixel*)out->plane[i])+off, out->stride[i]/sizeof(pixel), \
  55. -                ((uint16_t*)img->plane[i])+off, img->stride[i]/2, width, height, error_buf )
  56. +                ((uint16_t*)img->plane[i])+off, img->stride[i]/2, width, height, error_buf, full_range )
  57.  
  58.          if( num_interleaved == 1 )
  59.          {
  60. @@ -112,7 +113,7 @@ static void dither_image( cli_image_t *out, cli_image_t *img, int16_t *error_buf
  61.      }
  62.  }
  63.  
  64. -static void scale_image( cli_image_t *output, cli_image_t *img )
  65. +static void scale_image( cli_image_t *output, cli_image_t *img, int full_range )
  66.  {
  67.      /* this function mimics how swscale does upconversion. 8-bit is converted
  68.       * to 16-bit through left shifting the orginal value with 8 and then adding
  69. @@ -120,7 +121,8 @@ static void scale_image( cli_image_t *output, cli_image_t *img )
  70.       * while also being fast. for n-bit we basically do the same thing, but we
  71.       * discard the lower 16-n bits. */
  72.      int csp_mask = img->csp & X264_CSP_MASK;
  73. -    const int shift = 16-BIT_DEPTH;
  74. +    /* Decide the amount of shift needed by the type of color range */
  75. +    const int shift = full_range ? 16 - BIT_DEPTH : BIT_DEPTH - 8;
  76.      for( int i = 0; i < img->planes; i++ )
  77.      {
  78.          uint8_t *src = img->plane[i];
  79. @@ -128,14 +130,25 @@ static void scale_image( cli_image_t *output, cli_image_t *img )
  80.          int height = x264_cli_csps[csp_mask].height[i] * img->height;
  81.          int width = x264_cli_csps[csp_mask].width[i] * img->width;
  82.  
  83. -        for( int j = 0; j < height; j++ )
  84. -        {
  85. -            for( int k = 0; k < width; k++ )
  86. -                dst[k] = ((src[k] << 8) + src[k]) >> shift;
  87. +#define LOOP(math)                              \
  88. +    do {                                        \
  89. +        for( int j = 0; j < height; j++ )       \
  90. +        {                                       \
  91. +            for( int k = 0; k < width; k++ )    \
  92. +                dst[k] = math;                  \
  93. +            src += img->stride[i];              \
  94. +            dst += output->stride[i]/2;         \
  95. +        }                                       \
  96. +    } while (0)
  97. +
  98. +        if( full_range )
  99. +            /* x264's original algorithm */
  100. +            LOOP( ((src[k] << 8) + src[k]) >> shift );
  101. +        else
  102. +            /* Limited range algorithm mentioned in BT.709, Part 2 */
  103. +            LOOP( src[k] << shift );
  104.  
  105. -            src += img->stride[i];
  106. -            dst += output->stride[i]/2;
  107. -        }
  108. +#undef LOOP
  109.      }
  110.  }
  111.  
  112. @@ -148,12 +161,12 @@ static int get_frame( hnd_t handle, cli_pic_t *output, int frame )
  113.  
  114.      if( h->bit_depth < 16 && output->img.csp & X264_CSP_HIGH_DEPTH )
  115.      {
  116. -        dither_image( &h->buffer.img, &output->img, h->error_buf );
  117. +        dither_image( &h->buffer.img, &output->img, h->error_buf, h->full_range );
  118.          output->img = h->buffer.img;
  119.      }
  120.      else if( h->bit_depth > 8 && !(output->img.csp & X264_CSP_HIGH_DEPTH) )
  121.      {
  122. -        scale_image( &h->buffer.img, &output->img );
  123. +        scale_image( &h->buffer.img, &output->img, h->full_range );
  124.          output->img = h->buffer.img;
  125.      }
  126.      return 0;
  127. @@ -180,6 +193,7 @@ static int init( hnd_t *handle, cli_vid_filter_t *filter, video_info_t *info,
  128.      int change_fmt = (info->csp ^ param->i_csp) & X264_CSP_HIGH_DEPTH;
  129.      int csp = ~(~info->csp ^ change_fmt);
  130.      int bit_depth = 8*x264_cli_csp_depth_factor( csp );
  131. +    int full_range = info->full_range == 1;
  132.  
  133.      if( opt_string )
  134.      {
  135. @@ -214,6 +228,7 @@ static int init( hnd_t *handle, cli_vid_filter_t *filter, video_info_t *info,
  136.  
  137.          h->error_buf = (int16_t*)(h + 1);
  138.          h->dst_csp = csp;
  139. +        h->full_range = full_range;
  140.          h->bit_depth = bit_depth;
  141.          h->prev_hnd = *handle;
  142.          h->prev_filter = *filter;
  143. diff --git a/input/raw.c b/input/raw.c
  144. index 6d4bb28..9b08ae0 100644
  145. --- a/input/raw.c
  146. +++ b/input/raw.c
  147. @@ -35,6 +35,7 @@ typedef struct
  148.      uint64_t plane_size[4];
  149.      uint64_t frame_size;
  150.      int bit_depth;
  151. +    int full_range;
  152.  } raw_hnd_t;
  153.  
  154.  static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, cli_input_opt_t *opt )
  155. @@ -43,6 +44,8 @@ static int open_file( char *psz_filename, hnd_t *p_handle, video_info_t *info, c
  156.      if( !h )
  157.          return -1;
  158.  
  159. +    h->full_range = info->full_range == 1;
  160. +
  161.      if( !opt->resolution )
  162.      {
  163.          /* try to parse the file name */
  164. @@ -114,8 +117,14 @@ static int read_frame_internal( cli_pic_t *pic, raw_hnd_t *h )
  165.              uint64_t pixel_count = h->plane_size[i];
  166.              int lshift = 16 - h->bit_depth;
  167.              int rshift = 2*h->bit_depth - 16;
  168. -            for( uint64_t j = 0; j < pixel_count; j++ )
  169. -                plane[j] = (plane[j] << lshift) + (plane[j] >> rshift);
  170. +            if( h->full_range )
  171. +                for( uint64_t j = 0; j < pixel_count; j++ )
  172. +                    /* x264's original algorithm */
  173. +                    plane[j] = (plane[j] << lshift) + (plane[j] >> rshift);
  174. +            else
  175. +                for( uint64_t j = 0; j < pixel_count; j++ )
  176. +                    /* Limited range algorithm mentioned in BT.709, Part 2 */
  177. +                    plane[j] = plane[j] << lshift;
  178.          }
  179.      }
  180.      return error;
  181. --
  182. 1.7.5.1
Add Comment
Please, Sign In to add comment