Skip to content

Commit

Permalink
Merge r243644 - [GStreamer] imxvpudecoder detection and handling
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=196346

Reviewed by Xabier Rodriguez-Calvar.

When the imxvpudecoder is used, the texture sampling of the
directviv-uploaded texture returns an RGB value, so there's no need
to convert it. This patch also includes a refactoring of the
ImageRotation flag handling. The flag is now computed once only
and stored in an instance variable.

* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::createGSTPlayBin):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
(WebCore::GstVideoFrameHolder::GstVideoFrameHolder):
(WebCore::MediaPlayerPrivateGStreamerBase::~MediaPlayerPrivateGStreamerBase):
(WebCore::MediaPlayerPrivateGStreamerBase::pushTextureToCompositor):
(WebCore::MediaPlayerPrivateGStreamerBase::flushCurrentBuffer):
(WebCore::MediaPlayerPrivateGStreamerBase::copyVideoTextureToPlatformTexture):
(WebCore::MediaPlayerPrivateGStreamerBase::nativeImageForCurrentTime):
(WebCore::MediaPlayerPrivateGStreamerBase::setVideoSourceOrientation):
(WebCore::MediaPlayerPrivateGStreamerBase::updateTextureMapperFlags):
(WebCore::texMapFlagFromOrientation): Deleted.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:
  • Loading branch information
philn authored and carlosgcampos committed May 9, 2019
1 parent e9f09b0 commit b6c873e
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 37 deletions.
27 changes: 27 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,30 @@
2019-03-29 Philippe Normand <pnormand@igalia.com>

[GStreamer] imxvpudecoder detection and handling
https://bugs.webkit.org/show_bug.cgi?id=196346

Reviewed by Xabier Rodriguez-Calvar.

When the imxvpudecoder is used, the texture sampling of the
directviv-uploaded texture returns an RGB value, so there's no need
to convert it. This patch also includes a refactoring of the
ImageRotation flag handling. The flag is now computed once only
and stored in an instance variable.

* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::createGSTPlayBin):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
(WebCore::GstVideoFrameHolder::GstVideoFrameHolder):
(WebCore::MediaPlayerPrivateGStreamerBase::~MediaPlayerPrivateGStreamerBase):
(WebCore::MediaPlayerPrivateGStreamerBase::pushTextureToCompositor):
(WebCore::MediaPlayerPrivateGStreamerBase::flushCurrentBuffer):
(WebCore::MediaPlayerPrivateGStreamerBase::copyVideoTextureToPlatformTexture):
(WebCore::MediaPlayerPrivateGStreamerBase::nativeImageForCurrentTime):
(WebCore::MediaPlayerPrivateGStreamerBase::setVideoSourceOrientation):
(WebCore::MediaPlayerPrivateGStreamerBase::updateTextureMapperFlags):
(WebCore::texMapFlagFromOrientation): Deleted.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.h:

2019-04-24 Philippe Normand <pnormand@igalia.com>

[GStreamer] Crash in AudioTrackPrivate with playbin3 enabled
Expand Down
Expand Up @@ -2459,7 +2459,12 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin(const URL& url, const String&
return;

GUniquePtr<char> elementName(gst_element_get_name(element));
player->m_isVideoDecoderVideo4Linux = g_str_has_prefix(elementName.get(), "v4l2");
if (g_str_has_prefix(elementName.get(), "v4l2"))
player->m_videoDecoderPlatform = WebKitGstVideoDecoderPlatform::Video4Linux;
else if (g_str_has_prefix(elementName.get(), "imxvpudecoder"))
player->m_videoDecoderPlatform = WebKitGstVideoDecoderPlatform::ImxVPU;

player->updateTextureMapperFlags();
}), this);

g_signal_connect_swapped(m_pipeline.get(), "source-setup", G_CALLBACK(sourceSetupCallback), this);
Expand Down
Expand Up @@ -119,7 +119,6 @@
#include "BitmapTexturePool.h"
#include "GraphicsContext3D.h"
#include "TextureMapperContextAttributes.h"
#include "TextureMapperGL.h"
#include "TextureMapperPlatformLayerBuffer.h"
#include "TextureMapperPlatformLayerProxy.h"
#if USE(CAIRO) && ENABLE(ACCELERATED_2D_CANVAS)
Expand Down Expand Up @@ -149,26 +148,6 @@ static int greatestCommonDivisor(int a, int b)
return ABS(a);
}

