summaryrefslogtreecommitdiff
path: root/appl/lib/mpeg.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/lib/mpeg.b')
-rw-r--r--appl/lib/mpeg.b148
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);
+}