implement Mpegio; ## MPEG ISO 11172 IO module.# include "sys.m";include "mpegio.m"; sys: Sys; init(){ sys = load Sys Sys->PATH;} raisex(s: string){ raise MEXCEPT + s;} prepare(fd: ref Sys->FD, name: string): ref Mpegi{ m := ref Mpegi; m.fd = fd; m.name = name; m.seek = 0; m.looked = 0; m.index = 0; m.size = 0; m.buff = array[MBSZ] of byte; return m;} Mpegi.startsys(m: self ref Mpegi){ # 2.4.3.2 m.xnextsc(PACK_SC); m.packhdr(); m.xnextsc(SYSHD_SC); m.syssz = m.getw(); m.boundmr = m.get22("boundmr"); m.syspar = m.getw(); if ((m.syspar & 16r20) == 0 || m.getb() != 16rFF) m.fmterr("syspar"); t := m.syssz - 6; if (t <= 0 || (t % 3) != 0) m.fmterr("syssz"); t /= 3; m.nstream = t; m.streams = array[t] of Stream; for (i := 0; i < t; i++) { v := m.getb(); if ((v & 16r80) == 0) m.fmterr("streamid"); w := m.getb(); if ((w & 16rC0) != 16rC0) m.fmterr("stream mark"); m.streams[i] = (byte v, byte ((w >> 5) & 1), ((w & 16r1F) << 8) | m.getb(), nil); }} Mpegi.packetcp(m: self ref Mpegi): int{ while ((c := m.nextsc()) != STREAM_EC) { case c { PACK_SC => m.packhdr(); SYSHD_SC => m.syshdr(); * => if (c < STREAM_BASE) m.fmterr(sys->sprint("stream code %x", c)); # 2.4.3.3 l := m.getw(); fd := m.getfd(c); if (fd != nil) { if (c != PRIVSTREAM2) l -= m.stamps(); if (m.log != nil) sys->fprint(m.log, "%x %d %d\n", c & 16rFF, m.tell(), l); m.cpn(fd, l); } else m.skipn(l); return 1; } } return 0;} Mpegi.getfd(m: self ref Mpegi, c: int): ref Sys->FD{ id := byte c; n := m.nstream; for (i := 0; i < n; i++) { if (m.streams[i].id == id) return m.streams[i].fd; } return nil;} Mpegi.packhdr(m: self ref Mpegi){ # 2.4.3.2 t := m.getb(); if ((t & 16rF1) != 16r21) m.fmterr("pack tag"); m.packt0 = (t >> 1) & 7; v := m.getb() << 22; t = m.getb(); if ((t & 1) == 0) m.fmterr("packt mark 1"); v |= ((t & ~1) << 15) | (m.getb() << 7); t = m.getb(); if ((t & 1) == 0) m.fmterr("packt mark 2"); m.packt1 = v | (t >> 1); m.packmr = m.get22("packmr");} Mpegi.syshdr(m: self ref Mpegi){ l := m.getw(); if (l != m.syssz) m.fmterr("syshdr size mismatch"); m.skipn(l);} Mpegi.stamps(m: self ref Mpegi): int{ # 2.4.3.3 n := 1; while ((c := m.getb()) == 16rFF) n++; if ((c >> 6) == 1) { m.getb(); c = m.getb(); n += 2; } case c >> 4 { 2 => m.skipn(4); n += 4; 3 => m.skipn(9); n += 9; * => if (c != 16rF) m.fmterr("stamps"); } return n;} Mpegi.streaminit(m: self ref Mpegi, c: int){ m.inittables(); m.sid = c; s := m.peeksc(); if (s == PACK_SC) { m.startsys(); f := 0; id := byte m.sid; for (i := 0; i < m.nstream; i++) { if (m.streams[i].id == id) { f = 1; break; } } if (!f) m.fmterr(sys->sprint("%x: stream not found", c)); m.sseek(); } else if (s == SEQUENCE_SC) { m.sresid = -1; m.slim = m.size; } else m.fmterr(sys->sprint("start code = %x", s)); m.sbits = 0;} Mpegi.sseek(m: self ref Mpegi){ while ((c := m.nextsc()) != STREAM_EC) { case c { PACK_SC => m.packhdr(); SYSHD_SC => m.syshdr(); * => if (c < STREAM_BASE) m.fmterr(sys->sprint("stream code %x", c)); # 2.4.3.3 l := m.getw(); if (c == m.sid) { if (c != PRIVSTREAM2) l -= m.stamps(); n := m.size - m.index; if (l <= n) { m.slim = m.index + l; m.sresid = 0; } else { m.slim = m.size; m.sresid = l - n; } return; } else m.skipn(l); } } m.fmterr("end of stream");} Mpegi.getpicture(m: self ref Mpegi, detail: int): ref Picture{ g := 0; for (;;) { case c := m.snextsc() { SEQUENCE_SC => m.seqhdr(); GROUP_SC => m.grphdr(); g = 1; PICTURE_SC => p := m.picture(detail); if (g) p.flags |= GSTART; return p; SEQUENCE_EC => return nil; * => m.fmterr(sys->sprint("start code %x", c)); } }} Mpegi.seqhdr(m: self ref Mpegi){ # 2.4.2.3 c := m.sgetb(); d := m.sgetb(); m.width = (c << 4) | (d >> 4); m.height = ((d & 16rF) << 8) | m.sgetb(); c = m.sgetb(); m.aspect = c >> 4; m.frames = c & 16rF; m.rate = m.sgetn(18); m.smarker(); m.vbv = m.sgetn(10); m.flags = 0; if (m.sgetn(1)) m.flags |= CONSTRAINED; if (m.sgetn(1)) m.intra = m.getquant(); if (m.sgetn(1)) m.nintra = m.getquant(); if (m.speeksc() == EXTENSION_SC) m.sseeksc(); if (m.speeksc() == USER_SC) m.sseeksc();} Mpegi.grphdr(m: self ref Mpegi){ # 2.4.2.4 v := m.sgetb() << 17; v |= m.sgetb() << 9; v |= m.sgetb() << 1; c := m.sgetb(); m.smpte = v | (c >> 7); if (c & (1 << 6)) m.flags |= CLOSED; else m.flags &= ~CLOSED; if (c & (1 << 5)) m.flags |= BROKEN; else m.flags &= ~BROKEN; if (m.speeksc() == EXTENSION_SC) m.sseeksc(); if (m.speeksc() == USER_SC) m.sseeksc();} Mpegi.getquant(m: self ref Mpegi): array of int{ a := array[64] of int; for (i := 0; i < 64; i++) a[i] = m.sgetn(8); return a;} Mpegi.picture(m: self ref Mpegi, detail: int): ref Picture{ # 2.4.2.5 p := ref Picture; p.temporal = m.sgetn(10); p.ptype = m.sgetn(3); p.vbvdelay = m.sgetn(16); p.flags = 0; if (p.ptype == PPIC || p.ptype == BPIC) { if (m.sgetn(1)) p.flags |= FPFV; p.forwfc = m.sgetn(3); if (p.forwfc == 0) m.fmterr("forwfc"); p.forwfc--; if (p.ptype == BPIC) { if (m.sgetn(1)) p.flags |= FPBV; p.backfc = m.sgetn(3); if (p.backfc == 0) m.fmterr("backfc"); p.backfc--; } else p.backfc = 0; } else { p.forwfc = 0; p.backfc = 0; } while (m.sgetn(1)) m.sgetn(8); if (m.speeksc() == EXTENSION_SC) m.sseeksc(); if (m.speeksc() == USER_SC) m.sseeksc(); p.seek = m.tell() - 3; if (m.sresid < 0) p.eos = -1; else p.eos = m.seek - m.size + m.slim + m.sresid; if (detail) m.detail(p); else m.skipdetail(); return p;} Mpegi.detail(m: self ref Mpegi, p: ref Picture){ l: list of ref Slice; p.addr = -1; while ((c := m.speeksc()) >= SLICE1_SC && c <= SLICEN_SC) l = m.slice(p) :: l; if (l == nil) m.fmterr("slice sc"); n := len l; a := array[n] of ref Slice; while (--n >= 0) { a[n] = hd l; l = tl l; } p.slices = a;} Mpegi.skipdetail(m: self ref Mpegi){ while ((c := m.speeksc()) >= SLICE1_SC && c <= SLICEN_SC) { m.looked = 0; m.sseeksc(); }} ESC, EOB, C0, C1, C2, C3, C4, C5, C6, C7: con -(iota + 1); include "mai.tab";include "mbi.tab";include "mbp.tab";include "mbb.tab";include "motion.tab";include "cbp.tab";include "cdc.tab";include "ydc.tab";include "rl0f.tab";include "rl0n.tab";include "c0.tab";include "c1.tab";include "c2.tab";include "c3.tab";include "c4.tab";include "c5.tab";include "c6.tab";include "c7.tab"; mbif := array[] of { MB_I, MB_I | MB_Q,}; mbpf := array[] of { MB_MF, MB_P, MB_P | MB_Q, MB_P | MB_MF, MB_P | MB_MF | MB_Q, MB_I, MB_I | MB_Q,}; mbbf := array[] of { MB_MF, MB_MB, MB_MB | MB_MF, MB_P | MB_MF, MB_P | MB_MF | MB_Q, MB_P | MB_MB, MB_P | MB_MB | MB_Q, MB_P | MB_MB | MB_MF, MB_P | MB_MB | MB_MF | MB_Q, MB_I, MB_I | MB_Q,}; c_bits := array[] of { c1_bits, c2_bits, c3_bits, c4_bits, c5_bits, c6_bits, c7_bits, }; c_tables: array of array of Pair; patcode := array[] of { 1<<5, 1<<4, 1<<3, 1<<2, 1<<1, 1<<0,}; Mpegi.inittables(){ if (c_tables == nil) { c_tables = array[] of { c1_table, c2_table, c3_table, c4_table, c5_table, c6_table, c7_table, }; }} Mpegi.slice(m: self ref Mpegi, p: ref Picture): ref Slice{ m.snextsc(); s := ref Slice; q := m.sgetn(5); while (m.sgetn(1)) m.sgetn(8); x := p.addr; l: list of ref MacroBlock; while (m.speekn(23) != 0) { while (m.speekn(11) == 16rF) m.sbits -= 11; while (m.speekn(11) == 16r8) { x += 33; m.sbits -= 11; } i := m.svlc(mai_table, mai_bits, "mai"); x += i; b := ref MacroBlock; b.addr = x; case p.ptype { IPIC => b.flags = mbif[m.svlc(mbi_table, mbi_bits, "mbi")]; PPIC => b.flags = mbpf[m.svlc(mbp_table, mbp_bits, "mbp")]; BPIC => b.flags = mbbf[m.svlc(mbb_table, mbb_bits, "mbb")]; DPIC => if (!m.sgetn(1)) m.fmterr("mbd flags"); b.flags = MB_I; * => m.fmterr("ptype"); } if (b.flags & MB_Q) q = m.sgetn(5); b.qscale = q; if (b.flags & MB_MF) { i = m.svlc(motion_table, motion_bits, "mhfc"); b.mhfc = i; if (i != 0 && p.forwfc != 0) b.mhfr = m.sgetn(p.forwfc); i = m.svlc(motion_table, motion_bits, "mvfc"); b.mvfc = i; if (i != 0 && p.forwfc != 0) b.mvfr = m.sgetn(p.forwfc); } if (b.flags & MB_MB) { i = m.svlc(motion_table, motion_bits, "mhbc"); b.mhbc = i; if (i != 0 && p.backfc != 0) b.mhbr = m.sgetn(p.backfc); i = m.svlc(motion_table, motion_bits, "mvbc"); b.mvbc = i; if (i != 0 && p.backfc != 0) b.mvbr = m.sgetn(p.backfc); } if (b.flags & MB_I)Lines 1–500 of 870. Load more
implement Mpegio; # # MPEG ISO 11172 IO module. # include "sys.m"; include "mpegio.m"; sys: Sys; init() { sys = load Sys Sys->PATH; } raisex(s: string) { raise MEXCEPT + s; } prepare(fd: ref Sys->FD, name: string): ref Mpegi { m := ref Mpegi; m.fd = fd; m.name = name; m.seek = 0; m.looked = 0; m.index = 0; m.size = 0; m.buff = array[MBSZ] of byte; return m; } Mpegi.startsys(m: self ref Mpegi) { # 2.4.3.2 m.xnextsc(PACK_SC); m.packhdr(); m.xnextsc(SYSHD_SC); m.syssz = m.getw(); m.boundmr = m.get22("boundmr"); m.syspar = m.getw(); if ((m.syspar & 16r20) == 0 || m.getb() != 16rFF) m.fmterr("syspar"); t := m.syssz - 6; if (t <= 0 || (t % 3) != 0) m.fmterr("syssz"); t /= 3; m.nstream = t; m.streams = array[t] of Stream; for (i := 0; i < t; i++) { v := m.getb(); if ((v & 16r80) == 0) m.fmterr("streamid"); w := m.getb(); if ((w & 16rC0) != 16rC0) m.fmterr("stream mark"); m.streams[i] = (byte v, byte ((w >> 5) & 1), ((w & 16r1F) << 8) | m.getb(), nil); } } Mpegi.packetcp(m: self ref Mpegi): int { while ((c := m.nextsc()) != STREAM_EC) { case c { PACK_SC => m.packhdr(); SYSHD_SC => m.syshdr(); * => if (c < STREAM_BASE) m.fmterr(sys->sprint("stream code %x", c)); # 2.4.3.3 l := m.getw(); fd := m.getfd(c); if (fd != nil) { if (c != PRIVSTREAM2) l -= m.stamps(); if (m.log != nil) sys->fprint(m.log, "%x %d %d\n", c & 16rFF, m.tell(), l); m.cpn(fd, l); } else m.skipn(l); return 1; } } return 0; } Mpegi.getfd(m: self ref Mpegi, c: int): ref Sys->FD { id := byte c; n := m.nstream; for (i := 0; i < n; i++) { if (m.streams[i].id == id) return m.streams[i].fd; } return nil; } Mpegi.packhdr(m: self ref Mpegi) { # 2.4.3.2 t := m.getb(); if ((t & 16rF1) != 16r21) m.fmterr("pack tag"); m.packt0 = (t >> 1) & 7; v := m.getb() << 22; t = m.getb(); if ((t & 1) == 0) m.fmterr("packt mark 1"); v |= ((t & ~1) << 15) | (m.getb() << 7); t = m.getb(); if ((t & 1) == 0) m.fmterr("packt mark 2"); m.packt1 = v | (t >> 1); m.packmr = m.get22("packmr"); } Mpegi.syshdr(m: self ref Mpegi) { l := m.getw(); if (l != m.syssz) m.fmterr("syshdr size mismatch"); m.skipn(l); } Mpegi.stamps(m: self ref Mpegi): int { # 2.4.3.3 n := 1; while ((c := m.getb()) == 16rFF) n++; if ((c >> 6) == 1) { m.getb(); c = m.getb(); n += 2; } case c >> 4 { 2 => m.skipn(4); n += 4; 3 => m.skipn(9); n += 9; * => if (c != 16rF) m.fmterr("stamps"); } return n; } Mpegi.streaminit(m: self ref Mpegi, c: int) { m.inittables(); m.sid = c; s := m.peeksc(); if (s == PACK_SC) { m.startsys(); f := 0; id := byte m.sid; for (i := 0; i < m.nstream; i++) { if (m.streams[i].id == id) { f = 1; break; } } if (!f) m.fmterr(sys->sprint("%x: stream not found", c)); m.sseek(); } else if (s == SEQUENCE_SC) { m.sresid = -1; m.slim = m.size; } else m.fmterr(sys->sprint("start code = %x", s)); m.sbits = 0; } Mpegi.sseek(m: self ref Mpegi) { while ((c := m.nextsc()) != STREAM_EC) { case c { PACK_SC => m.packhdr(); SYSHD_SC => m.syshdr(); * => if (c < STREAM_BASE) m.fmterr(sys->sprint("stream code %x", c)); # 2.4.3.3 l := m.getw(); if (c == m.sid) { if (c != PRIVSTREAM2) l -= m.stamps(); n := m.size - m.index; if (l <= n) { m.slim = m.index + l; m.sresid = 0; } else { m.slim = m.size; m.sresid = l - n; } return; } else m.skipn(l); } } m.fmterr("end of stream"); } Mpegi.getpicture(m: self ref Mpegi, detail: int): ref Picture { g := 0; for (;;) { case c := m.snextsc() { SEQUENCE_SC => m.seqhdr(); GROUP_SC => m.grphdr(); g = 1; PICTURE_SC => p := m.picture(detail); if (g) p.flags |= GSTART; return p; SEQUENCE_EC => return nil; * => m.fmterr(sys->sprint("start code %x", c)); } } } Mpegi.seqhdr(m: self ref Mpegi) { # 2.4.2.3 c := m.sgetb(); d := m.sgetb(); m.width = (c << 4) | (d >> 4); m.height = ((d & 16rF) << 8) | m.sgetb(); c = m.sgetb(); m.aspect = c >> 4; m.frames = c & 16rF; m.rate = m.sgetn(18); m.smarker(); m.vbv = m.sgetn(10); m.flags = 0; if (m.sgetn(1)) m.flags |= CONSTRAINED; if (m.sgetn(1)) m.intra = m.getquant(); if (m.sgetn(1)) m.nintra = m.getquant(); if (m.speeksc() == EXTENSION_SC) m.sseeksc(); if (m.speeksc() == USER_SC) m.sseeksc(); } Mpegi.grphdr(m: self ref Mpegi) { # 2.4.2.4 v := m.sgetb() << 17; v |= m.sgetb() << 9; v |= m.sgetb() << 1; c := m.sgetb(); m.smpte = v | (c >> 7); if (c & (1 << 6)) m.flags |= CLOSED; else m.flags &= ~CLOSED; if (c & (1 << 5)) m.flags |= BROKEN; else m.flags &= ~BROKEN; if (m.speeksc() == EXTENSION_SC) m.sseeksc(); if (m.speeksc() == USER_SC) m.sseeksc(); } Mpegi.getquant(m: self ref Mpegi): array of int { a := array[64] of int; for (i := 0; i < 64; i++) a[i] = m.sgetn(8); return a; } Mpegi.picture(m: self ref Mpegi, detail: int): ref Picture { # 2.4.2.5 p := ref Picture; p.temporal = m.sgetn(10); p.ptype = m.sgetn(3); p.vbvdelay = m.sgetn(16); p.flags = 0; if (p.ptype == PPIC || p.ptype == BPIC) { if (m.sgetn(1)) p.flags |= FPFV; p.forwfc = m.sgetn(3); if (p.forwfc == 0) m.fmterr("forwfc"); p.forwfc--; if (p.ptype == BPIC) { if (m.sgetn(1)) p.flags |= FPBV; p.backfc = m.sgetn(3); if (p.backfc == 0) m.fmterr("backfc"); p.backfc--; } else p.backfc = 0; } else { p.forwfc = 0; p.backfc = 0; } while (m.sgetn(1)) m.sgetn(8); if (m.speeksc() == EXTENSION_SC) m.sseeksc(); if (m.speeksc() == USER_SC) m.sseeksc(); p.seek = m.tell() - 3; if (m.sresid < 0) p.eos = -1; else p.eos = m.seek - m.size + m.slim + m.sresid; if (detail) m.detail(p); else m.skipdetail(); return p; } Mpegi.detail(m: self ref Mpegi, p: ref Picture) { l: list of ref Slice; p.addr = -1; while ((c := m.speeksc()) >= SLICE1_SC && c <= SLICEN_SC) l = m.slice(p) :: l; if (l == nil) m.fmterr("slice sc"); n := len l; a := array[n] of ref Slice; while (--n >= 0) { a[n] = hd l; l = tl l; } p.slices = a; } Mpegi.skipdetail(m: self ref Mpegi) { while ((c := m.speeksc()) >= SLICE1_SC && c <= SLICEN_SC) { m.looked = 0; m.sseeksc(); } } ESC, EOB, C0, C1, C2, C3, C4, C5, C6, C7: con -(iota + 1); include "mai.tab"; include "mbi.tab"; include "mbp.tab"; include "mbb.tab"; include "motion.tab"; include "cbp.tab"; include "cdc.tab"; include "ydc.tab"; include "rl0f.tab"; include "rl0n.tab"; include "c0.tab"; include "c1.tab"; include "c2.tab"; include "c3.tab"; include "c4.tab"; include "c5.tab"; include "c6.tab"; include "c7.tab"; mbif := array[] of { MB_I, MB_I | MB_Q, }; mbpf := array[] of { MB_MF, MB_P, MB_P | MB_Q, MB_P | MB_MF, MB_P | MB_MF | MB_Q, MB_I, MB_I | MB_Q, }; mbbf := array[] of { MB_MF, MB_MB, MB_MB | MB_MF, MB_P | MB_MF, MB_P | MB_MF | MB_Q, MB_P | MB_MB, MB_P | MB_MB | MB_Q, MB_P | MB_MB | MB_MF, MB_P | MB_MB | MB_MF | MB_Q, MB_I, MB_I | MB_Q, }; c_bits := array[] of { c1_bits, c2_bits, c3_bits, c4_bits, c5_bits, c6_bits, c7_bits, }; c_tables: array of array of Pair; patcode := array[] of { 1<<5, 1<<4, 1<<3, 1<<2, 1<<1, 1<<0, }; Mpegi.inittables() { if (c_tables == nil) { c_tables = array[] of { c1_table, c2_table, c3_table, c4_table, c5_table, c6_table, c7_table, }; } } Mpegi.slice(m: self ref Mpegi, p: ref Picture): ref Slice { m.snextsc(); s := ref Slice; q := m.sgetn(5); while (m.sgetn(1)) m.sgetn(8); x := p.addr; l: list of ref MacroBlock; while (m.speekn(23) != 0) { while (m.speekn(11) == 16rF) m.sbits -= 11; while (m.speekn(11) == 16r8) { x += 33; m.sbits -= 11; } i := m.svlc(mai_table, mai_bits, "mai"); x += i; b := ref MacroBlock; b.addr = x; case p.ptype { IPIC => b.flags = mbif[m.svlc(mbi_table, mbi_bits, "mbi")]; PPIC => b.flags = mbpf[m.svlc(mbp_table, mbp_bits, "mbp")]; BPIC => b.flags = mbbf[m.svlc(mbb_table, mbb_bits, "mbb")]; DPIC => if (!m.sgetn(1)) m.fmterr("mbd flags"); b.flags = MB_I; * => m.fmterr("ptype"); } if (b.flags & MB_Q) q = m.sgetn(5); b.qscale = q; if (b.flags & MB_MF) { i = m.svlc(motion_table, motion_bits, "mhfc"); b.mhfc = i; if (i != 0 && p.forwfc != 0) b.mhfr = m.sgetn(p.forwfc); i = m.svlc(motion_table, motion_bits, "mvfc"); b.mvfc = i; if (i != 0 && p.forwfc != 0) b.mvfr = m.sgetn(p.forwfc); } if (b.flags & MB_MB) { i = m.svlc(motion_table, motion_bits, "mhbc"); b.mhbc = i; if (i != 0 && p.backfc != 0) b.mhbr = m.sgetn(p.backfc); i = m.svlc(motion_table, motion_bits, "mvbc"); b.mvbc = i; if (i != 0 && p.backfc != 0) b.mvbr = m.sgetn(p.backfc); } if (b.flags & MB_I)