]> granicus.if.org Git - handbrake/commitdiff
LinGui/CLI/libhb: add nlmeans denoise filter to lingui
authorjstebbins <jstebbins.hb@gmail.com>
Mon, 21 Jul 2014 15:01:13 +0000 (15:01 +0000)
committerjstebbins <jstebbins.hb@gmail.com>
Mon, 21 Jul 2014 15:01:13 +0000 (15:01 +0000)
Move nlmeans preset&tune parsing from cli to libhb

git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6239 b64f7644-9d1e-0410-96f1-a4d463321fa5

gtk/src/ghb.ui
gtk/src/hb-backend.c
gtk/src/internal_defaults.xml
gtk/src/makedeps.py
gtk/src/presets.c
gtk/src/queuehandler.c
gtk/src/standard_presets.xml
libhb/common.h
libhb/param.c [new file with mode: 0644]
test/test.c

index ca0284495ad24eef97642b71d7bb354ed81c1bf4..e4089c5b6738a2a824c3287b2577d69afc458e7d 100644 (file)
@@ -1619,9 +1619,9 @@ This allows a player to initiate playback before downloading the entire file.</p
             </child>
           </object>
           <packing>
-            <property name="expand">True</property>
+            <property name="expand">False</property>
             <property name="fill">True</property>
-            <property name="position">2</property>
+            <property name="position">1</property>
           </packing>
         </child>
         <child>
@@ -2941,11 +2941,10 @@ This allows a player to initiate playback before downloading the entire file.</p
                                     <property name="can_focus">False</property>
                                     <property name="spacing">16</property>
                                     <child>
-                                      <object class="GtkBox" id="vbox8">
-                                        <property name="orientation">vertical</property>
+                                      <object class="GtkGrid" id="table90">
                                         <property name="visible">True</property>
                                         <property name="can_focus">False</property>
-                                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                        <property name="column_spacing">5</property>
                                         <child>
                                           <object class="GtkCheckButton" id="VideoGrayScale">
                                             <property name="label" translatable="yes">Grayscale</property>
@@ -2959,108 +2958,43 @@ This allows a player to initiate playback before downloading the entire file.</p
                                             <signal name="toggled" handler="setting_widget_changed_cb" swapped="no"/>
                                           </object>
                                           <packing>
-                                            <property name="expand">False</property>
-                                            <property name="fill">True</property>
-                                            <property name="position">0</property>
+                                            <property name="top_attach">0</property>
+                                            <property name="left_attach">0</property>
+                                            <property name="width">2</property>
+                                            <property name="height">1</property>
                                           </packing>
                                         </child>
                                         <child>
-                                          <object class="GtkGrid" id="table90">
+                                          <object class="GtkLabel" id="label41">
                                             <property name="visible">True</property>
                                             <property name="can_focus">False</property>
-                                            <property name="column_spacing">5</property>
-                                            <child>
-                                              <placeholder/>
-                                            </child>
-                                            <child>
-                                              <object class="GtkLabel" id="label41">
-                                                <property name="visible">True</property>
-                                                <property name="can_focus">False</property>
-                                                <property name="xalign">0</property>
-                                                <property name="label" translatable="yes">Deblock:</property>
-                                              </object>
-                                              <packing>
-                                                <property name="top_attach">0</property>
-                                                <property name="left_attach">0</property>
-                                                <property name="width">1</property>
-                                                <property name="height">1</property>
-                                              </packing>
-                                            </child>
-                                            <child>
-                                              <object class="GtkScale" id="PictureDeblock">
-                                                <property name="visible">True</property>
-                                                <property name="can_focus">True</property>
-                                                <property name="tooltip_text" translatable="yes">The deblocking filter removes a common type of compression artifact.
-            If your source exhibits 'blockiness', this filter may help clean it up.</property>
-                                                <property name="adjustment">adjustment20</property>
-                                                <property name="digits">0</property>
-                                                <property name="value_pos">right</property>
-                                                <signal name="format-value" handler="format_deblock_cb" swapped="no"/>
-                                                <signal name="value-changed" handler="setting_widget_changed_cb" swapped="no"/>
-                                              </object>
-                                              <packing>
-                                                <property name="top_attach">0</property>
-                                                <property name="left_attach">1</property>
-                                                <property name="width">1</property>
-                                                <property name="height">1</property>
-                                              </packing>
-                                            </child>
-                                            <child>
-                                              <object class="GtkLabel" id="label32">
-                                                <property name="visible">True</property>
-                                                <property name="can_focus">False</property>
-                                                <property name="xalign">0</property>
-                                                <property name="label" translatable="yes">Denoise:</property>
-                                              </object>
-                                              <packing>
-                                                <property name="top_attach">1</property>
-                                                <property name="left_attach">0</property>
-                                                <property name="width">1</property>
-                                                <property name="height">1</property>
-                                              </packing>
-                                            </child>
-                                            <child>
-                                              <object class="GtkComboBox" id="PictureDenoise">
-                                                <property name="valign">GTK_ALIGN_CENTER</property>
-                                                <property name="width_request">100</property>
-                                                <property name="visible">True</property>
-                                                <property name="can_focus">False</property>
-                                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                                <property name="tooltip_text" translatable="yes">The denoise filter is a low pass filter that removes noise.
-            Film grain and other types of high frequency noise are difficult to compress.
-            Using this filter on such sources can result in smaller file sizes.</property>
-                                                <signal name="changed" handler="setting_widget_changed_cb" swapped="no"/>
-                                              </object>
-                                              <packing>
-                                                <property name="top_attach">1</property>
-                                                <property name="left_attach">1</property>
-                                                <property name="width">1</property>
-                                                <property name="height">1</property>
-                                              </packing>
-                                            </child>
-                                            <child>
-                                              <object class="GtkEntry" id="PictureDenoiseCustom">
-                                                <property name="can_focus">True</property>
-                                                <property name="tooltip_text" translatable="yes">Custom denoise filter string format
-
-            SpatialLuma:SpatialChroma:TemporalLuma:TemporalChroma</property>
-                                                <property name="width_chars">8</property>
-                                                <property name="primary_icon_activatable">False</property>
-                                                <property name="secondary_icon_activatable">False</property>
-                                                <signal name="changed" handler="setting_widget_changed_cb" swapped="no"/>
-                                              </object>
-                                              <packing>
-                                                <property name="top_attach">2</property>
-                                                <property name="left_attach">1</property>
-                                                <property name="width">1</property>
-                                                <property name="height">1</property>
-                                              </packing>
-                                            </child>
+                                            <property name="xalign">0</property>
+                                            <property name="label" translatable="yes">Deblock:</property>
                                           </object>
                                           <packing>
