]> granicus.if.org Git - handbrake/commitdiff
libhb: Add Unsharp sharpening filter.
authorBradley Sepos <bradley@bradleysepos.com>
Tue, 23 May 2017 23:22:37 +0000 (19:22 -0400)
committerBradley Sepos <bradley@bradleysepos.com>
Tue, 30 May 2017 18:00:27 +0000 (14:00 -0400)
Closes #525.

12 files changed:
libhb/common.c
libhb/common.h
libhb/internal.h
libhb/param.c
libhb/preset.c
libhb/preset_builtin.h
libhb/unsharp.c [new file with mode: 0644]
preset/preset_builtin.json
preset/preset_builtin.list
preset/preset_cli_default.json
preset/preset_template.json
test/test.c

index 11928e519624a5c3d20d10ce77f00e2f443a9111..c8a2f22f770484c9427fc20ef474022fd1fb53da 100644 (file)
@@ -3959,6 +3959,10 @@ hb_filter_object_t * hb_filter_get( int filter_id )
             filter = &hb_filter_crop_scale;
             break;
 
+        case HB_FILTER_UNSHARP:
+            filter = &hb_filter_unsharp;
+            break;
+
         case HB_FILTER_AVFILTER:
             filter = &hb_filter_avfilter;
             break;
index 266f13fe28ae5788d8da5cb1ee0bad4a01b64a87..562bbc362d91e56a9518fb858476e7696871442f 100644 (file)
@@ -1270,6 +1270,7 @@ enum
     HB_FILTER_NLMEANS,
     HB_FILTER_RENDER_SUB,
     HB_FILTER_CROP_SCALE,
+    HB_FILTER_UNSHARP,
     HB_FILTER_ROTATE,
     HB_FILTER_GRAYSCALE,
     HB_FILTER_PAD,
index 4aaba97ba0e708c055f83f83efd605ad60e8de21..0cffbdff418d53aeb9d229ab0ce033ec57609311 100644 (file)
@@ -465,6 +465,7 @@ extern hb_filter_object_t hb_filter_crop_scale;
 extern hb_filter_object_t hb_filter_rotate;
 extern hb_filter_object_t hb_filter_grayscale;
 extern hb_filter_object_t hb_filter_pad;
+extern hb_filter_object_t hb_filter_unsharp;
 extern hb_filter_object_t hb_filter_avfilter;
 
 #ifdef USE_QSV
index 456ba4d2456867828faae18427b21fdb5fe5e0ec..ae8d9961821d6c76ecfa7f34d005148b06808e47 100644 (file)
@@ -70,6 +70,26 @@ static hb_filter_param_t hqdn3d_presets[] =
                                                         },
 };
 
