-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmake-json
executable file
·102 lines (88 loc) · 3.02 KB
/
make-json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/usr/bin/python3
# Given a .tbc file using PAL 4xfSC subcarrier-locked sampling, generate a
# .tbc.json that describes it.
#
# Usage: make-json input.tbc [output.tbc.json]
import json
import optparse
import os
import sys
# Parse command-line options
parser = optparse.OptionParser(usage="usage: %prog [options] TBC-FILE [JSON-FILE]")
options, args = parser.parse_args(sys.argv[1:])
# Subcarrier frequency in Hz
fSC = 4433618.75
# Working out activeVideoStart/End:
#
# The active area should be 922 samples wide, for 4:3 aspect ratio against 575
# vertical lines.
#
# The first sample in the .tbc is the left edge (not the middle) of the field 1
# line 1 sync pulse -- sample 955 going by EBU Tech 3280's numbering -- so 0H
# occurs 2.5 samples into the .tbc. The "digital active line" therefore starts
# at sample 1135-955 = 180 and ends at 180+948 = 1128.
#
# Drop (948-922)/2 = 13 samples on either side, and the active region on line 1
# is 193 to 1115.
# Parameters we're trying to generate (based upon ld-decode output)
videoParameters = {
"sampleRate": fSC * 4,
"isSubcarrierLocked": True,
"isSourcePal": True,
"fsc": fSC,
"black16bIre": 16384.0,
"white16bIre": 54016.0,
"fieldWidth": 1135,
"fieldHeight": 313,
"colourBurstStart": 104.0,
"colourBurstEnd": 144.0,
"activeVideoStart": 193.0,
"activeVideoEnd": 1115.0,
"numberOfSequentialFields": 0, # We'll fill this in later
}
# Parse positional args
if len(args) == 1:
input_tbc = args[0]
output_json = input_tbc + ".json"
elif len(args) == 2:
input_tbc = args[0]
output_json = args[1]
else:
parser.error("no input/output filenames specified")
# Measure the length of the video
input_len = os.stat(input_tbc).st_size
field_size = 2 * videoParameters["fieldHeight"] * videoParameters["fieldWidth"]
numFields = input_len // field_size
if (input_len % field_size) != 0:
print("TBC length", input_len, "is not a multiple of field size",
field_size, file=sys.stderr)
sys.exit(1)
# ld-decode computes medianBurstIRE as sqrt(2) * RMS(samples in colourburst in
# IRE form), i.e. half the P-P amplitude of the colourburst. This is used as
# part of the chroma gain calculation in ld-chroma-decoder to compensate for HF
# rolloff.
medianBurstIRE = (3.0 / 7.0) * 100.0 / 2
# Generate JSON info for fields
fields = []
for i in range(numFields):
field = {
# ld-chroma-decoder cares about these values:
"isFirstField": (i % 2) == 0,
"seqNo": i + 1,
"medianBurstIRE": medianBurstIRE,
# And doesn't care about these, so provide dummy values:
"syncConf": 100,
"diskLoc": i + 1,
"decodeFaults": 0,
"vitsMetrics": {"wSNR": 42.0, "bPSNR": 42.0},
"vbi": {"vbiData": [42, 42, 42]},
"audioSamples": 42,
}
fields.append(field)
# Write the JSON
videoParameters["numberOfSequentialFields"] = numFields
with open(output_json, "w") as f:
json.dump({
"videoParameters": videoParameters,
"fields": fields,
}, f, indent=2)