-                                            <property name="expand">False</property>
-                                            <property name="fill">True</property>
-                                            <property name="position">1</property>
+                                            <property name="top_attach">1</property>
+                                            <property name="left_attach">0</property>
+                                            <property name="width">1</property>
+                                            <property name="height">1</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkScale" id="PictureDeblock">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="tooltip_text" translatable="yes">The deblocking filter removes a common type of compression artifact.
+        If your source exhibits 'blockiness', this filter may help clean it up.</property>
+                                            <property name="adjustment">adjustment20</property>
+                                            <property name="digits">0</property>
+                                            <property name="value_pos">right</property>
+                                            <signal name="format-value" handler="format_deblock_cb" swapped="no"/>
+                                            <signal name="value-changed" handler="setting_widget_changed_cb" swapped="no"/>
+                                          </object>
+                                          <packing>
+                                            <property name="top_attach">1</property>
+                                            <property name="left_attach">1</property>
+                                            <property name="width">1</property>
+                                            <property name="height">1</property>
                                           </packing>
                                         </child>
                                       </object>
@@ -3071,6 +3005,136 @@ This allows a player to initiate playback before downloading the entire file.</p
                                         <property name="position">0</property>
                                       </packing>
                                     </child>
+                                    <child>
+                                      <object class="GtkGrid" id="table1">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="column_spacing">5</property>
+                                        <child>
+                                          <object class="GtkLabel" id="label32">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">False</property>
+                                            <property name="xalign">0</property>
+                                            <property name="label" translatable="yes">Denoise Filter:</property>
+                                          </object>
+                                          <packing>
+                                            <property name="top_attach">1</property>
+                                            <property name="left_attach">0</property>
+                                            <property name="width">1</property>
+                                            <property name="height">1</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkComboBox" id="PictureDenoiseFilter">
+                                            <property name="valign">GTK_ALIGN_CENTER</property>
+                                            <property name="width_request">100</property>
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">False</property>
+                                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                            <property name="tooltip_text" translatable="yes">The denoise filter is a low pass filter that removes noise.
+        Film grain and other types of high frequency noise are difficult to compress.
+        Using this filter on such sources can result in smaller file sizes.</property>
+                                            <signal name="changed" handler="setting_widget_changed_cb" swapped="no"/>
+                                          </object>
+                                          <packing>
+                                            <property name="top_attach">1</property>
+                                            <property name="left_attach">1</property>
+                                            <property name="width">1</property>
+                                            <property name="height">1</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkLabel" id="PictureDenoisePresetLabel">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">False</property>
+                                            <property name="xalign">0</property>
+                                            <property name="label" translatable="yes">Denoise Preset:</property>
+                                          </object>
+                                          <packing>
+                                            <property name="top_attach">2</property>
+                                            <property name="left_attach">0</property>
+                                            <property name="width">1</property>
+                                            <property name="height">1</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkComboBox" id="PictureDenoisePreset">
+                                            <property name="valign">GTK_ALIGN_CENTER</property>
+                                            <property name="width_request">100</property>
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">False</property>
+                                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                            <property name="tooltip_text" translatable="yes">The denoise filter is a low pass filter that removes noise.
+        Film grain and other types of high frequency noise are difficult to compress.
+        Using this filter on such sources can result in smaller file sizes.</property>
+                                            <signal name="changed" handler="setting_widget_changed_cb" swapped="no"/>
+                                          </object>
+                                          <packing>
+                                            <property name="top_attach">2</property>
+                                            <property name="left_attach">1</property>
+                                            <property name="width">1</property>
+                                            <property name="height">1</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkLabel" id="PictureDenoiseTuneLabel">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">False</property>
+                                            <property name="xalign">0</property>
+                                            <property name="label" translatable="yes">Denoise Tune:</property>
+                                          </object>
+                                          <packing>
+                                            <property name="top_attach">3</property>
+                                            <property name="left_attach">0</property>
+                                            <property name="width">1</property>
+                                            <property name="height">1</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkComboBox" id="PictureDenoiseTune">
+                                            <property name="valign">GTK_ALIGN_CENTER</property>
+                                            <property name="width_request">100</property>
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">False</property>
+                                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                            <property name="tooltip_text" translatable="yes">The denoise filter is a low pass filter that removes noise.
+        Film grain and other types of high frequency noise are difficult to compress.
+        Using this filter on such sources can result in smaller file sizes.</property>
+                                            <signal name="changed" handler="setting_widget_changed_cb" swapped="no"/>
+                                          </object>
+                                          <packing>
+                                            <property name="top_attach">3</property>
+                                            <property name="left_attach">1</property>
+                                            <property name="width">1</property>
+                                            <property name="height">1</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkEntry" id="PictureDenoiseCustom">
+                                            <property name="can_focus">True</property>
+                                            <property name="tooltip_text" translatable="yes">Custom denoise filter string format
+
+        SpatialLuma:SpatialChroma:TemporalLuma:TemporalChroma</property>
+                                            <property name="width_chars">8</property>
+                                            <property name="primary_icon_activatable">False</property>
+                                            <property name="secondary_icon_activatable">False</property>
+                                            <signal name="changed" handler="setting_widget_changed_cb" swapped="no"/>
+                                          </object>
+                                          <packing>
+                                            <property name="top_attach">3</property>
+                                            <property name="left_attach">1</property>
+                                            <property name="width">1</property>
+                                            <property name="height">1</property>
+                                          </packing>
+                                        </child>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">True</property>
+                                        <property name="padding">2</property>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
                                     <child>
                                       <object class="GtkGrid" id="table10">
                                         <property name="visible">True</property>
@@ -3284,7 +3348,7 @@ This allows a player to initiate playback before downloading the entire file.</p
                                         <property name="expand">False</property>
                                         <property name="fill">True</property>
                                         <property name="padding">2</property>
-                                        <property name="position">1</property>
+                                        <property name="position">2</property>
                                       </packing>
                                     </child>
                                   </object>
