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
6static int
7Bu16le(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
20static int
21Bu32le(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
36static int
37Bu64le(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
52int
53ivfopen(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;
79err:
80 werrstr("ivfopen: %r");
81 return -1;
82}
83
84int
85ivfread(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;
114err:
115 werrstr("ivfread: %r");
116 return -1;
117}
118
119u64int
120ivfns(IVF *ivf, u64int ts)
121{
122 return ts * ivf->tbnum * 1000000000ULL / ivf->tbdenum;
123}
ivf.h+21−0
@@ -0,0 +1,21 @@
1typedef struct IVF IVF;
2typedef struct IVFrame IVFrame;
3
4struct IVF {
5 u32int tbdenum;
6 u32int tbnum;
7 u16int w;
8 u16int h;
9 char type[6];
10};
11
12struct IVFrame {
13 u64int ts;
14 u8int *buf;
15 int bufsz;
16 int sz;
17};
18
19int ivfopen(Biobuf *v, IVF *ivf);
20int ivfread(Biobuf *v, IVFrame *f);
21u64int ivfns(IVF *ivf, u64int ts);
mkfile+4−0
@@ -3,7 +3,11 @@ · 2 unmodified lines
3BIN=/$objtype/bin/video3BIN=/$objtype/bin/video
4TARG=rtmp4TARG=rtmp
5 5
6HFILES=\
7 ivf.h\
8
6OFILES=\9OFILES=\
10 ivf.$O\
7 rtmp.$O\11 rtmp.$O\
8 12
9default:V: all13default:V: all
rtmp.c+8−131
@@ -3,6 +3,7 @@ · 2 unmodified lines
3#include <thread.h>3#include <thread.h>
4#include <bio.h>4#include <bio.h>
5#include <libsec.h>5#include <libsec.h>
6#include "ivf.h"
6 7
7enum {8enum {
8 Port = 1935,9 Port = 1935,
@@ -23,21 +24,8 @@ enum { · 14 unmodified lines
23 FlHdr = 1<<1,24 FlHdr = 1<<1,
24 25
25 Sigsz = 1536,26 Sigsz = 1536,
26};
27
28typedef struct Frame Frame;
29typedef struct IVF IVF;
30
31struct Frame {
32 u64int ts;
33 u8int *buf;
34 int bufsz;
35 int sz;
36};
37 27
38struct IVF {28 ChanCtl = 3,
39 u16int w, h;
40 u32int tbdenum, tbnum;
41};29};
42 30
43int mainstacksize = 65536;31int mainstacksize = 65536;
@@ -252,121 +240,6 @@ flvdata(u8int *p, u8int *e, u32int pts, u32int dts, void *data, int sz, int type · 208 unmodified lines
252 return amfi32(p, e, p-p0);240 return amfi32(p, e, p-p0);
253}241}
254 242
255static int
256Bu16le(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
269static int
270Bu32le(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
285static int
286Bu64le(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
301static int
302ivfopen(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;
330err:
331 werrstr("ivf: %r");
332 return -1;
333}
334
335static int
336ivfread(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;
365err:
366 werrstr("ivf: %r");
367 return -1;
368}
369
370static int243static int
371handshake(int f, char *path)244handshake(int f, char *path)
372{245{
@@ -450,7 +323,8 @@ threadmain(int argc, char **argv) · 77 unmodified lines
450 Biobuf *a, *v, o;323 Biobuf *a, *v, o;
451 u8int *b, *p, *e;324 u8int *b, *p, *e;
452 int bufsz, fd;325 int bufsz, fd;
453 Frame f;326 u64int ns;
327 IVFrame f;
454 IVF ivf;328 IVF ivf;
455 329
456 a = nil;330 a = nil;
@@ -474,6 +348,8 @@ threadmain(int argc, char **argv) · 17 unmodified lines
474 sysfatal("no video specified");348 sysfatal("no video specified");
475 if(ivfopen(v, &ivf) != 0)349 if(ivfopen(v, &ivf) != 0)
476 sysfatal("%r");350 sysfatal("%r");
351 if(strcmp(ivf.type, "AVC1") != 0)
352 sysfatal("not H.264");
477 srand(time(nil));353 srand(time(nil));
478 if((fd = rtmpdial(argv[0])) < 0 || Binit(&o, fd, OWRITE) < 0)354 if((fd = rtmpdial(argv[0])) < 0 || Binit(&o, fd, OWRITE) < 0)
479 sysfatal("%r");355 sysfatal("%r");
@@ -499,7 +375,8 @@ threadmain(int argc, char **argv) · 19 unmodified lines
499 sysfatal("memory");375 sysfatal("memory");
500 e = b + bufsz;376 e = b + bufsz;
501 }377 }
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)
503 sysfatal("video: flvdata: %r");380 sysfatal("video: flvdata: %r");
504 if(Bwrite(&o, b, p-b) < 0)381 if(Bwrite(&o, b, p-b) < 0)
505 sysfatal("%r");382 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