ref: 58c648070bfcaa2cfacfccdd2ffec7fe73f7af13
parent: d314994309c751e5a983797760e8386d82ae60eb
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Thu Apr 22 06:23:08 EDT 2021
iso: support nal lengths other than 4
--- a/iso.c
+++ b/iso.c
@@ -567,10 +567,10 @@
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;
@@ -577,6 +577,11 @@
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 @@
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 @@
}
}
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 @@
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 @@
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 @@
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 @@
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 @@
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);