ref: 97b0ebb4108acac122371253a54785ef54281648
parent: 70b1cf8ab9292b471f6414b17895f583bc61ccfc
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sun Jul 16 16:27:39 EDT 2023
extend the image if its size is not modulo 16
--- a/hj264.c
+++ b/hj264.c
@@ -63,7 +63,7 @@
};
static uvlong tstart, debug;
-static int opt;
+static int opt, noenc;
#pragma varargck type "ℏ" int
static int
@@ -169,10 +169,6 @@
return nil;
}
- /* YUV logic requires alignment */
- ww = ((ww-1) | 15) + 1;
- hh = ((hh-1) | 15) + 1;
-
szyuv = ww*hh*3/2;
if((h = calloc(1, sizeof(*h) + Align+szyuv + Align+szpersist + Align+szscratch)) == nil)
return nil;
@@ -253,6 +249,8 @@
free(img);
}
+ if(noenc)
+ continue;
if(hj264_encode(h, &data, &sz) != 0)
sysfatal("hj264_encode: %r");
if(h->fmt == FmtIVF){
@@ -287,15 +285,16 @@
}
static Img *
-imgread(int f, int w, int h)
+imgread(int f, int w, int h, int tw, int th)
{
int r, n, e;
+ u8int *p, *tp;
Img *i;
+ i = malloc(sizeof(*i) + tw*th*4);
+ i->w = tw;
+ i->h = th;
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);
@@ -303,6 +302,15 @@
}
}
i->ns = tstart + npe_nanosec();
+ if(tw > w){
+ p = i->bgrx + w*h*4;
+ tp = i->bgrx + tw*h*4;
+ for(n = h-1; n > 0; n--){
+ p -= w*4;
+ tp -= tw*4;
+ memmove(tp, p, w*4);
+ }
+ }
return i;
}
@@ -320,7 +328,7 @@
int nthreads, fps, kbps, denoise, quality, qp, gop;
uvlong fstart, fend, f₀, nframes;
char *s, tmp[61], *f[5];
- int ww, hh, in, fmt;
+ int ww₀, hh₀, ww, hh, in, fmt;
u8int v[20];
Img *img;
Hj264 *h;
@@ -341,6 +349,9 @@
case 'D':
denoise++;
break;
+ case 'E':
+ noenc++;
+ break;
case 'f':
fps = atoi(EARGF(usage()));
break;
@@ -394,9 +405,13 @@
sysfatal("invalid image");
if(strcmp(f[0]+1, "8r8g8b8") != 0)
sysfatal("only [ax]8r8g8b8 is supported");
- ww = atoi(f[3]) - atoi(f[1]);
- hh = atoi(f[4]) - atoi(f[2]);
+ ww₀ = atoi(f[3]) - atoi(f[1]);
+ hh₀ = atoi(f[4]) - atoi(f[2]);
+ /* YUV logic requires alignment */
+ ww = ((ww₀-1) | 15) + 1;
+ hh = ((hh₀-1) | 15) + 1;
+
if((h = hj264new(nthreads, denoise, kbps, gop, ww, hh)) == nil)
sysfatal("hj264new: %r");
if(Binit(&h->out, 1, OWRITE) < 0)
@@ -417,10 +432,10 @@
if(h->fmt == FmtIVF){
Bwrite(&h->out, "DKIF\x00\x00\x20\x00AVC1", 12);
- v[0] = ww;
- v[1] = ww >> 8;
- v[2] = hh;
- v[3] = hh >> 8;
+ v[0] = ww₀;
+ v[1] = ww₀ >> 8;
+ v[2] = hh₀;
+ v[3] = hh₀ >> 8;
v[4] = TimedenumIVF;
v[5] = TimedenumIVF >> 8;
v[6] = TimedenumIVF >> 16;
@@ -439,7 +454,7 @@
tstart = nsec() - f₀;
for(nframes = 0;; nframes++){
fstart = npe_nanosec();
- if((img = imgread(in, ww, hh)) == nil)
+ if((img = imgread(in, ww₀, hh₀, ww, hh)) == nil)
break;
if(sendp(h->frame, img) != 1)
break;
--- a/minih264e.h
+++ b/minih264e.h
@@ -11050,7 +11050,6 @@
{
return H264E_STATUS_SIZE_NOT_MULTIPLE_2; // frame size must be multiple of 2
}
-/*
if (((par->width | par->height) & 15) && !par->const_input_flag)
{
// if input buffer reused as scratch (par->const_input_flag == 0)
@@ -11057,7 +11056,6 @@
// frame size must be multiple of 16
return H264E_STATUS_SIZE_NOT_MULTIPLE_16;
}
-*/
return H264E_STATUS_SUCCESS;
};