@@ -147,6 +147,7 @@ struct priv {
147147 pl_options pars ;
148148 struct m_config_cache * opts_cache ;
149149 struct m_config_cache * next_opts_cache ;
150+ struct m_config_cache * filter_opts_cache ;
150151 struct gl_next_opts * next_opts ;
151152 struct cache shader_cache , icc_cache ;
152153 struct mp_csp_equalizer_state * video_eq ;
@@ -890,6 +891,7 @@ static void update_options(struct vo *vo)
890891 pl_options pars = p -> pars ;
891892 bool changed = m_config_cache_update (p -> opts_cache );
892893 changed = m_config_cache_update (p -> next_opts_cache ) || changed ;
894+ changed = m_config_cache_update (p -> filter_opts_cache ) || changed ;
893895 if (changed )
894896 update_render_options (vo );
895897
@@ -1143,13 +1145,29 @@ static bool draw_frame(struct vo *vo, struct vo_frame *frame)
11431145 mpi -> priv = fp ;
11441146 fp -> vo = vo ;
11451147
1148+ bool use_fields = params .deinterlace_params &&
1149+ mpi -> fields & MP_IMGFIELD_INTERLACED ;
1150+
1151+ // vf_fieldrate emits a frame for each field only to make mpv render
1152+ // at the second field PTS. But don't actually push it to pl_queue,
1153+ // because it already derives it internally from first_field.
1154+ if (use_fields && (mpi -> fields & MP_IMGFIELD_TICK_SECOND )) {
1155+ talloc_free (mpi );
1156+ p -> last_id = id ;
1157+ continue ;
1158+ }
1159+ int first_field = !use_fields ? PL_FIELD_NONE :
1160+ (mpi -> fields & MP_IMGFIELD_TOP_FIRST ) ? PL_FIELD_TOP : PL_FIELD_BOTTOM ;
1161+
11461162 pl_queue_push (p -> queue , & (struct pl_source_frame ) {
11471163 .pts = mpi -> pts ,
1148- .duration = can_interpolate ? frame -> approx_duration : 0 ,
1164+ .duration = can_interpolate ? frame -> approx_duration :
1165+ use_fields ? mpi -> pkt_duration : 0 ,
11491166 .frame_data = mpi ,
11501167 .map = map_frame ,
11511168 .unmap = unmap_frame ,
11521169 .discard = discard_frame ,
1170+ .first_field = first_field ,
11531171 });
11541172
11551173 p -> last_id = id ;
@@ -2229,6 +2247,7 @@ static int preinit(struct vo *vo)
22292247{
22302248 struct priv * p = vo -> priv ;
22312249 p -> opts_cache = m_config_cache_alloc (p , vo -> global , & gl_video_conf );
2250+ p -> filter_opts_cache = m_config_cache_alloc (p , vo -> global , & filter_conf );
22322251 p -> next_opts_cache = m_config_cache_alloc (p , vo -> global , & gl_next_conf );
22332252 p -> next_opts = p -> next_opts_cache -> opts ;
22342253 p -> video_eq = mp_csp_equalizer_create (p , vo -> global );
@@ -2556,6 +2575,7 @@ static void update_render_options(struct vo *vo)
25562575 struct priv * p = vo -> priv ;
25572576 pl_options pars = p -> pars ;
25582577 const struct gl_video_opts * opts = p -> opts_cache -> opts ;
2578+ const struct filter_opts * fopts = p -> filter_opts_cache -> opts ;
25592579 pars -> params .background_color [0 ] = opts -> background_color .r / 255.0 ;
25602580 pars -> params .background_color [1 ] = opts -> background_color .g / 255.0 ;
25612581 pars -> params .background_color [2 ] = opts -> background_color .b / 255.0 ;
@@ -2589,6 +2609,9 @@ static void update_render_options(struct vo *vo)
25892609 pars -> params .plane_upscaler = map_scaler (p , SCALER_CSCALE );
25902610 pars -> params .frame_mixer = opts -> interpolation ? map_scaler (p , SCALER_TSCALE ) : NULL ;
25912611
2612+ pars -> params .deinterlace_params = fopts -> deinterlace != 0 ? & pars -> deinterlace_params : NULL ;
2613+ pars -> deinterlace_params .algo = PL_DEINTERLACE_BWDIF ;
2614+
25922615 // Request as many frames as required from the decoder, depending on the
25932616 // speed VPS/FPS ratio libplacebo may need more frames. Request frames up to
25942617 // ratio of 1/2, but only if anti aliasing is enabled.
@@ -2706,6 +2729,7 @@ const struct vo_driver video_out_gpu_next = {
27062729 .caps = VO_CAP_ROTATE90 |
27072730 VO_CAP_FILM_GRAIN |
27082731 VO_CAP_VFLIP |
2732+ VO_CAP_DEINTERLACE |
27092733 0x0 ,
27102734 .preinit = preinit ,
27112735 .query_format = query_format ,
0 commit comments