shithub: hj264

Download patch

ref: a3dc6a1a11abd625563c2caa0303c8dde6fcf2f7
parent: 74fed9d1f3ffaa24369691159d758f6c08edd586
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Tue Jul 13 10:37:20 EDT 2021

encode in a separate thread

--- a/hj264.c
+++ b/hj264.c
@@ -38,6 +38,8 @@
 	H264E_scratch_t *scratch;
 	H264E_run_param_t rp;
 	H264E_io_yuv_t yuv;
+	Biobuf out;
+	Channel *frame;
 	Hjthread threads[H264E_MAX_THREADS];
 	Hjob jobs[H264E_MAX_THREADS];
 	int nthreads;
@@ -259,6 +261,38 @@
 }
 
 static void
+encthread(void *p)
+{
+	u8int *src, *data;
+	int srcsz, sz;
+	Memimage *im;
+	Hj264 *h;
+
+	h = p;
+	src = nil;
+	for(;;){
+		if((im = recvp(h->frame)) == nil)
+			break;
+		srcsz = Dy(im->r)*(2+bytesperline(im->r, im->depth));
+		if(src == nil && (src = malloc(srcsz)) == nil)
+			sysfatal("memory");
+		unloadmemimage(im, im->r, src, srcsz);
+		xrgb2yuv(src, Dx(im->r), Dy(im->r), &h->yuv);
+		freememimage(im);
+
+		if(hj264_encode(h, &data, &sz) != 0)
+			sysfatal("hj264_encode: %r");
+		if(Bwrite(&h->out, data, sz) != sz)
+			break;
+	}
+
+	Bflush(&h->out);
+	hj264free(h);
+
+	threadexits(nil);
+}
+
+static void
 usage(void)
 {
 	fprint(2, "usage: %s [-d] [-f FPS] [-n THREADS] [-k KBPS] [-q 0…10] [-Q QP]\n", argv0);
@@ -269,11 +303,9 @@
 main(int argc, char **argv)
 {
 	int nthreads, fps, kbps, denoise, quality, qp;
-	int ww, hh, in, sz, srcsz, nframes;
+	int ww, hh, in, nframes;
 	uvlong start, end;
-	u8int *data, *src;
 	Memimage *im;
-	Biobuf out;
 	Hj264 *h;
 	char *s;
 
@@ -311,8 +343,6 @@
 		usage();
 	if((in = open(*argv, OREAD)) < 0)
 		sysfatal("input: %r");
-	if(Binit(&out, 1, OWRITE) < 0)
-		sysfatal("Binit failed: %r");
 
 	memimageinit();
 	nanosec();
@@ -322,8 +352,6 @@
 	if(kbps < 0)
 		kbps = 0;
 
-	src = nil;
-	srcsz = 0;
 	h = nil;
 	start = nanosec();
 	for(nframes = 0;; nframes++){
@@ -334,13 +362,11 @@
 		hh = Dy(im->r);
 
 		if(h == nil){
-			srcsz = Dy(im->r)*(2+bytesperline(im->r, im->depth));
-			if((src = malloc(srcsz)) == nil)
-				sysfatal("memory");
-			unloadmemimage(im, im->r, src, srcsz);
-
 			if((h = hj264new(nthreads, denoise, kbps, ww, hh)) == nil)
 				sysfatal("hj264new: %r");
+			if(Binit(&h->out, 1, OWRITE) < 0)
+				sysfatal("Binit failed: %r");
+			h->frame = chancreate(sizeof(void*), fps);
 			h->rp.encode_speed = Maxquality - quality;
 			h->rp.qp_min = h->rp.qp_max = qp;
 			if(kbps > 0){
@@ -348,16 +374,11 @@
 				h->rp.qp_max = 50;
 				h->rp.desired_frame_bytes = kbps*1000/8/fps;
 			}
+			proccreate(encthread, h, mainstacksize);
 		}
 
-		unloadmemimage(im, im->r, src, srcsz);
-		xrgb2yuv(src, Dx(im->r), Dy(im->r), &h->yuv);
-		freememimage(im);
+		sendp(h->frame, im);
 
-		if(hj264_encode(h, &data, &sz) != 0)
-			sysfatal("hj264_encode: %r");
-		if(Bwrite(&out, data, sz) != sz)
-			break;
 		if(nanosec() - start > 4000000000ULL)
 			break;
 	}
@@ -364,9 +385,7 @@
 	end = nanosec();
 	fprint(2, "%d fps\n", (int)(nframes / ((end - start)/1000000000ULL)));
 
-	/* FIXME flush on note */
-	Bflush(&out);
-	hj264free(h);
+	chanclose(h->frame);
 
 	threadexitsall(nil);