ref: 60d780e420499ff353979ad938a6b2204a8d1863
parent: 54828ea624dfe47847b4efe66687daa8bb215e03
author: Sigrid Solveig Haflínudóttir <[email protected]>
date: Mon Jul 19 10:55:06 EDT 2021
use IVF by default
--- a/hj264.c
+++ b/hj264.c
@@ -17,6 +17,9 @@
#define align(p,a) (void*)((((uintptr)p - 1) | (a-1)) + 1)
enum {
+ FmtRaw,
+ FmtIVF,
+
Align = 64,
Maxquality = 10,
};
@@ -42,7 +45,9 @@
H264E_scratch_t *scratch;
H264E_run_param_t rp;
H264E_io_yuv_t ioyuv;
+ int w, h;
YUV yuv;
+ int fmt;
Biobuf out;
Channel *frame;
Channel *done;
@@ -187,6 +192,8 @@
h->yuv.v = h->ioyuv.yuv[2]; h->yuv.vs = h->ioyuv.stride[2];
h->persist = align(p+szyuv, Align);
h->scratch = align(h->persist+szpersist, Align);
+ h->w = ww;
+ h->h = hh;
cp.token = h;
cp.run_func_in_thread = hjobsrun;
@@ -224,23 +231,59 @@
static void
encthread(void *p)
{
- u8int *data;
- uvlong ns;
+ u8int *data, v[20];
+ uvlong ts;
Img *img;
Hj264 *h;
int sz;
h = p;
+ if(h->fmt == FmtIVF){
+ enum{
+ Timedenum = 1000ULL,
+ };
+ Bwrite(&h->out, "DKIF\x00\x00\x20\x00AVC1", 12);
+ v[0] = h->w;
+ v[1] = h->w >> 8;
+ v[2] = h->h;
+ v[3] = h->h >> 8;
+ v[4] = Timedenum;
+ v[5] = Timedenum >> 8;
+ v[6] = Timedenum >> 16;
+ v[7] = Timedenum >> 24;
+ v[8] = 1;
+ v[9] = 0;
+ v[10] = 0;
+ v[11] = 0;
+ memset(v+12, 0, 8); /* unknown duration */
+ Bwrite(&h->out, v, sizeof(v));
+ }
+
for(;;){
if((img = recvp(h->frame)) == nil)
break;
xrgb2yuv420(img->bgrx, img->w, img->h, &h->yuv);
- ns = img->ns;
- USED(ns);
+ ts = img->ns / 1000000ULL;
free(img);
if(hj264_encode(h, &data, &sz) != 0)
sysfatal("hj264_encode: %r");
+ if(h->fmt == FmtIVF){
+ v[0] = sz;
+ v[1] = sz >> 8;
+ v[2] = sz >> 16;
+ v[3] = sz >> 24;
+ v[4] = ts;
+ v[5] = ts >> 8;
+ v[6] = ts >> 16;
+ v[7] = ts >> 24;
+ v[8] = ts >> 32;
+ v[9] = ts >> 40;
+ v[10] = ts >> 48;
+ v[11] = ts >> 56;
+ if(Bwrite(&h->out, v, 12) != 12)
+ break;
+ }
if(Bwrite(&h->out, data, sz) != sz)
break;
}
@@ -277,7 +320,7 @@
static void
usage(void)
{
- fprint(2, "usage: %s [-D] [-f FPS] [-g GOP] [-n THREADS] [-k KBPS] [-q 0…10] [-Q QP] FILE\n", argv0);
+ fprint(2, "usage: %s [-D] [-f FPS] [-F FORMAT] [-g GOP] [-n THREADS] [-k KBPS] [-q 0…10] [-Q QP] FILE\n", argv0);
threadexitsall("usage");
}
@@ -307,7 +350,7 @@
int nthreads, fps, kbps, denoise, quality, qp, gop;
char *s, tmp[61], *f[5];
uvlong fstart, fend;
- int ww, hh, in;
+ int ww, hh, in, fmt;
Img *img;
Hj264 *h;
@@ -319,6 +362,7 @@
fps = 30;
qp = 33;
gop = 20;
+ fmt = FmtIVF;
ARGBEGIN{
case 'd':
debug++;
@@ -329,6 +373,15 @@
case 'f':
fps = atoi(EARGF(usage()));
break;
+ case 'F':
+ s = EARGF(usage());
+ if(cistrcmp(s, "ivf") == 0)
+ fmt = FmtIVF;
+ else if(cistrcmp(s, "raw") == 0)
+ fmt = FmtRaw;
+ else
+ sysfatal("unknown format %s", s);
+ break;
case 'g':
gop = atoi(EARGF(usage()));
break;
@@ -378,6 +431,7 @@
sysfatal("Binit failed: %r");
h->frame = chancreate(sizeof(void*), 1); /* FIXME this is wrong as the encoder might be too late */
h->done = chancreate(sizeof(void*), 0);
+ h->fmt = fmt;
/* FIXME how about changing these on the fly? */
h->rp.encode_speed = Maxquality - quality;