Skip to content

Commit

Permalink
Merge pull request #400 from atsampson/vbifixes
Browse files Browse the repository at this point in the history
Three VBI fixes for ld-decode
  • Loading branch information
happycube committed Jan 5, 2020
2 parents 990c23e + 480843a commit 74c467e
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 40 deletions.
8 changes: 7 additions & 1 deletion ld-cut
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,19 @@ if args.MTF_offset is not None:

if args.seek != -1:
startloc = ldd.seek(args.start, args.seek)
if startloc > 1:
if startloc is None:
print("ERROR: Seeking failed")
exit(1)
elif startloc > 1:
startloc -= 1
else:
startloc = args.start * 2

if args.end != -1:
endloc = ldd.seek(startloc, args.end)
if endloc is None:
print("ERROR: Seeking failed")
exit(1)
elif args.length != -1:
endloc = startloc + (args.length * 2)
else:
Expand Down
4 changes: 3 additions & 1 deletion ld-decode
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ if system == 'NTSC' and not args.ntscj:
#print(ldd.blackIRE)

if args.seek != -1:
ldd.seek(firstframe, args.seek)
if ldd.seek(firstframe, args.seek) is None:
print("ERROR: Seeking failed")
exit(1)

if args.MTF is not None:
ldd.rf.mtf_mult = args.MTF
Expand Down
86 changes: 48 additions & 38 deletions lddecode/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2489,6 +2489,7 @@ def __init__(self, fname_in, fname_out, freader, analog_audio = 0, digital_audio

self.fieldinfo = []

self.leadIn = False
self.leadOut = False
self.isCLV = False
self.frameNumber = None
Expand Down Expand Up @@ -2659,44 +2660,53 @@ def decodeFrameNumber(self, f1, f2):
self.clvSeconds = None
self.clvFrameNum = None

def decodeBCD(bcd):
"""Read a BCD-encoded number.
Raise ValueError if any of the digits aren't valid BCD."""

if bcd == 0:
return 0
else:
digit = bcd & 0xF
if digit > 9:
raise ValueError("Non-decimal BCD digit")
return (10 * decodeBCD(bcd >> 4)) + digit

leadoutCount = 0

for l in f1.linecode + f2.linecode:
if l is None:
continue

if l == 0x80eeee: # lead-out reached
leadoutCount += 1
elif l == 0x88ffff: # lead-in
self.leadIn = True
elif (l & 0xf0dd00) == 0xf0dd00: # CLV minutes/hours
self.clvMinutes = (l & 0xf) + (((l >> 4) & 0xf) * 10) + (((l >> 16) & 0xf) * 60)
self.isCLV = True
#logging.info('CLV', mins)
try:
self.clvMinutes = decodeBCD(l & 0xff) + (decodeBCD((l >> 16) & 0xf) * 60)
self.isCLV = True
#logging.info('CLV', mins)
except ValueError:
pass
elif (l & 0xf00000) == 0xf00000: # CAV frame
# Ignore the top bit of the first digit, used for PSC
l &= 0x7ffff

fnum = 0
for y in range(16, -1, -4):
fnum *= 10
toadd = l >> y & 0x0f
if toadd > 9:
fnum = -1
break
fnum += toadd

fnum = fnum if fnum < 80000 else fnum - 80000

if fnum >= 0:
return fnum

try:
return decodeBCD(l & 0x7ffff)
except ValueError:
pass
elif (l & 0x80f000) == 0x80e000: # CLV picture #
self.clvSeconds = (((l >> 16) & 0xf) - 10) * 10
self.clvSeconds += ((l >> 8) & 0xf)

self.clvFrameNum = ((l >> 4) & 0xf) * 10
self.clvFrameNum += (l & 0xf)

self.isCLV = True
try:
sec1s = decodeBCD((l >> 8) & 0xf)
sec10s = ((l >> 16) & 0xf) - 0xa
if sec10s < 0:
raise ValueError("Digit 2 not in range A-F")

self.clvFrameNum = decodeBCD(l & 0xff)
self.clvSeconds = sec1s + (10 * sec10s)
self.isCLV = True
except ValueError:
pass

if self.clvMinutes is not None:
if self.clvSeconds is not None: # newer CLV
Expand Down Expand Up @@ -2913,6 +2923,8 @@ def buildmetadata(self, f):
print("file frame %d CLV timecode %d:%.2d.%.2d frame %d" % (rawloc, self.clvMinutes, self.clvSeconds, self.clvFrameNum, self.frameNumber), file=sys.stderr)
elif self.frameNumber:
print("file frame %d CAV frame %d" % (rawloc, self.frameNumber), file=sys.stderr)
elif self.leadIn:
print("file frame %d lead in" % (rawloc), file=sys.stderr)
elif self.leadOut:
print("file frame %d lead out" % (rawloc), file=sys.stderr)
else:
Expand Down Expand Up @@ -2968,21 +2980,19 @@ def seek(self, start, target):

for retries in range(3):
fnr = self.seek_getframenr(cur)
cur = int((self.fieldloc / self.bytes_per_field))
if fnr is None:
return None
else:
if fnr == target:
logging.info("Finished seek")
print("Finished seeking, starting at frame", fnr, file=sys.stderr)
self.roughseek(cur)
return cur
else:
cur += ((target - fnr) * 2) - 1

print("Finished seeking, starting at frame", fnr, file=sys.stderr)
cur = int((self.fieldloc / self.bytes_per_field))
if fnr == target:
logging.info("Finished seek")
print("Finished seeking, starting at frame", fnr, file=sys.stderr)
self.roughseek(cur)
return cur

cur += ((target - fnr) * 2) - 1

return cur - 0
return None

def build_json(self, f):
''' build up the JSON structure for file output. '''
Expand Down

0 comments on commit 74c467e

Please sign in to comment.