]> git.sesse.net Git - nageru/commitdiff
Open up for inputs that are different from the native resolution. No deinterlacing...
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 21 Nov 2015 20:51:35 +0000 (21:51 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 21 Nov 2015 20:51:35 +0000 (21:51 +0100)
bmusb
mixer.cpp
pbo_frame_allocator.cpp
pbo_frame_allocator.h
theme.cpp
theme.h
theme.lua

diff --git a/bmusb b/bmusb
index 8eb0e99394c2ffa361c9dd7eb22bc176e6e4c899..62463c958d6109af87bc22f3d5ccad0421889a5e 160000 (submodule)
--- a/bmusb
+++ b/bmusb
@@ -1 +1 @@
-Subproject commit 8eb0e99394c2ffa361c9dd7eb22bc176e6e4c899
+Subproject commit 62463c958d6109af87bc22f3d5ccad0421889a5e
index 5fd5d1f7b452f2cda88a56cc6cccc2df62fe00df..e3af8789530f06186c527c31334d071cd49572f6 100644 (file)
--- a/mixer.cpp
+++ b/mixer.cpp
@@ -218,7 +218,7 @@ void Mixer::bm_frame(unsigned card_index, uint16_t timecode,
 {
        CaptureCard *card = &cards[card_index];
 
-       int width, height, frame_rate_nom, frame_rate_den, extra_lines_top, extra_lines_bottom;
+       unsigned width, height, frame_rate_nom, frame_rate_den, extra_lines_top, extra_lines_bottom;
        bool interlaced;
 
        decode_video_format(video_format, &width, &height, &extra_lines_top, &extra_lines_bottom,
@@ -300,8 +300,7 @@ void Mixer::bm_frame(unsigned card_index, uint16_t timecode,
        }
 
        if (video_frame.len - video_offset == 0 ||
-           video_frame.len - video_offset != size_t(width * (height + extra_lines_top + extra_lines_bottom) * 2) ||
-           width != WIDTH || height != HEIGHT) {  // TODO: Remove this once the rest of the infrastructure is in place.
+           video_frame.len - video_offset != size_t(width * (height + extra_lines_top + extra_lines_bottom) * 2)) {
                if (video_frame.len != 0) {
                        printf("Card %d: Dropping video frame with wrong length (%ld)\n",
                                card_index, video_frame.len - video_offset);
@@ -324,7 +323,7 @@ void Mixer::bm_frame(unsigned card_index, uint16_t timecode,
                return;
        }
 
-       const PBOFrameAllocator::Userdata *userdata = (const PBOFrameAllocator::Userdata *)video_frame.userdata;
+       PBOFrameAllocator::Userdata *userdata = (PBOFrameAllocator::Userdata *)video_frame.userdata;
        GLuint pbo = userdata->pbo;
        check_error();
        glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
@@ -339,14 +338,30 @@ void Mixer::bm_frame(unsigned card_index, uint16_t timecode,
        size_t cbcr_offset = video_offset / 2;
        size_t y_offset = video_frame.size / 2 + video_offset / 2;
 
-       glBindTexture(GL_TEXTURE_2D, userdata->tex_cbcr);
-       check_error();
-       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, cbcr_width, height, GL_RG, GL_UNSIGNED_BYTE, BUFFER_OFFSET(cbcr_offset + cbcr_width * extra_lines_top * sizeof(uint16_t)));
-       check_error();
-       glBindTexture(GL_TEXTURE_2D, userdata->tex_y);
-       check_error();
-       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, BUFFER_OFFSET(y_offset + width * extra_lines_top));
-       check_error();
+       if (width != userdata->last_width || height != userdata->last_height) {
+               // We changed resolution since last use of this texture, so we need to create
+               // a new object. Note that this each card has its own PBOFrameAllocator,
+               // we don't need to worry about these flip-flopping between resolutions.
+               glBindTexture(GL_TEXTURE_2D, userdata->tex_cbcr);
+               check_error();
+               glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, cbcr_width, height, 0, GL_RG, GL_UNSIGNED_BYTE, BUFFER_OFFSET(cbcr_offset + cbcr_width * extra_lines_top * sizeof(uint16_t)));
+               check_error();
+               glBindTexture(GL_TEXTURE_2D, userdata->tex_y);
+               check_error();
+               glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, BUFFER_OFFSET(y_offset + width * extra_lines_top));
+               check_error();
+               userdata->last_width = width;
+               userdata->last_height = height;
+       } else {
+               glBindTexture(GL_TEXTURE_2D, userdata->tex_cbcr);
+               check_error();
+               glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, cbcr_width, height, GL_RG, GL_UNSIGNED_BYTE, BUFFER_OFFSET(cbcr_offset + cbcr_width * extra_lines_top * sizeof(uint16_t)));
+               check_error();
+               glBindTexture(GL_TEXTURE_2D, userdata->tex_y);
+               check_error();
+               glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, BUFFER_OFFSET(y_offset + width * extra_lines_top));
+               check_error();
+       }
        glBindTexture(GL_TEXTURE_2D, 0);
        check_error();
        GLsync fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, /*flags=*/0);              