@@ -6588,6 +6652,11 @@ This allows a player to initiate playback before downloading the entire file.</p
               </packing>
             </child>
           </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
         </child>
         <child>
           <object class="GtkAlignment" id="alignment66">
@@ -6638,7 +6707,7 @@ This allows a player to initiate playback before downloading the entire file.</p
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
-            <property name="position">5</property>
+            <property name="position">3</property>
           </packing>
         </child>
         <child>
@@ -6660,7 +6729,7 @@ This allows a player to initiate playback before downloading the entire file.</p
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
-            <property name="position">6</property>
+            <property name="position">4</property>
           </packing>
         </child>
       </object>
index 781bba223ffc2ed5084423f58c0a85faf24b15de..dc6359445525f811f27cc95c4f7d2d008c2b3e09 100644 (file)
@@ -222,11 +222,9 @@ combo_opts_t deint_opts =
 
 static options_map_t d_denoise_opts[] =
 {
-    {N_("Off"),    "off",    0, ""},
-    {N_("Custom"), "custom", 1, ""},
-    {N_("Weak"),   "weak",   2, "2:1:1:2:3:3"},
-    {N_("Medium"), "medium", 3, "3:2:2:2:3:3"},
-    {N_("Strong"), "strong", 4, "7:7:7:5:5:5"},
+    {N_("Off"),     "off",     0, ""},
+    {N_("NLMeans"), "nlmeans", 1, ""},
+    {N_("HQDN3D"),  "hqdn3d",  2, ""},
 };
 combo_opts_t denoise_opts =
 {
@@ -234,6 +232,34 @@ combo_opts_t denoise_opts =
     d_denoise_opts
 };
 
+static options_map_t d_denoise_preset_opts[] =
+{
+    {N_("Custom"),     "custom",     1, ""},
+    {N_("Ultralight"), "ultralight", 5, ""},
+    {N_("Light"),      "light",      2, ""},
+    {N_("Medium"),     "medium",     3, ""},
+    {N_("Strong"),     "strong",     4, ""},
+};
+combo_opts_t denoise_preset_opts =
+{
+    sizeof(d_denoise_preset_opts)/sizeof(options_map_t),
+    d_denoise_preset_opts
+};
+
+static options_map_t d_nlmeans_tune_opts[] =
+{
+    {N_("None"),        "none",       0, ""},
+    {N_("Film"),        "film",       1, ""},
+    {N_("Grain"),       "grain",      2, ""},
+    {N_("High Motion"), "highmotion", 3, ""},
+    {N_("Animation"),   "animation",  4, ""},
+};
+combo_opts_t nlmeans_tune_opts =
+{
+    sizeof(d_nlmeans_tune_opts)/sizeof(options_map_t),
+    d_nlmeans_tune_opts
+};
+
 static options_map_t d_direct_opts[] =
 {
     {N_("None"),      "none",     0, "none"},
@@ -365,7 +391,9 @@ combo_name_map_t combo_name_map[] =
     {"PictureDeinterlace", &deint_opts},
     {"PictureDecomb", &decomb_opts},
     {"PictureDetelecine", &detel_opts},
-    {"PictureDenoise", &denoise_opts},
+    {"PictureDenoiseFilter", &denoise_opts},
+    {"PictureDenoisePreset", &denoise_preset_opts},
+    {"PictureDenoiseTune", &nlmeans_tune_opts},
     {"x264_direct", &direct_opts},
     {"x264_b_adapt", &badapt_opts},
     {"x264_bpyramid", &bpyramid_opts},
@@ -2526,7 +2554,9 @@ ghb_update_ui_combo_box(
         small_opts_set(ud->builder, "PictureDeinterlace", &deint_opts);
         small_opts_set(ud->builder, "PictureDetelecine", &detel_opts);
         small_opts_set(ud->builder, "PictureDecomb", &decomb_opts);
-        small_opts_set(ud->builder, "PictureDenoise", &denoise_opts);
+        small_opts_set(ud->builder, "PictureDenoiseFilter", &denoise_opts);
+        small_opts_set(ud->builder, "PictureDenoisePreset", &denoise_preset_opts);
+        small_opts_set(ud->builder, "PictureDenoiseTune", &nlmeans_tune_opts);
         small_opts_set(ud->builder, "x264_direct", &direct_opts);
         small_opts_set(ud->builder, "x264_b_adapt", &badapt_opts);
         small_opts_set(ud->builder, "x264_bpyramid", &bpyramid_opts);
@@ -3874,23 +3904,8 @@ ghb_validate_filters(GValue *settings)
         }
         g_free(str);
     }
-    // denois
-    index = ghb_settings_combo_int(settings, "PictureDenoise");
-    if (index == 1)
-    {
-        str = ghb_settings_get_string(settings, "PictureDenoiseCustom");
-        if (!ghb_validate_filter_string(str, -1))
-        {
-            message = g_strdup_printf(
-                        _("Invalid Denoise Settings:\n\n%s\n"),
-                        str);
-            ghb_message_dialog(GTK_MESSAGE_ERROR, message, _("Cancel"), NULL);
-            g_free(str);
-            g_free(message);
-            return FALSE;
-        }
-        g_free(str);
-    }
+    // denoise
+    // TODO
     return TRUE;
 }
 
@@ -4403,20 +4418,29 @@ add_job(hb_handle_t *h, GValue *js, gint unique_id, int titleindex)
         hb_add_filter( job, filter, filter_str );
         g_free(filter_str);
     }
