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

Skip to content

Commit f1cda91

Browse files
committed
This module can now be used asynchronously. Also, some commands
have been added.
1 parent 827cc19 commit f1cda91

1 file changed

Lines changed: 127 additions & 25 deletions

File tree

Demo/sgi/video/VCR.py

Lines changed: 127 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import struct
66
import select
77
import posix
8+
import time
89

910
DEVICE='/dev/ttyd2'
1011

@@ -75,20 +76,8 @@ def initline(name):
7576
dummy = fcntl.ioctl(fd, IOCTL.TCSETA, arg)
7677
return fp, ofp
7778

78-
#ifp, ofp = initline('/dev/ttyd2')
79-
#while 1:
80-
# print 'GO'
81-
# inset, d, d = select.select([sys.stdin, ifp], [], [])
82-
# if sys.stdin in inset:
83-
# cmd = eval(sys.stdin.readline(100))
84-
# print 'CMD:', `cmd`
85-
# if cmd:
86-
# ofp.write(cmd)
87-
# ofp.flush()
88-
# if ifp in inset:
89-
# data = ifp.read(1)
90-
# print 'LEN', len(data), 'DATA', `data`
91-
79+
#
80+
#
9281
error = 'VCR.error'
9382

9483
# Commands/replies:
@@ -116,12 +105,17 @@ def initline(name):
116105
STEP_FWD ='\x2b' # Was: '\xad'
117106
FM_SELECT=EXP_8 + '\xc8'
118107
FM_STILL=EXP_8 + '\xcd'
108+
PREVIEW=EXP_7 + '\x9d'
109+
REVIEW=EXP_7 + '\x9e'
119110
DM_OFF=EXP_8 + '\xc9'
120111
DM_SET=EXP_8 + '\xc4'
121112
FWD_SHUTTLE='\xb5'
122113
REV_SHUTTLE='\xb6'
123114
EM_SELECT=EXP_8 + '\xc0'
124115
N_FRAME_REC=EXP_8 + '\x92'
116+
SEARCH_PREROLL=EXP_8 + '\x90'
117+
EDIT_PB_STANDBY=EXP_8 + '\x96'
118+
EDIT_PLAY=EXP_8 + '\x98'
125119

126120
IN_ENTRY=EXP_7 + '\x90'
127121
IN_ENTRY_RESET=EXP_7 + '\x91'
@@ -137,13 +131,55 @@ def initline(name):
137131
OUT_ENTRY_DEC=EXP_7 + '\x98'
138132
OUT_ENTRY_SENSE=EXP_7 + '\x9b'
139133

134+
MUTE_AUDIO = '\x24'
135+
MUTE_AUDIO_OFF = '\x25'
136+
MUTE_VIDEO = '\x26'
137+
MUTE_VIDEO_OFF = '\x27'
138+
MUTE_AV = EXP_7 + '\xc6'
139+
MUTE_AV_OFF = EXP_7 + '\xc7'
140+
140141
DEBUG=0
141142

142143
class VCR:
143144
def init(self):
144145
self.ifp, self.ofp = initline(DEVICE)
146+
self.busy_cmd = None
147+
self.async = 0
148+
self.cb = None
149+
self.cb_arg = None
145150
return self
146151

152+
def _check(self):
153+
if self.busy_cmd:
154+
raise error, 'Another command active: '+self.busy_cmd
155+
156+
def _endlongcmd(self, name):
157+
if not self.async:
158+
self.waitready()
159+
return 1
160+
self.busy_cmd = name
161+
return 'VCR BUSY'
162+
163+
def fileno(self):
164+
return self.ifp.fileno()
165+
166+
def setasync(self, async):
167+
self.async = async
168+
169+
def setcallback(self, cb, arg):
170+
self.setasync(1)
171+
self.cb = cb
172+
self.cb_arg = arg
173+
174+
def poll(self):
175+
if not self.async:
176+
raise error, 'Can only call poll() in async mode'
177+
if not self.busy_cmd:
178+
return
179+
if self.testready():
180+
if self.cb:
181+
apply(self.cb, self.cb_arg)
182+
147183
def _cmd(self, cmd):
148184
if DEBUG:
149185
print '>>>',`cmd`
@@ -153,12 +189,16 @@ def _cmd(self, cmd):
153189
def _waitdata(self, len, tout):
154190
rep = ''
155191
while len > 0:
156-
ready, d1, d2 = select.select([self.ifp], [], [], tout)
192+
if tout == None:
193+
ready, d1, d2 = select.select( \
194+
[self.ifp], [], [])
195+
else:
196+
ready, d1, d2 = select.select( \
197+
[self.ifp], [], [], tout)
157198
if ready == []:
158199
## if rep:
159200
## print 'FLUSHED:', `rep`
160201
return None
161-
# XXXX Niet goed: er is meer gebufferd!
162202
data = self.ifp.read(1)
163203
if DEBUG:
164204
print '<<<',`data`
@@ -219,27 +259,47 @@ def _number(self, number, digits):
219259
if not ok:
220260
raise error, 'Error while transmitting number'
221261

