History

extract raw streams

Sigrid Haflínudóttir committed 6 years ago

Commit 1cd6fa11 parent cb8864e1 file · +98 −7Browse files

Unified · Split

iso.c+98−7
@@ -4,6 +4,8 @@ · 3 unmodified lines
4 4
5typedef struct Box Box;5typedef struct Box Box;
6typedef struct RunSample RunSample;6typedef struct RunSample RunSample;
7typedef struct Track Track;
8typedef struct SampleToChunk SampleToChunk;
7 9
8struct Box {10struct Box {
9 vlong dsz;11 vlong dsz;
@@ -88,11 +90,7 @@ struct Box { · 78 unmodified lines
88 90
89 struct {91 struct {
90 u32int entrycount;92 u32int entrycount;
91 struct {93 SampleToChunk *entry;
92 u32int firstchunk;
93 u32int samplesperchunk;
94 u32int sdt;
95 }*entry;
96 }stsc;94 }stsc;
97 95
98 struct {96 struct {
@@ -129,6 +127,25 @@ struct RunSample { · 30 unmodified lines
129 vlong timeoffset;127 vlong timeoffset;
130};128};
131 129
130struct Track {
131 u64int *chunkoffset;
132 u32int numchunks;
133
134 u32int *samplesize;
135 u32int numsamples;
136
137 SampleToChunk *stc;
138 u32int numstc;
139
140 int id;
141};
142
143struct SampleToChunk {
144 u32int firstchunk;
145 u32int samplesperchunk;
146 u32int sdt;
147};
148
132enum {149enum {
133 BoxUuid = 0x75756964u,150 BoxUuid = 0x75756964u,
134 BoxFtyp = 0x66747970u,151 BoxFtyp = 0x66747970u,
@@ -146,6 +163,7 @@ enum { · 11 unmodified lines
146 BoxMinf = 0x6d696e66u,163 BoxMinf = 0x6d696e66u,
147 BoxDinf = 0x64696e66u,164 BoxDinf = 0x64696e66u,
148 BoxStbl = 0x7374626cu,165 BoxStbl = 0x7374626cu,
166 BoxCtts = 0x63747473u,
149 BoxStsd = 0x73747364u,167 BoxStsd = 0x73747364u,
150 BoxStts = 0x73747473u,168 BoxStts = 0x73747473u,
151 BoxStsc = 0x73747363u,169 BoxStsc = 0x73747363u,
@@ -173,15 +191,18 @@ enum { · 21 unmodified lines
173 b->type == BoxMfhd || b->type == BoxTfhd || b->type == BoxTfdt || b->type == BoxTrun || \191 b->type == BoxMfhd || b->type == BoxTfhd || b->type == BoxTfdt || b->type == BoxTrun || \
174 b->type == BoxStsd || b->type == BoxStts || b->type == BoxStss || b->type == BoxTkhd || \192 b->type == BoxStsd || b->type == BoxStts || b->type == BoxStss || b->type == BoxTkhd || \
175 b->type == BoxElst || b->type == BoxStsc || b->type == BoxStco || b->type == BoxCo64 || \193 b->type == BoxElst || b->type == BoxStsc || b->type == BoxStco || b->type == BoxCo64 || \
176 b->type == BoxStsz \194 b->type == BoxStsz || b->type == BoxCtts \
177)195)
178 196
179#define eBread(sz, e) if(Bread(f, d, (sz)) != (sz)){ werrstr(e); goto err; }197#define eBread(sz, e) if(Bread(f, d, (sz)) != (sz)){ werrstr(e); goto err; }
180 198
181static int dflag;199static int dflag;
182static int dind;200static int dind;
201static int trackdump = -1;
183static u32int defsamplesize;202static u32int defsamplesize;
184 203
204static Track track;
205
185static int parsebox(Biobuf *f, Box *b, int *eof);206static int parsebox(Biobuf *f, Box *b, int *eof);
186 207
187#pragma varargck type "T" u32int208#pragma varargck type "T" u32int
@@ -332,6 +353,47 @@ printbox(Box *b) · 144 unmodified lines
332 }353 }
333}354}
334 355
356static void
357dumptrack(Biobuf *f)
358{
359 SampleToChunk *stc;
360 u32int si, ch, lastch;
361 u32int samplelast, sample, rawsz;
362 vlong o;
363 u8int *raw;
364 Biobuf out;
365
366 Binit(&out, 1, OWRITE);
367 raw = nil;
368 rawsz = 0;
369 sample = samplelast = 0;
370 stc = track.stc;
371 for(si = 0; si < track.numstc; si++, stc++){
372 lastch = si+1 < track.numstc ? stc[1].firstchunk : track.numchunks;
373 for(ch = stc->firstchunk-1; ch < lastch && ch < track.numchunks; ch++){
374 o = track.chunkoffset[ch];
375 if(Bseek(f, o, 0) != o)
376 sysfatal("chunk %ud: %r", ch);
377 for(; sample < samplelast+stc->samplesperchunk && sample < track.numsamples; sample++){
378 if(track.samplesize[sample] == 0)
379 break;
380 if(rawsz < track.samplesize[sample]){
381 rawsz = track.samplesize[sample] * 2;
382 raw = realloc(raw, rawsz);
383 }
384 if(Bread(f, raw, track.samplesize[sample]) != track.samplesize[sample])
385 sysfatal("chunk %ud sample %ud size %ud: %r", ch, sample, track.samplesize[sample]);
386 if(Bwrite(&out, raw, track.samplesize[sample]) != track.samplesize[sample])
387 exits(nil);
388 }
389 samplelast = sample;
390 }
391 }
392 fprint(2, "%ud samples\n", sample);
393 Bterm(&out);
394 free(raw);
395};
396
335static int397static int
336parseboxdata(Biobuf *f, Box *b)398parseboxdata(Biobuf *f, Box *b)
337{399{
@@ -369,6 +431,17 @@ parseboxdata(Biobuf *f, Box *b) · 31 unmodified lines
369 if(inner.dstart+inner.dsz >= b->dstart+b->dsz)431 if(inner.dstart+inner.dsz >= b->dstart+b->dsz)
370 break;432 break;
371 }433 }
434 if(b->type == BoxTrak){
435 if(track.id == trackdump){
436 u = Boffset(f);
437 dumptrack(f);
438 Bseek(f, u, 0);
439 }
440 free(track.chunkoffset);
441 free(track.samplesize);
442 free(track.stc);
443 memset(&track, 0, sizeof(track));
444 }
372 dind--;445 dind--;
373 }else if(b->type == BoxMvhd){446 }else if(b->type == BoxMvhd){
374 n = b->version == 0 ? 96 : 108;447 n = b->version == 0 ? 96 : 108;
@@ -506,7 +579,7 @@ parseboxdata(Biobuf *f, Box *b) · 131 unmodified lines
506 }else if(b->type == BoxStsc){579 }else if(b->type == BoxStsc){
507 eBread(4, "entry_count");580 eBread(4, "entry_count");
508 b->stsc.entrycount = bu32(d);581 b->stsc.entrycount = bu32(d);
509 b->stsc.entry = calloc(b->stsc.entrycount, sizeof(*b->stsc.entry));582 b->stsc.entry = calloc(b->stsc.entrycount, sizeof(SampleToChunk));
510 for(u = 0; u < b->stsc.entrycount; u++){583 for(u = 0; u < b->stsc.entrycount; u++){
511 eBread(4, "first_chunk");584 eBread(4, "first_chunk");
512 b->stsc.entry[u].firstchunk = bu32(d);585 b->stsc.entry[u].firstchunk = bu32(d);
@@ -515,6 +588,8 @@ parseboxdata(Biobuf *f, Box *b) · 2 unmodified lines
515 eBread(4, "sample_description_table");588 eBread(4, "sample_description_table");
516 b->stsc.entry[u].sdt = bu32(d);589 b->stsc.entry[u].sdt = bu32(d);
517 }590 }
591 track.numstc = b->stsc.entrycount;
592 track.stc = b->stsc.entry;
518 printbox(b);593 printbox(b);
519 }else if(b->type == BoxStco || b->type == BoxCo64){594 }else if(b->type == BoxStco || b->type == BoxCo64){
520 eBread(4, "entry_count");595 eBread(4, "entry_count");
@@ -524,6 +599,8 @@ parseboxdata(Biobuf *f, Box *b) · 3 unmodified lines
524 eBread(b->type == BoxStco ? 4 : 8, "chunk_offset");599 eBread(b->type == BoxStco ? 4 : 8, "chunk_offset");
525 b->stco_co64.chunkoffset[u] = b->type == BoxStco ? bu32(d) : bu64(d);600 b->stco_co64.chunkoffset[u] = b->type == BoxStco ? bu32(d) : bu64(d);
526 }601 }
602 track.numchunks = b->stco_co64.entrycount;
603 track.chunkoffset = b->stco_co64.chunkoffset;
527 printbox(b);604 printbox(b);
528 }else if(b->type == BoxStsz){605 }else if(b->type == BoxStsz){
529 eBread(4, "sample_size");606 eBread(4, "sample_size");
@@ -536,6 +613,8 @@ parseboxdata(Biobuf *f, Box *b) · 6 unmodified lines
536 eBread(4, "chunk_offset");613 eBread(4, "chunk_offset");
537 b->stsz.entrysize[u] = bu32(d);614 b->stsz.entrysize[u] = bu32(d);
538 }615 }
616 track.numsamples = b->stsz.samplecount;
617 track.samplesize = b->stsz.entrysize;
539 }618 }
540 printbox(b);619 printbox(b);
541 }else if(b->type == BoxTkhd){620 }else if(b->type == BoxTkhd){
@@ -546,6 +625,7 @@ parseboxdata(Biobuf *f, Box *b) · 4 unmodified lines
546 b->tkhd.modtime = bu64(d);625 b->tkhd.modtime = bu64(d);
547 eBread(8, "track_id"); /* skipping 4 reserved as well */626 eBread(8, "track_id"); /* skipping 4 reserved as well */
548 b->tkhd.trackid = bu32(d);627 b->tkhd.trackid = bu32(d);
628 track.id = b->tkhd.trackid;
549 eBread(8, "duration");629 eBread(8, "duration");
550 b->tkhd.duration = bu64(d);630 b->tkhd.duration = bu64(d);
551 }else if(b->version == 0){631 }else if(b->version == 0){
@@ -555,6 +635,7 @@ parseboxdata(Biobuf *f, Box *b) · 3 unmodified lines
555 b->tkhd.modtime = bu32(d);635 b->tkhd.modtime = bu32(d);
556 eBread(8, "track_id"); /* skipping 4 reserved as well */636 eBread(8, "track_id"); /* skipping 4 reserved as well */
557 b->tkhd.trackid = bu32(d);637 b->tkhd.trackid = bu32(d);
638 track.id = b->tkhd.trackid;
558 eBread(4, "duration");639 eBread(4, "duration");
559 b->tkhd.duration = bu32(d);640 b->tkhd.duration = bu32(d);
560 }else{641 }else{
@@ -651,6 +732,13 @@ err: · 90 unmodified lines
651 return -1;732 return -1;
652}733}
653 734
735static void
736usage(void)
737{
738 fprint(2, "usage: iso [-d] [-t TRACK] FILE\n");
739 exits("usage");
740}
741
654int742int
655main(int argc, char **argv)743main(int argc, char **argv)
656{744{
@@ -663,6 +751,9 @@ main(int argc, char **argv) · 6 unmodified lines
663 case 'd':751 case 'd':
664 dflag = 1;752 dflag = 1;
665 break;753 break;
754 case 't':
755 trackdump = atoi(EARGF(usage()));
756 break;
666 }ARGEND757 }ARGEND
667 758
668 fmtinstall('T', typefmt);759 fmtinstall('T', typefmt);

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