shithub: rtmp

Download patch

ref: 36986cc948a8f422bed5631bf3582ce5657bcde3
parent: 354c3b1554f91af178c28cf6e34ac1585df5b757
author: Sigrid Solveig Haflínudóttir <[email protected]>
date: Mon Aug 2 15:04:38 EDT 2021

more logic (not working yet)

--- a/amf0.c
+++ b/amf0.c
@@ -168,6 +168,14 @@
 }
 
 u8int *
+a₀data(u8int *p, u8int *e, u8int *d, int sz)
+{
+	atleast("data", sz);
+
+	return (u8int*)memmove(p, d, sz) + sz;
+}
+
+u8int *
 a₀byteget(u8int *p, u8int *e, u8int *byte)
 {
 	atleast("byte", 1);
--- a/amf0.h
+++ b/amf0.h
@@ -41,6 +41,7 @@
 u8int *a₀kvnum(u8int *p, u8int *e, char *name, double v);
 u8int *a₀kvstr(u8int *p, u8int *e, char *name, char *v);
 u8int *a₀kvbool(u8int *p, u8int *e, char *name, int v);
+u8int *a₀data(u8int *p, u8int *e, u8int *d, int sz);
 
 u8int *a₀byteget(u8int *p, u8int *e, u8int *byte);
 u8int *a₀i16get(u8int *p, u8int *e, s16int *i);
--- a/flv.c
+++ /dev/null
@@ -1,86 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include "amf0.h"
-#include "flv.h"
-
-enum {
-	EncH264 = 7,
-	EncAAC = 10,
-};
-
-u8int *
-flvscript(u8int *p, u8int *e, int w, int h, int audio)
-{
-	u8int *psz, *d, *p0;
-	int stream;
-	u32int ts;
-
-	if(p+16 > e){
-		werrstr("buffer short");
-		return nil;
-	}
-
-	/* FIXME ever need to change these? */
-	stream = 0;
-	ts = 0;
-
-	p0 = p;
-	*p++ = Fvideo;
-	psz = p;
-	p = a₀i24(p, e, 0); /* sz set later */
-	p = a₀i24(p, e, ts);
-	*p++ = ts>>24;
-	p = a₀i24(p, e, stream);
-
-	d = p;
-	p = a₀str(p, e, "onMetaData");
-	p = a₀arr(p, e);
-	p = a₀i32(p, e, audio ? 5 : 4);
-	p = a₀kvnum(p, e, "duration", 0.0);
-	p = a₀kvnum(p, e, "width", w);
-	p = a₀kvnum(p, e, "height", h);
-	p = a₀kvnum(p, e, "videocodecid", EncH264);
-	if(audio)
-		p = a₀kvnum(p, e, "audiocodecid", EncAAC);
-	p = a₀end(p, e);
-	a₀i24(psz, e, p-d);
-
-	return a₀i32(p, e, p-p0);
-}
-
-u8int *
-flvdata(u8int *p, u8int *e, u32int pts, u32int dts, void *data, int sz, int type, int fl)
-{
-	u8int *p0, *psz, *d;
-	int stream;
-
-	/* FIXME ever need to change these? */
-	stream = 0;
-
-	assert(type == Faudio || type == Fvideo);
-	p0 = p;
-	*p++ = type;
-	psz = p;
-	p = a₀i24(p, e, 0); /* size to be set later */
-	p = a₀i24(p, e, dts);
-	*p++ = dts >> 24;
-	p = a₀i24(p, e, stream);
-
-	d = p;
-	if(type == Faudio){
-		*p++ = (EncAAC<<4) | 0x0f;
-		*p++ = (fl & FlHdr) ? 0 : 1;
-	}
-	if(type == Fvideo){
-		*p++ = ((fl & FlKey) ? 0x10 : 0x20) | EncH264;
-		*p++ = (fl & FlHdr) ? 0 : 1;
-		pts = ((fl & FlHdr) || pts < dts) ? 0 : (pts - dts);
-		p = a₀i24(p, e, pts);
-		if((fl & FlHdr) == 0)
-			p = a₀i32(p, e, sz);
-	}
-	p = (u8int*)memmove(p, data, sz) + sz;
-	a₀i24(psz, e, p-d);
-
-	return a₀i32(p, e, p-p0);
-}
--- a/flv.h
+++ /dev/null
@@ -1,11 +1,0 @@
-enum {
-	Faudio = 8,
-	Fvideo = 9,
-	Fscript = 18,
-
-	FlKey = 1<<0,
-	FlHdr = 1<<1,
-};
-
-u8int *flvscript(u8int *p, u8int *e, int w, int h, int audio);
-u8int *flvdata(u8int *p, u8int *e, u32int pts, u32int dts, void *data, int sz, int type, int fl);
--- a/main.c
+++ b/main.c
@@ -3,7 +3,6 @@
 #include <thread.h>
 #include <bio.h>
 #include "ivf.h"
-#include "flv.h"
 #include "rtmp.h"
 #include "util.h"
 
@@ -20,10 +19,8 @@
 void
 threadmain(int argc, char **argv)
 {
-	u8int *b, *p, *e;
+	u64int ns, ons;
 	Biobuf *a, *v;
-	int bufsz;
-	u64int ns;
 	IVFrame f;
 	IVF ivf;
 	RTMP *r;
@@ -62,25 +59,19 @@
 
 	if(rtmpstream(r, &sid) == 0){
 		fprint(2, "stream: %lud\n", sid);
-		if(rtmppublish(r, sid, PubLive, "live") == 0)
+		if(rtmppublish(r, sid, PubLive, "live") == 0){
 			fprint(2, "stream published\n");
-		else
+			if(rtmpmeta(r, sid, VcodecH264, 1920, 1080, -1) == 0)
+				fprint(2, "metadata sent\n");
+			else
+				fprint(2, "metadata failed: %r\n");
+		}else
 			fprint(2, "stream publish failed: %r\n");
 	}else{
 		fprint(2, "stream failed\n");
 	}
 
-	while(1)
-		sleep(100);
-	threadexitsall(nil);
-
-	bufsz = 65536;
-	b = emalloc(bufsz);
-	e = b + bufsz;
-
-	if((p = flvscript(b, e, ivf.w, ivf.h, a != nil)) == nil)
-		sysfatal("%r");
-
+	ons = 0;
 	memset(&f, 0, sizeof(f));
 	for(;;){
 		if(ivfread(v, &f) != 0)
@@ -87,15 +78,10 @@
 			sysfatal("%r");
 		if(f.sz == 0)
 			break;
-		if(bufsz < f.sz+64){
-			free(b);
-			bufsz *= 2;
-			b = emalloc(bufsz);
-			e = b + bufsz;
-		}
 		ns = ivfns(&ivf, f.ts);
-		if((p = flvdata(b, e, ns, ns, f.buf, f.sz, Fvideo, FlHdr)) == nil)
+		if(rtmpdata(r, sid, (ns - ons) / 1000000ULL, Tvideo, FlHdr, f.buf, f.sz) != 0)
 			sysfatal("video: flvdata: %r");
+		ons = ns;
 	}
 
 	threadexitsall(nil);
--- a/mkfile
+++ b/mkfile
@@ -5,7 +5,6 @@
 
 HFILES=\
 	amf0.h\
-	flv.h\
 	ivf.h\
 	rtmp.h\
 	util.h\
@@ -12,7 +11,6 @@
 
 OFILES=\
 	amf0.$O\
-	flv.$O\
 	ivf.$O\
 	main.$O\
 	rtmp.$O\
--- a/rtmp.c
+++ b/rtmp.c
@@ -121,6 +121,8 @@
 };
 
 #define putnull() do{ r->o.p = a₀null(r->o.p, r->o.e); }while(0)
+#define putbyte(b) do{ r->o.p = a₀byte(r->o.p, r->o.e, b); }while(0)
+#define putdata(d, sz) do { r->o.p = a₀data(r->o.p, r->o.e, d, sz); }while(0)
 #define puti16(i) do{ r->o.p = a₀i16(r->o.p, r->o.e, i); }while(0)
 #define puti24(i) do{ r->o.p = a₀i24(r->o.p, r->o.e, i); }while(0)
 #define puti32(i) do{ r->o.p = a₀i32(r->o.p, r->o.e, i); }while(0)
@@ -721,6 +723,73 @@
 	}
 
 	return (n == 0 && e == nil) ? 0 : -1;