+static hb_filter_param_t unsharp_presets[] =
+{
+    { 1, "Custom",      "custom",     NULL              },
+    { 2, "Ultralight",  "ultralight", NULL              },
+    { 3, "Light",       "light",      NULL              },
+    { 4, "Medium",      "medium",     NULL              },
+    { 5, "Strong",      "strong",     NULL              },
+    { 6, "Stronger",    "stronger",   NULL              },
+    { 0, NULL,          NULL,         NULL              }
+};
+
+static hb_filter_param_t unsharp_tunes[] =
+{
+    { 0, "None",        "none",       NULL              },
+    { 1, "Fine",        "fine",       NULL              },
+    { 2, "Medium",      "medium",     NULL              },
+    { 3, "Coarse",      "coarse",     NULL              },
+    { 0, NULL,          NULL,         NULL              }
+};
+
 static hb_filter_param_t detelecine_presets[] =
 {
     { 0, "Off",         "off",        "disable=1"       },
@@ -141,6 +161,9 @@ static filter_param_map_t param_map[] =
     { HB_FILTER_HQDN3D,      hqdn3d_presets,      NULL,
       sizeof(hqdn3d_presets) / sizeof(hb_filter_param_t)         },
 
+    { HB_FILTER_UNSHARP,     unsharp_presets,     unsharp_tunes,
+      sizeof(unsharp_presets) / sizeof(hb_filter_param_t)        },
+
     { HB_FILTER_DETELECINE,  detelecine_presets,  NULL,
       sizeof(detelecine_presets) / sizeof(hb_filter_param_t)     },
 
@@ -408,6 +431,137 @@ static hb_dict_t * generate_nlmeans_settings(const char *preset,
     return settings;
 }
 
+static hb_dict_t * generate_unsharp_settings(const char *preset,
+                                             const char *tune,
+                                             const char *custom)
+{
+    hb_dict_t * settings;
+
+    if (preset == NULL)
+        return NULL;
+
+    if (preset == NULL || !strcasecmp(preset, "custom"))
+    {
+        return hb_parse_filter_settings(custom);
+    }
+    if (!strcasecmp(preset, "ultralight") ||
+        !strcasecmp(preset, "light") ||
+        !strcasecmp(preset, "medium") ||
+        !strcasecmp(preset, "strong") ||
+        !strcasecmp(preset, "stronger"))
+    {
+        double strength[2];
+        int    size[2];
+
+        if (tune == NULL || !strcasecmp(tune, "none"))
+        {
+            strength[0]     = strength[1] = 0.25;
+            size[0]         =     size[1] = 7;
+            if (!strcasecmp(preset, "ultralight"))
+            {
+                strength[0] = strength[1] = 0.05;
+            }
+            else if (!strcasecmp(preset, "light"))
+            {
+                strength[0] = strength[1] = 0.15;
+            }
+            else if (!strcasecmp(preset, "strong"))
+            {
+                strength[0] = strength[1] = 0.5;
+            }
+            else if (!strcasecmp(preset, "stronger"))
+            {
+                strength[0] = strength[1] = 0.8;
+            }
+        }
+        else if (!strcasecmp(tune, "fine"))
+        {
+            strength[0]     = 0.4; strength[1] = 0.25;
+            size[0]         =      size[1]     = 3;
+            if (!strcasecmp(preset, "ultralight"))
+            {
+                strength[0] = 0.15; strength[1] = 0.1;
+            }
+            else if (!strcasecmp(preset, "light"))
+            {
+                strength[0] = 0.25; strength[1] = 0.15;
+            }
+            else if (!strcasecmp(preset, "strong"))
+            {
+                strength[0] = 0.8;  strength[1] = 0.5;
+            }
+            else if (!strcasecmp(preset, "stronger"))
+            {
+                strength[0] = 0.8;  strength[1] = 0.5;
+            }
+        }
+        else if (!strcasecmp(tune, "medium"))
+        {
+            strength[0]     = 0.275; strength[1] = 0.165;
+            size[0]         = 7;     size[1] = 5;
+            if (!strcasecmp(preset, "ultralight"))
+            {
+                strength[0] = 0.055; strength[1] = 0.033;
+            }
+            else if (!strcasecmp(preset, "light"))
+            {
+                strength[0] = 0.165; strength[1] = 0.1;
+            }
+            else if (!strcasecmp(preset, "strong"))
+            {
+                strength[0] = 0.55;  strength[1] = 0.33;
+            }
+            else if (!strcasecmp(preset, "stronger"))
+            {
+                strength[0] = 0.9;   strength[1] = 0.6;
+            }
+        }
+        else if (!strcasecmp(tune, "coarse"))
+        {
+            strength[0]     = 0.275; strength[1] = 0.165;
+            size[0]         = 13;    size[1] = 9;
+            if (!strcasecmp(preset, "ultralight"))
+            {
+                strength[0] = 0.055; strength[1] = 0.033;
+            }
+            else if (!strcasecmp(preset, "light"))
+            {
+                strength[0] = 0.165; strength[1] = 0.1;
+            }
+            else if (!strcasecmp(preset, "strong"))
+            {
+                strength[0] = 0.55;  strength[1] = 0.33;
+            }
+            else if (!strcasecmp(preset, "stronger"))
+            {
+                strength[0] = 0.9;   strength[1] = 0.6;
+            }
+        }
+        else
+        {
+            fprintf(stderr, "Unrecognized unsharp tune (%s).\n", tune);
+            return NULL;
+        }
+
+        settings = hb_dict_init();
+        hb_dict_set(settings, "y-strength", hb_value_double(strength[0]));
+        hb_dict_set(settings, "y-size",     hb_value_int(size[0]));
+
+        hb_dict_set(settings, "cb-strength", hb_value_double(strength[1]));
+        hb_dict_set(settings, "cb-size",     hb_value_int(size[1]));
+    }
+    else
+    {
+        settings = hb_parse_filter_settings(preset);
+        if (tune != NULL)
+        {
+            fprintf(stderr, "Custom unsharp parameters specified; ignoring unsharp tune (%s).\n", tune);
+        }
+    }
+
+    return settings;
+}
+
 int hb_validate_param_string(const char *regex_pattern, const char *param_string)
 {
     regex_t regex_temp;
@@ -668,6 +822,9 @@ hb_generate_filter_settings(int filter_id, const char *preset, const char *tune,
         case HB_FILTER_NLMEANS:
             settings = generate_nlmeans_settings(preset, tune, custom);
             break;
+        case HB_FILTER_UNSHARP:
+            settings = generate_unsharp_settings(preset, tune, custom);
+            break;
         case HB_FILTER_COMB_DETECT:
         case HB_FILTER_DECOMB:
         case HB_FILTER_DETELECINE:
index 5741362fccb76807357d5bb72fbd1d0d405646ed..08f7d186c00e93593658636e51f9eaf5f30aba40 100644 (file)
@@ -1371,6 +1371,52 @@ int hb_preset_apply_filters(const hb_dict_t *preset, hb_dict_t *job_dict)
         }
     }
 
+    // Sharpen filter
+    const char *sharpen_filter, *sharpen_preset, *sharpen_tune, *sharpen_custom;
+    sharpen_filter = hb_value_get_string(hb_dict_get(preset,
+                                                   "PictureSharpenFilter"));
+    sharpen_preset = hb_value_get_string(hb_dict_get(preset,
+                                                   "PictureSharpenPreset"));
+    sharpen_tune   = hb_value_get_string(hb_dict_get(preset,
+                                                   "PictureSharpenTune"));
+    sharpen_custom = hb_value_get_string(hb_dict_get(preset,
+                                                   "PictureSharpenCustom"));
+    if (sharpen_filter != NULL && sharpen_preset != NULL &&
+        strcasecmp(sharpen_filter, "off"))
+    {
+        int filter_id;
+        if (!strcasecmp(sharpen_filter, "unsharp"))
+        {
+            filter_id = HB_FILTER_UNSHARP;
+        }
+        else
+        {
+            hb_error("Invalid sharpen filter (%s)", sharpen_filter);
+            return -1;
+        }
+        filter_settings = hb_generate_filter_settings(filter_id,
+                            sharpen_preset, sharpen_tune, sharpen_custom);
+        if (filter_settings == NULL)
+        {
+            hb_error("Invalid sharpen filter settings (%s%s%s)",
+                     sharpen_preset,
+                     sharpen_tune ? "," : "",
+                     sharpen_tune ? sharpen_tune : "");
+            return -1;
+        }
+        else if (!hb_dict_get_bool(filter_settings, "disable"))
+        {
+            filter_dict = hb_dict_init();
+            hb_dict_set(filter_dict, "ID", hb_value_int(filter_id));
+            hb_dict_set(filter_dict, "Settings", filter_settings);
+            hb_add_filter2(filter_list, filter_dict);
+        }
+        else
+        {
+            hb_value_free(&filter_settings);
+        }
+    }
+
     // Deblock filter
     char *deblock = hb_value_get_string_xform(
                         hb_dict_get(preset, "PictureDeblock"));
index 356f8b4317ee63dc27014c0da3c951846206909c..296e0d5ad1fe4e7dc0abcdada81463f738011216 100644 (file)
@@ -63,6 +63,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"Small H.264 video (up to 1080p30) and AAC stereo audio, in an MP4 container.\", \n"
@@ -159,6 +163,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1280, \n"
 "                    \"PresetDescription\": \"Small H.264 video (up to 720p30) and AAC stereo audio, in an MP4 container.\", \n"
@@ -255,6 +263,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"Small H.264 video (up to 576p25) and AAC stereo audio, in an MP4 container.\", \n"
@@ -351,6 +363,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"Small H.264 video (up to 480p30) and AAC stereo audio, in an MP4 container.\", \n"
@@ -447,6 +463,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 1080p30) and AAC stereo audio, in an MP4 container.\", \n"
@@ -543,6 +563,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1280, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 720p30) and AAC stereo audio, in an MP4 container.\", \n"
@@ -639,6 +663,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 576p25) and AAC stereo audio, in an MP4 container.\", \n"
@@ -735,6 +763,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 480p30) and AAC stereo audio, in an MP4 container.\", \n"
@@ -845,6 +877,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"High quality H.264 video (up to 1080p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container.\", \n"
@@ -955,6 +991,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1280, \n"
 "                    \"PresetDescription\": \"High quality H.264 video (up to 720p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container.\", \n"
