Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 605b127

Browse files
committed
Jack's VCR control module
1 parent a849b83 commit 605b127

1 file changed

Lines changed: 297 additions & 0 deletions

File tree

Demo/sgi/video/VCR.py

Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
import fcntl
2+
import IOCTL
3+
from IOCTL import *
4+
import sys
5+
import struct
6+
import select
7+
8+
DEVICE='/dev/ttyd2'
9+
10+
def packttyargs(*args):
11+
if type(args) <> type(()):
12+
raise 'Incorrect argtype for packttyargs'
13+
if type(args[0]) == type(1):
14+
iflag, oflag, cflag, lflag, line, chars = args
15+
elif type(args[0]) == type(()):
16+
if len(args) <> 1:
17+
raise 'Only 1 argument expected'
18+
iflag, oflag, cflag, lflag, line, chars = args[0]
19+
elif type(args[0]) == type([]):
20+
if len(args) <> 1:
21+
raise 'Only 1 argument expected'
22+
[iflag, oflag, cflag, lflag, line, chars] = args[0]
23+
str = struct.pack('hhhhb', iflag, oflag, cflag, lflag, line)
24+
for c in chars:
25+
str = str + c
26+
return str
27+
28+
def nullttyargs():
29+
chars = ['\0']*IOCTL.NCCS
30+
return packttyargs(0, 0, 0, 0, 0, chars)
31+
32+
def unpackttyargs(str):
33+
args = str[:-IOCTL.NCCS]
34+
rawchars = str[-IOCTL.NCCS:]
35+
chars = []
36+
for c in rawchars:
37+
chars.append(c)
38+
iflag, oflag, cflag, lflag, line = struct.unpack('hhhhb', args)
39+
return (iflag, oflag, cflag, lflag, line, chars)
40+
41+
def initline(name):
42+
fp = open(name, 'r')
43+
ofp = open(name, 'w')
44+
fd = fp.fileno()
45+
rv = fcntl.ioctl(fd, IOCTL.TCGETA, nullttyargs())
46+
iflag, oflag, cflag, lflag, line, chars = unpackttyargs(rv)
47+
iflag = iflag & ~(INPCK|ISTRIP|INLCR|IUCLC|IXON|IXOFF)
48+
oflag = oflag & ~OPOST
49+
cflag = B9600|CS8|CREAD|CLOCAL
50+
lflag = lflag & ~(ISIG|ICANON|ECHO|TOSTOP)
51+
chars[VMIN] = chr(1)
52+
chars[VTIME] = chr(0)
53+
arg = packttyargs(iflag, oflag, cflag, lflag, line, chars)
54+
dummy = fcntl.ioctl(fd, IOCTL.TCSETA, arg)
55+
return fp, ofp
56+
57+
#ifp, ofp = initline('/dev/ttyd2')
58+
#while 1:
59+
# print 'GO'
60+
# inset, d, d = select.select([sys.stdin, ifp], [], [])
61+
# if sys.stdin in inset:
62+
# cmd = eval(sys.stdin.readline(100))
63+
# print 'CMD:', `cmd`
64+
# if cmd:
65+
# ofp.write(cmd)
66+
# ofp.flush()
67+
# if ifp in inset:
68+
# data = ifp.read(1)
69+
# print 'LEN', len(data), 'DATA', `data`
70+
71+
error = 'VCR.error'
72+
73+
# Commands/replies:
74+
COMPLETION = '\x01'
75+
ACK ='\x0a'
76+
NAK ='\x0b'
77+
78+
NUMBER_N = 0x30
79+
ENTER = '\x40'
80+
81+
EXP_7= '\xde'
82+
EXP_8= '\xdf'
83+
84+
CL ='\x56'
85+
CTRL_ENABLE = EXP_8 + '\xc6'
86+
SEARCH_DATA = EXP_8 + '\x93'
87+
ADDR_SENSE = '\x60'
88+
89+
PLAY ='\x3a'
90+
STOP ='\x3f'
91+
EJECT='\x2a'
92+
FF ='\xab'
93+
REW ='\xac'
94+
STILL='\x4f'
95+
STEP_FWD ='\xad'
96+
FM_SELECT=EXP_8 + '\xc8'
97+
FM_STILL=EXP_8 + '\xcd'
98+
DM_OFF=EXP_8 + '\xc9'
99+
DM_SET=EXP_8 + '\xc4'
100+
FWD_SHUTTLE='\xb5'
101+
REV_SHUTTLE='\xb6'
102+
103+
class VCR():
104+
def init(self):
105+
self.ifp, self.ofp = initline(DEVICE)
106+
return self
107+
108+
def _cmd(self, cmd):
109+
## print '>>>',`cmd`
110+
self.ofp.write(cmd)
111+
self.ofp.flush()
112+
113+
def _waitdata(self, len, tout):
114+
rep = ''
115+
while len > 0:
116+
ready, d1, d2 = select.select([self.ifp], [], [], tout)
117+
if ready == []:
118+
## if rep:
119+
## print 'FLUSHED:', `rep`
120+
return None
121+
data = self.ifp.read(1)
122+
## print '<<<',`data`
123+
if data == NAK:
124+
return NAK
125+
rep = rep + data
126+
len = len - 1
127+
return rep
128+
129+
def _reply(self, len):
130+
data = self._waitdata(len, 10)
131+
if data == None:
132+
raise error, 'Lost contact with VCR'
133+
return data
134+
135+
def _getnumber(self, len):
136+
data = self._reply(len)
137+
number = 0
138+
for c in data:
139+
digit = ord(c) - NUMBER_N
140+
if digit < 0 or digit > 9:
141+
raise error, 'Non-digit in number'+`c`
142+
number = number*10 + digit
143+
return number
144+
145+
def _iflush(self):
146+
dummy = self._waitdata(10000, 1)
147+
## if dummy:
148+
## print 'IFLUSH:', dummy
149+
150+
def simplecmd(self,cmd):
151+
for ch in cmd:
152+
self._cmd(ch)
153+
rep = self._reply(1)
154+
if rep == NAK:
155+
return 0
156+
elif rep <> ACK:
157+
raise error, 'Unexpected reply:' + `rep`
158+
return 1
159+
160+
def _number(self, number, digits):
161+
if number < 0:
162+
raise error, 'Unexpected negative number:'+ `number`
163+
maxnum = pow(10, digits)
164+
if number > maxnum:
165+
raise error, 'Number too big'
166+
while maxnum > 1:
167+
number = number % maxnum
168+
maxnum = maxnum / 10
169+
digit = number / maxnum
170+
ok = self.simplecmd(chr(NUMBER_N + digit))
171+
if not ok:
172+
raise error, 'Error while transmitting number'
173+
174+
def wait(self):
175+
self._iflush()
176+
while 1:
177+
## print 'SENDCL'
178+
self._cmd(CL)
179+
rep = self._waitdata(1, 2)
180+
## print `rep`
181+
if rep in ( None, CL, NAK ):
182+
continue
183+
break
184+
if rep <> ACK:
185+
raise error, 'Unexpected reply:' + `rep`
186+
dummy = self.simplecmd(CTRL_ENABLE)
187+
188+
def waitready(self):
189+
rep = self._waitdata(1, 60)
190+
if rep == None:
191+
raise error, 'Command not finished in one minute'
192+
if rep not in (COMPLETION, ACK):
193+
self._iflush()
194+
raise error, 'Unexpected waitready reply:' + `rep`
195+
196+
def play(self): return self.simplecmd(PLAY)
197+
def stop(self): return self.simplecmd(STOP)
198+
def ff(self): return self.simplecmd(FF)
199+
def rew(self): return self.simplecmd(REW)
200+
def eject(self):return self.simplecmd(EJECT)
201+
def still(self):return self.simplecmd(STILL)
202+
def step(self): return self.simplecmd(STEP_FWD)
203+
204+
def goto(self, (h, m, s, f)):
205+
if not self.simplecmd(SEARCH_DATA):
206+
return 0
207+
self._number(h, 2)
208+
self._number(m, 2)
209+
self._number(s, 2)
210+
self._number(f, 2)
211+
if not self.simplecmd(ENTER):
212+
return 0
213+
self.waitready()
214+
return 1
215+
216+
# XXXX TC_SENSE doesn't seem to work
217+
def faulty_where(self):
218+
self._cmd(TC_SENSE)
219+
h = self._getnumber(2)
220+
m = self._getnumber(2)
221+
s = self._getnumber(2)
222+
f = self._getnumber(2)
223+
return (h, m, s, f)
224+
225+
def where(self):
226+
return self.addr2tc(self.sense())
227+
228+
def sense(self):
229+
self._cmd(ADDR_SENSE)
230+
num = self._getnumber(5)
231+
return num
232+
233+
def addr2tc(self, num):
234+
f = num % 25
235+
num = num / 25
236+
s = num % 60
237+
num = num / 60
238+
m = num % 60
239+
h = num / 60
240+
return (h, m, s, f)
241+
242+
def tc2addr(self, (h, m, s, f)):
243+
return ((h*60 + m)*60 + s)*25 + f
244+
245+
def fmmode(self, mode):
246+
if mode == 'off':
247+
arg = 0
248+
elif mode == 'buffer':
249+
arg = 1
250+
elif mode == 'dnr':
251+
arg = 2
252+
else:
253+
raise error, 'fmmode arg should be off, buffer or dnr'
254+
if not self.simplecmd(FM_SELECT):
255+
return 0
256+
self._number(arg, 1)
257+
if not self.simplecmd(ENTER):
258+
return 0
259+
return 1
260+
261+
def fmstill(self):
262+
if not self.simplecmd(FM_STILL):
263+
return 0
264+
self.waitready()
265+
return 1
266+
267+
def dmcontrol(self, mode):
268+
if mode == 'off':
269+
return self.simplecmd(DM_OFF)
270+
if mode == 'multi freeze':
271+
num = 1000
272+
elif mode == 'zoom freeze':
273+
num = 2000
274+
elif mode == 'digital slow':
275+
num = 3000
276+
elif mode == 'freeze':
277+
num = 4011
278+
else:
279+
raise error, 'unknown dmcontrol argument: ' + `mode`
280+
if not self.simplecmd(DM_SET):
281+
return 0
282+
self._number(num, 4)
283+
if not self.simplecmd(ENTER):
284+
return 0
285+
return 1
286+
287+
def fwdshuttle(self, num):
288+
if not self.simplecmd(FWD_SHUTTLE):
289+
return 0
290+
self._number(num, 1)
291+
return 1
292+
293+
def revshuttle(self, num):
294+
if not self.simplecmd(REV_SHUTTLE):
295+
return 0
296+
self._number(num, 1)
297+
return 1

0 commit comments

Comments
 (0)