-    gint denoise = ghb_settings_combo_int(js, "PictureDenoise");
-    if( denoise )
+    if (strcmp(ghb_settings_get_const_string(js, "PictureDenoiseFilter"), "off"))
     {
-        filter_str = NULL;
-        if (denoise != 1)
+        int filter_id = HB_FILTER_HQDN3D;
+        if (!strcmp(ghb_settings_get_const_string(js, "PictureDenoiseFilter"), "nlmeans"))
+            filter_id = HB_FILTER_NLMEANS;
+
+        if (!strcmp(ghb_settings_get_const_string(js, "PictureDenoisePreset"), "custom"))
         {
-            if (denoise_opts.map[denoise].svalue != NULL)
-                filter_str = g_strdup(denoise_opts.map[denoise].svalue);
+            const char *filter_str;
+            filter_str = ghb_settings_get_const_string(js, "PictureDenoiseCustom");
+            filter = hb_filter_init(filter_id);
+            hb_add_filter( job, filter, filter_str );
         }
         else
-            filter_str = ghb_settings_get_string(js, "PictureDenoiseCustom");
-        filter = hb_filter_init(HB_FILTER_DENOISE);
-        hb_add_filter( job, filter, filter_str );
-        g_free(filter_str);
+        {
+            const char *preset, *tune;
+            preset = ghb_settings_get_const_string(js, "PictureDenoisePreset");
+            tune = ghb_settings_get_const_string(js, "PictureDenoiseTune");
+            filter_str = hb_generate_filter_settings(filter_id, preset, tune);
+            filter = hb_filter_init(filter_id);
+            hb_add_filter( job, filter, filter_str );
+            g_free(filter_str);
+        }
     }
     gint deblock = ghb_settings_get_int(js, "PictureDeblock");
     if( deblock >= 5 )
index a7d0a05d561ed3c0dce6887bec7ddbcca59217ca..6cf0feb83ee0926d726de3952e479c0d99edf439 100644 (file)
         <string>off</string>
         <key>PictureDeinterlaceCustom</key>
         <string></string>
-        <key>PictureDenoise</key>
+        <key>PictureDenoiseFilter</key>
         <string>off</string>
+        <key>PictureDenoisePreset</key>
+        <string>medium</string>
+        <key>PictureDenoiseTune</key>
+        <string>none</string>
         <key>PictureDenoiseCustom</key>
         <string></string>
         <key>PictureDetelecine</key>
index d0b4ac2ce842d5567a1e0b3d0496a5e9d6e3941f..c4944d78659f358a4aa3d867b773e13018a80da8 100644 (file)
@@ -35,7 +35,14 @@ dep_map = (
     DepEntry("PictureDecombDeinterlace", "PictureDecombCustom", "FALSE", True, True),
     DepEntry("PictureDecombDeinterlace", "PictureDecombLabel", "FALSE", True, True),
     DepEntry("PictureDeinterlace", "PictureDeinterlaceCustom", "custom", False, True),
-    DepEntry("PictureDenoise", "PictureDenoiseCustom", "custom", False, True),
+    DepEntry("PictureDenoiseFilter", "PictureDenoisePreset", "off", True, True),
+    DepEntry("PictureDenoiseFilter", "PictureDenoisePresetLabel", "off", True, True),
+    DepEntry("PictureDenoiseFilter", "PictureDenoiseTune", "nlmeans", False, True),
+    DepEntry("PictureDenoiseFilter", "PictureDenoiseTuneLabel", "nlmeans", False, True),
+    DepEntry("PictureDenoiseFilter", "PictureDenoiseCustom", "off", True, True),
+    DepEntry("PictureDenoisePreset", "PictureDenoiseCustom", "custom", False, True),
+    DepEntry("PictureDenoisePreset", "PictureDenoiseTune", "custom", True, True),
+    DepEntry("PictureDenoisePreset", "PictureDenoiseTuneLabel", "custom", True, True),
     DepEntry("PictureDecomb", "PictureDecombCustom", "custom", False, True),
     DepEntry("PictureDetelecine", "PictureDetelecineCustom", "custom", False, True),
     DepEntry("PictureWidthEnable", "PictureWidth", "TRUE", False, False),
index 3bf9ee970fc6850a3b7f7e0f534568ef3b06add2..f2749e8df7f4bb7e593be2ce240107fb744bcdb2 100644 (file)
@@ -1927,9 +1927,10 @@ value_map_t denoise_xlat[] =
 {
     {"0", "off"},
     {"1", "custom"},
-    {"2", "weak"},
+    {"2", "light"},
     {"3", "medium"},
     {"4", "strong"},
+    {"5", "ultralight"},
     {NULL, NULL}
 };
 
@@ -2178,11 +2179,13 @@ export_value_xlat(GValue *dict)
     gval = export_value_xlat2(deint_xlat, lin_val, G_TYPE_INT);
     if (gval)
         ghb_dict_insert(dict, g_strdup(key), gval);
-    key = "PictureDenoise";
+#if 0
+    key = "PictureDenoisePreset";
     lin_val = ghb_dict_lookup(dict, key);
     gval = export_value_xlat2(denoise_xlat, lin_val, G_TYPE_INT);
     if (gval)
         ghb_dict_insert(dict, g_strdup(key), gval);
+#endif
 
     gint count, ii;
     GValue *alist;
@@ -2429,7 +2432,7 @@ import_value_xlat(GValue *dict)
     gval = import_value_xlat2(defaults, deint_xlat, key, mac_val);
     if (gval)
         ghb_dict_insert(dict, g_strdup(key), gval);
-    key = "PictureDenoise";
+    key = "PictureDenoisePreset";
     mac_val = ghb_dict_lookup(dict, key);
     gval = import_value_xlat2(defaults, denoise_xlat, key, mac_val);
     if (gval)
index 1e5243aa698815ab1aef81c046e4aca2fe1cf20a..6ad412a08aa2bee79713b92a8600e4148b678f5b 100644 (file)
@@ -308,8 +308,9 @@ add_to_queue_list(signal_user_data_t *ud, GValue *settings, GtkTreeIter *piter)
     // Next line in the display (Filter settings)
     // Filters: - Deinterlace
     gint decomb, detel, deint, deblock, denoise;
-    const gchar *detel_cust, *deint_cust, *decomb_cust, *denoise_cust;
-    const gchar *deint_opt, *decomb_opt, *denoise_opt;
+    const gchar *detel_cust, *deint_cust, *decomb_cust;
+    const gchar *deint_opt, *decomb_opt;
+    const gchar *denoise_opt, *denoise_preset, *denoise_tune, *denoise_cust;
     gboolean decomb_deint;
     gboolean grayscale;
     gboolean filters;
@@ -327,8 +328,10 @@ add_to_queue_list(signal_user_data_t *ud, GValue *settings, GtkTreeIter *piter)
     detel_cust = ghb_settings_get_const_string(settings,
                                                "PictureDetelecineCustom");
     deblock = ghb_settings_get_int(settings, "PictureDeblock");
-    denoise = ghb_settings_combo_int(settings, "PictureDenoise");
-    denoise_opt = ghb_settings_combo_option(settings, "PictureDenoise");
+    denoise = ghb_settings_combo_int(settings, "PictureDenoiseFilter");
+    denoise_opt = ghb_settings_combo_option(settings, "PictureDenoiseFilter");
+    denoise_preset = ghb_settings_combo_option(settings, "PictureDenoisePreset");
+    denoise_tune = ghb_settings_combo_option(settings, "PictureDenoiseTune");
     denoise_cust = ghb_settings_get_const_string(settings,
                                                  "PictureDenoiseCustom");
     grayscale = ghb_settings_get_boolean(settings, "VideoGrayScale");
@@ -376,14 +379,18 @@ add_to_queue_list(signal_user_data_t *ud, GValue *settings, GtkTreeIter *piter)
         }
         if (denoise)
         {
-            XPRINT("%sDenoise", prefix);
-            if (denoise == 1)
+            XPRINT("%sDenoise Filter %s:", prefix, denoise_opt);
+            if (ghb_settings_combo_int(settings, "PictureDenoisePreset") == 1)
             {
-                XPRINT(": %s", denoise_cust);
+                XPRINT(" %s", denoise_cust);
             }
             else
             {
-                XPRINT(": %s", denoise_opt);
+                XPRINT(" %s", denoise_preset);
+                if (denoise == 1 && strcmp(denoise_tune, "None"))
+                {
+                    XPRINT(",%s", denoise_tune);
+                }
             }
             prefix = " - ";
         }