@@ -1065,6 +1105,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"High quality H.264 video (up to 576p25), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container.\", \n"
@@ -1175,6 +1219,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"High quality H.264 video (up to 480p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container.\", \n"
@@ -1285,6 +1333,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"Super high quality H.264 video (up to 1080p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container.\", \n"
@@ -1395,6 +1447,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1280, \n"
 "                    \"PresetDescription\": \"Super high quality H.264 video (up to 720p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container.\", \n"
@@ -1505,6 +1561,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"Super high quality H.264 video (up to 576p25), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container.\", \n"
@@ -1615,6 +1675,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"Super high quality H.264 video (up to 480p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container.\", \n"
@@ -1718,6 +1782,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1280, \n"
 "                    \"PresetDescription\": \"Encode up to 3 minutes of video in large size for Gmail (25 MB or less). H.264 video (up to 720p30) and AAC stereo audio, in an MP4 container.\", \n"
@@ -1814,6 +1882,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"Encode up to 5 minutes of video in medium size for Gmail (25 MB or less). H.264 video (up to 480p30) and AAC stereo audio, in an MP4 container.\", \n"
@@ -1910,6 +1982,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 384, \n"
 "                    \"PresetDescription\": \"Encode up to 10 minutes of video in small size for Gmail (25 MB or less). H.264 video (up to 288p30) and AAC mono audio, in an MP4 container.\", \n"
@@ -2013,6 +2089,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 1080p30) and AAC stereo audio, in an MP4 container. Compatible with Android devices.\", \n"
@@ -2109,6 +2189,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1280, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 720p30) and AAC stereo audio, in an MP4 container. Compatible with Android devices.\", \n"
@@ -2205,6 +2289,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 576p25) and AAC stereo audio, in an MP4 container. Compatible with Android devices.\", \n"
@@ -2301,6 +2389,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 480p30) and AAC stereo audio, in an MP4 container. Compatible with Android devices.\", \n"
@@ -2411,6 +2503,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 1080p60), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container. Compatible with Apple iPad Pro; iPad Air; iPad mini 2nd, 3rd Generation and later; Apple TV 4th Generation and later.\", \n"
@@ -2521,6 +2617,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 1080p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container. Compatible with Apple iPhone 5, 5S, 6, 6s, and later; iPod touch 6th Generation and later; iPad Pro; iPad Air; iPad 3rd, 4th Generation and later; iPad mini; Apple TV 3rd Generation and later.\", \n"
@@ -2631,6 +2731,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1280, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 720p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container. Compatible with Apple iPhone 4 and later; iPod touch 4th, 5th Generation and later; Apple TV 2nd Generation and later.\", \n"
@@ -2741,6 +2845,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 960, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 540p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container. Compatible with Apple iPhone 1st Generation, 3G, 3GS, and later; iPod touch 1st, 2nd, 3rd Generation and later; iPod Classic; Apple TV 1st Generation and later.\", \n"
@@ -2837,6 +2945,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 320, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 240p30) and AAC stereo audio, in an MP4 container. Compatible with Apple iPod 5th Generation and later.\", \n"
@@ -2947,6 +3059,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 1080p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container. Compatible with Google Chromecast.\", \n"
@@ -3057,6 +3173,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 1080p30), AAC stereo audio, and Dolby Digital (AC-3) audio, in an MP4 container. Compatible with Amazon Fire TV.\", \n"
@@ -3167,6 +3287,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 1080p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container. Compatible with Playstation 3 and 4.\", \n"
@@ -3263,6 +3387,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1280, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 720p30) and AAC stereo audio, in an MP4 container. Compatible with Playstation Vita TV.\", \n"
@@ -3359,6 +3487,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 960, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 540p30) and AAC stereo audio, in an MP4 container. Compatible with Playstation Vita.\", \n"
@@ -3472,6 +3604,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 3840, \n"
 "                    \"PresetDescription\": \"H.265 video (up to 2160p60), AAC stereo audio, and surround audio, in an MKV container. Compatible with Roku 4.\", \n"
