Changeset 249428 in webkit
- Timestamp:
- Sep 3, 2019 7:14:57 AM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r249427 r249428 1 2019-09-03 Chris Lord <clord@igalia.com> 2 3 [GStreamer] Add support to copy YUV video textures into platform textures 4 https://bugs.webkit.org/show_bug.cgi?id=200914 5 6 Reviewed by Xabier Rodriguez-Calvar and Miguel Gomez. 7 8 Enable YUV (including planar and semi-planar) video texture to platform 9 texture copy in VideoTextureCopierGStreamer. 10 11 No new tests, not changing behavior. 12 13 * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp: 14 (WebCore::GstVideoFrameHolder::platformLayerBuffer): 15 (WebCore::MediaPlayerPrivateGStreamerBase::pushTextureToCompositor): 16 (WebCore::MediaPlayerPrivateGStreamerBase::copyVideoTextureToPlatformTexture): 17 (WebCore::MediaPlayerPrivateGStreamerBase::nativeImageForCurrentTime): 18 * platform/graphics/gstreamer/VideoTextureCopierGStreamer.cpp: 19 (WebCore::VideoTextureCopierGStreamer::VideoTextureCopierGStreamer): 20 (WebCore::VideoTextureCopierGStreamer::copyVideoTextureToPlatformTexture): 21 * platform/graphics/gstreamer/VideoTextureCopierGStreamer.h: 22 * platform/graphics/texmap/TextureMapperPlatformLayerBuffer.h: 23 (WebCore::TextureMapperPlatformLayerBuffer::textureVariant): 24 1 25 2019-09-03 Zan Dobersek <zdobersek@igalia.com> and Chris Lord <clord@igalia.com> 2 26 -
trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp
r249427 r249428 217 217 } 218 218 219 std::unique_ptr<TextureMapperPlatformLayerBuffer> platformLayerBuffer() 220 { 221 if (!m_hasMappedTextures) 222 return nullptr; 223 224 using Buffer = TextureMapperPlatformLayerBuffer; 225 226 if ((GST_VIDEO_INFO_IS_RGB(&m_videoFrame.info) && GST_VIDEO_INFO_N_PLANES(&m_videoFrame.info) == 1)) 227 return makeUnique<Buffer>(Buffer::TextureVariant { Buffer::RGBTexture { *static_cast<GLuint*>(m_videoFrame.data[0]) } }, m_size, m_flags, GraphicsContext3D::RGBA); 228 229 if (GST_VIDEO_INFO_IS_YUV(&m_videoFrame.info)) { 230 if (GST_VIDEO_INFO_N_COMPONENTS(&m_videoFrame.info) < 3 || GST_VIDEO_INFO_N_PLANES(&m_videoFrame.info) > 3) 231 return nullptr; 232 233 unsigned numberOfPlanes = GST_VIDEO_INFO_N_PLANES(&m_videoFrame.info); 234 std::array<GLuint, 3> planes; 235 std::array<unsigned, 3> yuvPlane; 236 std::array<unsigned, 3> yuvPlaneOffset; 237 for (unsigned i = 0; i < numberOfPlanes; ++i) 238 planes[i] = *static_cast<GLuint*>(m_videoFrame.data[i]); 239 for (unsigned i = 0; i < 3; ++i) { 240 yuvPlane[i] = GST_VIDEO_INFO_COMP_PLANE(&m_videoFrame.info, i); 241 yuvPlaneOffset[i] = GST_VIDEO_INFO_COMP_POFFSET(&m_videoFrame.info, i); 242 } 243 244 std::array<GLfloat, 9> yuvToRgb; 245 if (gst_video_colorimetry_matches(&GST_VIDEO_INFO_COLORIMETRY(&m_videoFrame.info), GST_VIDEO_COLORIMETRY_BT709)) { 246 yuvToRgb = { 247 1.164f, 0.0f, 1.787f, 248 1.164f, -0.213f, -0.531f, 249 1.164f, 2.112f, 0.0f 250 }; 251 } else { 252 // Default to bt601. This is the same behaviour as GStreamer's glcolorconvert element. 253 yuvToRgb = { 254 1.164f, 0.0f, 1.596f, 255 1.164f, -0.391f, -0.813f, 256 1.164f, 2.018f, 0.0f 257 }; 258 } 259 260 return makeUnique<Buffer>( Buffer::TextureVariant { Buffer::YUVTexture { numberOfPlanes, planes, yuvPlane, yuvPlaneOffset, yuvToRgb } }, m_size, m_flags, GraphicsContext3D::RGBA); 261 } 262 263 return nullptr; 264 } 265 219 266 private: 220 267 GstBuffer* m_buffer; … … 733 780 std::unique_ptr<GstVideoFrameHolder> frameHolder = makeUnique<GstVideoFrameHolder>(m_sample.get(), m_textureMapperFlags, !m_usingFallbackVideoSink); 734 781 735 using Buffer = TextureMapperPlatformLayerBuffer; 736 std::unique_ptr<Buffer> layerBuffer; 782 std::unique_ptr<TextureMapperPlatformLayerBuffer> layerBuffer; 737 783 if (frameHolder->hasMappedTextures()) { 738 auto& videoFrame = frameHolder->videoFrame(); 739 [&] { 740 if ((GST_VIDEO_INFO_IS_RGB(&videoFrame.info) && GST_VIDEO_INFO_N_PLANES(&videoFrame.info) == 1)) { 741 layerBuffer = makeUnique<Buffer>( 742 Buffer::TextureVariant { Buffer::RGBTexture { *static_cast<GLuint*>(videoFrame.data[0]) } }, 743 frameHolder->size(), frameHolder->flags(), GraphicsContext3D::RGBA); 744 return; 745 } 746 747 if (GST_VIDEO_INFO_IS_YUV(&videoFrame.info)) { 748 if (GST_VIDEO_INFO_N_COMPONENTS(&videoFrame.info) < 3 || GST_VIDEO_INFO_N_PLANES(&videoFrame.info) > 3) 749 return; 750 751 unsigned numberOfPlanes = GST_VIDEO_INFO_N_PLANES(&videoFrame.info); 752 std::array<GLuint, 3> planes; 753 std::array<unsigned, 3> yuvPlane; 754 std::array<unsigned, 3> yuvPlaneOffset; 755 for (unsigned i = 0; i < numberOfPlanes; ++i) 756 planes[i] = *static_cast<GLuint*>(videoFrame.data[i]); 757 for (unsigned i = 0; i < 3; ++i) { 758 yuvPlane[i] = GST_VIDEO_INFO_COMP_PLANE(&videoFrame.info, i); 759 yuvPlaneOffset[i] = GST_VIDEO_INFO_COMP_POFFSET(&videoFrame.info, i); 760 } 761 762 std::array<GLfloat, 9> yuvToRgb; 763 if (gst_video_colorimetry_matches(&GST_VIDEO_INFO_COLORIMETRY(&videoFrame.info), GST_VIDEO_COLORIMETRY_BT709)) { 764 yuvToRgb = { 765 1.164f, 0.0f, 1.787f, 766 1.164f, -0.213f, -0.531f, 767 1.164f, 2.112f, 0.0f 768 }; 769 } else { 770 // Default to bt601. This is the same behaviour as GStreamer's glcolorconvert element. 771 yuvToRgb = { 772 1.164f, 0.0f, 1.596f, 773 1.164f, -0.391f, -0.813f, 774 1.164f, 2.018f, 0.0f 775 }; 776 } 777 778 layerBuffer = makeUnique<Buffer>(Buffer::TextureVariant { Buffer::YUVTexture { numberOfPlanes, planes, yuvPlane, yuvPlaneOffset, yuvToRgb } }, 779 frameHolder->size(), frameHolder->flags(), GraphicsContext3D::RGBA); 780 } 781 }(); 782 784 layerBuffer = frameHolder->platformLayerBuffer(); 783 785 if (!layerBuffer) 784 786 return; 785 786 787 layerBuffer->setUnmanagedBufferDataHolder(WTFMove(frameHolder)); 787 788 } else { … … 994 995 std::unique_ptr<GstVideoFrameHolder> frameHolder = makeUnique<GstVideoFrameHolder>(m_sample.get(), m_textureMapperFlags, true); 995 996 996 auto textureID = frameHolder->textureID();997 if (! textureID)997 std::unique_ptr<TextureMapperPlatformLayerBuffer> layerBuffer = frameHolder->platformLayerBuffer(); 998 if (!layerBuffer) 998 999 return false; 999 1000 … … 1005 1006 m_videoTextureCopier = makeUnique<VideoTextureCopierGStreamer>(TEXTURE_COPIER_COLOR_CONVERT_FLAG); 1006 1007 1007 return m_videoTextureCopier->copyVideoTextureToPlatformTexture(textureID, size, outputTexture, outputTarget, level, internalFormat, format, type, flipY, m_videoSourceOrientation); 1008 frameHolder->waitForCPUSync(); 1009 1010 return m_videoTextureCopier->copyVideoTextureToPlatformTexture(*layerBuffer.get(), size, outputTexture, outputTarget, level, internalFormat, format, type, flipY, m_videoSourceOrientation); 1008 1011 } 1009 1012 … … 1021 1024 std::unique_ptr<GstVideoFrameHolder> frameHolder = makeUnique<GstVideoFrameHolder>(m_sample.get(), m_textureMapperFlags, true); 1022 1025 1023 auto textureID = frameHolder->textureID();1024 if (! textureID)1026 std::unique_ptr<TextureMapperPlatformLayerBuffer> layerBuffer = frameHolder->platformLayerBuffer(); 1027 if (!layerBuffer) 1025 1028 return nullptr; 1026 1029 … … 1035 1038 m_videoTextureCopier = makeUnique<VideoTextureCopierGStreamer>(TEXTURE_COPIER_COLOR_CONVERT_FLAG); 1036 1039 1037 if (!m_videoTextureCopier->copyVideoTextureToPlatformTexture(textureID, size, 0, GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, false, m_videoSourceOrientation)) 1040 frameHolder->waitForCPUSync(); 1041 1042 if (!m_videoTextureCopier->copyVideoTextureToPlatformTexture(*layerBuffer.get(), size, 0, GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, false, m_videoSourceOrientation)) 1038 1043 return nullptr; 1039 1044 -
trunk/Source/WebCore/platform/graphics/gstreamer/VideoTextureCopierGStreamer.cpp
r249427 r249428 35 35 ASSERT(previousContext); 36 36 PlatformDisplay::sharedDisplayForCompositing().sharingGLContext()->makeContextCurrent(); 37 38 m_shaderProgram = TextureMapperShaderProgram::create(TextureMapperShaderProgram::TextureRGB);39 37 40 38 glGenFramebuffers(1, &m_framebuffer); … … 138 136 } 139 137 140 bool VideoTextureCopierGStreamer::copyVideoTextureToPlatformTexture( GLuintinputTexture, IntSize& frameSize, GLuint outputTexture, GLenum outputTarget, GLint level, GLenum internalFormat, GLenum format, GLenum type, bool flipY, ImageOrientation sourceOrientation)141 { 142 if (!m_ shaderProgram || !m_framebuffer || !m_vbo || frameSize.isEmpty())138 bool VideoTextureCopierGStreamer::copyVideoTextureToPlatformTexture(TextureMapperPlatformLayerBuffer& inputTexture, IntSize& frameSize, GLuint outputTexture, GLenum outputTarget, GLint level, GLenum internalFormat, GLenum format, GLenum type, bool flipY, ImageOrientation sourceOrientation) 139 { 140 if (!m_framebuffer || !m_vbo || frameSize.isEmpty()) 143 141 return false; 144 142 … … 158 156 ASSERT(previousContext); 159 157 PlatformDisplay::sharedDisplayForCompositing().sharingGLContext()->makeContextCurrent(); 158 159 // Determine what shader program to use and create it if necessary. 160 using Buffer = TextureMapperPlatformLayerBuffer; 161 TextureMapperShaderProgram::Options options; 162 WTF::switchOn(inputTexture.textureVariant(), 163 [&](const Buffer::RGBTexture&) { options = TextureMapperShaderProgram::TextureRGB; }, 164 [&](const Buffer::YUVTexture& texture) { 165 switch (texture.numberOfPlanes) { 166 case 1: 167 ASSERT(texture.yuvPlane[0] == texture.yuvPlane[1] && texture.yuvPlane[1] == texture.yuvPlane[2]); 168 ASSERT(texture.yuvPlaneOffset[0] == 2 && texture.yuvPlaneOffset[1] == 1 && !texture.yuvPlaneOffset[2]); 169 options = TextureMapperShaderProgram::TexturePackedYUV; 170 break; 171 case 2: 172 ASSERT(!texture.yuvPlaneOffset[0]); 173 options = texture.yuvPlaneOffset[1] ? TextureMapperShaderProgram::TextureNV21 : TextureMapperShaderProgram::TextureNV12; 174 break; 175 case 3: 176 ASSERT(!texture.yuvPlaneOffset[0] && !texture.yuvPlaneOffset[1] && !texture.yuvPlaneOffset[2]); 177 options = TextureMapperShaderProgram::TextureYUV; 178 break; 179 } 180 }); 181 182 if (options != m_shaderOptions) { 183 m_shaderProgram = TextureMapperShaderProgram::create(options); 184 m_shaderOptions = options; 185 } 186 if (!m_shaderProgram) { 187 previousContext->makeContextCurrent(); 188 return false; 189 } 160 190 161 191 // Save previous bound framebuffer, texture and viewport. … … 182 212 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, outputTexture, 0); 183 213 184 // Set proper wrap parameter to the source texture.185 glBindTexture(GL_TEXTURE_2D, inputTexture);186 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);187 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);188 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);189 190 214 // Set the viewport. 191 215 glViewport(0, 0, m_size.width(), m_size.height()); … … 193 217 // Set program parameters. 194 218 glUseProgram(m_shaderProgram->programID()); 195 glUniform1i(m_shaderProgram->samplerLocation(), 0); 219 220 WTF::switchOn(inputTexture.textureVariant(), 221 [&](const Buffer::RGBTexture& texture) { 222 glUniform1i(m_shaderProgram->samplerLocation(), 0); 223 224 glActiveTexture(GL_TEXTURE0); 225 glBindTexture(GL_TEXTURE_2D, texture.id); 226 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 227 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 228 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 229 }, 230 [&](const Buffer::YUVTexture& texture) { 231 switch (texture.numberOfPlanes) { 232 case 1: 233 glUniform1i(m_shaderProgram->samplerLocation(), texture.yuvPlane[0]); 234 break; 235 case 2: 236 glUniform1i(m_shaderProgram->samplerYLocation(), texture.yuvPlane[0]); 237 glUniform1i(m_shaderProgram->samplerULocation(), texture.yuvPlane[1]); 238 break; 239 case 3: 240 glUniform1i(m_shaderProgram->samplerYLocation(), texture.yuvPlane[0]); 241 glUniform1i(m_shaderProgram->samplerULocation(), texture.yuvPlane[1]); 242 glUniform1i(m_shaderProgram->samplerVLocation(), texture.yuvPlane[2]); 243 break; 244 } 245 glUniformMatrix3fv(m_shaderProgram->yuvToRgbLocation(), 1, GL_FALSE, static_cast<const GLfloat *>(&texture.yuvToRgbMatrix[0])); 246 247 for (int i = texture.numberOfPlanes - 1; i >= 0; --i) { 248 glActiveTexture(GL_TEXTURE0 + i); 249 glBindTexture(GL_TEXTURE_2D, texture.planes[i]); 250 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 251 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 252 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 253 } 254 }); 255 196 256 m_shaderProgram->setMatrix(m_shaderProgram->modelViewMatrixLocation(), m_modelViewMatrix); 197 257 m_shaderProgram->setMatrix(m_shaderProgram->projectionMatrixLocation(), m_projectionMatrix); -
trunk/Source/WebCore/platform/graphics/gstreamer/VideoTextureCopierGStreamer.h
r248946 r249428 25 25 #include "ImageOrientation.h" 26 26 #include "TextureMapperGLHeaders.h" 27 #include "TextureMapperPlatformLayerBuffer.h" 27 28 #include "TransformationMatrix.h" 28 29 #include <wtf/RefPtr.h> … … 45 46 ~VideoTextureCopierGStreamer(); 46 47 47 bool copyVideoTextureToPlatformTexture( GLuintinputTexture, IntSize& frameSize, GLuint outputTexture, GLenum outputTarget, GLint level, GLenum internalFormat, GLenum format, GLenum type, bool flipY, ImageOrientation sourceOrientation);48 bool copyVideoTextureToPlatformTexture(TextureMapperPlatformLayerBuffer& inputTexture, IntSize& frameSize, GLuint outputTexture, GLenum outputTarget, GLint level, GLenum internalFormat, GLenum format, GLenum type, bool flipY, ImageOrientation sourceOrientation); 48 49 void updateColorConversionMatrix(ColorConversion); 49 50 void updateTextureSpaceMatrix(); … … 53 54 private: 54 55 RefPtr<TextureMapperShaderProgram> m_shaderProgram; 56 unsigned m_shaderOptions { 0 }; 55 57 GLuint m_framebuffer { 0 }; 56 58 GLuint m_vbo { 0 }; -
trunk/Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayerBuffer.h
r249427 r249428 93 93 void setHolePunchClient(std::unique_ptr<HolePunchClient>&& client) { m_holePunchClient = WTFMove(client); } 94 94 95 const TextureVariant& textureVariant() { return m_variant; } 96 95 97 private: 96 98
Note: See TracChangeset
for help on using the changeset viewer.