+}
+
+int
+rtmpmeta(RTMP *r, ulong sid, int vcodec, int w, int h, int acodec)
+{
+	int res;
+
+	assert(vcodec < 0 || vcodec == VcodecH264);
+	assert(acodec < 0 || acodec == AcodecAAC);
+
+	qlock(r);
+
+	newmsg(r, AMF0Metadata, Type0, CSCtl);
+	r->o.msg.sid = sid;
+
+	putstr("onMetaData");
+	putnum(0);
+	putobj();
+	putkvnum("duration", 0.0);
+	if(vcodec >= 0){
+		putkvnum("videocodecid", vcodec);
+		putkvnum("width", w);
+		putkvnum("height", h);
+	}
+	if(acodec >= 0)
+		putkvnum("audiocodecid", acodec);
+	putend();
+
+	res = rtmpsend(r);
+
+	qunlock(r);
+
+	return res;
+}
+
+int
+rtmpdata(RTMP *r, ulong sid, u32int dt, int type, int fl, void *data, int sz)
+{
+	int res;
+
+	assert(type == Taudio || type == Tvideo);
+
+	qlock(r);
+
+	bextend(&r->o, 64 + sz);
+
+	newmsg(r, type == Taudio ? Audio : Video, Type0, CSCtl);
+	r->o.msg.sid = sid;
+
+	if(type == Taudio){
+		putbyte(AcodecAAC<<4 | 0x0f);
+		putbyte((fl & FlHdr) ? 0 : 1);
+	}
+	if(type == Tvideo){
+		putbyte(((fl & FlKey) ? 0x10 : 0x20) | VcodecH264);
+		putbyte((fl & FlHdr) ? 0 : 1);
+		puti24(dt);
+		if((fl & FlHdr) == 0)
+			puti32(sz);
+	}
+	putdata(data, sz);
+
+	res = rtmpsend(r);
+
+	qunlock(r);
+
+	return res;
 }
 
 static void
--- a/rtmp.h
+++ b/rtmp.h
@@ -11,5 +11,20 @@
 };
 int rtmppublish(RTMP *r, ulong sid, int type, char *name);
 
+enum {
+	VcodecH264 = 7,
+	AcodecAAC = 10,
+};
+int rtmpmeta(RTMP *r, ulong sid, int vcodec, int w, int h, int acodec);
+
+enum {
+	Taudio,
+	Tvideo,
+
+	FlKey = 1<<0,
+	FlHdr = 1<<1,
+};
+int rtmpdata(RTMP *r, ulong sid, u32int ts, int type, int fl, void *data, int sz);
+
 RTMP *rtmpdial(char *url);
 void rtmpclose(RTMP *r);