@@ -3585,6 +3721,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 3840, \n"
 "                    \"PresetDescription\": \"H.265 video (up to 2160p30), AAC stereo audio, and surround audio, in an MKV container. Compatible with Roku 4.\", \n"
@@ -3695,6 +3835,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 1080p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container. Compatible with Roku 1080p models.\", \n"
@@ -3805,6 +3949,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1280, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 720p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container. Compatible with Roku 720p models.\", \n"
@@ -3901,6 +4049,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 576p25) and AAC stereo audio, in an MP4 container. Compatible with Roku standard definition models.\", \n"
@@ -3997,6 +4149,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 480p30) and AAC stereo audio, in an MP4 container. Compatible with Roku standard definition models.\", \n"
@@ -4093,6 +4249,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 1080p30) and AAC stereo audio, in an MP4 container. Compatible with Windows Mobile devices with Qualcomm Snapdragon 800 (MSM8974), S4 (MSM8x30, MSM8960), and better CPUs.\", \n"
@@ -4189,6 +4349,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1280, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 720p30) and AAC stereo audio, in an MP4 container. Compatible with Windows Mobile devices with Qualcomm Snapdragon S4 (MSM8x27), S2 (MSM8x55), S1 (MSM8x50), and better CPUs.\", \n"
@@ -4285,6 +4449,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 960, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 540p30) and AAC stereo audio, in an MP4 container. Compatible with Windows Mobile devices with Qualcomm Snapdragon 200 (MSM8210, MSM8212) and better CPUs.\", \n"
@@ -4381,6 +4549,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 480p30) and AAC stereo audio, in an MP4 container. Compatible with Windows Mobile devices with Qualcomm Snapdragon S1 (MSM7x27a) and better CPUs.\", \n"
@@ -4491,6 +4663,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 1080p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container. Compatible with Xbox One.\", \n"
@@ -4601,6 +4777,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 1080p30), AAC stereo audio, and Dolby Digital (AC-3) surround audio, in an MP4 container. Compatible with Xbox 360.\", \n"
@@ -4704,6 +4884,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 1080p30) and AAC stereo audio, in an MKV container.\", \n"
@@ -4800,6 +4984,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1280, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 720p30) and AAC stereo audio, in an MKV container.\", \n"
@@ -4896,6 +5084,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 576p25) and AAC stereo audio, in an MKV container.\", \n"
@@ -4992,6 +5184,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"H.264 video (up to 480p30) and AAC stereo audio, in an MKV container.\", \n"
@@ -5088,6 +5284,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"H.265 video (up to 1080p30) and AAC stereo audio, in an MKV container.\", \n"
@@ -5184,6 +5384,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1280, \n"
 "                    \"PresetDescription\": \"H.265 video (up to 720p30) and AAC stereo audio, in an MKV container.\", \n"
@@ -5280,6 +5484,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"H.265 video (up to 576p25) and AAC stereo audio, in an MKV container.\", \n"
@@ -5376,6 +5584,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"H.265 video (up to 480p30) and AAC stereo audio, in an MKV container.\", \n"
@@ -5470,6 +5682,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"VP8 video (up to 1080p30) and Vorbis stereo audio, in an MKV container.\", \n"
@@ -5564,6 +5780,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1280, \n"
 "                    \"PresetDescription\": \"VP8 video (up to 720p30) and Vorbis stereo audio, in an MKV container.\", \n"
@@ -5658,6 +5878,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"VP8 video (up to 576p25) and Vorbis stereo audio, in an MKV container.\", \n"
@@ -5752,6 +5976,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"VP8 video (up to 480p30) and Vorbis stereo audio, in an MKV container.\", \n"
@@ -5846,6 +6074,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1920, \n"
 "                    \"PresetDescription\": \"VP9 video (up to 1080p30) and Opus stereo audio, in an MKV container.\", \n"
@@ -5940,6 +6172,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 1280, \n"
 "                    \"PresetDescription\": \"VP9 video (up to 720p30) and Opus stereo audio, in an MKV container.\", \n"
