diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /appl/lib/mpeg.b | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'appl/lib/mpeg.b')
| -rw-r--r-- | appl/lib/mpeg.b | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/appl/lib/mpeg.b b/appl/lib/mpeg.b new file mode 100644 index 00000000..f1cd00f0 --- /dev/null +++ b/appl/lib/mpeg.b @@ -0,0 +1,148 @@ +implement Mpeg; + +include "sys.m"; +sys: Sys; +FD, Connection: import Sys; +include "draw.m"; +draw: Draw; +Display, Rect, Image: import draw; +include "mpeg.m"; + +Chroma: con 16r05; + +getenv() +{ + if(sys != nil) + return; + + sys = load Sys Sys->PATH; + draw = load Draw Draw->PATH; +} + +copy(files: list of string, notify: chan of string, mpctl, mpdata: ref FD) +{ + ok, n: int; + c: Connection; + name: list of string; + + while(files != nil) { + file := hd files; + (n, name) = sys->tokenize(file, "@"); + m : ref FD; + case n { + 1 => + m = sys->open(file, sys->OREAD); + if(m == nil) { + notify <-= "mpeg open:" + file; + return; + } + 2 => + (ok, c) = sys->dial(hd tl name, nil); + if(ok < 0) { + notify <-= "dial:" + hd tl name; + return; + } + sys->fprint(c.dfd, "%s\n", hd name); + c.cfd = nil; + m = c.dfd; + * => + notify <-= "bad file:"+hd name; + return; + } + sys->stream(m, mpdata, 64*1024); + files = tl files; + } + sys->fprint(mpctl, "stop"); + sys->fprint(mpctl, "window 0 0 0 0"); + notify <-= ""; +} + +play(display: ref Display, w: ref Image, paint: int, r: Rect, file: string, notify: chan of string): string +{ + i, j: int; + line: string; + cfg: array of byte; + buf := array[1024] of byte; + arg, words, files: list of string; + + getenv(); + + mpdata := sys->open("/dev/mpeg", sys->OWRITE); + if(mpdata == nil) + return sys->sprint("can't open /dev/mpeg: %r"); + + obj := sys->open(file, sys->OREAD); + if(obj == nil) + return "open failed:"+file; + + n := sys->read(obj, buf, len buf); + if(n < 0) + return "mpeg object: read error"; + + mpctl := sys->open("/dev/mpegctl", sys->OWRITE); + if(mpctl == nil) + return "open mpeg ctl file"; + + # Parse into lines + (n, arg) = sys->tokenize(string buf[0:n], "\n"); + for(i = 0; i < n; i++) { + # Parse into words + line = hd arg; + (j, words) = sys->tokenize(line, " \t"); + + # Pass device config lines through to the ctl file + if(hd words == "files") + files = tl words; + else { + cfg = array of byte line; + if(sys->write(mpctl, cfg, len cfg) < 0) + return "invalid device config:"+line; + } + arg = tl arg; + } + + if(files == nil) + return "no file to play"; + + # now the driver is configured initialize the dsp's + # and set up the trident overlay + sys->fprint(mpctl, "init"); + sys->fprint(mpctl, "window %d %d %d %d", + r.min.x, r.min.y, r.max.x, r.max.y); + + # paint the window with the chroma key color + if(paint) + w.draw(r, keycolor(display), nil, r.min); + + if(notify != nil) { + spawn copy(files, notify, mpctl, mpdata); + return ""; + } + notify = chan of string; + spawn copy(files, notify, mpctl, mpdata); + return <-notify; +} + +ctl(msg: string): int +{ + mpc: ref FD; + + getenv(); + + mpc = sys->open("/dev/mpegctl", sys->OWRITE); + if(mpc == nil) + return -1; + + b := array of byte msg; + n := sys->write(mpc, b, len b); + if(n != len b) + n = -1; + + return n; +} + +keycolor(display: ref Display): ref Image +{ + getenv(); + return display.color(Chroma); +} |
