ref: 041e2ada566d991e41dc0f626d1d20582276a6c0
dir: /common.h/
enum { Nodump = -1, Dumpaudio = -2, Dumpvideo = -3, FmtAv01 = 0x61763031u, FmtAvc1 = 0x61766331u, FmtMp4a = 0x6d703461u, FmtOpus = 0x6f707573u, FmtVp08 = 0x76703038u, FmtVp09 = 0x76703039u, /* fake ones, not supposed to show up in a mp4 */ FmtVorbis = 0x766f7262u, FmtSrt = 0x00737274u, /* srt subtitles */ FmtMp3 = 0x006d7033u, }; typedef struct Ebml Ebml; typedef struct Packet Packet; typedef struct Packetctx Packetctx; typedef int (*packet_f)(Biobuf *out, Packetctx *ctx, Packet *p, int np, uvlong ts); struct Packet { uchar *data; int sz; }; struct Packetctx { uvlong frid; uvlong duration; uvlong seekpreroll; vlong discardpad; vlong blockdur; struct { char name[16]; vlong delay; struct { uchar *data; int sz; }priv; }codec; u32int trackuid; u32int fmt; struct { int width, height; struct { int left, right, top, bottom; }crop; struct { int width, height; int unit; int aspectmode; }display; }video; struct { float samplerate; int channels; int bps; }audio; }; struct Ebml { Packetctx; packet_f fpacket; vlong timestampscale; vlong perframe; int tracknum; int tracktype; vlong codecdelay; char lang[8]; }; extern Biobuf stderr, out; extern int dflag, trackdump; #pragma varargck type "T" u32int int isotypefmt(Fmt *f); #pragma varargck type "P" uvlong int srttsfmt(Fmt *f); int isorun(Biobuf *f); int ebmlrun(Biobuf *f); u32int crc32(u32int init, u8int *d, ulong len); int ivfpacket(Biobuf *out, Packetctx *ctx, Packet *p, int np, uvlong ts); int oggpacket(Biobuf *out, Packetctx *ctx, Packet *p, int np, uvlong ts); int srtpacket(Biobuf *out, Packetctx *ctx, Packet *p, int np, uvlong ts); int ebmlint(Biobuf *f, vlong *out, int isid); vlong ebmlel(Biobuf *f, vlong sz, vlong *id, vlong *esz); vlong ebmlrawint(Biobuf *f, vlong sz, vlong *dst); #define ebmlgetnumber(expid, dest) \ if(id == expid){ \ vlong x; \ if(ebmlrawint(f, sz, &x) < 0) \ return -1; \ dest = x; \ left -= sz; \ continue; \ } #define ebmlgetstring(expid, dest) \ if(id == expid){ \ n = min(sizeof(dest)-1, sz); \ if(Bread(f, dest, n) != n) \ return -1; \ dest[n] = 0; \ if(n != sz) \ Bseek(f, sz-n, 1); \ left -= sz; \ continue; \ } #define ebmlgetbytes(expid, dest) \ if(id == expid){ \ dest.data = malloc(sz); \ if(Bread(f, dest.data, sz) != sz) \ return -1; \ dest.sz = sz; \ left -= sz; \ continue; \ } #define ebmlgetfloat(expid, dest) \ if(id == expid){ \ u32int u; \ union { \ uchar b[8]; \ u32int u[2]; \ float f; \ double d; \ }x; \ if(sz == 4){ \ if(Bread(f, x.b, 4) != 4) \ return -1; \ x.u[0] = (x.u[0]&0xff000000)>>24 | (x.u[0]&0x00ff0000)>>8 | (x.u[0]&0x0000ff00)<<8 | (x.u[0]&0x000000ff)<<24; \ dest = x.f; \ }else if(sz == 8){ \ if(Bread(f, x.b, 8) != 8) \ return -1; \ u = (x.u[0]&0xff000000)>>24 | (x.u[0]&0x00ff0000)>>8 | (x.u[0]&0x0000ff00)<<8 | (x.u[0]&0x000000ff)<<24; \ x.u[0] = (x.u[1]&0xff000000)>>24 | (x.u[1]&0x00ff0000)>>8 | (x.u[1]&0x0000ff00)<<8 | (x.u[1]&0x000000ff)<<24; \ x.u[1] = u; \ dest = x.d; \ }else{ \ werrstr("invalid float size"); \ break; \ } \ left -= sz; \ continue; \ } #define min(a,b) ((a)<=(b)?(a):(b))