@@ -6034,6 +6270,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"VP9 video (up to 576p25) and Opus stereo audio, in an MKV container.\", \n"
@@ -6128,6 +6368,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 720, \n"
 "                    \"PresetDescription\": \"VP9 video (up to 480p30) and Opus stereo audio, in an MKV container.\", \n"
@@ -6985,6 +7229,10 @@ const char hb_builtin_presets_json[] =
 "                    \"PicturePARWidth\": 853, \n"
 "                    \"PictureRightCrop\": 0, \n"
 "                    \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"                    \"PictureSharpenCustom\": \"\", \n"
+"                    \"PictureSharpenFilter\": \"off\", \n"
+"                    \"PictureSharpenPreset\": \"medium\", \n"
+"                    \"PictureSharpenTune\": \"none\", \n"
 "                    \"PictureTopCrop\": 0, \n"
 "                    \"PictureWidth\": 0, \n"
 "                    \"PresetDescription\": \"\", \n"
@@ -7097,6 +7345,10 @@ const char hb_builtin_presets_json[] =
 "            \"PicturePARWidth\": 853, \n"
 "            \"PictureRightCrop\": 0, \n"
 "            \"PictureRotate\": \"angle=0:hflip=0\", \n"
+"            \"PictureSharpenCustom\": \"\", \n"
+"            \"PictureSharpenFilter\": \"off\", \n"
+"            \"PictureSharpenPreset\": \"medium\", \n"
+"            \"PictureSharpenTune\": \"none\", \n"
 "            \"PictureTopCrop\": 0, \n"
 "            \"PictureWidth\": 0, \n"
 "            \"PresetDescription\": \"\", \n"
@@ -7133,7 +7385,7 @@ const char hb_builtin_presets_json[] =
 "            \"x264Option\": \"\", \n"
 "            \"x264UseAdvancedOptions\": false\n"
 "        }, \n"
-"        \"VersionMajor\": 24, \n"
+"        \"VersionMajor\": 25, \n"
 "        \"VersionMicro\": 0, \n"
 "        \"VersionMinor\": 0\n"
 "    }\n"
