shithub: hj264

Download patch

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;