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);