History

split ivf logic out

Sigrid Solveig Haflínudóttir committed 5 years ago

Commit 3168be11 parent 74213ea4 files · +156 −131Browse files

Unified · Split

4 files
  1. ivf.c +123 −0
  2. ivf.h +21 −0
  3. mkfile +4 −0
  4. rtmp.c +8 −131
ivf.c+123−0
@@ -0,0 +1,123 @@
1+#include <u.h>
2+#include <libc.h>
3+#include <bio.h>
4+#include "ivf.h"
5+
6+static int
7+Bu16le(Biobuf *b, u16int *o)
8+{
9+ int x;
10+
11+ x = Bgetc(b);
12+ x |= Bgetc(b)<<8;
13+ *o = x;
14+ if(x < 0)
15+ werrstr("failed to read 2 bytes");
16+
17+ return x < 0 ? -1 : 0;
18+}
19+
20+static int
21+Bu32le(Biobuf *b, u32int *o)
22+{
23+ int x, i;
24+
25+ *o = 0;
26+ for(i = 0; i < 4; *o |= x<<(i*8), i++){
27+ if((x = Bgetc(b)) < 0){
28+ werrstr("failed to read 4 bytes");
29+ return -1;
30+ }
31+ }
32+
33+ return 0;
34+}
35+
36+static int
37+Bu64le(Biobuf *b, u64int *o)
38+{
39+ int x, i;
40+
41+ *o = 0;
42+ for(i = 0; i < 8; *o |= x<<(i*8), i++){
43+ if((x = Bgetc(b)) < 0){
44+ werrstr("failed to read 8 bytes");
45+ return -1;
46+ }
47+ }
48+
49+ return 0;
50+}
51+
52+int
53+ivfopen(Biobuf *v, IVF *ivf)
54+{
55+ u16int hlen;
56+ u8int b[6];
57+
58+ if(Bread(v, b, 6) != 6 || Bu16le(v, &hlen) < 0 ||
59+ hlen < 0x20 || memcmp(b, "DKIF", 4) != 0 ||
60+ Bread(v, b, 4) != 4){
61+ werrstr("invalid header");
62+ goto err;
63+ }
64+ memmove(ivf->type, b, 4);
65+ ivf->type[4] = 0;
66+ if(Bu16le(v, &ivf->w) < 0 ||
67+ Bu16le(v, &ivf->h) < 0 ||
68+ Bu32le(v, &ivf->tbdenum) < 0 ||
69+ Bu32le(v, &ivf->tbnum) < 0){
70+ werrstr("invalid data");
71+ goto err;
72+ }
73+ if(Bseek(v, hlen, 0) != hlen){
74+ werrstr("broken stream");
75+ goto err;
76+ }
77+
78+ return 0;
79+err:
80+ werrstr("ivfopen: %r");
81+ return -1;
82+}
83+
84+int
85+ivfread(Biobuf *v, IVFrame *f)
86+{
87+ u8int *buf;
88+ u64int ts;
89+ u32int sz;
90+ int n;
91+
92+ if(Bu32le(v, &sz) < 0 || Bu64le(v, &ts) < 0 || (int)sz < 0){
93+ /* eof */
94+ f->sz = 0;
95+ return 0;
96+ }
97+ buf = f->buf;
98+ if(sz > f->bufsz){
99+ if((buf = realloc(f->buf, sz)) == nil){
100+ werrstr("frame is too big: %d bytes", sz);
101+ goto err;
102+ }
103+ f->buf = buf;
104+ }
105+ if((n = Bread(v, buf, sz)) != sz){
106+ werrstr("short read (%d < %d)", n, sz);
107+ goto err;
108+ }
109+ f->buf = buf;
110+ f->sz = sz;
111+ f->ts = ts;
112+
113+ return 0;
114+err:
115+ werrstr("ivfread: %r");
116+ return -1;
117+}
118+
119+u64int
120+ivfns(IVF *ivf, u64int ts)
121+{
122+ return ts * ivf->tbnum * 1000000000ULL / ivf->tbdenum;
123+}
ivf.h+21−0
@@ -0,0 +1,21 @@
1+typedef struct IVF IVF;
2+typedef struct IVFrame IVFrame;
3+
4+struct IVF {
5+ u32int tbdenum;
6+ u32int tbnum;
7+ u16int w;
8+ u16int h;
9+ char type[6];
10+};
11+
12+struct IVFrame {
13+ u64int ts;
14+ u8int *buf;
15+ int bufsz;
16+ int sz;
17+};
18+
19+int ivfopen(Biobuf *v, IVF *ivf);
20+int ivfread(Biobuf *v, IVFrame *f);
21+u64int ivfns(IVF *ivf, u64int ts);
mkfile+4−0
@@ -3,7 +3,11 @@ · 2 unmodified lines
33 BIN=/$objtype/bin/video
44 TARG=rtmp
55
6+HFILES=\
7+ ivf.h\
8+
69 OFILES=\
10+ ivf.$O\
711 rtmp.$O\
812
913 default:V: all
rtmp.c+8−131
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 #include <thread.h>
44 #include <bio.h>
55 #include <libsec.h>
6+#include "ivf.h"
67
78 enum {
89 Port = 1935,
@@ -23,21 +24,8 @@ enum { · 14 unmodified lines
2324 FlHdr = 1<<1,
2425
2526 Sigsz = 1536,
26−};
27−
28−typedef struct Frame Frame;
29−typedef struct IVF IVF;
30−
31−struct Frame {
32− u64int ts;
33− u8int *buf;
34− int bufsz;
35− int sz;
36−};
3727
38−struct IVF {
39− u16int w, h;
40− u32int tbdenum, tbnum;
28+ ChanCtl = 3,
4129 };
4230
4331 int mainstacksize = 65536;
@@ -252,121 +240,6 @@ flvdata(u8int *p, u8int *e, u32int pts, u32int dts, void *data, int sz, int type · 208 unmodified lines
252240 return amfi32(p, e, p-p0);
253241 }
254242
255−static int
256−Bu16le(Biobuf *b, u16int *o)
257−{
258− int x;
259−
260− x = Bgetc(b);
261− x |= Bgetc(b)<<8;
262− *o = x;
263− if(x < 0)
264− werrstr("failed to read 2 bytes");
265−
266− return x < 0 ? -1 : 0;
267−}
268−
269−static int
270−Bu32le(Biobuf *b, u32int *o)
271−{
272− int x, i;
273−
274− *o = 0;
275− for(i = 0; i < 4; *o |= x<<(i*8), i++){
276− if((x = Bgetc(b)) < 0){
277− werrstr("failed to read 4 bytes");
278− return -1;
279− }
280− }
281−
282− return 0;
283−}
284−
285−static int
286−Bu64le(Biobuf *b, u64int *o)
287−{
288− int x, i;
289−
290− *o = 0;
291− for(i = 0; i < 8; *o |= x<<(i*8), i++){
292− if((x = Bgetc(b)) < 0){
293− werrstr("failed to read 8 bytes");
294− return -1;
295− }
296− }
297−
298− return 0;
299−}
300−
301−static int
302−ivfopen(Biobuf *v, IVF *o)
303−{
304− u16int hlen;
305− u8int b[6];
306−
307− if(Bread(v, b, 6) != 6 || Bu16le(v, &hlen) < 0 ||
308− hlen < 0x20 || memcmp(b, "DKIF", 4) != 0 ||
309− Bread(v, b, 4) != 4){
310− werrstr("invalid header");
311− goto err;
312− }
313− if(memcmp(b, "AVC1", 4) != 0){
314− werrstr("not H.264");
315− goto err;
316− }
317− if(Bu16le(v, &o->w) < 0 ||
318− Bu16le(v, &o->h) < 0 ||
319− Bu32le(v, &o->tbdenum) < 0 ||
320− Bu32le(v, &o->tbnum) < 0){
321− werrstr("invalid data");
322− goto err;
323− }
324− if(Bseek(v, hlen, 0) != hlen){
325− werrstr("broken stream");
326− goto err;
327− }
328−
329− return 0;
330−err:
331− werrstr("ivf: %r");
332− return -1;
333−}
334−
335−static int
336−ivfread(Biobuf *v, Frame *f)
337−{
338− u8int *buf;
339− u64int ts;
340− u32int sz;
341− int n;
342−
343− if(Bu32le(v, &sz) < 0 || Bu64le(v, &ts) < 0 || (int)sz < 0){
344− /* eof */
345− f->sz = 0;
346− return 0;
347− }
348− buf = f->buf;
349− if(sz > f->bufsz){
350− if((buf = realloc(f->buf, sz)) == nil){
351− werrstr("frame is too big: %d bytes", sz);
352− goto err;
353− }
354− f->buf = buf;
355− }
356− if((n = Bread(v, buf, sz)) != sz){
357− werrstr("short read (%d < %d)", n, sz);
358− goto err;
359− }
360− f->buf = buf;
361− f->sz = sz;
362− f->ts = ts;
363−
364− return 0;
365−err:
366− werrstr("ivf: %r");
367− return -1;
368−}
369−
370243 static int
371244 handshake(int f, char *path)
372245 {
@@ -450,7 +323,8 @@ threadmain(int argc, char **argv) · 77 unmodified lines
450323 Biobuf *a, *v, o;
451324 u8int *b, *p, *e;
452325 int bufsz, fd;
453− Frame f;
326+ u64int ns;
327+ IVFrame f;
454328 IVF ivf;
455329
456330 a = nil;
@@ -474,6 +348,8 @@ threadmain(int argc, char **argv) · 17 unmodified lines
474348 sysfatal("no video specified");
475349 if(ivfopen(v, &ivf) != 0)
476350 sysfatal("%r");
351+ if(strcmp(ivf.type, "AVC1") != 0)
352+ sysfatal("not H.264");
477353 srand(time(nil));
478354 if((fd = rtmpdial(argv[0])) < 0 || Binit(&o, fd, OWRITE) < 0)
479355 sysfatal("%r");
@@ -499,7 +375,8 @@ threadmain(int argc, char **argv) · 19 unmodified lines
499375 sysfatal("memory");
500376 e = b + bufsz;
501377 }
502− if((p = flvdata(b, e, f.ts, f.ts, f.buf, f.sz, Fvideo, FlHdr)) == nil)
378+ ns = ivfns(&ivf, f.ts);
379+ if((p = flvdata(b, e, ns, ns, f.buf, f.sz, Fvideo, FlHdr)) == nil)
503380 sysfatal("video: flvdata: %r");
504381 if(Bwrite(&o, b, p-b) < 0)
505382 sysfatal("%r");

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t