Python 3 fixes, and add average video frame rate readout.
[dcpomatic.git] / hacks / examine.py
1 #!/usr/bin/python
2
3 import subprocess
4 import shlex
5 import sys
6
7 AUDIO_STREAM = "1"
8 types = ['video']
9 VIDEO_RATE = 29.97
10
11 last_video = None
12 last_video_pts = None
13
14 last_audio_pts = {}
15 last_channels = {}
16
17 video_frame_rates = []
18
19 video_frame_count = 0
20
21 def check_pts_dts(frame):
22     if 'pkt_dts_time' in frame:
23         diff = frame['pkt_pts_time'] - frame['pkt_dts_time']
24         if abs(diff) > 1e-8:
25             print("\tPTS != DTS: %f" % diff)
26
27 def handle(frame):
28     global last_video
29     global last_video_pts
30     global last_audio_pts
31     global video_frame_count
32     global video_frame_rates
33     if frame['media_type'] == 'video' and 'video' in types:
34         if last_video_pts is not None and frame['pkt_pts_time'] <= last_video_pts:
35             print('Out of order video frame %f (%d) is same as or behind %f (%d)' % (frame['pkt_pts_time'], frame['pkt_pts'], last_video_pts, last_video))
36         elif last_video_pts is not None:
37             pkt_dts_time = frame['pkt_dts_time'] if 'pkt_dts_time' in frame else 0.0
38             rate = 1 / (frame['pkt_pts_time'] - last_video_pts)
39             print(f'OK V    frame %f %f %f %f %d indices %d/%d' % (frame['pkt_pts_time'], pkt_dts_time, frame['pkt_pts_time'] - last_video_pts, rate, frame['pkt_size'], video_frame_count, frame['pkt_pts_time'] * VIDEO_RATE))
40             check_pts_dts(frame)
41             video_frame_rates.append(rate)
42         else:
43             print('OK V    frame %f counted %d' % (frame['pkt_pts_time'], video_frame_count))
44         last_video = frame['pkt_pts']
45         last_video_pts = frame['pkt_pts_time']
46         video_frame_count += 1
47     elif frame['media_type'] == 'audio' and 'audio' in types:
48         stream_index = frame['stream_index']
49         if stream_index in last_audio_pts and (stream_index == AUDIO_STREAM or AUDIO_STREAM is None):
50             print('OK A[%s] frame %4.8f %4.8f %4.8f %4.8f %d' % (stream_index, frame['pkt_pts_time'], frame['pkt_dts_time'], frame['pkt_pts_time'] - last_audio_pts[stream_index], 1 / (frame['pkt_pts_time'] - last_audio_pts[stream_index]), frame['pkt_size']))
51             check_pts_dts(frame)
52         if stream_index in last_channels and frame['channels'] != last_channels[stream_index]:
53             print("\t*** unusual channel count")
54         last_audio_pts[stream_index] = frame['pkt_pts_time']
55         last_channels[stream_index] = frame['channels']
56
57
58 p = subprocess.Popen(shlex.split('ffprobe -show_frames "%s"' % sys.argv[1]), stdin=None, stdout=subprocess.PIPE)
59 frame = dict()
60 while True:
61     l = p.stdout.readline()
62     if l == b'':
63         break
64
65     l = l.strip().decode('UTF-8')
66
67     if l == '[/FRAME]':
68         handle(frame)
69         frame = dict()
70     elif l != '[FRAME]' and l != '[SIDE_DATA]' and l != '[/SIDE_DATA]':
71         s = l.split('=')
72         if s[0] in ['pkt_pts_time', 'pkt_dts_time', 'pkt_pts', 'pkt_dts']:
73             if s[1] != 'N/A':
74                 frame[s[0]] = float(s[1])
75         elif s[0] in ['channels', 'pkt_size', 'nb_samples']:
76             frame[s[0]] = int(s[1])
77         elif len(s) > 1:
78             frame[s[0]] = s[1]
79
80
81 print(f'Average frame rate: {sum(video_frame_rates) / float(len(video_frame_rates))}')