ref: 0ec0e4fde657c442431548180c91018078c2bf3c
dir: /main.c/
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <bio.h>
#include "ivf.h"
#include "flv.h"
#include "rtmp.h"
int mainstacksize = 65536;
static void
usage(void)
{
fprint(2, "usage: %s [-a AUDIO] -v VIDEO [URL]\n", argv0);
threadexitsall("usage");
}
void
threadmain(int argc, char **argv)
{
Biobuf *a, *v, o;
u8int *b, *p, *e;
int bufsz;
u64int ns;
IVFrame f;
IVF ivf;
RTMP *r;
a = nil;
v = nil;
ARGBEGIN{
case 'a':
if((a = Bopen(EARGF(usage()), OREAD)) == nil)
sysfatal("%r");
break;
case 'v':
if((v = Bopen(EARGF(usage()), OREAD)) == nil)
sysfatal("%r");
break;
default:
usage();
}ARGEND
if(argc != 1)
usage();
if(v == nil)
sysfatal("no video specified");
if(ivfopen(v, &ivf) != 0)
sysfatal("%r");
if(strcmp(ivf.type, "AVC1") != 0)
sysfatal("not H.264");
srand(time(nil));
if((r = rtmpdial(argv[0])) < 0 || Binit(&o, fd, OWRITE) < 0)
sysfatal("%r");
bufsz = 65536;
if((b = malloc(bufsz)) == nil)
sysfatal("memory");
e = b + bufsz;
if((p = flvscript(b, e, ivf.w, ivf.h, 0)) == nil || Bwrite(&o, b, p-b) < 0)
sysfatal("%r");
memset(&f, 0, sizeof(f));
for(;;){
if(ivfread(v, &f) != 0)
sysfatal("%r");
if(f.sz == 0)
break;
if(bufsz < f.sz+64){
free(b);
bufsz *= 2;
if((b = malloc(bufsz)) == nil)
sysfatal("memory");
e = b + bufsz;
}
ns = ivfns(&ivf, f.ts);
if((p = flvdata(b, e, ns, ns, f.buf, f.sz, Fvideo, FlHdr)) == nil)
sysfatal("video: flvdata: %r");
if(Bwrite(&o, b, p-b) < 0)
sysfatal("%r");
Bflush(&o);
}
threadexitsall(nil);
}