@@ -327,54 +327,94 @@ def get_line0_fallback(
327327 linelen / 2
328328 )
329329 line_offset = None
330- phase_cnt = [0 , 0 , 0 ]
331- for d in range (15 , min (i , 30 ) + 1 ):
332- pp = np .array (
333- [
334- (filtered_pulses [i - 2 ].start - filtered_pulses [i - d ].start )
335- / measured_linelen ,
336- (
337- filtered_pulses [i - 2 ].start
338- - filtered_pulses [i - d + 1 ].start
339- )
340- / measured_linelen ,
341- (
342- filtered_pulses [i - 2 ].start
343- - filtered_pulses [i - d + 2 ].start
344- )
345- / measured_linelen ,
346- ]
347- )
348- # PAL: for start of first field all values should be 1, for second field all should be 0
349- # NTSC: for start of first field all values should be 0, for second field all should be 1
350- pps = np .sum (np .mod (np .round (pp * 2 ), 2 ))
351- if pps == 0 :
352- phase_cnt [0 ] += 1
353- elif pps == 3 :
354- phase_cnt [1 ] += 1
355- else :
356- phase_cnt [2 ] += 1
357- if sum (phase_cnt [0 :2 ]) >= 5 :
330+ # count "half lines" for detecting top/bottom field:
331+ half_lines = 0
332+ j = i
333+ while j < i + 9 :
334+ dis = (filtered_pulses [j + 1 ].start - filtered_pulses [j ].start ) / linelen
335+ if (
336+ abs (dis - 0.5 ) < 0.06
337+ and filtered_pulses [j ].len < SHORT_PULSE_MAX
338+ and filtered_pulses [j + 1 ].len < SHORT_PULSE_MAX
339+ ):
340+ half_lines += 1
341+ elif (
342+ abs (dis - 1.0 ) < 0.06
343+ and filtered_pulses [j ].len < SHORT_PULSE_MAX
344+ and filtered_pulses [j + 1 ].len < SHORT_PULSE_MAX
345+ ):
358346 break
359- phase = np .argmax (phase_cnt )
360- if phase == 0 :
361- # we need to differ between 625 and 525 line
362- if frame_lines == 625 :
363- first_field = 0
364- line_offset = 5.0
365347 else :
366- first_field = 1
367- line_offset = 6.0
368- first_field_confidence = phase_cnt [0 ] * 100 // sum (phase_cnt )
369- elif phase == 1 :
370- # we need to differ between 625 and 525 line
348+ half_lines = 0
349+ break
350+ j += 1
351+ if half_lines == 4 and frame_lines == 625 :
352+ first_field = 0
353+ first_field_confidence = 100
354+ line_offset = 5.0
355+ elif half_lines == 5 :
371356 if frame_lines == 625 :
372357 first_field = 1
358+ first_field_confidence = 100
373359 line_offset = 4.5
374360 else :
375361 first_field = 0
362+ first_field_confidence = 100
376363 line_offset = 5.5
377- first_field_confidence = phase_cnt [1 ] * 100 // sum (phase_cnt )
364+ elif half_lines == 6 and frame_lines == 525 :
365+ first_field = 1
366+ line_offset = 6.0
367+
368+ # if we couldn't detect field type based on half lines check phase
369+ if line_offset is None :
370+ phase_cnt = [0 , 0 , 0 ]
371+ for d in range (15 , min (i , 30 ) + 1 ):
372+ pp = np .array (
373+ [
374+ (filtered_pulses [i - 2 ].start - filtered_pulses [i - d ].start )
375+ / measured_linelen ,
376+ (
377+ filtered_pulses [i - 2 ].start
378+ - filtered_pulses [i - d + 1 ].start
379+ )
380+ / measured_linelen ,
381+ (
382+ filtered_pulses [i - 2 ].start
383+ - filtered_pulses [i - d + 2 ].start
384+ )
385+ / measured_linelen ,
386+ ]
387+ )
388+ # PAL: for start of first field all values should be 1, for second field all should be 0
389+ # NTSC: for start of first field all values should be 0, for second field all should be 1
390+ pps = np .sum (np .mod (np .round (pp * 2 ), 2 ))
391+ if pps == 0 :
392+ phase_cnt [0 ] += 1
393+ elif pps == 3 :
394+ phase_cnt [1 ] += 1
395+ else :
396+ phase_cnt [2 ] += 1
397+ if sum (phase_cnt [0 :2 ]) >= 5 :
398+ break
399+ phase = np .argmax (phase_cnt )
400+ if phase == 0 :
401+ # we need to differ between 625 and 525 line
402+ if frame_lines == 625 :
403+ first_field = 0
404+ line_offset = 5.0
405+ else :
406+ first_field = 1
407+ line_offset = 6.0
408+ first_field_confidence = phase_cnt [0 ] * 100 // sum (phase_cnt )
409+ elif phase == 1 :
410+ # we need to differ between 625 and 525 line
411+ if frame_lines == 625 :
412+ first_field = 1
413+ line_offset = 4.5
414+ else :
415+ first_field = 0
416+ line_offset = 5.5
417+ first_field_confidence = phase_cnt [1 ] * 100 // sum (phase_cnt )
378418
379419 if line_offset is not None :
380420 # in case we cannot find a matching pulse, we can still use this prediction
@@ -761,7 +801,8 @@ def get_line0_fallback(
761801 "WARNING, line0 hsync not found in entire block, but vsync area found, using predicted position, result may be garbled."
762802 )
763803 line_0 = line_0_backup
764- first_field_confidence -= 20
804+ first_field = first_field_backup
805+ first_field_confidence = first_field_confidence_backup - 20
765806
766807 if line_0 is not None :
767808 if DEBUG_PLOT :
0 commit comments