| @@ -3,6 +3,7 @@ · 2 unmodified lines |
| 3 | 3 | #include <thread.h> |
| 4 | 4 | #include <bio.h> |
| 5 | 5 | #include <libsec.h> |
| 6 | +#include "ivf.h" |
| 6 | 7 | |
| 7 | 8 | enum { |
| 8 | 9 | Port = 1935, |
| @@ -23,21 +24,8 @@ enum { · 14 unmodified lines |
| 23 | 24 | FlHdr = 1<<1, |
| 24 | 25 | |
| 25 | 26 | 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 | | −}; |
| 37 | 27 | |
| 38 | | −struct IVF { |
| 39 | | − u16int w, h; |
| 40 | | − u32int tbdenum, tbnum; |
| 28 | + ChanCtl = 3, |
| 41 | 29 | }; |
| 42 | 30 | |
| 43 | 31 | 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 |
| 252 | 240 | return amfi32(p, e, p-p0); |
| 253 | 241 | } |
| 254 | 242 | |
| 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 | | − |
| 370 | 243 | static int |
| 371 | 244 | handshake(int f, char *path) |
| 372 | 245 | { |
| @@ -450,7 +323,8 @@ threadmain(int argc, char **argv) · 77 unmodified lines |
| 450 | 323 | Biobuf *a, *v, o; |
| 451 | 324 | u8int *b, *p, *e; |
| 452 | 325 | int bufsz, fd; |
| 453 | | − Frame f; |
| 326 | + u64int ns; |
| 327 | + IVFrame f; |
| 454 | 328 | IVF ivf; |
| 455 | 329 | |
| 456 | 330 | a = nil; |
| @@ -474,6 +348,8 @@ threadmain(int argc, char **argv) · 17 unmodified lines |
| 474 | 348 | sysfatal("no video specified"); |
| 475 | 349 | if(ivfopen(v, &ivf) != 0) |
| 476 | 350 | sysfatal("%r"); |
| 351 | + if(strcmp(ivf.type, "AVC1") != 0) |
| 352 | + sysfatal("not H.264"); |
| 477 | 353 | srand(time(nil)); |
| 478 | 354 | if((fd = rtmpdial(argv[0])) < 0 || Binit(&o, fd, OWRITE) < 0) |
| 479 | 355 | sysfatal("%r"); |
| @@ -499,7 +375,8 @@ threadmain(int argc, char **argv) · 19 unmodified lines |
| 499 | 375 | sysfatal("memory"); |
| 500 | 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 | 380 | sysfatal("video: flvdata: %r"); |
| 504 | 381 | if(Bwrite(&o, b, p-b) < 0) |
| 505 | 382 | sysfatal("%r"); |