shithub: hj264

Download patch

ref: 1bb6244c718c49c0f7cab1c82e37748c9f1add4f
parent: aa0b72fe651b4241e529889865b47956acaee76b
author: Sigrid Solveig Haflínudóttir <[email protected]>
date: Wed Jul 14 04:44:06 EDT 2021

read image directly, bypassing memimage and header generated by rio

--- a/hj264.c
+++ b/hj264.c
@@ -23,6 +23,7 @@
 typedef struct Hjob Hjob;
 typedef struct Hjthread Hjthread;
 typedef struct Hj264 Hj264;
+typedef struct Img Img;
 
 struct Hjob {
 	void (*run)(void *);
@@ -48,6 +49,12 @@
 	u8int buf[1];
 };
 
+struct Img {
+	int w;
+	int h;
+	u8int bgrx[];
+};
+
 static void
 xrgb2yuv(u8int *bgrx, int w, int h, H264E_io_yuv_t *io)
 {
@@ -265,22 +272,17 @@
 static void
 encthread(void *p)
 {
-	u8int *src, *data;
-	int srcsz, sz;
-	Memimage *im;
+	u8int *data;
+	Img *img;
 	Hj264 *h;
+	int sz;
 
 	h = p;
-	src = nil;
 	for(;;){
-		if((im = recvp(h->frame)) == nil)
+		if((img = 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);
+		xrgb2yuv(img->bgrx, img->w, img->h, &h->yuv);
+		free(img);
 
 		if(hj264_encode(h, &data, &sz) != 0)
 			sysfatal("hj264_encode: %r");
@@ -294,6 +296,26 @@
 	threadexits(nil);
 }
 
+static Img *
+imgread(int f, int w, int h)
+{
+	int r, n, e;
+	Img *i;
+
+	e = w*h*4;
+	i = malloc(sizeof(*i) + e);
+	i->w = w;
+	i->h = h;
+	for(n = 0; n < e; n += r){
+		if((r = pread(f, i->bgrx+n, e-n, n+5*12)) <= 0){
+			free(i);
+			return nil;
+		}
+	}
+
+	return i;
+}
+
 static void
 usage(void)
 {
@@ -308,6 +330,7 @@
 	uvlong start, end, fstart, fend;
 	int ww, hh, in, nframes;
 	Memimage *im;
+	Img *img;
 	Hj264 *h;
 	char *s;
 
@@ -341,6 +364,11 @@
 		usage();
 	}ARGEND
 
+	if(quality > Maxquality)
+		quality = Maxquality;
+	if(kbps < 0)
+		kbps = 0;
+
 	if(argc < 1)
 		usage();
 	if((in = open(*argv, OREAD)) < 0)
@@ -347,42 +375,34 @@
 		sysfatal("input: %r");
 
 	memimageinit();
-	nanosec();
+	if((im = readmemimage(in)) == nil)
+		sysfatal("image: %r");
+	ww = Dx(im->r);
+	hh = Dy(im->r);
+	freememimage(im);
 
-	if(quality > Maxquality)
-		quality = Maxquality;
-	if(kbps < 0)
-		kbps = 0;
+	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 = nil;
+	/* FIXME how about changing these on the fly? */
+	h->rp.encode_speed = Maxquality - quality;
+	h->rp.qp_min = h->rp.qp_max = qp;
+	if(kbps > 0){
+		h->rp.qp_min = 10;
+		h->rp.qp_max = 50;
+		h->rp.desired_frame_bytes = kbps*1000/8/fps;
+	}
+	proccreate(encthread, h, mainstacksize);
+
 	start = nanosec();
 	for(nframes = 0;; nframes++){
 		fstart = nanosec();
-		seek(in, 0, 0);
-		if((im = readmemimage(in)) == nil)
+		if((img = imgread(in, ww, hh)) == nil)
 			break;
-		ww = Dx(im->r);
-		hh = Dy(im->r);
-
-		if(h == nil){
-			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);
-
-			/* FIXME how about changing these on the fly? */
-			h->rp.encode_speed = Maxquality - quality;
-			h->rp.qp_min = h->rp.qp_max = qp;
-			if(kbps > 0){
-				h->rp.qp_min = 10;
-				h->rp.qp_max = 50;
-				h->rp.desired_frame_bytes = kbps*1000/8/fps;
-			}
-			proccreate(encthread, h, mainstacksize);
-		}
-
-		if(sendp(h->frame, im) != 1)
+		if(sendp(h->frame, img) != 1)
 			break;
 		fend = nanosec();