@@ -472,7 +487,7 @@ void Mixer::thread_func()
                                check_error();
                        }
                        const PBOFrameAllocator::Userdata *userdata = (const PBOFrameAllocator::Userdata *)card->new_frame->userdata;
-                       theme->set_input_textures(card_index, userdata->tex_y, userdata->tex_cbcr);
+                       theme->set_input_textures(card_index, userdata->tex_y, userdata->tex_cbcr, userdata->last_width, userdata->last_height);
                }
 
                // Get the main chain from the theme, and set its state immediately.
index 1c370b4266d4f09609a8d657d1f8bda86fa1d85b..613506dcb61b1eb16c4bdc92dbdf88141a95db39 100644 (file)
@@ -59,6 +59,9 @@ PBOFrameAllocator::PBOFrameAllocator(size_t frame_size, GLuint width, GLuint hei
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, width / 2, height, 0, GL_RG, GL_UNSIGNED_BYTE, NULL);
                check_error();
 
+               userdata[i].last_width = width;
+               userdata[i].last_height = height;
+
                freelist.push(frame);
        }
        glBindBuffer(buffer, 0);
index 452c006bd2d36c290de9cd456b4c4edbf4b87b85..aedae3b99cc89d5d8085c95694d73ea95a49d458 100644 (file)
@@ -29,6 +29,7 @@ public:
        struct Userdata {
                GLuint pbo;
                GLuint tex_y, tex_cbcr;
+               GLuint last_width, last_height;
        };
 
 private:
index 61e2aedf743002c3784bebb63bc21a784f937efe..61e149c3320c9256d0985d51a3db26dc913e99f2 100644 (file)
--- a/theme.cpp
+++ b/theme.cpp
@@ -613,6 +613,8 @@ void Theme::connect_signal(YCbCrInput *input, int signal_num)
        }
        input->set_texture_num(0, input_textures[signal_num].tex_y);
        input->set_texture_num(1, input_textures[signal_num].tex_cbcr);
+       input->set_width(input_textures[signal_num].width);
+       input->set_height(input_textures[signal_num].height);
 }
 
 void Theme::transition_clicked(int transition_num, float t)
diff --git a/theme.h b/theme.h
index f00c7a2acc2067b656af4598b1b9c2022e1af756..a5ecebc5d8ba3746733a162383c3bfd82daac216 100644 (file)
--- a/theme.h
+++ b/theme.h
@@ -15,6 +15,8 @@
 #include <utility>
 #include <vector>
 
+#include "defs.h"
+
 namespace movit {
 class ResourcePool;
 struct ImageFormat;
@@ -41,9 +43,12 @@ public:
        std::pair<movit::EffectChain *, std::function<void()>>
        get_chain(unsigned num, float t, unsigned width, unsigned height);
 
-       void set_input_textures(int signal_num, GLuint tex_y, GLuint tex_cbcr) {
-               input_textures[signal_num].tex_y = tex_y;
-               input_textures[signal_num].tex_cbcr = tex_cbcr;
+       void set_input_textures(int signal_num, GLuint tex_y, GLuint tex_cbcr, GLuint width, GLuint height) {
+               auto &tex = input_textures[signal_num];
+               tex.tex_y = tex_y;
+               tex.tex_cbcr = tex_cbcr;
+               tex.width = width;
+               tex.height = height;
        }
        int get_num_channels() { return num_channels; }
        std::string get_channel_name(unsigned channel);
@@ -64,6 +69,7 @@ private:
        movit::ResourcePool *resource_pool;
        struct {
                GLuint tex_y = 0, tex_cbcr = 0;
+               GLuint width = WIDTH, height = HEIGHT;
        } input_textures[MAX_CARDS];
        int num_channels;
        unsigned num_cards;
index abba2202250b34bb5e428bb3c3eab7eded453d16..1243ad15de6be7cfb64d059969f958487de837f3 100644 (file)
--- a/theme.lua
+++ b/theme.lua
@@ -7,6 +7,8 @@
 -- where all the low-level details (such as texture formats) are handled by the
 -- C++ side and you generally just build chains.
 
+-- TODO: Deal with inputs that are different from our native 1280x720 resolution.
+
 local transition_start = -2.0
 local transition_end = -1.0
 local zoom_src = 0.0