222-
def wait(self):
262+
def initvcr(self, *optarg):
263+
timeout = None
264+
if optarg <> ():
265+
timeout = optarg[0]
266+
starttime = time.time()
267+
self.busy_cmd = None
223268
self._iflush()
224269
while 1:
225270
## print 'SENDCL'
226271
self._cmd(CL)
227272
rep = self._waitdata(1, 2)
228273
## print `rep`
229274
if rep in ( None, CL, NAK ):
275+
if timeout:
276+
if time.time() - starttime > timeout:
277+
raise error, \
278+
'No reply from VCR'
230279
continue
231280
break
232281
if rep <> ACK:
233282
raise error, 'Unexpected reply:' + `rep`
234283
dummy = self.simplecmd(CTRL_ENABLE)
235284

236285
def waitready(self):
237-
rep = self._waitdata(1, 60)
286+
rep = self._waitdata(1, None)
287+
if rep == None:
288+
raise error, 'Unexpected None reply from waitdata'
289+
if rep not in (COMPLETION, ACK):
290+
self._iflush()
291+
raise error, 'Unexpected waitready reply:' + `rep`
292+
self.busy_cmd = None
293+
294+
def testready(self):
295+
rep = self._waitdata(1, 0)
238296
if rep == None:
239-
raise error, 'Command not finished in one minute'
297+
return 0
240298
if rep not in (COMPLETION, ACK):
241299
self._iflush()
242300
raise error, 'Unexpected waitready reply:' + `rep`
301+
self.busy_cmd = None
302+
return 1
243303

244304
def play(self): return self.simplecmd(PLAY)
245305
def stop(self): return self.simplecmd(STOP)
@@ -258,11 +318,11 @@ def goto(self, (h, m, s, f)):
258318
self._number(f, 2)
259319
if not self.simplecmd(ENTER):
260320
return 0
261-
self.waitready()
262-
return 1
321+
return self._endlongcmd('goto')
263322

264323
# XXXX TC_SENSE doesn't seem to work
265324
def faulty_where(self):
325+
self._check()
266326
self._cmd(TC_SENSE)
267327
h = self._getnumber(2)
268328
m = self._getnumber(2)
@@ -274,6 +334,7 @@ def where(self):
274334
return self.addr2tc(self.sense())
275335

276336
def sense(self):
337+
self._check()
277338
self._cmd(ADDR_SENSE)
278339
num = self._getnumber(5)
279340
return num
@@ -291,6 +352,7 @@ def tc2addr(self, (h, m, s, f)):
291352
return ((h*60 + m)*60 + s)*25 + f
292353

293354
def fmmode(self, mode):
355+
self._check()
294356
if mode == 'off':
295357
arg = 0
296358
elif mode == 'buffer':
@@ -306,7 +368,21 @@ def fmmode(self, mode):
306368
return 0
307369
return 1
308370

371+
def mute(self, mode, value):
372+
self._check()
373+
if mode == 'audio':
374+
cmds = (MUTE_AUDIO_OFF, MUTE_AUDIO)
375+
elif mode == 'video':
376+
cmds = (MUTE_VIDEO_OFF, MUTE_VIDEO)
377+
elif mode == 'av':
378+
cmds = (MUTE_AV_OFF, MUTE_AV)
379+
else:
380+
raise error, 'mute type should be audio, video or av'
381+
cmd = cmds[value]
382+
return self.simplecmd(cmd)
383+
309384
def editmode(self, mode):
385+
self._check()
310386
if mode == 'off':
311387
a0 = a1 = a2 = 0
312388
elif mode == 'format':
@@ -338,16 +414,40 @@ def nframerec(self, num):
338414
self._number(num, 4)
339415
if not self.simplecmd(ENTER):
340416
return 0
341-
self.waitready()
342-
return 1
417+
return self._endlongcmd('nframerec')
343418

344419
def fmstill(self):
345420
if not self.simplecmd(FM_STILL):
346421
return 0
347-
self.waitready()
348-
return 1
422+
return self._endlongcmd('fmstill')
423+
424+
def preview(self):
425+
if not self.simplecmd(PREVIEW):
426+
return 0
427+
return self._endlongcmd('preview')
428+
429+
def review(self):
430+
if not self.simplecmd(REVIEW):
431+
return 0
432+
return self._endlongcmd('review')
433+
434+
def search_preroll(self):
435+
if not self.simplecmd(SEARCH_PREROLL):
436+
return 0
437+
return self._endlongcmd('search_preroll')
438+
439+
def edit_pb_standby(self):
440+
if not self.simplecmd(EDIT_PB_STANDBY):
441+
return 0
442+
return self._endlongcmd('edit_pb_standby')
443+
444+
def edit_play(self):
445+
if not self.simplecmd(EDIT_PLAY):
446+
return 0
447+
return self._endlongcmd('edit_play')
349448

350449
def dmcontrol(self, mode):
450+
self._check()
351451
if mode == 'off':
352452
return self.simplecmd(DM_OFF)
353453
if mode == 'multi freeze':
@@ -380,6 +480,7 @@ def revshuttle(self, num):
380480
return 1
381481

382482
def getentry(self, which):
483+
self._check()
383484
if which == 'in':
384485
cmd = IN_ENTRY_SENSE
385486
elif which == 'out':
@@ -404,6 +505,7 @@ def outentry(self, arg):
404505
OUT_ENTRY_SET, OUT_ENTRY_INC, OUT_ENTRY_DEC))
405506

406507
def ioentry(self, arg, (Load, Clear, Set, Inc, Dec)):
508+
self._check()
407509
if type(arg) == type(()):
408510
h, m, s, f = arg
409511
if not self.simplecmd(Set):

0 commit comments

Comments
 (0)