@@ -127,22 +127,23 @@ su_tv_processor_params_ntsc(
127127 struct sigutils_tv_processor_params * self ,
128128 SUFLOAT samp_rate )
129129{
130- self -> enable_sync = SU_TRUE ;
131- self -> reverse = SU_FALSE ;
132- self -> interlace = SU_TRUE ;
133- self -> enable_agc = SU_TRUE ;
134- self -> x_off = 0 ;
135- self -> dominance = SU_TRUE ;
136- self -> frame_lines = 525 ;
137-
138- self -> enable_comb = SU_TRUE ;
139- self -> comb_reverse = SU_FALSE ;
140-
141- self -> hsync_len = SU_T2N_FLOAT (samp_rate , 4.749e-6 );
142- self -> vsync_len = SU_T2N_FLOAT (samp_rate , 2.375e-6 );
143- self -> line_len = SU_T2N_FLOAT (samp_rate , 63.556e-6 );
130+ self -> enable_sync = SU_TRUE ;
131+ self -> reverse = SU_FALSE ;
132+ self -> interlace = SU_TRUE ;
133+ self -> enable_agc = SU_TRUE ;
134+ self -> x_off = 0 ;
135+ self -> dominance = SU_TRUE ;
136+ self -> frame_lines = 525 ;
137+ self -> frame_spacing = 0.0 ;
138+
139+ self -> enable_comb = SU_TRUE ;
140+ self -> comb_reverse = SU_FALSE ;
141+
142+ self -> hsync_len = SU_T2N_FLOAT (samp_rate , 4.749e-6 );
143+ self -> vsync_len = SU_T2N_FLOAT (samp_rate , 2.375e-6 );
144+ self -> line_len = SU_T2N_FLOAT (samp_rate , 63.556e-6 );
144145 self -> vsync_odd_trigger = 6 ; /* VSYNC counter to trigger vertical sync */
145-
146+
146147 self -> t_tol = 1e-1 ; /* Timing error tolerance */
147148 self -> l_tol = 1e-1 ; /* Level error tolerance */
148149 self -> g_tol = 1e-1 ; /* Geometry adjustment tolerance */
@@ -166,20 +167,21 @@ su_tv_processor_params_pal(
166167 struct sigutils_tv_processor_params * self ,
167168 SUFLOAT samp_rate )
168169{
169- self -> enable_sync = SU_TRUE ;
170- self -> reverse = SU_FALSE ;
171- self -> interlace = SU_TRUE ;
172- self -> enable_agc = SU_TRUE ;
173- self -> x_off = 0 ;
174- self -> dominance = SU_TRUE ;
175- self -> frame_lines = 625 ;
170+ self -> enable_sync = SU_TRUE ;
171+ self -> reverse = SU_FALSE ;
172+ self -> interlace = SU_TRUE ;
173+ self -> enable_agc = SU_TRUE ;
174+ self -> x_off = 0 ;
175+ self -> dominance = SU_TRUE ;
176+ self -> frame_lines = 625 ;
177+ self -> frame_spacing = 0.0 ;
176178
177- self -> enable_comb = SU_TRUE ;
179+ self -> enable_comb = SU_TRUE ;
178180 self -> comb_reverse = SU_FALSE ;
179181
180- self -> hsync_len = SU_T2N_FLOAT (samp_rate , 4e-6 );
181- self -> vsync_len = SU_T2N_FLOAT (samp_rate , 2e-6 );
182- self -> line_len = SU_T2N_FLOAT (samp_rate , 64e-6 );
182+ self -> hsync_len = SU_T2N_FLOAT (samp_rate , 4e-6 );
183+ self -> vsync_len = SU_T2N_FLOAT (samp_rate , 2e-6 );
184+ self -> line_len = SU_T2N_FLOAT (samp_rate , 64e-6 );
183185 self -> vsync_odd_trigger = 5 ; /* VSYNC counter to trigger vertical sync */
184186
185187 self -> t_tol = 1e-1 ; /* Timing error tolerance */
@@ -211,7 +213,10 @@ SU_INSTANCER(
211213 new -> width = SU_CEIL (params -> line_len );
212214 new -> height = params -> frame_lines ;
213215
214- SU_ALLOCATE_MANY_FAIL (new -> buffer , new -> width * new -> height , SUFLOAT );
216+ /*
217+ * Allocate extra line for fractional line numbers.
218+ */
219+ SU_ALLOCATE_MANY_FAIL (new -> buffer , new -> width * (new -> height + 1 ), SUFLOAT );
215220
216221 return new ;
217222
@@ -274,12 +279,23 @@ SU_INSTANCER(su_tv_processor, const struct sigutils_tv_processor_params *params)
274279SUINLINE
275280SU_METHOD (su_tv_processor , void , swap_field )
276281{
282+ SUBOOL spacing = SU_TRUE ;
283+
277284 if (self -> params .interlace ) {
285+ spacing = self -> field_parity ;
278286 self -> field_parity = !self -> field_parity ;
279287 self -> field_lines = self -> params .frame_lines / 2 + self -> field_parity ;
280288 } else {
281289 self -> field_lines = self -> params .frame_lines ;
282290 }
291+
292+ if (spacing ) {
293+ self -> field_line_due += self -> params .frame_spacing ;
294+ if (self -> field_line_due >= 1 ) {
295+ self -> field_line_due -= 1. ;
296+ ++ self -> field_lines ;
297+ }
298+ }
283299}
284300
285301SUINLINE
@@ -359,6 +375,9 @@ SU_METHOD(
359375 self -> agc_lines = 0 ;
360376 }
361377
378+ /* Reset line due */
379+ self -> field_line_due = 0. ;
380+
362381 /* Reset pulse filter state */
363382 self -> pulse_x = 0 ;
364383
@@ -423,7 +442,7 @@ SU_METHOD(
423442 self -> hsync_slow_track_alpha = SU_SPLPF_ALPHA (params -> hsync_slow_track_tau );
424443 self -> hsync_fast_track_alpha = SU_SPLPF_ALPHA (params -> hsync_fast_track_tau );
425444 self -> line_len_alpha = SU_SPLPF_ALPHA (params -> line_len_tau );
426-
445+
427446 ok = SU_TRUE ;
428447
429448fail :
0 commit comments