@@ -170,6 +170,8 @@ struct priv {
170170 bool target_hint ;
171171
172172 float corner_rounding ;
173+ float sharpen ;
174+ const struct pl_hook * sharpen_hook ;
173175
174176 struct pl_hdr_metadata last_hdr_metadata ;
175177};
@@ -1875,6 +1877,8 @@ static void uninit(struct vo *vo)
18751877 pl_tex_destroy (p -> gpu , & p -> sub_tex [i ]);
18761878 for (int i = 0 ; i < p -> num_user_hooks ; i ++ )
18771879 pl_mpv_user_shader_destroy (& p -> user_hooks [i ].hook );
1880+ if (p -> sharpen_hook )
1881+ pl_mpv_user_shader_destroy (& p -> sharpen_hook );
18781882
18791883 if (vo -> hwdec_devs ) {
18801884 ra_hwdec_mapper_free (& p -> hwdec_mapper );
@@ -2202,6 +2206,43 @@ static void update_hook_opts(struct priv *p, char **opts, const char *shaderpath
22022206 }
22032207}
22042208
2209+ static const struct pl_hook * create_sharpen_hook (struct priv * p , float param )
2210+ {
2211+ if (param == 0.0f )
2212+ return NULL ;
2213+
2214+ // Unsharp mask shader compatible with libplacebo's hook system
2215+ // This matches the algorithm from gpu/video_shaders.c pass_sample_unsharp
2216+ const char * sharpen_shader = talloc_asprintf (p ,
2217+ "//!HOOK MAIN\n"
2218+ "//!BIND HOOKED\n"
2219+ "//!DESC Sharpen (unsharp mask)\n"
2220+ "\n"
2221+ "vec4 hook()\n"
2222+ "{\n"
2223+ " float st1 = 1.2;\n"
2224+ " vec4 p = HOOKED_tex(HOOKED_pos);\n"
2225+ " vec4 sum1 = HOOKED_texOff(st1 * vec2(+1.0, +1.0))\n"
2226+ " + HOOKED_texOff(st1 * vec2(+1.0, -1.0))\n"
2227+ " + HOOKED_texOff(st1 * vec2(-1.0, +1.0))\n"
2228+ " + HOOKED_texOff(st1 * vec2(-1.0, -1.0));\n"
2229+ " float st2 = 1.5;\n"
2230+ " vec4 sum2 = HOOKED_texOff(st2 * vec2(+1.0, 0.0))\n"
2231+ " + HOOKED_texOff(st2 * vec2( 0.0, +1.0))\n"
2232+ " + HOOKED_texOff(st2 * vec2(-1.0, 0.0))\n"
2233+ " + HOOKED_texOff(st2 * vec2( 0.0, -1.0));\n"
2234+ " vec4 t = p * 0.859375 + sum2 * -0.1171875 + sum1 * -0.09765625;\n"
2235+ " return p + t * %f;\n"
2236+ "}\n" ,
2237+ param );
2238+
2239+ const struct pl_hook * hook = pl_mpv_user_shader_parse (p -> gpu , sharpen_shader , strlen (sharpen_shader ));
2240+ if (!hook )
2241+ MP_ERR (p , "Failed to create sharpen shader hook\n" );
2242+
2243+ return hook ;
2244+ }
2245+
22052246static void update_render_options (struct vo * vo )
22062247{
22072248 struct priv * p = vo -> priv ;
@@ -2352,6 +2393,21 @@ static void update_render_options(struct vo *vo)
23522393 }
23532394 }
23542395
2396+ if (p -> sharpen != 0.0f ) {
2397+ if (p -> sharpen_hook )
2398+ pl_mpv_user_shader_destroy (& p -> sharpen_hook );
2399+
2400+ p -> sharpen_hook = create_sharpen_hook (p , p -> sharpen );
2401+ if (p -> sharpen_hook )
2402+ MP_TARRAY_APPEND (p , p -> hooks , pars -> params .num_hooks , p -> sharpen_hook );
2403+ } else {
2404+ // Clean up sharpen hook when disabled
2405+ if (p -> sharpen_hook ) {
2406+ pl_mpv_user_shader_destroy (& p -> sharpen_hook );
2407+ p -> sharpen_hook = NULL ;
2408+ }
2409+ }
2410+
23552411 pars -> params .hooks = p -> hooks ;
23562412}
23572413
@@ -2398,6 +2454,7 @@ const struct vo_driver video_out_default = {
23982454 {"image-lut-type" , OPT_CHOICE_C (image_lut .type , lut_types )},
23992455 {"target-lut" , OPT_STRING (target_lut .opt ), .flags = M_OPT_FILE },
24002456 {"target-colorspace-hint" , OPT_BOOL (target_hint )},
2457+ {"sharpen" , OPT_FLOAT (sharpen )},
24012458 // No `target-lut-type` because we don't support non-RGB targets
24022459 {"libplacebo-opts" , OPT_KEYVALUELIST (raw_opts )},
24032460 {0 }
0 commit comments