index 0d15877e37882c467699edd45973b42062a08bf5..b438ff3ed195bacde696627477efd945360ff91e 100644 (file)
@@ -83,8 +83,8 @@
                                <integer>0</integer>
                                <key>PictureDeinterlaceCustom</key>
                                <string></string>
-                               <key>PictureDenoise</key>
-                               <integer>0</integer>
+                               <key>PictureDenoiseFilter</key>
+                               <integer>off</integer>
                                <key>PictureDenoiseCustom</key>
                                <string></string>
                                <key>PictureDetelecine</key>
                                <integer>0</integer>
                                <key>PictureDeinterlaceCustom</key>
                                <string></string>
-                               <key>PictureDenoise</key>
-                               <integer>0</integer>
+                               <key>PictureDenoiseFilter</key>
+                               <integer>off</integer>
                                <key>PictureDenoiseCustom</key>
                                <string></string>
                                <key>PictureDetelecine</key>
                                <integer>0</integer>
                                <key>PictureDeinterlaceCustom</key>
                                <string></string>
-                               <key>PictureDenoise</key>
-                               <integer>0</integer>
+                               <key>PictureDenoiseFilter</key>
+                               <integer>off</integer>
                                <key>PictureDenoiseCustom</key>
                                <string></string>
                                <key>PictureDetelecine</key>
                                <integer>0</integer>
                                <key>PictureDeinterlaceCustom</key>
                                <string></string>
-                               <key>PictureDenoise</key>
-                               <integer>0</integer>
+                               <key>PictureDenoiseFilter</key>
+                               <integer>off</integer>
                                <key>PictureDenoiseCustom</key>
                                <string></string>
                                <key>PictureDetelecine</key>
                                <integer>0</integer>
                                <key>PictureDeinterlaceCustom</key>
                                <string></string>
-                               <key>PictureDenoise</key>
-                               <integer>0</integer>
+                               <key>PictureDenoiseFilter</key>
+                               <integer>off</integer>
                                <key>PictureDenoiseCustom</key>
                                <string></string>
                                <key>PictureDetelecine</key>
                                <integer>0</integer>
                                <key>PictureDeinterlaceCustom</key>
                                <string></string>
-                               <key>PictureDenoise</key>
-                               <integer>0</integer>
+                               <key>PictureDenoiseFilter</key>
+                               <integer>off</integer>
                                <key>PictureDenoiseCustom</key>
                                <string></string>
                                <key>PictureDetelecine</key>
                                <integer>0</integer>
                                <key>PictureDeinterlaceCustom</key>
                                <string></string>
-                               <key>PictureDenoise</key>
-                               <integer>0</integer>
+                               <key>PictureDenoiseFilter</key>
+                               <integer>off</integer>
                                <key>PictureDenoiseCustom</key>
                                <string></string>
                                <key>PictureDetelecine</key>
                                <integer>0</integer>
                                <key>PictureDeinterlaceCustom</key>
                                <string></string>
-                               <key>PictureDenoise</key>
-                               <integer>0</integer>
+                               <key>PictureDenoiseFilter</key>
+                               <integer>off</integer>
                                <key>PictureDenoiseCustom</key>
                                <string></string>
                                <key>PictureDetelecine</key>
                                <integer>0</integer>
                                <key>PictureDeinterlaceCustom</key>
                                <string></string>
-                               <key>PictureDenoise</key>
-                               <integer>0</integer>
+                               <key>PictureDenoiseFilter</key>
+                               <integer>off</integer>
                                <key>PictureDenoiseCustom</key>
                                <string></string>
                                <key>PictureDetelecine</key>
                                <integer>0</integer>
                                <key>PictureDeinterlaceCustom</key>
                                <string></string>
-                               <key>PictureDenoise</key>
-                               <integer>0</integer>
+                               <key>PictureDenoiseFilter</key>
+                               <integer>off</integer>
                                <key>PictureDenoiseCustom</key>
                                <string></string>
                                <key>PictureDetelecine</key>
                                <integer>0</integer>
                                <key>PictureDeinterlaceCustom</key>
                                <string></string>
-                               <key>PictureDenoise</key>
-                               <integer>0</integer>
+                               <key>PictureDenoiseFilter</key>
+                               <integer>off</integer>
                                <key>PictureDenoiseCustom</key>
                                <string></string>
                                <key>PictureDetelecine</key>
                                <integer>0</integer>
                                <key>PictureDeinterlaceCustom</key>
                                <string></string>
-                               <key>PictureDenoise</key>
-                               <integer>0</integer>
+                               <key>PictureDenoiseFilter</key>
+                               <integer>off</integer>
                                <key>PictureDenoiseCustom</key>
                                <string></string>
                                <key>PictureDetelecine</key>
index 275761803f0aaf822d65428e5341803a93b80030..c3bbc2c21242523cee6a736f62ade49f8035cb00 100644 (file)
@@ -1210,6 +1210,7 @@ enum
     // Filters that must operate on the original source image are next
     HB_FILTER_DEBLOCK,
     HB_FILTER_DENOISE,
