ref: 49dc43fd64bb77001494be6721380895f1bba971
dir: /extra/adtsdump.c/
#include <u.h> #include <libc.h> #include <bio.h> static char *objtype[] = { "aac main", "aac lc ", "aac ssr ", "aac ltp ", }; static char *rate[] = { "96000", "88200", "64000", "48000", "44100", "32000", "24000", "22050", "16000", "12000", "11025", "8000 ", "7350 ", "??? ", "??? ", "expl ", }; static char *chan[] = { "AOT", "1 ", "2 ", "3 ", "4 ", "5 ", "6 ", "8 ", "???", "???", "???", "???", "???", "???", "???", "???", }; static void usage(void) { fprint(2, "usage: %s [-h hxsz] [file.aac]\n", argv0); exits("usage"); } void main(int argc, char **argv) { int hxsz, fd, d, n, sz; Biobuf in, out; u8int b[7], *h; hxsz = 0; ARGBEGIN{ case 'h': if((hxsz = atoi(EARGF(usage()))) > 0){ fmtinstall('H', encodefmt); break; } default: usage(); }ARGEND fd = 0; if(argc == 1){ if((fd = open(*argv, OREAD)) < 0) sysfatal("%r"); }else if(argc != 0) usage(); if((h = malloc(hxsz)) == nil) sysfatal("memory"); Binit(&in, fd, OREAD); Binit(&out, 1, OWRITE); fmtinstall('H', encodefmt); for(;;){ if((n = Bread(&in, b, 7)) == 0) break; if(n < 0) goto err; if(n != 7){ werrstr("short ADTS: %d != 7", n); goto err; } if(b[0] != 0xff || (b[0]&0xf0) != 0xf0){ werrstr("invalid syncword %2x%02x", b[0], b[1]); goto err; } sz = (b[3]&3)<<11 | b[4]<<3 | b[5]>>5; sz -= 7; Bprint(&out, "%s %s %s %s %d %d", (b[1]&8) ? "mpeg2" : "mpeg4", objtype[b[2]>>6], rate[(b[2]>>2)&0xf], chan[(b[2]&3)<<2 | b[3]>>6], sz - ((b[1]&1) == 0 ? 2 : 0), (b[6]&3)+1 ); if((b[1]&1) == 0){ /* skip crc */ if((n = Bread(&in, b, 2)) != 2){ werrstr("short ADTS.crc: %d != 2", n); goto err; } sz -= 2; } d = sz < hxsz ? sz : hxsz; sz -= d; if(d > 0){ if((n = Bread(&in, h, d)) != d){ werrstr("short read: %d != %d", n, d); goto err; } Bprint(&out, " [%.*H]", d, h); } Bprint(&out, "\n"); if(Bseek(&in, sz, 1) < 0) goto err; } Bterm(&out); Bterm(&in); exits(nil); err: fprint(2, "%s: %r (at %#llx)\n", fd == 0 ? "stdin" : *argv, Boffset(&in)); exits("error"); }