From 3d72cc54197e54fb694dab34e13b65359f9ecb45 Mon Sep 17 00:00:00 2001 From: Mark Kendall Date: Fri, 15 Mar 2019 11:40:33 +0000 Subject: [PATCH] MythVideoTexture: Optimise YV12 and NV12 texture uploads - use GL_UNPACK_ROW_LENGTH to handle different pitches instead of creating a software buffer and copying. - remove bogus attempt at optimisation for YV12 to YUYV conversion. - make MythFrame::copyplane private again --- mythtv/libs/libmythtv/mythframe.cpp | 12 +++ mythtv/libs/libmythtv/mythframe.h | 12 --- mythtv/libs/libmythtv/mythvideotexture.cpp | 113 +++++---------------- mythtv/libs/libmythtv/mythvideotexture.h | 4 +- 4 files changed, 42 insertions(+), 99 deletions(-) diff --git a/mythtv/libs/libmythtv/mythframe.cpp b/mythtv/libs/libmythtv/mythframe.cpp index a9331508723..0c668f767c9 100644 --- a/mythtv/libs/libmythtv/mythframe.cpp +++ b/mythtv/libs/libmythtv/mythframe.cpp @@ -286,6 +286,18 @@ static inline void SSE_splitplanes(uint8_t* dstu, int dstu_pitch, } #endif /* ARCH_X86 */ +static inline void copyplane(uint8_t* dst, int dst_pitch, + const uint8_t* src, int src_pitch, + int width, int height) +{ + for (int y = 0; y < height; y++) + { + memcpy(dst, src, width); + src += src_pitch; + dst += dst_pitch; + } +} + static void splitplanes(uint8_t* dstu, int dstu_pitch, uint8_t* dstv, int dstv_pitch, const uint8_t* src, int src_pitch, diff --git a/mythtv/libs/libmythtv/mythframe.h b/mythtv/libs/libmythtv/mythframe.h index 8125a596eb9..41d36ce4320 100644 --- a/mythtv/libs/libmythtv/mythframe.h +++ b/mythtv/libs/libmythtv/mythframe.h @@ -433,18 +433,6 @@ static inline void copybuffer(uint8_t *dstbuffer, const VideoFrame *src, copy(&frameout, src); } } - -static inline void copyplane(uint8_t* dst, int dst_pitch, - const uint8_t* src, int src_pitch, - int width, int height) -{ - for (int y = 0; y < height; y++) - { - memcpy(dst, src, width); - src += src_pitch; - dst += dst_pitch; - } -} #endif /* __cplusplus */ #endif diff --git a/mythtv/libs/libmythtv/mythvideotexture.cpp b/mythtv/libs/libmythtv/mythvideotexture.cpp index 5e4d11fdf02..e9491949d58 100644 --- a/mythtv/libs/libmythtv/mythvideotexture.cpp +++ b/mythtv/libs/libmythtv/mythvideotexture.cpp @@ -249,7 +249,7 @@ void MythVideoTexture::UpdateTextures(MythRenderOpenGL *Context, { switch (texture->m_frameFormat) { - case FMT_YV12: YV12ToYV12(Frame, texture, i); break; + case FMT_YV12: YV12ToYV12(Context, Frame, texture, i); break; case FMT_YUY2: YV12ToYUYV(Frame, texture); break; case FMT_YUYVHQ: YV12ToYUYVHQ(Frame, texture); break; default: break; @@ -260,7 +260,7 @@ void MythVideoTexture::UpdateTextures(MythRenderOpenGL *Context, { switch (texture->m_frameFormat) { - case FMT_NV12: NV12ToNV12(Frame, texture, i); break; + case FMT_NV12: NV12ToNV12(Context, Frame, texture, i); break; default: break; } break; @@ -328,78 +328,44 @@ MythVideoTexture* MythVideoTexture::CreateTexture(MythRenderOpenGL *Context, } /// \brief Copy YV12 frame data to 'YV12' textures. -void MythVideoTexture::YV12ToYV12(const VideoFrame *Frame, - MythVideoTexture *Texture, int Plane) +inline void MythVideoTexture::YV12ToYV12(MythRenderOpenGL *Context, const VideoFrame *Frame, + MythVideoTexture *Texture, int Plane) { - void *buffer = nullptr; - int offset = 0; - int width = Texture->m_size.width(); - - // Direct copy - if (Frame->pitches[Plane] == width) - { - buffer = Frame->buf; - offset = Frame->offsets[Plane]; - } - else - { - // Create a buffer - if (!Texture->m_data) - if (!CreateBuffer(Texture, Texture->m_bufferSize)) - return; - buffer = Texture->m_data; - - // Refresh - copyplane(static_cast(buffer), width, Frame->buf + Frame->offsets[Plane], - Frame->pitches[Plane], width, Texture->m_size.height()); - } - - // Update + Context->glPixelStorei(GL_UNPACK_ROW_LENGTH, Frame->pitches[Plane]); Texture->m_texture->setData(Texture->m_pixelFormat, Texture->m_pixelType, - static_cast(buffer) + offset); + static_cast(Frame->buf) + Frame->offsets[Plane]); Texture->m_valid = true; + Context->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } /// \brief Copy YV12 frame data to a YUYV texture. -void MythVideoTexture::YV12ToYUYV(const VideoFrame *Frame, - MythVideoTexture *Texture) +inline void MythVideoTexture::YV12ToYUYV(const VideoFrame *Frame, MythVideoTexture *Texture) { - void * buffer = nullptr; + // Create a buffer + if (!Texture->m_data) + if (!CreateBuffer(Texture, Texture->m_bufferSize)) + return; + void* buffer = Texture->m_data; - // Direct copy - if (Frame->pitches[0] == Texture->m_size.width()) - { - buffer = Frame->buf; - } - else + // Create a copy context + if (!Texture->m_copyContext) { - // Create a buffer - if (!Texture->m_data) - if (!CreateBuffer(Texture, Texture->m_bufferSize)) - return; - buffer = Texture->m_data; - - // Create a copy context + Texture->m_copyContext = new MythAVCopy(); if (!Texture->m_copyContext) - { - Texture->m_copyContext = new MythAVCopy(); - if (!Texture->m_copyContext) - return; - } - - // Convert - AVFrame out; - Texture->m_copyContext->Copy(&out, Frame, static_cast(buffer), AV_PIX_FMT_UYVY422); + return; } + // Convert + AVFrame out; + Texture->m_copyContext->Copy(&out, Frame, static_cast(buffer), AV_PIX_FMT_UYVY422); + // Update Texture->m_texture->setData(Texture->m_pixelFormat, Texture->m_pixelType, buffer); Texture->m_valid = true; } /// \brief Copy YV12 frame data to a YUYV texture with high quality interlaced chroma sampling. -void MythVideoTexture::YV12ToYUYVHQ(const VideoFrame *Frame, - MythVideoTexture *Texture) +inline void MythVideoTexture::YV12ToYUYVHQ(const VideoFrame *Frame, MythVideoTexture *Texture) { // Create a buffer if (!Texture->m_data) @@ -424,41 +390,18 @@ void MythVideoTexture::YV12ToYUYVHQ(const VideoFrame *Frame, } /// \brief Copy NV12 video frame data to 'NV12' textures. -void MythVideoTexture::NV12ToNV12(const VideoFrame *Frame, MythVideoTexture *Texture, int Plane) +inline void MythVideoTexture::NV12ToNV12(MythRenderOpenGL *Context, const VideoFrame *Frame, + MythVideoTexture *Texture, int Plane) { - void *buffer = nullptr; - int offset = 0; - int width = Texture->m_size.width(); - if (Plane) - width *= 2; - - // Direct copy - if (Frame->pitches[Plane] == width) - { - buffer = Frame->buf; - offset = Frame->offsets[Plane]; - } - else - { - // Create a buffer - if (!Texture->m_data) - if (!CreateBuffer(Texture, Texture->m_bufferSize)) - return; - buffer = Texture->m_data; - - // Refresh - copyplane(static_cast(buffer), width, Frame->buf + Frame->offsets[Plane], - Frame->pitches[Plane], width, Texture->m_size.height()); - } - - // Update + Context->glPixelStorei(GL_UNPACK_ROW_LENGTH, Plane ? Frame->pitches[Plane] >> 1 : Frame->pitches[Plane]); Texture->m_texture->setData(Texture->m_pixelFormat, Texture->m_pixelType, - static_cast(buffer) + offset); + static_cast(Frame->buf) + Frame->offsets[Plane]); Texture->m_valid = true; + Context->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } /// \brief Create a data buffer for holding CPU side texture data. -bool MythVideoTexture::CreateBuffer(MythVideoTexture *Texture, int Size) +inline bool MythVideoTexture::CreateBuffer(MythVideoTexture *Texture, int Size) { if (!Texture || Size < 1) return false; diff --git a/mythtv/libs/libmythtv/mythvideotexture.h b/mythtv/libs/libmythtv/mythvideotexture.h index 1b152e8491e..50d359b30bd 100644 --- a/mythtv/libs/libmythtv/mythvideotexture.h +++ b/mythtv/libs/libmythtv/mythvideotexture.h @@ -63,10 +63,10 @@ class MythVideoTexture : public MythGLTexture private: Q_DISABLE_COPY(MythVideoTexture) - static void YV12ToYV12 (const VideoFrame *Frame, MythVideoTexture* Texture, int Plane); + static void YV12ToYV12 (MythRenderOpenGL *Context, const VideoFrame *Frame, MythVideoTexture* Texture, int Plane); static void YV12ToYUYV (const VideoFrame *Frame, MythVideoTexture* Texture); static void YV12ToYUYVHQ (const VideoFrame *Frame, MythVideoTexture* Texture); - static void NV12ToNV12 (const VideoFrame *Frame, MythVideoTexture* Texture, int Plane); + static void NV12ToNV12 (MythRenderOpenGL *Context, const VideoFrame *Frame, MythVideoTexture* Texture, int Plane); static bool CreateBuffer (MythVideoTexture* Texture, int Size); static void StoreBicubicWeights(float X, float *Dest); };