+    HB_FILTER_HQDN3D = HB_FILTER_DENOISE,
     HB_FILTER_NLMEANS,
     HB_FILTER_RENDER_SUB,
     HB_FILTER_CROP_SCALE,
@@ -1228,6 +1229,8 @@ hb_filter_object_t * hb_filter_init( int filter_id );
 hb_filter_object_t * hb_filter_copy( hb_filter_object_t * filter );
 hb_list_t *hb_filter_list_copy(const hb_list_t *src);
 void hb_filter_close( hb_filter_object_t ** );
+char * hb_generate_filter_settings(int filter_id, const char *preset,
+                                                  const char *tune);
 
 typedef void hb_error_handler_t( const char *errmsg );
 
diff --git a/libhb/param.c b/libhb/param.c
new file mode 100644 (file)
index 0000000..d95bf14
--- /dev/null
@@ -0,0 +1,226 @@
+/* param.c
+ *
+ * Copyright (c) 2003-2014 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"
+
+/* NL-means presets and tunes
+ *
+ * Presets adjust strength:
+ * ultralight - visually transparent
+ * light
+ * medium
+ * strong
+ *
+ * Tunes adjust settings to the specified content type:
+ * none
+ * film       - most content, live action
+ * grain      - like film but preserves luma grain
+ * highmotion - like film but avoids color smearing with stronger settings
+ * animation  - cel animation such as cartoons, anime
+ */
+static char * generate_nlmeans_settings(const char *preset, const char *tune)
+{
+    char   *opt = NULL;
+
+    if (preset == NULL)
+        return NULL;
+
+    if (!strcasecmp(preset, "ultralight") ||
+        !strcasecmp(preset, "light") ||
+        !strcasecmp(preset, "medium") ||
+        !strcasecmp(preset, "strong"))
+    {
+        double strength[2],
+               origin_tune[2];
+        int    patch_size[2],
+               range[2],
+               frames[2],
+               prefilter[2];
+
+        if (tune == NULL || !strcasecmp(tune, "none"))
+        {
+            strength[0]    = strength[1]    = 6;
+            origin_tune[0] = origin_tune[1] = 1;
+            patch_size[0]  = patch_size[1]  = 7;
+            range[0]       = range[1]       = 3;
+            frames[0]      = frames[1]      = 2;
+            prefilter[0]   = prefilter[1]   = 0;
+            if (!strcasecmp(preset, "ultralight"))
+            {
+                strength[0] = strength[1] = 1.5;
+            }
+            else if (!strcasecmp(preset, "light"))
+            {
+                strength[0] = strength[1] = 3;
+            }
+            else if (!strcasecmp(preset, "strong"))
+            {
+                strength[0] = strength[1] = 10;
+            }
+        }
+        else if (!strcasecmp(tune, "film"))
+        {
+            strength[0]    = 6; strength[1] = 8;
+            origin_tune[0] = origin_tune[1] = 0.8;
+            patch_size[0]  = patch_size[1]  = 7;
+            range[0]       = range[1]       = 3;
+            frames[0]      = frames[1]      = 2;
+            prefilter[0]   = prefilter[1]   = 0;
+            if (!strcasecmp(preset, "ultralight"))
+            {
+                strength[0]    = 1.5;   strength[1]  = 2.4;
+                origin_tune[0] = 0.9; origin_tune[1] = 0.9;
+            }
+            else if (!strcasecmp(preset, "light"))
+            {
+                strength[0]    = 3;   strength[1]    = 4;
+                origin_tune[0] = 0.9; origin_tune[1] = 0.9;
+            }
+            else if (!strcasecmp(preset, "strong"))
+            {
+                strength[0]    = 8;   strength[1]    = 10;
+                origin_tune[0] = 0.6; origin_tune[1] = 0.6;
+            }
+        }
+        else if (!strcasecmp(tune, "grain"))
+        {
+            strength[0]    = 0; strength[1] = 6;
+            origin_tune[0] = origin_tune[1] = 0.8;
+            patch_size[0]  = patch_size[1]  = 7;
+            range[0]       = range[1]       = 3;
+            frames[0]      = frames[1]      = 2;
+            prefilter[0]   = prefilter[1]   = 0;
+            if (!strcasecmp(preset, "ultralight"))
+            {
+                strength[0]    = 0;   strength[1]    = 2.4;
+                origin_tune[0] = 0.9; origin_tune[1] = 0.9;
+            }
+            else if (!strcasecmp(preset, "light"))
+            {
+                strength[0]    = 0;   strength[1]    = 3.5;
+                origin_tune[0] = 0.9; origin_tune[1] = 0.9;
+            }
+            else if (!strcasecmp(preset, "strong"))
+            {
+                strength[0]    = 0;   strength[1]    = 8;
+                origin_tune[0] = 0.6; origin_tune[1] = 0.6;
+            }
+        }
+        else if (!strcasecmp(tune, "highmotion"))
+        {
+            strength[0]    = 6;   strength[1]    = 6;
+            origin_tune[0] = 0.8; origin_tune[1] = 0.7;
+            patch_size[0]  = 7;   patch_size[1]  = 7;
+            range[0]       = 3;   range[1]       = 5;
+            frames[0]      = 2;   frames[1]      = 1;
+            prefilter[0]   = 0;   prefilter[1]   = 0;
+            if (!strcasecmp(preset, "ultralight"))
+            {
+                strength[0]    = 1.5;   strength[1]  = 2.4;
+                origin_tune[0] = 0.9; origin_tune[1] = 0.9;
+            }
+            else if (!strcasecmp(preset, "light"))
+            {
+                strength[0]    = 3;   strength[1]    = 3.25;
+                origin_tune[0] = 0.9; origin_tune[1] = 0.8;
+            }
+            else if (!strcasecmp(preset, "strong"))
+            {
+                strength[0]    = 8;   strength[1]    = 6.75;
+                origin_tune[0] = 0.6; origin_tune[1] = 0.5;
+            }
+        }
+        else if (!strcasecmp(tune, "animation"))
+        {
+            strength[0]    = 5; strength[1] = 4;
+            origin_tune[0] = origin_tune[1] = 0.15;
+            patch_size[0]  = patch_size[1]  = 5;
+            range[0]       = range[1]       = 7;
+            frames[0]      = frames[1]      = 4;
+            prefilter[0]   = prefilter[1]   = 0;
+            if (!strcasecmp(preset, "ultralight"))
+            {
+                strength[0] = 2.5; strength[1] = 2;
+                frames[0]   = 2;   frames[1]   = 2;
+            }
+            else if (!strcasecmp(preset, "light"))
+            {
+                strength[0] = 3; strength[1] = 2.25;
+                frames[0]   = 3; frames[1]   = 3;
+            }
+            else if (!strcasecmp(preset, "strong"))
+            {
+                strength[0] = 10; strength[1] = 8;
+            }
+        }
+        else
+        {
+            hb_log("Unrecognized nlmeans tune (%s).\n", tune);
+            return NULL;
+        }
+
+        opt = hb_strdup_printf("%lf:%lf:%d:%d:%d:%d:%lf:%lf:%d:%d:%d:%d",
+                               strength[0], origin_tune[0], patch_size[0],
+                               range[0], frames[0], prefilter[0],
+                               strength[1], origin_tune[1], patch_size[1],
+                               range[1], frames[1], prefilter[1]);
+
+
+    }
+    else
+    {
+        opt = strdup(preset);
+        if (tune != NULL)
+        {
+            hb_log("Custom nlmeans parameters specified; ignoring nlmeans tune (%s).\n", tune);
+        }
+    }
+
+    return opt;
+}
+
+/* HQDN3D presets
+ *
+ * Presets adjust strength:
+ * ultralight - visually transparent
+ * light
+ * medium
+ * strong
+ */
+static char * generate_hqdn3d_settings(const char *preset, const char *tune)
+{
+    if (!strcasecmp(preset, "strong"))
+        return strdup("7:7:7:5:5:5");
+    else if (!strcasecmp(preset, "medium"))
+        return strdup("3:2:2:2:3:3");
+    else if (!strcasecmp(preset, "light") || !strcasecmp(preset, "weak"))
+        return strdup("2:1:1:2:3:3");
+    else if (!strcasecmp(preset, "ultralight"))
+        return strdup("1:0.7:0.7:1:2:2");
+    else
+        return strdup(preset);
+}
+
+char * hb_generate_filter_settings(int filter_id, const char *preset, const char *tune)
+{
+    switch (filter_id)
+    {
+        case HB_FILTER_NLMEANS:
+            return generate_nlmeans_settings(preset, tune);
+        case HB_FILTER_HQDN3D:
+            return generate_hqdn3d_settings(preset, tune);
+        default:
+            hb_log("hb_generate_filter_settings: Unrecognized filter %d\n",
+                   filter_id);
+            break;
+    }
+    return NULL;
+}
+
index b0c5b6010152ba747af37f448f0996fea5d34214..0c3b0ab7453ea64b7b47d171e727597917a4c846 100644 (file)
@@ -3327,7 +3327,7 @@ if (hb_qsv_available())
      "                            specify a constant framerate (--rate 29.97)\n"
      "          <L:R:T:B:SB:MP:FD> (default 1:1:4:4:0:0:-1)\n"
      "    -8, --denoise           Denoise video with hqdn3d filter\n"