#if USE(TEXTURE_MAPPER_GL)
static inline TextureMapperGL::Flags texMapFlagFromOrientation(const ImageOrientation& orientation)
{
switch (orientation) {
case DefaultImageOrientation:
return 0;
case OriginRightTop:
return TextureMapperGL::ShouldRotateTexture90;
case OriginBottomRight:
return TextureMapperGL::ShouldRotateTexture180;
case OriginLeftBottom:
return TextureMapperGL::ShouldRotateTexture270;
default:
ASSERT_NOT_REACHED();
}

return 0;
}
#endif

#if USE(TEXTURE_MAPPER_GL)
class GstVideoFrameHolder : public TextureMapperPlatformLayerBuffer::UnmanagedBufferDataHolder {
public:
Expand All @@ -185,7 +164,7 @@ class GstVideoFrameHolder : public TextureMapperPlatformLayerBuffer::UnmanagedBu
return;

#if USE(GSTREAMER_GL)
m_flags = flags | (m_hasAlphaChannel ? TextureMapperGL::ShouldBlend : 0) | TEXTURE_MAPPER_COLOR_CONVERT_FLAG;
m_flags = flags | (m_hasAlphaChannel ? TextureMapperGL::ShouldBlend : 0);

if (gstGLEnabled) {
m_isMapped = gst_video_frame_map(&m_videoFrame, &videoInfo, m_buffer, static_cast<GstMapFlags>(GST_MAP_READ | GST_MAP_GL));
Expand Down Expand Up @@ -274,7 +253,7 @@ MediaPlayerPrivateGStreamerBase::MediaPlayerPrivateGStreamerBase(MediaPlayer* pl
MediaPlayerPrivateGStreamerBase::~MediaPlayerPrivateGStreamerBase()
{
#if USE(GSTREAMER_GL)
if (m_isVideoDecoderVideo4Linux)
if (m_videoDecoderPlatform == WebKitGstVideoDecoderPlatform::Video4Linux)
flushCurrentBuffer();
#endif
#if USE(TEXTURE_MAPPER_GL) && USE(NICOSIA)
Expand Down Expand Up @@ -733,7 +712,7 @@ void MediaPlayerPrivateGStreamerBase::pushTextureToCompositor()
if (!proxy.isActive())
return;

std::unique_ptr<GstVideoFrameHolder> frameHolder = std::make_unique<GstVideoFrameHolder>(m_sample.get(), texMapFlagFromOrientation(m_videoSourceOrientation), !m_usingFallbackVideoSink);
std::unique_ptr<GstVideoFrameHolder> frameHolder = std::make_unique<GstVideoFrameHolder>(m_sample.get(), m_textureMapperFlags, !m_usingFallbackVideoSink);

GLuint textureID = frameHolder->textureID();
std::unique_ptr<TextureMapperPlatformLayerBuffer> layerBuffer;
Expand All @@ -748,7 +727,7 @@ void MediaPlayerPrivateGStreamerBase::pushTextureToCompositor()
layerBuffer = std::make_unique<TextureMapperPlatformLayerBuffer>(WTFMove(texture));
}
frameHolder->updateTexture(layerBuffer->textureGL());
layerBuffer->setExtraFlags(texMapFlagFromOrientation(m_videoSourceOrientation) | (frameHolder->hasAlphaChannel() ? TextureMapperGL::ShouldBlend : 0));
layerBuffer->setExtraFlags(m_textureMapperFlags | (frameHolder->hasAlphaChannel() ? TextureMapperGL::ShouldBlend : 0));
}
proxy.pushNextBuffer(WTFMove(layerBuffer));
};
Expand Down Expand Up @@ -874,15 +853,14 @@ void MediaPlayerPrivateGStreamerBase::flushCurrentBuffer()
gst_sample_get_segment(m_sample.get()), info ? gst_structure_copy(info) : nullptr));
}

auto proxyOperation =
[shouldWait = m_isVideoDecoderVideo4Linux, pipeline = pipeline()](TextureMapperPlatformLayerProxy& proxy)
{
GST_DEBUG_OBJECT(pipeline, "Flushing video sample %s", shouldWait ? "synchronously" : "");
LockHolder locker(!shouldWait ? &proxy.lock() : nullptr);
bool shouldWait = m_videoDecoderPlatform == WebKitGstVideoDecoderPlatform::Video4Linux;
auto proxyOperation = [shouldWait, pipeline = pipeline()](TextureMapperPlatformLayerProxy& proxy) {
GST_DEBUG_OBJECT(pipeline, "Flushing video sample %s", shouldWait ? "synchronously" : "");
LockHolder locker(!shouldWait ? &proxy.lock() : nullptr);

if (proxy.isActive())
proxy.dropCurrentBufferWhilePreservingTexture(shouldWait);
};
if (proxy.isActive())
proxy.dropCurrentBufferWhilePreservingTexture(shouldWait);
};

