pass in input resolution
This commit is contained in:
+1
-1
@@ -25,7 +25,7 @@ build:
|
|||||||
|
|
||||||
.PHONY: run
|
.PHONY: run
|
||||||
run: build
|
run: build
|
||||||
./build/$(TARGET) $(TEST_ARGS) --monitor-only --internal-size=480 --hot-reload
|
./build/$(TARGET) $(TEST_ARGS) --monitor-only --internal-size=240 --hot-reload
|
||||||
|
|
||||||
.PHONY: demo
|
.PHONY: demo
|
||||||
demo: build
|
demo: build
|
||||||
|
|||||||
@@ -134,11 +134,12 @@ make -f Makefile.dev release-arch
|
|||||||
- [ ] Clean code and fix things
|
- [ ] Clean code and fix things
|
||||||
- [ ] Video input
|
- [ ] Video input
|
||||||
- [x] Fixed camera video
|
- [x] Fixed camera video
|
||||||
- [ ] Pass video info to shaders
|
- [x] Pass video info to shaders
|
||||||
- [x] Sub process video reading
|
- [x] Sub process video reading
|
||||||
- [x] Shader based format mapping
|
- [x] Shader based format mapping
|
||||||
- [x] Video mapping config file
|
- [x] Video mapping config file
|
||||||
- [x] Get first video size matching internal size
|
- [x] Get first video size matching internal size
|
||||||
|
- [ ] other internal size for video
|
||||||
- [ ] Clean code and fix things
|
- [ ] Clean code and fix things
|
||||||
- [x] Monitor screen
|
- [x] Monitor screen
|
||||||
- [x] 2nd window
|
- [x] 2nd window
|
||||||
|
|||||||
+16
-7
@@ -798,15 +798,15 @@ float write_20(vec2 uv, vec2 pos, int str[20])
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
float write_int(vec2 uv, vec2 pos, int value, int magnitude)
|
float write_int(vec2 uv, vec2 pos, uint value, uint magnitude)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int m = 1;
|
uint m = 1;
|
||||||
float d = 0;
|
float d = 0;
|
||||||
for (i = 0; i < magnitude; i++) {
|
for (i = 0; i < magnitude; i++) {
|
||||||
if (i == 0 || value >= m) {
|
if (i == 0 || value >= m) {
|
||||||
d += char_at(uv, pos + vec2(magnitude - i - 1, 0), int(0x30 + (value % (m * 10)) / m));
|
d += char_at(uv, pos + vec2(magnitude - i - 1, 0), int(0x30 + (value % (m * 10u)) / m));
|
||||||
m *= 10;
|
m *= 10u;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
@@ -1924,15 +1924,24 @@ subroutine(mix_stage_sub) vec4 mix_16(vec2 vUV, sampler2D ta, sampler2D tb, int
|
|||||||
|
|
||||||
const mat3x3 yuv_to_rgb = {{1,1,1},{0,-0.39465,2.03211},{1.13983,-0.5806,0}};
|
const mat3x3 yuv_to_rgb = {{1,1,1},{0,-0.39465,2.03211},{1.13983,-0.5806,0}};
|
||||||
|
|
||||||
|
const float YUYV_FOURCC = 1448695129.0;
|
||||||
|
|
||||||
vec4 yuyvTex(sampler2D tex, vec2 vUV, int base_width) {
|
vec4 yuyvTex(sampler2D tex, vec2 vUV, int base_width) {
|
||||||
float w = base_width - 1;
|
float w = base_width - 1;
|
||||||
|
|
||||||
int x = int(vUV.x * w);
|
int x = int(vUV.x * w);
|
||||||
|
|
||||||
int xU = x - x % 2;
|
int xU = x - x % 2;
|
||||||
int xV = x - x % 2 + 1;
|
int xV = x - x % 2 + 1;
|
||||||
|
|
||||||
|
vec4 tU = texture(tex, vec2(xU / w, 1 - vUV.y));
|
||||||
|
vec4 tV = texture(tex, vec2(xV / w, 1 - vUV.y));
|
||||||
|
|
||||||
vec3 yuv = vec3(
|
vec3 yuv = vec3(
|
||||||
texture(tex, vec2(vUV.x, 1 - vUV.y)).x,
|
x % 2 == 0 ? tU.x : tV.x,
|
||||||
texture(tex, vec2(xU / w, 1 - vUV.y)).y - 0.5,
|
tU.y - 0.5,
|
||||||
texture(tex, vec2(xV / w, 1 - vUV.y)).y - 0.5
|
tV.y - 0.5
|
||||||
);
|
);
|
||||||
|
|
||||||
return vec4(yuv_to_rgb * yuv, 1.0);
|
return vec4(yuv_to_rgb * yuv, 1.0);
|
||||||
}
|
}
|
||||||
+7
-1
@@ -6,6 +6,12 @@
|
|||||||
in vec2 vUV;
|
in vec2 vUV;
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
uniform vec3 iInputResolution1;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
fragColor = yuyvTex(tex1, vUV, 848); // TODO uniform
|
if (iInputResolution1.z == YUYV_FOURCC) {
|
||||||
|
fragColor = yuyvTex(tex1, vUV, int(iInputResolution1.x));
|
||||||
|
} else {
|
||||||
|
fragColor = vec4(0, 0, 0, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+7
-1
@@ -6,6 +6,12 @@
|
|||||||
in vec2 vUV;
|
in vec2 vUV;
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
uniform vec3 iInputResolution2;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
fragColor = yuyvTex(tex2, vUV, 320); // TODO uniform
|
if (iInputResolution2.z == YUYV_FOURCC) {
|
||||||
|
fragColor = yuyvTex(tex2, vUV, int(iInputResolution2.x));
|
||||||
|
} else {
|
||||||
|
fragColor = vec4(0, 0, 0, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+21
-6
@@ -61,12 +61,8 @@ static void init_context(Parameters params) {
|
|||||||
context.demo = params.demo;
|
context.demo = params.demo;
|
||||||
context.monitor = params.monitor;
|
context.monitor = params.monitor;
|
||||||
|
|
||||||
context.sub_state = malloc(program.frag_count * program.sub_type_count *
|
context.sub_state = (unsigned int *)calloc(
|
||||||
sizeof(unsigned int));
|
program.frag_count * program.sub_type_count, sizeof(unsigned int));
|
||||||
|
|
||||||
for (i = 0; i < program.frag_count * program.sub_type_count; i++) {
|
|
||||||
context.sub_state[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params.demo) {
|
if (params.demo) {
|
||||||
randomize_context_state();
|
randomize_context_state();
|
||||||
@@ -76,11 +72,30 @@ static void init_context(Parameters params) {
|
|||||||
for (i = 0; i < program.frag_count; i++) {
|
for (i = 0; i < program.frag_count; i++) {
|
||||||
context.seeds[i] = rand_uint(1000);
|
context.seeds[i] = rand_uint(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context.input_widths =
|
||||||
|
(unsigned int *)calloc(program.in_count, sizeof(unsigned int));
|
||||||
|
context.input_heights =
|
||||||
|
(unsigned int *)calloc(program.in_count, sizeof(unsigned int));
|
||||||
|
context.input_formats =
|
||||||
|
(unsigned int *)calloc(program.in_count, sizeof(unsigned int));
|
||||||
|
|
||||||
|
for (i = 0; i < program.in_count; i++) {
|
||||||
|
if (!inputs[i].error) {
|
||||||
|
context.input_widths[i] = inputs[i].width;
|
||||||
|
context.input_heights[i] = inputs[i].height;
|
||||||
|
context.input_formats[i] = inputs[i].pixelformat;
|
||||||
|
log_debug("%d %x", inputs[i].pixelformat, inputs[i].pixelformat);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_context() {
|
static void free_context() {
|
||||||
free(context.sub_state);
|
free(context.sub_state);
|
||||||
free(context.seeds);
|
free(context.seeds);
|
||||||
|
free(context.input_widths);
|
||||||
|
free(context.input_heights);
|
||||||
|
free(context.input_formats);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hot_reload() {
|
static void hot_reload() {
|
||||||
|
|||||||
+9
-1
@@ -435,6 +435,7 @@ static void use_program(ShaderProgram program, int i, bool output,
|
|||||||
unsigned int j, k;
|
unsigned int j, k;
|
||||||
GLuint *subroutines;
|
GLuint *subroutines;
|
||||||
vec2 resolution, tex_resolution;
|
vec2 resolution, tex_resolution;
|
||||||
|
vec3 in_resolution;
|
||||||
|
|
||||||
resolution[0] = (float)context.width;
|
resolution[0] = (float)context.width;
|
||||||
resolution[1] = (float)context.height;
|
resolution[1] = (float)context.height;
|
||||||
@@ -469,7 +470,14 @@ static void use_program(ShaderProgram program, int i, bool output,
|
|||||||
glUniform2fv(program.itexres_locations[i], 1,
|
glUniform2fv(program.itexres_locations[i], 1,
|
||||||
(const GLfloat *)&tex_resolution);
|
(const GLfloat *)&tex_resolution);
|
||||||
|
|
||||||
// TODO video resolution
|
for (j = 0; j < program.in_count; j++) {
|
||||||
|
in_resolution[0] = context.input_widths[j];
|
||||||
|
in_resolution[1] = context.input_heights[j];
|
||||||
|
in_resolution[2] = context.input_formats[j];
|
||||||
|
|
||||||
|
glUniform3fv(program.iinres_locations[i * program.in_count + j], 1,
|
||||||
|
(const GLfloat *)&in_resolution);
|
||||||
|
}
|
||||||
|
|
||||||
// set seeds uniforms
|
// set seeds uniforms
|
||||||
for (j = 0; j < program.frag_count; j++) {
|
for (j = 0; j < program.frag_count; j++) {
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ typedef struct Context {
|
|||||||
bool monitor;
|
bool monitor;
|
||||||
unsigned int *input_widths;
|
unsigned int *input_widths;
|
||||||
unsigned int *input_heights;
|
unsigned int *input_heights;
|
||||||
|
unsigned int *input_formats;
|
||||||
} Context;
|
} Context;
|
||||||
|
|
||||||
typedef struct Timer {
|
typedef struct Timer {
|
||||||
|
|||||||
+12
-3
@@ -107,6 +107,7 @@ static bool get_available_sizes(VideoCapture *video_capture,
|
|||||||
unsigned int preferred_height) {
|
unsigned int preferred_height) {
|
||||||
struct v4l2_frmsizeenum fmt_enum;
|
struct v4l2_frmsizeenum fmt_enum;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
memset(&fmt_enum, 0, sizeof(fmt_enum));
|
memset(&fmt_enum, 0, sizeof(fmt_enum));
|
||||||
|
|
||||||
@@ -114,6 +115,7 @@ static bool get_available_sizes(VideoCapture *video_capture,
|
|||||||
fmt_enum.index = index;
|
fmt_enum.index = index;
|
||||||
fmt_enum.pixel_format = V4L2_PIX_FMT_YUYV;
|
fmt_enum.pixel_format = V4L2_PIX_FMT_YUYV;
|
||||||
|
|
||||||
|
found = false;
|
||||||
video_capture->width = 0;
|
video_capture->width = 0;
|
||||||
video_capture->height = 0;
|
video_capture->height = 0;
|
||||||
|
|
||||||
@@ -124,12 +126,18 @@ static bool get_available_sizes(VideoCapture *video_capture,
|
|||||||
|
|
||||||
if (fmt_enum.discrete.height == preferred_height) {
|
if (fmt_enum.discrete.height == preferred_height) {
|
||||||
video_capture->height = preferred_height;
|
video_capture->height = preferred_height;
|
||||||
|
found = true;
|
||||||
if (video_capture->width == 0 ||
|
if (video_capture->width == 0 ||
|
||||||
video_capture->width < fmt_enum.discrete.width) {
|
video_capture->width < fmt_enum.discrete.width) {
|
||||||
video_capture->width = fmt_enum.discrete.width;
|
video_capture->width = fmt_enum.discrete.width;
|
||||||
}
|
}
|
||||||
} else if (fmt_enum.discrete.height < preferred_height &&
|
} else if (fmt_enum.discrete.height < preferred_height) {
|
||||||
fmt_enum.discrete.height > video_capture->height) {
|
if (!found || fmt_enum.discrete.height > video_capture->height) {
|
||||||
|
video_capture->height = fmt_enum.discrete.height;
|
||||||
|
video_capture->width = fmt_enum.discrete.width;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
} else if (video_capture->height == 0) {
|
||||||
video_capture->height = fmt_enum.discrete.height;
|
video_capture->height = fmt_enum.discrete.height;
|
||||||
video_capture->width = fmt_enum.discrete.width;
|
video_capture->width = fmt_enum.discrete.width;
|
||||||
}
|
}
|
||||||
@@ -141,6 +149,7 @@ static bool get_available_sizes(VideoCapture *video_capture,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (video_capture->height == 0) {
|
if (video_capture->height == 0) {
|
||||||
|
log_warn("(%s) No format found");
|
||||||
video_capture->error = true;
|
video_capture->error = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -159,7 +168,7 @@ static bool set_format(VideoCapture *video_capture) {
|
|||||||
fmt.fmt.pix.width = video_capture->width;
|
fmt.fmt.pix.width = video_capture->width;
|
||||||
fmt.fmt.pix.height = video_capture->height;
|
fmt.fmt.pix.height = video_capture->height;
|
||||||
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
|
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
|
||||||
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
|
fmt.fmt.pix.field = V4L2_FIELD_ANY;
|
||||||
|
|
||||||
if (ioctl(video_capture->fd, VIDIOC_S_FMT, &fmt) == -1) {
|
if (ioctl(video_capture->fd, VIDIOC_S_FMT, &fmt) == -1) {
|
||||||
fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
|
fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
|
||||||
|
|||||||
Reference in New Issue
Block a user