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
44
55 typedef struct Box Box;
66 typedef struct RunSample RunSample;
7+typedef struct Track Track;
8+typedef struct SampleToChunk SampleToChunk;
79
810 struct Box {
911 vlong dsz;
@@ -88,11 +90,7 @@ struct Box { · 78 unmodified lines
8890
8991 struct {
9092 u32int entrycount;
91− struct {
92− u32int firstchunk;
93− u32int samplesperchunk;
94− u32int sdt;
95− }*entry;
93+ SampleToChunk *entry;
9694 }stsc;
9795
9896 struct {
@@ -129,6 +127,25 @@ struct RunSample { · 30 unmodified lines
129127 vlong timeoffset;
130128 };
131129
130+struct 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+
143+struct SampleToChunk {
144+ u32int firstchunk;
145+ u32int samplesperchunk;
146+ u32int sdt;
147+};
148+
132149 enum {
133150 BoxUuid = 0x75756964u,
134151 BoxFtyp = 0x66747970u,
@@ -146,6 +163,7 @@ enum { · 11 unmodified lines
146163 BoxMinf = 0x6d696e66u,
147164 BoxDinf = 0x64696e66u,
148165 BoxStbl = 0x7374626cu,
166+ BoxCtts = 0x63747473u,
149167 BoxStsd = 0x73747364u,
150168 BoxStts = 0x73747473u,
151169 BoxStsc = 0x73747363u,
@@ -173,15 +191,18 @@ enum { · 21 unmodified lines
173191 b->type == BoxMfhd || b->type == BoxTfhd || b->type == BoxTfdt || b->type == BoxTrun || \
174192 b->type == BoxStsd || b->type == BoxStts || b->type == BoxStss || b->type == BoxTkhd || \
175193 b->type == BoxElst || b->type == BoxStsc || b->type == BoxStco || b->type == BoxCo64 || \
176− b->type == BoxStsz \
194+ b->type == BoxStsz || b->type == BoxCtts \
177195 )
178196
179197 #define eBread(sz, e) if(Bread(f, d, (sz)) != (sz)){ werrstr(e); goto err; }
180198
181199 static int dflag;
182200 static int dind;
201+static int trackdump = -1;
183202 static u32int defsamplesize;
184203
204+static Track track;
205+
185206 static int parsebox(Biobuf *f, Box *b, int *eof);
186207
187208 #pragma varargck type "T" u32int
@@ -332,6 +353,47 @@ printbox(Box *b) · 144 unmodified lines
332353 }
333354 }
334355
356+static void
357+dumptrack(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+
335397 static int
336398 parseboxdata(Biobuf *f, Box *b)
337399 {
@@ -369,6 +431,17 @@ parseboxdata(Biobuf *f, Box *b) · 31 unmodified lines
369431 if(inner.dstart+inner.dsz >= b->dstart+b->dsz)
370432 break;
371433 }
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+ }
372445 dind--;
373446 }else if(b->type == BoxMvhd){
374447 n = b->version == 0 ? 96 : 108;
@@ -506,7 +579,7 @@ parseboxdata(Biobuf *f, Box *b) · 131 unmodified lines
506579 }else if(b->type == BoxStsc){
507580 eBread(4, "entry_count");
508581 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));
510583 for(u = 0; u < b->stsc.entrycount; u++){
511584 eBread(4, "first_chunk");
512585 b->stsc.entry[u].firstchunk = bu32(d);
@@ -515,6 +588,8 @@ parseboxdata(Biobuf *f, Box *b) · 2 unmodified lines
515588 eBread(4, "sample_description_table");
516589 b->stsc.entry[u].sdt = bu32(d);
517590 }
591+ track.numstc = b->stsc.entrycount;
592+ track.stc = b->stsc.entry;
518593 printbox(b);
519594 }else if(b->type == BoxStco || b->type == BoxCo64){
520595 eBread(4, "entry_count");
@@ -524,6 +599,8 @@ parseboxdata(Biobuf *f, Box *b) · 3 unmodified lines
524599 eBread(b->type == BoxStco ? 4 : 8, "chunk_offset");
525600 b->stco_co64.chunkoffset[u] = b->type == BoxStco ? bu32(d) : bu64(d);
526601 }
602+ track.numchunks = b->stco_co64.entrycount;
603+ track.chunkoffset = b->stco_co64.chunkoffset;
527604 printbox(b);
528605 }else if(b->type == BoxStsz){
529606 eBread(4, "sample_size");
@@ -536,6 +613,8 @@ parseboxdata(Biobuf *f, Box *b) · 6 unmodified lines
536613 eBread(4, "chunk_offset");
537614 b->stsz.entrysize[u] = bu32(d);
538615 }
616+ track.numsamples = b->stsz.samplecount;
617+ track.samplesize = b->stsz.entrysize;
539618 }
540619 printbox(b);
541620 }else if(b->type == BoxTkhd){
@@ -546,6 +625,7 @@ parseboxdata(Biobuf *f, Box *b) · 4 unmodified lines
546625 b->tkhd.modtime = bu64(d);
547626 eBread(8, "track_id"); /* skipping 4 reserved as well */
548627 b->tkhd.trackid = bu32(d);
628+ track.id = b->tkhd.trackid;
549629 eBread(8, "duration");
550630 b->tkhd.duration = bu64(d);
551631 }else if(b->version == 0){
@@ -555,6 +635,7 @@ parseboxdata(Biobuf *f, Box *b) · 3 unmodified lines
555635 b->tkhd.modtime = bu32(d);
556636 eBread(8, "track_id"); /* skipping 4 reserved as well */
557637 b->tkhd.trackid = bu32(d);
638+ track.id = b->tkhd.trackid;
558639 eBread(4, "duration");
559640 b->tkhd.duration = bu32(d);
560641 }else{
@@ -651,6 +732,13 @@ err: · 90 unmodified lines
651732 return -1;
652733 }
653734
735+static void
736+usage(void)
737+{
738+ fprint(2, "usage: iso [-d] [-t TRACK] FILE\n");
739+ exits("usage");
740+}
741+
654742 int
655743 main(int argc, char **argv)
656744 {
@@ -663,6 +751,9 @@ main(int argc, char **argv) · 6 unmodified lines
663751 case 'd':
664752 dflag = 1;
665753 break;
754+ case 't':
755+ trackdump = atoi(EARGF(usage()));
756+ break;
666757 }ARGEND
667758
668759 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