123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- implement QuickTime;
- include "sys.m";
- sys: Sys;
- include "quicktime.m";
- init()
- {
- sys = load Sys Sys->PATH;
- }
- open(file: string): (ref QD, string)
- {
- fd := sys->open(file, sys->OREAD);
- if(fd == nil)
- return (nil, "open failed");
- r := ref QD;
- r.fd = fd;
- r.buf = array[DEFBUF] of byte;
- (hdr, l) := r.atomhdr();
- if(hdr != "mdat")
- return (nil, "not a QuickTime movie file");
- #
- # We are expecting a unified file with .data then .rsrc
- #
- r.skipatom(l);
- return (r, nil);
- }
- QD.atomhdr(r: self ref QD): (string, int)
- {
- b := array[8] of byte;
- if(r.readn(b, 8) != 8)
- return (nil, -1);
- for(i := 0; i < 8; i++)
- sys->print("%.2ux ", int b[i]);
- sys->print(" %s %d\n", string b[4:8], bedword(b, 0));
- return (string b[4:8], bedword(b, 0));
- }
- QD.skipatom(r: self ref QD, l: int): int
- {
- return r.skip(l - AtomHDR);
- }
- QD.mvhd(q: self ref QD, l: int): string
- {
- l -= AtomHDR;
- if(l != MvhdrSIZE)
- return "mvhd atom funny size";
- b := array[l] of byte;
- if(q.readn(b, l) != l)
- return "short read in mvhd";
- mvhdr := ref Mvhdr;
- mvhdr.version = bedword(b, 0);
- mvhdr.create = bedword(b, 4);
- mvhdr.modtime = bedword(b, 8);
- mvhdr.timescale = bedword(b, 12);
- mvhdr.duration = bedword(b, 16);
- mvhdr.rate = bedword(b, 20);
- mvhdr.vol = beword(b, 24);
- mvhdr.r1 = bedword(b, 26);
- mvhdr.r2 = bedword(b, 30);
- mvhdr.matrix = array[9] of int;
- for(i :=0; i<9; i++)
- mvhdr.matrix[i] = bedword(b, 34+i*4);
- mvhdr.r3 = beword(b, 70);
- mvhdr.r4 = bedword(b, 72);
- mvhdr.pvtime = bedword(b, 76);
- mvhdr.posttime = bedword(b, 80);
- mvhdr.seltime = bedword(b, 84);
- mvhdr.seldurat = bedword(b, 88);
- mvhdr.curtime = bedword(b, 92);
- mvhdr.nxttkid = bedword(b, 96);
- q.mvhdr = mvhdr;
- return nil;
- }
- QD.trak(q: self ref QD, l: int): string
- {
- (tk, tkl) := q.atomhdr();
- if(tk != "tkhd")
- return "missing track header atom";
- l -= tkl;
- tkl -= AtomHDR;
- b := array[tkl] of byte;
- if(q.readn(b, tkl) != tkl)
- return "short read in tkhd";
- tkhdr := ref Tkhdr;
- tkhdr.version = bedword(b, 0);
- tkhdr.creation = bedword(b, 4);
- tkhdr.modtime = bedword(b, 8);
- tkhdr.trackid = bedword(b, 12);
- tkhdr.timescale = bedword(b, 16);
- tkhdr.duration = bedword(b, 20);
- tkhdr.timeoff = bedword(b, 24);
- tkhdr.priority = bedword(b, 28);
- tkhdr.layer = beword(b, 32);
- tkhdr.altgrp = beword(b, 34);
- tkhdr.volume = beword(b, 36);
- tkhdr.matrix = array[9] of int;
- for(i := 0; i < 9; i++)
- tkhdr.matrix[i] = bedword(b, 38+i*4);
- tkhdr.width = bedword(b, 74);
- tkhdr.height = bedword(b, 78);
- (md, mdl) := q.atomhdr();
- if(md != "mdia")
- return "missing media atom";
- while(mdl != AtomHDR) {
- (atom, atoml) := q.atomhdr();
- sys->print("\t%s %d\n", atom, atoml);
- q.skipatom(atoml);
- mdl -= atoml;
- }
- return nil;
- }
- QD.readn(r: self ref QD, b: array of byte, l: int): int
- {
- if(r.nbyte < l) {
- c := 0;
- if(r.nbyte != 0) {
- b[0:] = r.buf[r.ptr:];
- l -= r.nbyte;
- c += r.nbyte;
- b = b[r.nbyte:];
- }
- bsize := len r.buf;
- while(l != 0) {
- r.nbyte = sys->read(r.fd, r.buf, bsize);
- if(r.nbyte <= 0) {
- r.nbyte = 0;
- return -1;
- }
- n := l;
- if(n > bsize)
- n = bsize;
- r.ptr = 0;
- b[0:] = r.buf[0:n];
- b = b[n:];
- r.nbyte -= n;
- r.ptr += n;
- l -= n;
- c += n;
- }
- return c;
- }
- b[0:] = r.buf[r.ptr:r.ptr+l];
- r.nbyte -= l;
- r.ptr += l;
- return l;
- }
- QD.skip(r: self ref QD, size: int): int
- {
- if(r.nbyte != 0) {
- n := size;
- if(n > r.nbyte)
- n = r.nbyte;
- r.ptr += n;
- r.nbyte -= n;
- size -= n;
- if(size == 0)
- return 0;
- }
- return int sys->seek(r.fd, big size, sys->SEEKRELA);
- }
- beword(b: array of byte, o: int): int
- {
- return (int b[o] << 8) | int b[o+1];
- }
- bedword(b: array of byte, o: int): int
- {
- return (int b[o] << 24) |
- (int b[o+1] << 16) |
- (int b[o+2] << 8) |
- int b[o+3];
- }
|