From 83e395e558735bd09d645e01b194f42f6764a503 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sun, 26 Feb 2017 18:14:41 +0100 Subject: [PATCH] Fix an issue where our v210 texture would be too narrow, since there are two different conventions for the width. --- mixer.cpp | 23 ++++++++++++++--------- pbo_frame_allocator.cpp | 6 ++++++ pbo_frame_allocator.h | 1 + 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/mixer.cpp b/mixer.cpp index a5ceeaf..f7b6a7c 100644 --- a/mixer.cpp +++ b/mixer.cpp @@ -78,7 +78,7 @@ void insert_new_frame(RefCountedFrame frame, unsigned field_num, bool interlaced } } -void ensure_texture_resolution(PBOFrameAllocator::Userdata *userdata, unsigned field, unsigned width, unsigned height) +void ensure_texture_resolution(PBOFrameAllocator::Userdata *userdata, unsigned field, unsigned width, unsigned height, unsigned v210_width) { bool first; if (global_flags.ten_bit_input) { @@ -94,12 +94,6 @@ void ensure_texture_resolution(PBOFrameAllocator::Userdata *userdata, unsigned f // a new object. Note that this each card has its own PBOFrameAllocator, // we don't need to worry about these flip-flopping between resolutions. if (global_flags.ten_bit_input) { - const size_t v210_width = v210Converter::get_minimum_v210_texture_width(width); - - glBindTexture(GL_TEXTURE_2D, userdata->tex_v210[field]); - check_error(); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, v210_width, height, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, nullptr); - check_error(); glBindTexture(GL_TEXTURE_2D, userdata->tex_444[field]); check_error(); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, width, height, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, nullptr); @@ -119,6 +113,15 @@ void ensure_texture_resolution(PBOFrameAllocator::Userdata *userdata, unsigned f userdata->last_width[field] = width; userdata->last_height[field] = height; } + if (global_flags.ten_bit_input && + (first || v210_width != userdata->last_v210_width[field])) { + // Same as above; we need to recreate the texture. + glBindTexture(GL_TEXTURE_2D, userdata->tex_v210[field]); + check_error(); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, v210_width, height, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, nullptr); + check_error(); + userdata->last_v210_width[field] = v210_width; + } } void upload_texture(GLuint tex, GLuint width, GLuint height, GLuint stride, bool interlaced_stride, GLenum format, GLenum type, GLintptr offset) @@ -563,14 +566,16 @@ void Mixer::bm_frame(unsigned card_index, uint16_t timecode, field_start_line = video_format.extra_lines_top; } - ensure_texture_resolution(userdata, field, video_format.width, video_format.height); + // For 8-bit input, v210_width will be nonsensical but not used. + size_t v210_width = video_format.stride / sizeof(uint32_t); + ensure_texture_resolution(userdata, field, video_format.width, video_format.height, v210_width); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, userdata->pbo); check_error(); if (global_flags.ten_bit_input) { size_t field_start = video_offset + video_format.stride * field_start_line; - upload_texture(userdata->tex_v210[field], video_format.stride / sizeof(uint32_t), video_format.height, video_format.stride, interlaced_stride, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, field_start); + upload_texture(userdata->tex_v210[field], v210_width, video_format.height, video_format.stride, interlaced_stride, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, field_start); v210_converter->convert(userdata->tex_v210[field], userdata->tex_444[field], video_format.width, video_format.height); } else { size_t field_y_start = y_offset + video_format.width * field_start_line; diff --git a/pbo_frame_allocator.cpp b/pbo_frame_allocator.cpp index 09f22f3..bfc65f2 100644 --- a/pbo_frame_allocator.cpp +++ b/pbo_frame_allocator.cpp @@ -54,10 +54,15 @@ PBOFrameAllocator::PBOFrameAllocator(size_t frame_size, GLuint width, GLuint hei glGenTextures(2, userdata[i].tex_cbcr); check_error(); } + userdata[i].last_width[0] = width; userdata[i].last_height[0] = height; + userdata[i].last_v210_width[0] = 0; + userdata[i].last_width[1] = 0; userdata[i].last_height[1] = 0; + userdata[i].last_v210_width[1] = 0; + userdata[i].last_interlaced = false; userdata[i].last_has_signal = false; userdata[i].last_is_connected = false; @@ -73,6 +78,7 @@ PBOFrameAllocator::PBOFrameAllocator(size_t frame_size, GLuint width, GLuint hei glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); check_error(); if (field == 0) { + userdata[i].last_v210_width[0] = v210_width; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, v210_width, height, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, NULL); check_error(); } diff --git a/pbo_frame_allocator.h b/pbo_frame_allocator.h index 43310ae..da3bd2e 100644 --- a/pbo_frame_allocator.h +++ b/pbo_frame_allocator.h @@ -34,6 +34,7 @@ public: GLuint tex_y[2], tex_cbcr[2]; // For 8-bit. GLuint tex_v210[2], tex_444[2]; // For 10-bit. GLuint last_width[2], last_height[2]; + GLuint last_v210_width[2]; // For 10-bit. bool last_interlaced, last_has_signal, last_is_connected; unsigned last_frame_rate_nom, last_frame_rate_den; }; -- 2.39.2