5#define LOC QString("MythVidTex: ")
19 if (!Context || !Texture)
26 delete Texture->
m_vbo;
33 if (!Context || Textures.empty())
35 for (
auto & Texture : Textures)
41 const std::vector<MythVideoTextureOpenGL *> &Textures,
42 QOpenGLTexture::Filter Filter,
43 QOpenGLTexture::WrapMode Wrap)
45 for (
uint i = 0; (i < Textures.size()) && Context; i++)
47 Textures[i]->m_filter = Filter;
60 std::vector<QSize> Sizes,
63 std::vector<MythVideoTextureOpenGL*> result;
64 if (!Context || Sizes.empty())
66 if (Sizes[0].isEmpty())
88 std::vector<QSize> Sizes,
91 std::vector<MythVideoTextureOpenGL*> result;
96 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid hardware frame format");
100 if (count != Sizes.size())
102 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Inconsistent plane count");
106 for (
uint plane = 0; plane < count; ++plane)
108 GLuint textureid = 0;
109 Context->glGenTextures(1, &textureid);
114 texture->m_frameType = Type;
115 texture->m_frameFormat =
Format;
116 texture->m_plane = plane;
117 texture->m_planeCount = count;
118 texture->m_target = Target;
119 texture->m_size = Sizes[plane];
120 texture->m_totalSize = Context->
GetTextureSize(Sizes[plane], texture->m_target != QOpenGLTexture::TargetRectangle);
122 result.push_back(texture);
136 std::vector<QSize> Sizes,
139 std::vector<MythVideoTextureOpenGL*> result;
144 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid software frame format");
157 bool gles3 = Context->isOpenGLES() && Context->format().majorVersion() > 2;
158 QOpenGLTexture::PixelFormat r8pixelfmtnorm = QOpenGLTexture::Red;
159 QOpenGLTexture::PixelFormat r8pixelfmtuint = QOpenGLTexture::Red;
160 QOpenGLTexture::PixelFormat rg8pixelfmtnorm = QOpenGLTexture::RG;
161 QOpenGLTexture::PixelFormat rg8pixelfmtuint = QOpenGLTexture::RG;
162 QOpenGLTexture::TextureFormat r8internalfmt = QOpenGLTexture::R8_UNorm;
163 QOpenGLTexture::TextureFormat r16internalfmt = QOpenGLTexture::R16_UNorm;
164 QOpenGLTexture::TextureFormat rg8internalfmt = QOpenGLTexture::RG8_UNorm;
165 QOpenGLTexture::TextureFormat rg16internalfmt = QOpenGLTexture::RG16_UNorm;
169 r8pixelfmtuint = QOpenGLTexture::Red_Integer;
170 rg8pixelfmtuint = QOpenGLTexture::RG_Integer;
171 r16internalfmt = QOpenGLTexture::R16U;
172 rg16internalfmt = QOpenGLTexture::RG16U;
176 r8pixelfmtnorm = QOpenGLTexture::Luminance;
177 r8internalfmt = QOpenGLTexture::LuminanceFormat;
180 for (
uint plane = 0; plane < count; ++plane)
182 QSize size = Sizes[0];
188 size = QSize(size.width() >> 1, size.height() >> 1);
190 QOpenGLTexture::UInt8, r8pixelfmtnorm, r8internalfmt);
198 size = QSize(size.width() >> 1, size.height() >> 1);
200 QOpenGLTexture::UInt16, r8pixelfmtuint, r16internalfmt);
203 size.setWidth(size.width() >> 1);
210 QOpenGLTexture::UInt8, r8pixelfmtnorm, r8internalfmt);
214 size = QSize(size.width() >> 1, size.height() >> 1);
216 QOpenGLTexture::UInt8, rg8pixelfmtnorm, rg8internalfmt);
224 QOpenGLTexture::UInt16, r8pixelfmtuint, r16internalfmt);
228 size = QSize(size.width() >> 1, size.height() >> 1);
230 QOpenGLTexture::UInt16, rg8pixelfmtuint, rg16internalfmt);
235 size = QSize(size.width() >> 1, size.height());
237 QOpenGLTexture::UInt8, r8pixelfmtnorm, r8internalfmt);
245 size = QSize(size.width() >> 1, size.height());
247 QOpenGLTexture::UInt16, r8pixelfmtuint, r16internalfmt);
251 QOpenGLTexture::UInt8, r8pixelfmtnorm, r8internalfmt);
259 QOpenGLTexture::UInt16, r8pixelfmtuint, r16internalfmt);
269 result.push_back(texture);
273 if (result.size() != count)
274 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Failed to create all textures: %1 < %2")
275 .arg(result.size()).arg(count));
283 const std::vector<MythVideoTextureOpenGL*> &Textures)
285 if (!Context || !
Frame || Textures.empty())
287 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Texture error: Context %1 Frame %2 Textures %3")
288 .arg(Context !=
nullptr).arg(
Frame !=
nullptr).arg(Textures.size()));
292 if (
Frame->m_type != Textures[0]->m_frameType)
294 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Inconsistent video and texture frame types");
299 if (!count || (count != Textures.size()))
301 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid software frame type");
307 for (
uint i = 0; i < count; ++i)
317 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Inconsistent plane numbering");
435 QOpenGLTexture::PixelType PixelType,
436 QOpenGLTexture::PixelFormat PixelFormat,
437 QOpenGLTexture::TextureFormat
Format,
438 QOpenGLTexture::Filter Filter,
439 QOpenGLTexture::WrapMode Wrap)
450 auto *texture =
new QOpenGLTexture(
static_cast<QOpenGLTexture::Target
>(Target));
451 texture->setAutoMipMapGenerationEnabled(
false);
452 texture->setMipLevels(1);
453 texture->setSize(Size.width(), Size.height());
454 if (!texture->textureId())
456 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Failed to create texture");
461 if (
Format == QOpenGLTexture::NoFormat)
464 Format = QOpenGLTexture::RGBAFormat;
466 Format = QOpenGLTexture::RGBA8_UNorm;
468 texture->setFormat(
Format);
469 texture->allocateStorage(PixelFormat, PixelType);
470 texture->setMinMagFilters(Filter, Filter);
471 texture->setWrapMode(Wrap);
474 result->m_target = Target;
475 result->m_pixelFormat = PixelFormat;
476 result->m_pixelType = PixelType;
478 result->m_totalSize = Context->
GetTextureSize(Size, result->m_target != QOpenGLTexture::TargetRectangle);
479 result->m_bufferSize = datasize;
480 result->m_size = Size;
491 Frame->m_pitches[Plane] :
Frame->m_pitches[Plane] >> 1;
494 static_cast<const uint8_t*
>(
Frame->m_buffer) +
Frame->m_offsets[Plane]);
505 Frame->m_pitches[Plane], pitch, Texture->
m_size.height());
507 static_cast<const uint8_t *
>(Texture->
m_data));
519 void* buffer = Texture->
m_data;
535 static_cast<const uint8_t *
>(buffer));
547 Frame->m_pitches[Plane] >> (hdr ? 1 : 0));
549 static_cast<const uint8_t*
>(
Frame->m_buffer) +
Frame->m_offsets[Plane]);
558 Frame->m_pitches[Plane],
Frame->m_pitches[Plane], Texture->
m_size.height());
560 static_cast<const uint8_t *
>(Texture->
m_data));
568 if (!Texture || Size < 1)
574 memset(scratch, 0,
static_cast<size_t>(Size));
575 Texture->
m_data = scratch;
579 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to allocate texture buffer");
584 QSize Size,
bool HighPrecision)
594 if (sixteenbitfb && sixteenbitvid)
595 LOG(VB_PLAYBACK, LOG_INFO,
LOC +
"Requesting 16bit framebuffer texture");
596 auto * framebuffer = Context->
CreateFramebuffer(Size, sixteenbitfb && sixteenbitvid);
597 if (framebuffer ==
nullptr)
598 return {
nullptr,
nullptr };
600 texture->m_size = texture->m_totalSize = framebuffer->size();
602 texture->m_flip =
false;
603 texture->m_planeCount = 1;
606 texture->m_valid =
true;
607 return { framebuffer, texture };
int Copy(AVFrame *To, const MythVideoFrame *From, unsigned char *Buffer, AVPixelFormat Fmt=AV_PIX_FMT_YUV420P)
Initialise AVFrame and copy contents of VideoFrame frame into it, performing any required conversion.
QOpenGLTexture::PixelType m_pixelType
QOpenGLTexture::PixelFormat m_pixelFormat
QOpenGLTexture * m_texture
static constexpr GLuint kVertexSize
static int GetBufferSize(QSize Size, QOpenGLTexture::PixelFormat Format, QOpenGLTexture::PixelType Type)
QOpenGLBuffer * CreateVBO(int Size, bool Release=true)
QOpenGLFramebufferObject * CreateFramebuffer(QSize &Size, bool SixteenBit=false)
QSize GetTextureSize(QSize Size, bool Normalised)
int GetExtraFeatures(void) const
void SetTextureFilters(MythGLTexture *Texture, QOpenGLTexture::Filter Filter, QOpenGLTexture::WrapMode Wrap=QOpenGLTexture::ClampToEdge)
static uint GetNumPlanes(VideoFrameType Type)
static uint8_t * GetAlignedBuffer(size_t Size)
static void CopyPlane(uint8_t *To, int ToPitch, const uint8_t *From, int FromPitch, int PlaneWidth, int PlaneHeight)
static int ColorDepth(int Format)
static bool HardwareFormat(VideoFrameType Type)
static void SetTextureFilters(MythRenderOpenGL *Context, const std::vector< MythVideoTextureOpenGL * > &Textures, QOpenGLTexture::Filter Filter, QOpenGLTexture::WrapMode Wrap=QOpenGLTexture::ClampToEdge)
MythVideoTextureOpenGL(GLuint Texture)
VideoFrameType m_frameFormat
static std::vector< MythVideoTextureOpenGL * > CreateTextures(MythRenderOpenGL *Context, VideoFrameType Type, VideoFrameType Format, std::vector< QSize > Sizes, GLenum Target=QOpenGLTexture::Target2D)
Create a set of textures suitable for the given Type and Format.
static VideoFramebuffer CreateVideoFrameBuffer(MythRenderOpenGL *Context, VideoFrameType OutputType, QSize Size, bool HighPrecision=true)
static std::vector< MythVideoTextureOpenGL * > CreateHardwareTextures(MythRenderOpenGL *Context, VideoFrameType Type, VideoFrameType Format, std::vector< QSize > Sizes, GLenum Target)
Create a set of hardware textures suitable for the given format.
static void DeleteTextures(MythRenderOpenGL *Context, std::vector< MythVideoTextureOpenGL * > &Textures)
static MythVideoTextureOpenGL * CreateTexture(MythRenderOpenGL *Context, QSize Size, GLenum Target=QOpenGLTexture::Target2D, QOpenGLTexture::PixelType PixelType=QOpenGLTexture::UInt8, QOpenGLTexture::PixelFormat PixelFormat=QOpenGLTexture::RGBA, QOpenGLTexture::TextureFormat Format=QOpenGLTexture::NoFormat, QOpenGLTexture::Filter Filter=QOpenGLTexture::Linear, QOpenGLTexture::WrapMode Wrap=QOpenGLTexture::ClampToEdge)
Create and initialise a MythVideoTexture that is backed by a QOpenGLTexture.
MythAVCopy * m_copyContext
static void YV12ToYUYV(const MythVideoFrame *Frame, MythVideoTextureOpenGL *Texture)
Copy YV12 frame data to a YUYV texture.
VideoFrameType m_frameType
static void NV12ToNV12(MythRenderOpenGL *Context, const MythVideoFrame *Frame, MythVideoTextureOpenGL *Texture, uint Plane)
Copy NV12 video frame data to 'NV12' textures.
static bool CreateBuffer(MythVideoTextureOpenGL *Texture, int Size)
Create a data buffer for holding CPU side texture data.
static void DeleteTexture(MythRenderOpenGL *Context, MythVideoTextureOpenGL *Texture)
static void YV12ToYV12(MythRenderOpenGL *Context, const MythVideoFrame *Frame, MythVideoTextureOpenGL *Texture, uint Plane)
Copy YV12 frame data to 'YV12' textures.
static std::vector< MythVideoTextureOpenGL * > CreateSoftwareTextures(MythRenderOpenGL *Context, VideoFrameType Type, VideoFrameType Format, std::vector< QSize > Sizes, GLenum Target)
Create a set of OpenGL textures to represent the given Format.
static void UpdateTextures(MythRenderOpenGL *Context, const MythVideoFrame *Frame, const std::vector< MythVideoTextureOpenGL * > &Textures)
Update the contents of the given Textures for data held in Frame.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
#define GL_UNPACK_ROW_LENGTH
std::pair< QOpenGLFramebufferObject *, MythVideoTextureOpenGL * > VideoFramebuffer
VERBOSE_PREAMBLE Most true