#if USE(NICOSIA)
proxyOperation(downcast<Nicosia::ContentLayerTextureMapperImpl>(m_nicosiaLayer->impl()).proxy());
Expand Down Expand Up @@ -936,7 +914,7 @@ bool MediaPlayerPrivateGStreamerBase::copyVideoTextureToPlatformTexture(Graphics
if (!GST_IS_SAMPLE(m_sample.get()))
return false;

std::unique_ptr<GstVideoFrameHolder> frameHolder = std::make_unique<GstVideoFrameHolder>(m_sample.get(), texMapFlagFromOrientation(m_videoSourceOrientation), true);
std::unique_ptr<GstVideoFrameHolder> frameHolder = std::make_unique<GstVideoFrameHolder>(m_sample.get(), m_textureMapperFlags, true);

auto textureID = frameHolder->textureID();
if (!textureID)
Expand All @@ -963,7 +941,7 @@ NativeImagePtr MediaPlayerPrivateGStreamerBase::nativeImageForCurrentTime()
if (!GST_IS_SAMPLE(m_sample.get()))
return nullptr;

std::unique_ptr<GstVideoFrameHolder> frameHolder = std::make_unique<GstVideoFrameHolder>(m_sample.get(), texMapFlagFromOrientation(m_videoSourceOrientation), true);
std::unique_ptr<GstVideoFrameHolder> frameHolder = std::make_unique<GstVideoFrameHolder>(m_sample.get(), m_textureMapperFlags, true);

auto textureID = frameHolder->textureID();
if (!textureID)
Expand Down Expand Up @@ -995,8 +973,41 @@ void MediaPlayerPrivateGStreamerBase::setVideoSourceOrientation(const ImageOrien
return;

m_videoSourceOrientation = orientation;
#if USE(TEXTURE_MAPPER_GL)
updateTextureMapperFlags();
#endif
}

#if USE(TEXTURE_MAPPER_GL)
void MediaPlayerPrivateGStreamerBase::updateTextureMapperFlags()
{
switch (m_videoSourceOrientation) {
case DefaultImageOrientation:
m_textureMapperFlags = 0;
break;
case OriginRightTop:
m_textureMapperFlags = TextureMapperGL::ShouldRotateTexture90;
break;
case OriginBottomRight:
m_textureMapperFlags = TextureMapperGL::ShouldRotateTexture180;
break;
case OriginLeftBottom:
m_textureMapperFlags = TextureMapperGL::ShouldRotateTexture270;
break;
default:
// FIXME: Handle OriginTopRight, OriginBottomLeft, OriginLeftTop and OriginRightBottom?
m_textureMapperFlags = 0;
break;
}

// When the imxvpudecoder is used, the texture sampling of the
// directviv-uploaded texture returns an RGB value, so there's no need to
// convert it.
if (m_videoDecoderPlatform != WebKitGstVideoDecoderPlatform::ImxVPU)
m_textureMapperFlags |= TEXTURE_MAPPER_COLOR_CONVERT_FLAG;
}
#endif

bool MediaPlayerPrivateGStreamerBase::supportsFullscreen() const
{
return true;
Expand Down
Expand Up @@ -38,6 +38,7 @@
#include <wtf/WeakPtr.h>

#if USE(TEXTURE_MAPPER_GL)
#include "TextureMapperGL.h"
#if USE(NICOSIA)
#include "NicosiaContentLayerTextureMapperImpl.h"
#else
Expand Down Expand Up @@ -221,6 +222,11 @@ class MediaPlayerPrivateGStreamerBase : public MediaPlayerPrivateInterface, publ
static void volumeChangedCallback(MediaPlayerPrivateGStreamerBase*);
static void muteChangedCallback(MediaPlayerPrivateGStreamerBase*);

#if USE(TEXTURE_MAPPER_GL)
void updateTextureMapperFlags();
TextureMapperGL::Flags m_textureMapperFlags;
#endif

enum MainThreadNotification {
VideoChanged = 1 << 0,
VideoCapsChanged = 1 << 1,
Expand Down Expand Up @@ -283,7 +289,9 @@ class MediaPlayerPrivateGStreamerBase : public MediaPlayerPrivateInterface, publ
bool m_waitingForKey { false };
#endif

mutable bool m_isVideoDecoderVideo4Linux { false };
enum class WebKitGstVideoDecoderPlatform { ImxVPU, Video4Linux };

WebKitGstVideoDecoderPlatform m_videoDecoderPlatform;
};

}
Expand Down

0 comments on commit b6c873e

Please sign in to comment.