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