diff --git a/libhb/unsharp.c b/libhb/unsharp.c
new file mode 100644 (file)
index 0000000..2d5a1d5
--- /dev/null
@@ -0,0 +1,274 @@
+/* unsharp.c
+
+   Copyright (c) 2002 Rémi Guyomarch <rguyom at pobox.com>
+   Copyright (c) 2003-2017 HandBrake Team
+   This file is part of the HandBrake source code
+   Homepage: <http://handbrake.fr/>.
+   It may be used under the terms of the GNU General Public License v2.
+   For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
+ */
+
+#include "hb.h"
+
+#define UNSHARP_STRENGTH_LUMA_DEFAULT 0.25
+#define UNSHARP_SIZE_LUMA_DEFAULT 7
+#define UNSHARP_STRENGTH_CHROMA_DEFAULT 0.25
+#define UNSHARP_SIZE_CHROMA_DEFAULT 7
+#define UNSHARP_SIZE_MIN 3
+#define UNSHARP_SIZE_MAX 63
+
+typedef struct
+{
+    double     strength;  // strength
+    int        size;      // pixel context region width (must be odd)
+
+    int        steps;
+    int        amount;
+    int        scalebits;
+    int32_t    halfscale;
+    uint32_t * SC[UNSHARP_SIZE_MAX - 1];
+} unsharp_plane_context_t;
+
+struct hb_filter_private_s
+{
+    unsharp_plane_context_t  plane_ctx[3];
+};
+
+static int hb_unsharp_init(hb_filter_object_t *filter,
+                           hb_filter_init_t   *init);
+
+static int hb_unsharp_work(hb_filter_object_t *filter,
+                           hb_buffer_t ** buf_in,
+                           hb_buffer_t ** buf_out);
+
+static void hb_unsharp_close(hb_filter_object_t *filter);
+
+static const char hb_unsharp_template[] =
+    "y-strength=^"HB_FLOAT_REG"$:y-size=^"HB_INT_REG"$:"
+    "cb-strength=^"HB_FLOAT_REG"$:cb-size=^"HB_INT_REG"$:"
+    "cr-strength=^"HB_FLOAT_REG"$:cr-size=^"HB_INT_REG"$";
+
+hb_filter_object_t hb_filter_unsharp =
+{
+    .id                = HB_FILTER_UNSHARP,
+    .enforce_order     = 1,
+    .name              = "Sharpen (unsharp)",
+    .settings          = NULL,
+    .init              = hb_unsharp_init,
+    .work              = hb_unsharp_work,
+    .close             = hb_unsharp_close,
+    .settings_template = hb_unsharp_template,
+};
+
+static void hb_unsharp(const uint8_t *src,
+                             uint8_t *dst,
+                       const int width,
+                       const int height,
+                       const int stride,
+                       unsharp_plane_context_t * ctx)
+{
+    uint32_t **SC = ctx->SC;
+    uint32_t SR[UNSHARP_SIZE_MAX - 1],
+             Tmp1,
+             Tmp2;
+    const uint8_t *src2 = src; // avoid gcc warning
+    int32_t res;
+    int x, y, z;
+    int amount        = ctx->amount;
+    int steps         = ctx->steps;
+    int scalebits     = ctx->scalebits;
+    int32_t halfscale = ctx->halfscale;
+
+    if (!amount)
+    {
+        if (src != dst)
+        {
+            memcpy(dst, src, stride*height);
+        }
+
+        return;
+    }
+
+    for (y = 0; y < 2 * steps; y++)
+    {
+        memset(SC[y], 0, sizeof(SC[y][0]) * (width + 2 * steps));
+    }
+
+    for (y = -steps; y < height + steps; y++)
+    {
+        if (y < height)
+        {
+            src2 = src;
+        }
+
+        memset(SR, 0, sizeof(SR[0]) * (2 * steps - 1));
+
+        for (x = -steps; x < width + steps; x++)
+        {
+            Tmp1 = x <= 0 ? src2[0] : x >= width ? src2[width - 1] : src2[x];
+
+            for (z = 0; z < steps * 2; z += 2)
+            {
+                Tmp2 = SR[z + 0] + Tmp1; SR[z + 0] = Tmp1;
+                Tmp1 = SR[z + 1] + Tmp2; SR[z + 1] = Tmp2;
+            }
+
+            for (z = 0; z < steps * 2; z += 2)
+            {
+                Tmp2 = SC[z + 0][x + steps] + Tmp1; SC[z + 0][x + steps] = Tmp1;
+                Tmp1 = SC[z + 1][x + steps] + Tmp2; SC[z + 1][x + steps] = Tmp2;
+            }
+
+            if (x >= steps && y >= steps)
+            {
+                const uint8_t * srx = src - steps * stride + x - steps;
+                uint8_t       * dsx = dst - steps * stride + x - steps;
+        
+                res = (int32_t)*srx + ((((int32_t)*srx -
+                     (int32_t)((Tmp1 + halfscale) >> scalebits)) * amount) >> 16);
+                *dsx = res > 255 ? 255 : res < 0 ? 0 : (uint8_t)res;
+            }
+        }
+
+        if (y >= 0)
+        {
+            dst += stride;
+            src += stride;
+        }
+    }
+}
+
+static int hb_unsharp_init(hb_filter_object_t *filter,
+                           hb_filter_init_t   *init)
+{
+    filter->private_data = calloc(sizeof(struct hb_filter_private_s), 1);
+    hb_filter_private_t * pv = filter->private_data;
+
+    // Mark parameters unset
+    for (int c = 0; c < 3; c++)
+    {
+        pv->plane_ctx[c].strength = -1;
+        pv->plane_ctx[c].size     = -1;
+    }
+
+    // Read user parameters
+    if (filter->settings != NULL)
+    {
+        hb_dict_t * dict = filter->settings;
+        hb_dict_extract_double(&pv->plane_ctx[0].strength, dict, "y-strength");
+        hb_dict_extract_int(&pv->plane_ctx[0].size,        dict, "y-size");
+
+        hb_dict_extract_double(&pv->plane_ctx[1].strength, dict, "cb-strength");
+        hb_dict_extract_int(&pv->plane_ctx[1].size,        dict, "cb-size");
+
+        hb_dict_extract_double(&pv->plane_ctx[2].strength, dict, "cr-strength");
+        hb_dict_extract_int(&pv->plane_ctx[2].size,        dict, "cr-size");
+    }
+
+    // Cascade values
+    // Cr not set; inherit Cb. Cb not set; inherit Y. Y not set; defaults.
+    for (int c = 1; c < 3; c++)
+    {
+        unsharp_plane_context_t * prev_ctx = &pv->plane_ctx[c - 1];
+        unsharp_plane_context_t * ctx      = &pv->plane_ctx[c];
+
+        if (ctx->strength == -1) ctx->strength = prev_ctx->strength;
+        if (ctx->size     == -1) ctx->size     = prev_ctx->size;
+    }
+
+    for (int c = 0; c < 3; c++)
+    {
+        unsharp_plane_context_t * ctx = &pv->plane_ctx[c];
+        int w = hb_image_width(init->pix_fmt, init->geometry.width, c);
+
+        // Replace unset values with defaults
+        if (ctx->strength == -1)
+        {
+            ctx->strength = c ? UNSHARP_STRENGTH_CHROMA_DEFAULT :
+                                UNSHARP_STRENGTH_LUMA_DEFAULT;
+        }
+        if (ctx->size     == -1)
+        {
+            ctx->size     = c ? UNSHARP_SIZE_CHROMA_DEFAULT :
+                                UNSHARP_SIZE_LUMA_DEFAULT;
+        }
+
+        // Sanitize
+        if (ctx->strength < 0)   ctx->strength = 0;
+        if (ctx->strength > 1.5) ctx->strength = 1.5;
+        if (ctx->size % 2 == 0) ctx->size--;
+        if (ctx->size < UNSHARP_SIZE_MIN) ctx->size = UNSHARP_SIZE_MIN;
+        if (ctx->size > UNSHARP_SIZE_MAX) ctx->size = UNSHARP_SIZE_MAX;
+
+        ctx->amount    = ctx->strength * 65536.0;
+        ctx->steps     = ctx->size / 2;
+        ctx->scalebits = ctx->steps * 4;
+        ctx->halfscale = 1 << (ctx->scalebits - 1);
+
+        int z;
+        for (z = 0; z < 2 * ctx->steps; z++)
+        {
+            ctx->SC[z] = malloc(sizeof(*(ctx->SC[z])) * (w + 2 * ctx->steps));
+        }
+    }
+
+    return 0;
+}
+
+static void hb_unsharp_close(hb_filter_object_t * filter)
+{
+    hb_filter_private_t *pv = filter->private_data;
+
+    if (pv == NULL)
+    {
+        return;
+    }
+
+    int c, z;
+    for (c = 0; c < 3; c++)
+    {
+        unsharp_plane_context_t * ctx = &pv->plane_ctx[c];
+        for (z = 0; z < ctx->steps; z++)
+        {
+            free(ctx->SC[z]);
+            ctx->SC[z] = NULL;
+        }
+    }
+
+    free(pv);
+    filter->private_data = NULL;
+}
+
+static int hb_unsharp_work(hb_filter_object_t *filter,
+                           hb_buffer_t ** buf_in,
+                           hb_buffer_t ** buf_out)
+{
+    hb_filter_private_t *pv = filter->private_data;
+    hb_buffer_t *in = *buf_in, *out;
+
+    if (in->s.flags & HB_BUF_FLAG_EOF)
+    {
+        *buf_out = in;
+        *buf_in = NULL;
+        return HB_FILTER_DONE;
+    }
+
+    out = hb_frame_buffer_init(in->f.fmt, in->f.width, in->f.height);
+
+    int c;
+    for (c = 0; c < 3; c++)
+    {
+        unsharp_plane_context_t * ctx = &pv->plane_ctx[c];
+        hb_unsharp(in->plane[c].data,
+                   out->plane[c].data,
+                   in->plane[c].width,
+                   in->plane[c].height,
+                   in->plane[c].stride,
+                   ctx);
+    }
+
+    out->s = in->s;
+    *buf_out = out;
+
+    return HB_FILTER_OK;
+}
index 62537415ca0e1bbb39fdba6beadbdebe31d7c15d..c29da549343b03b38cbe9876beb26378cc54cacb 100644 (file)
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "light",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
index ce58ee1786b3b438c747f4fee4ffa88fcf020d18..df9ef896b39027e113ae5c11d90d4ecef0d65c9a 100644 (file)
@@ -1,6 +1,6 @@
 <resources>
     <section name="PresetTemplate">
