@@ 567,16 567,21 @@ static int
dumpstc(Biobuf *f, Biobuf *out, Track *t, u8int *frame)
{
SampleToChunk *stc;
- u32int si, ch, nextch, n, len;
+ u32int si, ch, nextch, n, k, len, sz;
u32int samplelast, sample, rawsz, samplesz;
u64int ts;
- u8int *raw;
+ u8int *raw, h[4];
raw = nil;
rawsz = 0;
sample = samplelast = 0;
stc = t->stc;
ch = 0;
+ k = t->video.avc.nallen;
+ h[0] = 0;
+ h[1] = 0;
+ h[2] = 0;
+ h[3] = 1;
for(si = 0; si < t->numstc; si++, stc++){
nextch = t->numchunks;
if(si+1 < t->numstc)
@@ 613,11 618,21 @@ dumpstc(Biobuf *f, Biobuf *out, Track *t, u8int *frame)
break;
}
}else if(t->video.format != 0){ /* all video goes out as IVF */
+ if(t->video.format == FmtAvc1){
+ for(sz = 0, n = 0; n < samplesz; n += k+len){
+ len = raw[n+0];
+ if(k > 1) len = len<<8 | raw[n+1];
+ if(k > 2) len = len<<8 | raw[n+2];
+ if(k > 3) len = len<<8 | raw[n+3];
+ sz += 4+len;
+ }
+ }else
+ sz = samplesz;
ts = tts(t, sample);
- frame[0] = samplesz;
- frame[1] = samplesz >> 8;
- frame[2] = samplesz >> 16;
- frame[3] = samplesz >> 24;
+ frame[0] = sz;
+ frame[1] = sz >> 8;
+ frame[2] = sz >> 16;
+ frame[3] = sz >> 24;
frame[4] = ts;
frame[5] = ts >> 8;
frame[6] = ts >> 16;
@@ 632,15 647,15 @@ dumpstc(Biobuf *f, Biobuf *out, Track *t, u8int *frame)
}
}
if(t->video.format == FmtAvc1){
- for(n = 0; n < samplesz; n += len+4){
- len = raw[n+0]<<24 | raw[n+1]<<16 | raw[n+2]<<8 | raw[n+3];
- raw[n+0] = 0;
- raw[n+1] = 0;
- raw[n+2] = 0;
- raw[n+3] = 1;
+ for(n = 0; n < samplesz; n += k+len){
+ len = raw[n+0];
+ if(k > 1) len = len<<8 | raw[n+1];
+ if(k > 2) len = len<<8 | raw[n+2];
+ if(k > 3) len = len<<8 | raw[n+3];
+ Bwrite(out, h, 4);
+ Bwrite(out, raw+n+k, len);
}
- }
- if(Bwrite(out, raw, samplesz) != samplesz){ /* EOF? */
+ }else if(Bwrite(out, raw, samplesz) != samplesz){ /* EOF? */
werrstr("eof");
break;
}
@@ 656,9 671,9 @@ dumpstc(Biobuf *f, Biobuf *out, Track *t, u8int *frame)
static int
dumptrun(Biobuf *f, Biobuf *out, Track *t, u8int *frame)
{
- int i, j, len, n;
+ int i, j, len, n, k;
u64int ts;
- u8int *raw;
+ u8int *raw, h[4];
int maxsz, sz;
RunSample *s;
Moof *m;
@@ 668,6 683,11 @@ dumptrun(Biobuf *f, Biobuf *out, Track *t, u8int *frame)
ts = 0;
maxsz = 0;
raw = nil;
+ k = t->video.avc.nallen;
+ h[0] = 0;
+ h[1] = 0;
+ h[2] = 0;
+ h[3] = 1;
for(i = 0, m = t->moof; i < t->nmoof; i++, m++){
for(j = 0; j < m->trun.trun.samplecount; j++){
s = &m->trun.trun.samples[j];
@@ 717,15 737,27 @@ dumptrun(Biobuf *f, Biobuf *out, Track *t, u8int *frame)
return -1;
}
if(t->video.format == FmtAvc1){
- for(n = 12; n < 12+s->size; n += len+4){
- len = raw[n+0]<<24 | raw[n+1]<<16 | raw[n+2]<<8 | raw[n+3];
- raw[n+0] = 0;
- raw[n+1] = 0;
- raw[n+2] = 0;
- raw[n+3] = 1;
+ for(sz = 0, n = 12; n < 12+s->size; n += len+k){
+ len = raw[n+0];
+ if(k > 1) len = len<<8 | raw[n+1];
+ if(k > 2) len = len<<8 | raw[n+2];
+ if(k > 3) len = len<<8 | raw[n+3];
+ sz += 4+len;
}
- }
- if(Bwrite(out, raw, 12 + s->size) != 12 + s->size) /* eof? */
+ raw[0] = sz;
+ raw[1] = sz >> 8;
+ raw[2] = sz >> 16;
+ raw[3] = sz >> 24;
+ Bwrite(out, raw, 12);
+ for(n = 12; n < 12+s->size; n += len+k){
+ len = raw[n+0];
+ if(k > 1) len = len<<8 | raw[n+1];
+ if(k > 2) len = len<<8 | raw[n+2];
+ if(k > 3) len = len<<8 | raw[n+3];
+ Bwrite(out, h, 4);
+ Bwrite(out, raw+n+k, len);
+ }
+ }else if(Bwrite(out, raw, 12 + s->size) != 12 + s->size) /* eof? */
break;
ts += s->duration; /* sample's "time offset" is ignored here */
}else{
@@ 740,7 772,7 @@ dumptrun(Biobuf *f, Biobuf *out, Track *t, u8int *frame)
static int
dumptrack(Biobuf *f, int id)
{
- int i, j, x, res;
+ int i, j, x, k, res;
Biobuf out;
u64int dur;
Track *t;
@@ 832,8 864,8 @@ dumptrack(Biobuf *f, int id)
Bwrite(&out, frame, 0x20);
if(t->video.format == FmtAvc1){
- if(t->video.avc.nallen != 4){
- werrstr("avc1 nallen != 4 isn't supported yet");
+ if(t->video.avc.nallen < 1 || t->video.avc.nallen > 4){
+ werrstr("avc1: invalid nallen %d", t->video.avc.nallen);
return -1;
}
memset(frame, 0, 4+8+4);