diff --git a/VERSION b/VERSION index fa25d260..dd49e160 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -B1-173-g2e760c09b4+1 \ No newline at end of file +B1-173-gead09ed110+1 \ No newline at end of file diff --git a/client/renderers/EGL/texture.c b/client/renderers/EGL/texture.c index 4f04af5f..7d3c9305 100644 --- a/client/renderers/EGL/texture.c +++ b/client/renderers/EGL/texture.c @@ -33,7 +33,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA struct EGL_Texture { enum EGL_PixelFormat pixFmt; - size_t width, height; + size_t width, height, stride; + size_t bpp; bool streaming; bool ready; @@ -106,6 +107,7 @@ bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_ texture->pixFmt = pixFmt; texture->width = width; texture->height = height; + texture->stride = stride; texture->streaming = streaming; texture->ready = false; @@ -113,6 +115,7 @@ bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_ { case EGL_PF_BGRA: textureCount = 1; + texture->bpp = 4; texture->format = GL_BGRA; texture->planes[0][0] = width; texture->planes[0][1] = height; @@ -125,6 +128,7 @@ bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_ case EGL_PF_RGBA: textureCount = 1; + texture->bpp = 4; texture->format = GL_RGBA; texture->planes[0][0] = width; texture->planes[0][1] = height; @@ -137,6 +141,7 @@ bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_ case EGL_PF_RGBA10: textureCount = 1; + texture->bpp = 4; texture->format = GL_RGBA; texture->planes[0][0] = width; texture->planes[0][1] = height; @@ -149,6 +154,7 @@ bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_ case EGL_PF_YUV420: textureCount = 3; + texture->bpp = 4; texture->format = GL_RED; texture->planes[0][0] = width; texture->planes[0][1] = height; @@ -287,7 +293,16 @@ bool egl_texture_update_from_frame(EGL_Texture * texture, const FrameBuffer * fr if (texture->pboCount == 2) return true; - framebuffer_read(frame, texture->pboMap[texture->pboWIndex], texture->pboBufferSize); + framebuffer_read( + frame, + texture->pboMap[texture->pboWIndex], + texture->stride, + texture->height, + texture->width, + texture->bpp, + texture->stride + ); + texture->pboSync[texture->pboWIndex] = 0; if (++texture->pboWIndex == 2) @@ -383,4 +398,4 @@ enum EGL_TexStatus egl_texture_bind(EGL_Texture * texture) int egl_texture_count(EGL_Texture * texture) { return texture->textureCount; -} \ No newline at end of file +} diff --git a/client/renderers/OpenGL/opengl.c b/client/renderers/OpenGL/opengl.c index 2b227029..2047ae50 100644 --- a/client/renderers/OpenGL/opengl.c +++ b/client/renderers/OpenGL/opengl.c @@ -1274,14 +1274,19 @@ static bool draw_frame(struct Inst * this) glBindTexture(GL_TEXTURE_2D, this->frames[this->texIndex]); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vboID[this->texIndex]); - glPixelStorei(GL_UNPACK_ALIGNMENT , 4); - glPixelStorei(GL_UNPACK_ROW_LENGTH , this->format.stride); + const int bpp = this->format.bpp / 8; + glPixelStorei(GL_UNPACK_ALIGNMENT , bpp); + glPixelStorei(GL_UNPACK_ROW_LENGTH, this->format.width); this->texPos = 0; + framebuffer_read_fn( this->frame, + this->format.height, + this->format.width, + bpp, + this->format.pitch, opengl_buffer_fn, - this->format.height * this->format.stride * 4, this ); diff --git a/common/include/common/framebuffer.h b/common/include/common/framebuffer.h index 21a52e37..aa754cbf 100644 --- a/common/include/common/framebuffer.h +++ b/common/include/common/framebuffer.h @@ -40,12 +40,14 @@ void framebuffer_wait(const FrameBuffer * frame, size_t size); /** * Read data from the KVMFRFrame into the dst buffer */ -bool framebuffer_read(const FrameBuffer * frame, void * dst, size_t size); +bool framebuffer_read(const FrameBuffer * frame, void * dst, size_t dstpitch, + size_t height, size_t width, size_t bpp, size_t pitch); /** * Read data from the KVMFRFrame using a callback */ -bool framebuffer_read_fn(const FrameBuffer * frame, FrameBufferReadFn fn, size_t size, void * opaque); +bool framebuffer_read_fn(const FrameBuffer * frame, size_t height, size_t width, + size_t bpp, size_t pitch, FrameBufferReadFn fn, void * opaque); /** * Prepare the framebuffer for writing diff --git a/common/src/framebuffer.c b/common/src/framebuffer.c index 7d477be3..6b17a792 100644 --- a/common/src/framebuffer.c +++ b/common/src/framebuffer.c @@ -38,53 +38,55 @@ void framebuffer_wait(const FrameBuffer * frame, size_t size) while(atomic_load_explicit(&frame->wp, memory_order_relaxed) != size) {} } -bool framebuffer_read(const FrameBuffer * frame, void * dst, size_t size) + +bool framebuffer_read(const FrameBuffer * frame, void * dst, size_t dstpitch, + size_t height, size_t width, size_t bpp, size_t pitch) { - uint8_t *d = (uint8_t*)dst; - uint64_t rp = 0; - while(rp < size) + uint8_t *d = (uint8_t*)dst; + uint_least32_t rp = 0; + size_t y = 0; + const size_t linewidth = width * bpp; + + while(y < height) { uint_least32_t wp; /* spinlock */ do wp = atomic_load_explicit(&frame->wp, memory_order_relaxed); - while(rp == wp); + while(wp - rp < pitch); - /* copy what we can */ - uint64_t avail = wp - rp; - avail = avail > size ? size : avail; + memcpy(d, frame->data + rp, linewidth); - memcpy(d, frame->data + rp, avail); - - rp += avail; - d += avail; - size -= avail; + rp += pitch; + d += dstpitch; + ++y; } + return true; } -bool framebuffer_read_fn(const FrameBuffer * frame, FrameBufferReadFn fn, size_t size, void * opaque) +bool framebuffer_read_fn(const FrameBuffer * frame, size_t height, size_t width, + size_t bpp, size_t pitch, FrameBufferReadFn fn, void * opaque) { - uint64_t rp = 0; - while(rp < size) + uint_least32_t rp = 0; + size_t y = 0; + const size_t linewidth = width * bpp; + + while(y < height) { uint_least32_t wp; /* spinlock */ do wp = atomic_load_explicit(&frame->wp, memory_order_relaxed); - while(rp == wp); + while(wp - rp < pitch); - /* copy what we can */ - uint64_t avail = wp - rp; - avail = avail > size ? size : avail; - - if (!fn(opaque, frame->data + rp, avail)) + if (!fn(opaque, frame->data + rp, linewidth)) return false; - rp += avail; - size -= avail; + rp += pitch; + ++y; } return true; diff --git a/obs/lg.c b/obs/lg.c index 38099e64..bc5ae40b 100644 --- a/obs/lg.c +++ b/obs/lg.c @@ -169,8 +169,16 @@ static void lgVideoTick(void * data, float seconds) uint8_t *texData; uint32_t linesize; gs_texture_map(this->texture, &texData, &linesize); - if (linesize == frame->pitch) - framebuffer_read(fb, texData, frame->height * frame->pitch); + + framebuffer_read( + fb, + texData, // dst + linesize, // dstpitch + frame->height, // height + frame->width, // width + 4, // bpp + frame->pitch // linepitch + ); gs_texture_unmap(this->texture); // gs_texture_set_image(this->texture, frameData, frame->pitch, false); @@ -229,4 +237,4 @@ struct obs_source_info lg_source = .get_width = lgGetWidth, .get_height = lgGetHeight, // .icon_type = OBS_ICON_TYPE_DESKTOP_CAPTURE -}; \ No newline at end of file +};