-        <integer name="VersionMajor" value="24" />
+        <integer name="VersionMajor" value="25" />
         <integer name="VersionMinor" value="0" />
         <integer name="VersionMicro" value="0" />
         <json name="Preset" file="preset_template.json" />
index e607218057bbf294d619b2757289015d0233dc49..a67225a70f7475972643fd36910640cd5b746cf6 100644 (file)
                     "PictureDenoiseFilter": "off",
                     "PictureDenoisePreset": "medium",
                     "PictureDenoiseTune": "none",
+                    "PictureSharpenCustom": "",
+                    "PictureSharpenFilter": "off",
+                    "PictureSharpenPreset": "medium",
+                    "PictureSharpenTune": "none",
                     "PictureDetelecine": "off",
                     "PictureDetelecineCustom": "",
                     "PictureItuPAR": false,
index 531ef40d5019954cf19af966ff0d5014440d6026..9a3f646cc68fdb96a82e8b19797a9e52cce579de 100644 (file)
         "PictureDenoiseFilter": "off",
         "PictureDenoisePreset": "medium",
         "PictureDenoiseTune": "none",
+        "PictureSharpenCustom": "",
+        "PictureSharpenFilter": "off",
+        "PictureSharpenPreset": "medium",
+        "PictureSharpenTune": "none",
         "PictureDetelecine": "off",
         "PictureDetelecineCustom": "",
         "PictureItuPAR": false,
index b23f73bb32cfcf67db8d42a029a0fc82d46bac3f..cc84d3e7b4f0c974faf00dce36da2c35abd422e4 100644 (file)
@@ -46,6 +46,7 @@
 #include <IOKit/storage/IODVDMedia.h>
 #endif
 
+#define UNSHARP_DEFAULT_PRESET      "medium"
 #define NLMEANS_DEFAULT_PRESET      "medium"
 #define DEINTERLACE_DEFAULT_PRESET  "default"
 #define DECOMB_DEFAULT_PRESET       "default"
@@ -81,6 +82,10 @@ static int     nlmeans_disable     = 0;
 static int     nlmeans_custom      = 0;
 static char *  nlmeans             = NULL;
 static char *  nlmeans_tune        = NULL;
+static int     unsharp_disable     = 0;
+static int     unsharp_custom      = 0;
+static char *  unsharp             = NULL;
+static char *  unsharp_tune        = NULL;
 static int     detelecine_disable  = 0;
 static int     detelecine_custom   = 0;
 static char *  detelecine          = NULL;
@@ -571,6 +576,8 @@ cleanup:
     free(hqdn3d);
     free(nlmeans);
     free(nlmeans_tune);
+    free(unsharp);
+    free(unsharp_tune);
     free(preset_export_name);
     free(preset_export_desc);
     free(preset_export_file);
