shithub: rtmp

Download patch

ref: 0afdf9bd00bd96f9af81eeecd9a158a059bd7f81
parent: b93aad5650ddf5cd776a0e7c827eaeae750b251c
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Fri Aug 6 07:53:59 EDT 2021

fix audio timestamps

--- a/adts.c
+++ b/adts.c
@@ -4,10 +4,30 @@
 #include "adts.h"
 #include "util.h"
 
+static int ratecfg[] = {
+	96000,
+	88200,
+	64000,
+	48000,
+	44100,
+	32000,
+	24000,
+	22050,
+	16000,
+	12000,
+	11025,
+	8000,
+	7350,
+	-1,
+	-1,
+	-1,
+};
+
 int
 adtsread(Biobuf *b, ADTSFrame *f)
 {
 	u8int h[7];
+	int ratei;
 
 	if(Bread(b, h, 7) != 7)
 		goto err;
@@ -29,6 +49,10 @@
 	memmove(f->buf, h, 7);
 	if(Bread(b, f->buf+7, f->sz-7) != f->sz-7)
 		goto err;
+
+	ratei = (h[2]>>2) & 7;
+
+	f->ns += 1000000000ULL * 1024ULL / ratecfg[ratei];
 
 	return 0;
 
--- a/adts.h
+++ b/adts.h
@@ -1,6 +1,7 @@
 typedef struct ADTSFrame ADTSFrame;
 
 struct ADTSFrame {
+	uvlong ns;
 	u8int *buf;
 	int bufsz;
 	int sz;
--- a/main.c
+++ b/main.c
@@ -20,10 +20,10 @@
 void
 threadmain(int argc, char **argv)
 {
+	u64int ms, until;
 	Biobuf *a, v;
 	ADTSFrame af;
 	IVFrame vf;
-	u64int ns;
 	ulong sid;
 	IVF ivf;
 	RTMP *r;
@@ -65,8 +65,8 @@
 			sysfatal("%r");
 		if(vf.sz == 0)
 			break;
-		ns = ivfns(&ivf, vf.ts)/1000000ULL;
-		if(rtmpdata(r, sid, ns, Tvideo, vf.buf, vf.sz) != 0){
+		ms = ivfns(&ivf, vf.ts)/1000000ULL;
+		if(rtmpdata(r, sid, ms, Tvideo, vf.buf, vf.sz) != 0){
 			fprint(2, "%r\n");
 			break;
 		}
@@ -74,14 +74,18 @@
 		/* FIXME obviously this has to run in a separate frame (same for video, actually) */
 		if(a == nil)
 			continue;
-		if(adtsread(a, &af) != 0)
-			sysfatal("%r");
-		if(af.sz == 0)
-			break;
-		if(rtmpdata(r, sid, ns, Taudio, af.buf, af.sz) != 0){
-			fprint(2, "%r\n");
-			break;
-		}
+		until = ms + 250; /* provide audio enough to cover + 250 ms over video */
+		do{
+			if(adtsread(a, &af) != 0)
+				sysfatal("%r");
+			if(af.sz == 0)
+				break;
+			ms = af.ns/1000000ULL;
+			if(rtmpdata(r, sid, ms, Taudio, af.buf, af.sz) != 0){
+				fprint(2, "%r\n");
+				break;
+			}
+		}while(ms < until);
 	}
 
 	if(a != nil)