shithub: aacenc

Download patch

ref: 167170d01b188e5a6b59cf2e2fb20177417c0d50
parent: df60d269323a7eeb1b98de06ede657fc49a8407f
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Mon Jul 19 12:11:33 EDT 2021

a bit more general version of PES writer

--- a/frontend/aacenc.c
+++ b/frontend/aacenc.c
@@ -24,34 +24,52 @@
 #include <bio.h>
 #include <faac.h>
 
+enum {
+	Taudio = 0xc0,
+	Tvideo = 0xe0,
+};
+
 static int
-pesheader(Biobuf *o, int srate, int nfr, int sz)
+peswrite(Biobuf *o, uvlong ns, int type, u8int *data, int sz)
 {
 	u8int p[] = {
 		0x00, 0x00, 0x01, /* start code */
-		0xc0, /* stream id: audio 0 */
+		type, /* stream id 0 */
 		0, 0, /* packet length */
 		0x00, /* a bunch of nothing */
 		0x80, /* PTS included */
 		5, /* PTS is 5 bytes */
 		0, 0, 0, 0, 0, /* PTS value */
+		0, 0, 0, 0, 0, /* DTS value */
 	};
-	int plen;
+	int plen, psz, dsz;
 	uvlong pts;
 
-	plen = sizeof(p)-6 + sz;
-	assert(plen < 65536);
-	p[4] = plen >> 8;
-	p[5] = plen;
-
-	pts = nfr * 90000ULL / srate;
+	pts = ns / 99999ULL;
 	p[9] = 1<<5 | (pts>>30)<<1 | 1;
 	p[10] = pts>>22;
 	p[11] = pts>>14 | 1;
 	p[12] = pts>>7;
 	p[13] = pts<<1 | 1;
+	psz = sizeof(p)-5;
+	if((type & 0xf0) == Tvideo){
+		psz += 5;
+		p[7] |= 0x40; /* DTS is included */
+		p[8] += 5;
+		memmove(p+14, p+9, 5);
+	}
 
-	return Bwrite(o, p, sizeof(p));
+	for(; sz > 0; sz -= dsz, data += dsz){
+		dsz = 0xffff - (psz-6); /* maximum */
+		dsz = sz <= dsz ? sz : dsz;
+		plen = psz-6 + dsz;
+		p[4] = plen >> 8;
+		p[5] = plen;
+		if(Bwrite(o, p, psz) < 0 || Bwrite(o, data, dsz) < 0)
+			return -1;
+	}
+
+	return 0;
 }
 
 static void
@@ -67,10 +85,10 @@
 	int nch, srate, type, brate, sz, n, r, q, pes, frsz;
 	ulong insamples, outsz, insz;
 	faacEncConfigurationPtr fmt;
+	uvlong mul, div, nfr;
 	faacEncHandle e;
 	s16int *pcm;
 	u8int *obuf;
-	uvlong nfr;
 	Biobuf out;
 	Biobuf in;
 	char *s;
@@ -121,6 +139,14 @@
 	if(Binit(&in, 0, OREAD) != 0 || Binit(&out, 1, OWRITE) != 0)
 		sysfatal("io init failed");
 
+	for(mul = 1000000000ULL, div = srate;;){
+		if((mul % 10) == 0 && (div % 10) == 0){
+			mul /= 10;
+			div /= 10;
+		}else
+			break;
+	}
+
 	setfcr(getfcr() & ~(FPINVAL|FPOVFL));
 
 	if((e = faacEncOpen(srate, nch, &insamples, &outsz)) == nil)
@@ -154,12 +180,11 @@
 		if((sz = faacEncEncode(e, pcm, n/sizeof(*pcm), obuf, outsz)) < 0)
 			sysfatal("faacEncEncode");
 		if(pes){
-			if(pesheader(&out, srate, nfr, sz) < 0)
+			if(peswrite(&out, nfr*mul/div, Taudio, obuf, sz) < 0)
 				break;
 			n = n / sizeof(*pcm) / nch;
 			nfr += n < frsz ? frsz : 0;
-		}
-		if(Bwrite(&out, obuf, sz) < 0)
+		}else if(Bwrite(&out, obuf, sz) < 0)
 			break;
 	}
 	Bflush(&out);