@@ -1085,6 +1092,9 @@ static void showFilterDefault(FILE* const out, int filter_id)
                  "                               ");
     switch (filter_id)
     {
+        case HB_FILTER_UNSHARP:
+            preset = UNSHARP_DEFAULT_PRESET;
+            break;
         case HB_FILTER_NLMEANS:
             preset = NLMEANS_DEFAULT_PRESET;
             break;
@@ -1110,6 +1120,7 @@ static void showFilterDefault(FILE* const out, int filter_id)
     {
         case HB_FILTER_DEINTERLACE:
         case HB_FILTER_NLMEANS:
+        case HB_FILTER_UNSHARP:
         case HB_FILTER_DECOMB:
         case HB_FILTER_DETELECINE:
         case HB_FILTER_HQDN3D:
@@ -1601,6 +1612,18 @@ static void ShowHelp()
     fprintf( out,
 "                           Applies to NLMeans presets only (does not affect\n"
 "                           custom settings)\n"
+"   --unsharp[=string]      Sharpen video with unsharp filter\n");
+    showFilterPresets(out, HB_FILTER_UNSHARP);
+    showFilterKeys(out, HB_FILTER_UNSHARP);
+    showFilterDefault(out, HB_FILTER_UNSHARP);
+    fprintf( out,
+
+"   --no-unsharp            Disable preset unsharp filter\n"
+"   --unsharp-tune <string> Tune unsharp filter\n");
+    showFilterTunes(out, HB_FILTER_UNSHARP);
+    fprintf( out,
+"                           Applies to unsharp presets only (does not affect\n"
+"                           custom settings)\n"
 "   -7, --deblock[=string]  Deblock video with pp7 filter\n");
     showFilterKeys(out, HB_FILTER_DEBLOCK);
     showFilterDefault(out, HB_FILTER_DEBLOCK);
@@ -1956,6 +1979,8 @@ static int ParseOptions( int argc, char ** argv )
     #define PAD                  309
     #define FILTER_COMB_DETECT   310
     #define QUEUE_IMPORT         311
+    #define FILTER_UNSHARP       312
+    #define FILTER_UNSHARP_TUNE  313
 
     for( ;; )
     {
@@ -2031,6 +2056,9 @@ static int ParseOptions( int argc, char ** argv )
             { "nlmeans",     optional_argument, NULL,    FILTER_NLMEANS },
             { "no-nlmeans",  no_argument,       &nlmeans_disable,     1 },
             { "nlmeans-tune",required_argument, NULL,    FILTER_NLMEANS_TUNE },
+            { "unsharp",     optional_argument, NULL,    FILTER_UNSHARP },
+            { "no-unsharp",  no_argument,       &unsharp_disable,     1 },
+            { "unsharp-tune",required_argument, NULL,    FILTER_UNSHARP_TUNE },
             { "detelecine",  optional_argument, NULL,    '9' },
             { "no-detelecine", no_argument,     &detelecine_disable,  1 },
             { "no-comb-detect", no_argument,    &comb_detect_disable, 1 },
@@ -2458,6 +2486,21 @@ static int ParseOptions( int argc, char ** argv )
                 free(nlmeans_tune);
                 nlmeans_tune = strdup(optarg);
                 break;
+            case FILTER_UNSHARP:
+                free(unsharp);
+                if (optarg != NULL)
+                {
+                    unsharp = strdup(optarg);
+                }
+                else
+                {
+                    unsharp = strdup(UNSHARP_DEFAULT_PRESET);
+                }
+                break;
+            case FILTER_UNSHARP_TUNE:
+                free(unsharp_tune);
+                unsharp_tune = strdup(optarg);
+                break;
             case '9':
                 free(detelecine);
                 if (optarg != NULL)
@@ -2949,6 +2992,32 @@ static int ParseOptions( int argc, char ** argv )
         }
     }
 
+    if (unsharp != NULL)
+    {
+        if (unsharp_disable)
+        {
+            fprintf(stderr,
+                    "Incompatible options --unsharp and --no-unsharp\n");
+            return -1;
+        }
+        if (!hb_validate_filter_preset(HB_FILTER_UNSHARP, unsharp,
+                                       unsharp_tune, NULL))
+        {
+            // Nothing to do, but must validate preset before
+            // attempting to validate custom settings to prevent potential
+            // false positive
+        }
+        else if (!hb_validate_filter_string(HB_FILTER_UNSHARP, unsharp))
+        {
+            unsharp_custom = 1;
+        }
+        else
+        {
+            fprintf(stderr, "Invalid unsharp option %s\n", unsharp);
+            return -1;
+        }
+    }
+
     return 0;
 }
 
@@ -3864,6 +3933,31 @@ static hb_dict_t * PreparePreset(const char *preset_name)
                         hb_value_string(nlmeans));
         }
     }
+    if (unsharp_disable && !strcasecmp(s, "unsharp"))
+    {
+        hb_dict_set(preset, "PictureSharpenFilter", hb_value_string("off"));
+    }
+    if (unsharp != NULL)
+    {
+        hb_dict_set(preset, "PictureSharpenFilter", hb_value_string("unsharp"));
+        if (!unsharp_custom)
+        {
+            hb_dict_set(preset, "PictureSharpenPreset",
+                        hb_value_string(unsharp));
+            if (unsharp_tune != NULL)
+            {
+                hb_dict_set(preset, "PictureSharpenTune",
+                            hb_value_string(unsharp_tune));
+            }
+        }
+        else
+        {
+            hb_dict_set(preset, "PictureSharpenPreset",
+                        hb_value_string("custom"));
+            hb_dict_set(preset, "PictureSharpenCustom",
+                        hb_value_string(unsharp));
+        }
+    }
     if (deblock_disable)
     {
         hb_dict_set(preset, "PictureDeblock", hb_value_string("0"));