Sigrid Solveig Haflínudóttirmkvdump: show hidden/discard block flags21b0ea35 years agoHistory
173 lines · 3.3 KB · C
RawDownload
#include "../ebml.c" #define min(a,b) ((a)<=(b)?(a):(b)) static vlong stack[128]; static voidusage(void){	fprint(2, "usage: %s [-d] [-h hxsz] [file.mkv]\n", argv0);	exits("usage");} voidmain(int argc, char **argv){	int n, sti, i, hxsz, lacing, fd, debug;	vlong sz, off, x;	uchar *b, t[3];	Biobuf in, out;	Elspec s;	double d;	Tm tm; 	debug = 0;	hxsz = 32;	ARGBEGIN{	case 'd':		debug++;		break;	case 'h':		if((hxsz = atoi(EARGF(usage()))) > 0)			break;	default:		usage();	}ARGEND 	fd = 0;	if(argc == 1){		if((fd = open(*argv, OREAD)) < 0)			sysfatal("%r");	}else if(argc != 0)		usage(); 	if((b = malloc(hxsz)) == nil)		sysfatal("memory"); 	quotefmtinstall();	fmtinstall('H', encodefmt);	tmfmtinstall();	Binit(&in, fd, OREAD);	Binit(&out, 1, OWRITE); 	sti = 0;	for(;;){		off = Boffset(&in);		if((n = ebmlel(&in, 0x7fffffffffffffffLL, &s, &sz)) < 0){			werrstr("invalid ebml: %r at %#llx (size %lld)", off, sz);			goto err;		}		if(s.type < 0)			continue;		if(n == 0) /* eof */			break;		while(sti > 0 && off >= stack[sti-1])			sti--;		if(s.name){			for(i = 0; i < sti; i++)				Bputc(&out, '\t');			Bprint(&out, "%s ", s.name);			if(debug)				Bprint(&out, " (id %#llx) ", s.id);			if(s.type == Emaster && sti < nelem(stack))				stack[sti++] = off+n+sz;		}else{			Bprint(&out, "%#llx ", s.id);		}		if(debug)			Bprint(&out, "(%lld bytes) ", sz); 		switch(s.type){		case Ebinary:			if(s.id == ESimpleBlock || s.id == EBlock){				if((n = ebmluint(&in, sz, &x)) < 0){					werrstr("block: %r");					goto err;				}				sz -= n;				if(Bread(&in, t, 3) != 3){					werrstr("block: %r");					goto err;				}				sz -= 3;				lacing = (t[2] >> 1) & 3;				Bprint(&out, "(track %lld, timecode %d) ", x, (s16int)(t[0]<<8 | t[1]));				if(s.id == ESimpleBlock){					if(t[2] & 0x80)						Bprint(&out, "(key) ");					if(t[2] & 0x01)						Bprint(&out, "(discard) ");				}				if(t[2] & 0x08)					Bprint(&out, "(hidden) ");				if(lacing != 0)					Bprint(&out, "(lacing %d) ", lacing);			}			n = min(hxsz, sz);			if(Bread(&in, b, n) != n){				werrstr("binary: %r");				goto err;			}			Bprint(&out, "[%.*H%s] (%lld bytes)", n, b, sz > n ? "..." : "", sz);			sz -= n;			break;		case Efloat:			if(ebmlfloat(&in, sz, &d) < 0)				goto err;			Bprint(&out, "%g", d);			sz = 0;			break;		case Eunsigned:			if(ebmlrawuint(&in, sz, &x) < 0)				goto err;			Bprint(&out, "%llud", (uvlong)x);			sz = 0;			break;		case Esigned:			if(ebmlrawsint(&in, sz, &x) < 0)				goto err;			Bprint(&out, "%lld", x);			sz = 0;			break;		case Eunicode:		case Eascii:			n = min(hxsz, sz);			if(Bread(&in, b, n) != n){				werrstr("string: %r");				goto err;			}			Bprint(&out, "%#.*q%s", n, (char*)b, sz > n ? "..." : "");			sz -= n;			break;		case Etimestamp:			if(ebmlrawsint(&in, sz, &x) < 0)				goto err;			x /= 1000000000LL;			x += 978307200LL;			Bprint(&out, "%τ", tmfmt(tmtime(&tm, x, nil), nil));			sz = 0;			break;		case Emaster:			break;		default:			Bprint(&out, "???");		} 		if(s.id == ETrackType)			Bprint(&out, " (%s)", ebmltracktype(x)); 		if(Bputc(&out, '\n') < 0)			break;		if(s.type != Emaster && sz > 0 && Bseek(&in, sz, 1) < 0)			goto err;				}	Bterm(&out);	Bterm(&in); 	exits(nil);err:	fprint(2, "%s: %r\n", fd == 0 ? "stdin" : *argv);	exits("error");}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t