ref: 36986cc948a8f422bed5631bf3582ce5657bcde3
parent: 354c3b1554f91af178c28cf6e34ac1585df5b757
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
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);