-     "          <weak/medium/strong> or omitted (default settings)\n"
+     "          <ultralight/light/medium/strong> or omitted (default settings)\n"
      "           or\n"
      "          <SL:SCb:SCr:TL:TCb:TCr>\n"
      "          (default: 4:3:3:6:4.5:4.5)\n"
@@ -3970,22 +3970,8 @@ static int ParseOptions( int argc, char ** argv )
             case '8':
                 if( optarg != NULL )
                 {
-                    if (!( strcmp( optarg, "weak" ) ))
-                    {
-                        denoise_opt = "2:1:1:2:3:3";
-                    }
-                    else if (!( strcmp( optarg, "medium" ) ))
-                    {
-                        denoise_opt = "3:2:2:2:3:3";
-                    }
-                    else if (!( strcmp( optarg, "strong" ) ))
-                    {
-                        denoise_opt = "7:7:7:5:5:5";
-                    }
-                    else
-                    {
-                        denoise_opt = strdup( optarg );
-                    }
+                    free(denoise_opt);
+                    denoise_opt = strdup( optarg );
                 }
                 denoise = 1;
                 break;
@@ -4307,179 +4293,29 @@ static int ParseOptions( int argc, char ** argv )
 
     }
 
-    /* NL-means presets (--nlmeans) and tunes (--nlmeans-tune)
-     *
-     * Presets adjust strength:
-     * ultralight - visually transparent
-     * light
-     * medium
-     * strong
-     *
-     * Tunes adjust settings to the specified content type:
-     * none
-     * film       - most content, live action
-     * grain      - like film but preserves luma grain
-     * highmotion - like film but avoids color smearing with stronger settings
-     * animation  - cel animation such as cartoons, anime
-     */
-    if (nlmeans == 1 && nlmeans_opt != NULL)
+    if (nlmeans)
     {
-        if (!strcmp(nlmeans_opt, "ultralight") ||
-            !strcmp(nlmeans_opt, "light") ||
-            !strcmp(nlmeans_opt, "medium") ||
-            !strcmp(nlmeans_opt, "strong"))
+        if (nlmeans_opt == NULL && nlmeans_tune_opt != NULL)
         {
-            char   opt[1024];
-            double strength[2],
-                   origin_tune[2];
-            int    patch_size[2],
-                   range[2],
-                   frames[2],
-                   prefilter[2];
-
-            if (nlmeans_tune_opt == NULL || !strcmp(nlmeans_tune_opt, "none"))
-            {
-                strength[0]    = strength[1]    = 6;
-                origin_tune[0] = origin_tune[1] = 1;
-                patch_size[0]  = patch_size[1]  = 7;
-                range[0]       = range[1]       = 3;
-                frames[0]      = frames[1]      = 2;
-                prefilter[0]   = prefilter[1]   = 0;
-                if (!strcmp(nlmeans_opt, "ultralight"))
-                {
-                    strength[0] = strength[1] = 1.5;
-                }
-                else if (!strcmp(nlmeans_opt, "light"))
-                {
-                    strength[0] = strength[1] = 3;
-                }
-                else if (!strcmp(nlmeans_opt, "strong"))
-                {
-                    strength[0] = strength[1] = 10;
-                }
-            }
-            else if (!strcmp(nlmeans_tune_opt, "film"))
-            {
-                strength[0]    = 6; strength[1] = 8;
-                origin_tune[0] = origin_tune[1] = 0.8;
-                patch_size[0]  = patch_size[1]  = 7;
-                range[0]       = range[1]       = 3;
-                frames[0]      = frames[1]      = 2;
-                prefilter[0]   = prefilter[1]   = 0;
-                if (!strcmp(nlmeans_opt, "ultralight"))
-                {
-                    strength[0]    = 1.5;   strength[1]  = 2.4;
-                    origin_tune[0] = 0.9; origin_tune[1] = 0.9;
-                }
-                else if (!strcmp(nlmeans_opt, "light"))
-                {
-                    strength[0]    = 3;   strength[1]    = 4;
-                    origin_tune[0] = 0.9; origin_tune[1] = 0.9;
-                }
-                else if (!strcmp(nlmeans_opt, "strong"))
-                {
-                    strength[0]    = 8;   strength[1]    = 10;
-                    origin_tune[0] = 0.6; origin_tune[1] = 0.6;
-                }
-            }
-            else if (!strcmp(nlmeans_tune_opt, "grain"))
-            {
-                strength[0]    = 0; strength[1] = 6;
-                origin_tune[0] = origin_tune[1] = 0.8;
-                patch_size[0]  = patch_size[1]  = 7;
-                range[0]       = range[1]       = 3;
-                frames[0]      = frames[1]      = 2;
-                prefilter[0]   = prefilter[1]   = 0;
-                if (!strcmp(nlmeans_opt, "ultralight"))
-                {
-                    strength[0]    = 0;   strength[1]    = 2.4;
-                    origin_tune[0] = 0.9; origin_tune[1] = 0.9;
-                }
-                else if (!strcmp(nlmeans_opt, "light"))
-                {
-                    strength[0]    = 0;   strength[1]    = 3.5;
-                    origin_tune[0] = 0.9; origin_tune[1] = 0.9;
-                }
-                else if (!strcmp(nlmeans_opt, "strong"))
-                {
-                    strength[0]    = 0;   strength[1]    = 8;
-                    origin_tune[0] = 0.6; origin_tune[1] = 0.6;
-                }
-            }
-            else if (!strcmp(nlmeans_tune_opt, "highmotion"))
-            {
-                strength[0]    = 6;   strength[1]    = 6;
-                origin_tune[0] = 0.8; origin_tune[1] = 0.7;
-                patch_size[0]  = 7;   patch_size[1]  = 7;
-                range[0]       = 3;   range[1]       = 5;
-                frames[0]      = 2;   frames[1]      = 1;
-                prefilter[0]   = 0;   prefilter[1]   = 0;
-                if (!strcmp(nlmeans_opt, "ultralight"))
-                {
-                    strength[0]    = 1.5;   strength[1]  = 2.4;
-                    origin_tune[0] = 0.9; origin_tune[1] = 0.9;
-                }
-                else if (!strcmp(nlmeans_opt, "light"))
-                {
-                    strength[0]    = 3;   strength[1]    = 3.25;
-                    origin_tune[0] = 0.9; origin_tune[1] = 0.8;
-                }
-                else if (!strcmp(nlmeans_opt, "strong"))
-                {
-                    strength[0]    = 8;   strength[1]    = 6.75;
-                    origin_tune[0] = 0.6; origin_tune[1] = 0.5;
-                }
-            }
-            else if (!strcmp(nlmeans_tune_opt, "animation"))
-            {
-                strength[0]    = 5; strength[1] = 4;
-                origin_tune[0] = origin_tune[1] = 0.15;
-                patch_size[0]  = patch_size[1]  = 5;
-                range[0]       = range[1]       = 7;
-                frames[0]      = frames[1]      = 4;
-                prefilter[0]   = prefilter[1]   = 0;
-                if (!strcmp(nlmeans_opt, "ultralight"))
-                {
-                    strength[0] = 2.5; strength[1] = 2;
-                    frames[0]   = 2;   frames[1]   = 2;
-                }
-                else if (!strcmp(nlmeans_opt, "light"))
-                {
-                    strength[0] = 3; strength[1] = 2.25;
-                    frames[0]   = 3; frames[1]   = 3;
-                }
-                else if (!strcmp(nlmeans_opt, "strong"))
-                {
-                    strength[0] = 10; strength[1] = 8;
-                }
-            }
-            else
-            {
-                fprintf(stderr, "Unrecognized nlmeans tune (%s).\n", nlmeans_tune_opt);
-                return -1;
-            }
-
-            sprintf(opt, "%lf:%lf:%d:%d:%d:%d:%lf:%lf:%d:%d:%d:%d",
-                    strength[0], origin_tune[0], patch_size[0], range[0], frames[0], prefilter[0],
-                    strength[1], origin_tune[1], patch_size[1], range[1], frames[1], prefilter[1]);
-
-            free(nlmeans_opt);
-            nlmeans_opt = strdup(opt);
-
+            fprintf(stdout, "Default nlmeans parameters specified; ignoring nlmeans tune (%s).\n", nlmeans_tune_opt);
         }
-        else
+
+        char *opt = hb_generate_filter_settings(HB_FILTER_NLMEANS,
+                                                nlmeans_opt, nlmeans_tune_opt);
+        if (opt != NULL)
         {
-            if (nlmeans_tune_opt != NULL)
-            {
-                fprintf(stdout, "Custom nlmeans parameters specified; ignoring nlmeans tune (%s).\n", nlmeans_tune_opt);
-            }
+            free(nlmeans_opt);
+            nlmeans_opt = opt;
         }
     }
-    else if (nlmeans == 1 && nlmeans_opt == NULL)
+    if (denoise)
     {
-        if (nlmeans_tune_opt != NULL)
+        char *opt = hb_generate_filter_settings(HB_FILTER_DENOISE,
+                                                denoise_opt, NULL);
+        if (opt != NULL)
         {
-            fprintf(stdout, "Default nlmeans parameters specified; ignoring nlmeans tune (%s).\n", nlmeans_tune_opt);
+            free(denoise_opt);
+            denoise_opt = opt;
         }
     }