Signed-off-by: Lim Siew Hoon <[email protected]>
---
 ...-stuttering-during-wayland-rendering.patch | 230 ++++++++++++++++++
 .../mediasdk/intel-mediasdk_20.3.0.bb         |   1 +
 2 files changed, 231 insertions(+)
 create mode 100644 
recipes-multimedia/mediasdk/files/0001-Fix-video-stuttering-during-wayland-rendering.patch

diff --git 
a/recipes-multimedia/mediasdk/files/0001-Fix-video-stuttering-during-wayland-rendering.patch
 
b/recipes-multimedia/mediasdk/files/0001-Fix-video-stuttering-during-wayland-rendering.patch
new file mode 100644
index 00000000..e987c110
--- /dev/null
+++ 
b/recipes-multimedia/mediasdk/files/0001-Fix-video-stuttering-during-wayland-rendering.patch
@@ -0,0 +1,230 @@
+From 0c07c8b9ecbb1224b74712f5b41f2504d27ff38f Mon Sep 17 00:00:00 2001
+From: Lim Siew Hoon <[email protected]>
+Date: Tue, 24 Nov 2020 14:44:05 +0800
+Subject: [PATCH] Fix video stuttering during wayland rendering
+
+The issue at here when RenderFrame exits, does not mean
+corresponding wl_buffer is not used anymore by weston.
+So, the wl_buffer has be wait until buffer_release function
+call out under wl_buffer_listener get trigger. Than only
+consider wl_buffer is no longer used anymore by weston and
+safe to use by previous upper component like vpp csc.
+
+The implementation code fixed at here is to prevent surface
+get overwrite and used back by vpp csc inside sample_decode
+when wl_buffer still not yet release when RenderFrame exits.
+
+Platform: EHL, TGL-U, TGL-H
+OS: Yocto native wayland weston
+Tested:
+./sample_decode h264 -i Puppies_1920x1080.h264 -rwld -rgb4 -f 30
+
+Signed-off-by: Lim Siew Hoon <[email protected]>
+
+The patch was imported from the MediaSDK git server
+([email protected]:Intel-Media-SDK/MediaSDK.git) as of commit id
+75bd6562f7ea90e2a2666dccab9c09ea58d3d23e.
+
+Upstream-Status: backport
+
+Signed-off-by: Lim Siew Hoon <[email protected]>
+---
+ samples/sample_common/src/vaapi_device.cpp    |  2 +-
+ .../wayland/include/class_wayland.h           | 16 ++++-
+ .../sample_misc/wayland/src/class_wayland.cpp | 67 +++++++++++++++++--
+ .../wayland/src/listener_wayland.cpp          |  2 +
+ 4 files changed, 78 insertions(+), 9 deletions(-)
+
+diff --git a/samples/sample_common/src/vaapi_device.cpp 
b/samples/sample_common/src/vaapi_device.cpp
+index de435fe7..238449ff 100644
+--- a/samples/sample_common/src/vaapi_device.cpp
++++ b/samples/sample_common/src/vaapi_device.cpp
+@@ -397,7 +397,7 @@ mfxStatus 
CVAAPIDeviceWayland::RenderFrame(mfxFrameSurface1 * pSurface, mfxFrame
+             return mfx_res;
+     }
+ 
+-    m_Wayland->RenderBuffer(m_wl_buffer, pSurface->Info.CropW, 
pSurface->Info.CropH);
++    m_Wayland->RenderBuffer(m_wl_buffer, pSurface);
+ 
+     return mfx_res;
+ }
+diff --git a/samples/sample_misc/wayland/include/class_wayland.h 
b/samples/sample_misc/wayland/include/class_wayland.h
+index c2c8cea0..18a1e406 100644
+--- a/samples/sample_misc/wayland/include/class_wayland.h
++++ b/samples/sample_misc/wayland/include/class_wayland.h
+@@ -28,7 +28,13 @@ extern "C"
+ }
+ #include <poll.h>
+ #include <wayland-client.h>
++#include <list>
+ #include "wayland-drm-client-protocol.h"
++#include "mfxstructures.h"
++#include "mfx_buffering.h"
++#include "sample_defs.h"
++
++typedef struct buffer wld_buffer;
+ 
+ /* ShmPool Struct */
+ struct ShmPool {
+@@ -38,7 +44,7 @@ struct ShmPool {
+     unsigned size;
+ };
+ 
+-class Wayland {
++class Wayland: public CBuffering {
+     public:
+         Wayland();
+         virtual ~Wayland();
+@@ -47,8 +53,7 @@ class Wayland {
+         virtual void FreeSurface();
+         virtual void SetRenderWinPos(int x, int y);
+         virtual void RenderBuffer(struct wl_buffer *buffer
+-            , int32_t width
+-            , int32_t height);
++            , mfxFrameSurface1 *surface);
+         virtual void RenderBufferWinPosSize(struct wl_buffer *buffer
+             , int x
+             , int y
+@@ -115,6 +120,9 @@ class Wayland {
+         void DestroyCallback();
+         virtual void Sync();
+         virtual void SetPerfMode(bool perf_mode);
++        void AddBufferToList(wld_buffer *buffer);
++        void RemoveBufferFromList(struct wl_buffer *buffer);
++        void DestroyBufferList();
+     private:
+         //no copies allowed
+         Wayland(const Wayland &);
+@@ -140,6 +148,8 @@ class Wayland {
+         char *m_device_name;
+         int m_x, m_y;
+         bool m_perf_mode;
++    protected:
++        std::list<wld_buffer*> m_buffers_list;
+ };
+ 
+ extern "C" Wayland* WaylandCreate();
+diff --git a/samples/sample_misc/wayland/src/class_wayland.cpp 
b/samples/sample_misc/wayland/src/class_wayland.cpp
+index 5d0e6208..62f326e3 100644
+--- a/samples/sample_misc/wayland/src/class_wayland.cpp
++++ b/samples/sample_misc/wayland/src/class_wayland.cpp
+@@ -35,6 +35,11 @@ extern "C" {
+ 
+ #define BATCH_SIZE 0x80000
+ 
++struct buffer {
++   struct wl_buffer *buffer;
++   mfxFrameSurface1 *pInSurface;
++};
++
+ static const struct wl_callback_listener frame_listener = {
+     handle_done
+ };
+@@ -169,15 +174,22 @@ void Wayland::SetRenderWinPos(int x, int y)
+ }
+ 
+ void Wayland::RenderBuffer(struct wl_buffer *buffer
+-     , int32_t width
+-     , int32_t height)
++     , mfxFrameSurface1 *surface)
+ {
++    wld_buffer *m_buffer = new wld_buffer;
++    if (m_buffer == NULL)
++      return;
++
++    m_buffer->buffer = buffer;
++    m_buffer->pInSurface = surface;
++
+     wl_surface_attach(m_surface, buffer, 0, 0);
+-    wl_surface_damage(m_surface, m_x, m_y, width, height);
++    wl_surface_damage(m_surface, m_x, m_y, surface->Info.CropW, 
surface->Info.CropH);
+ 
+     wl_proxy_set_queue((struct wl_proxy *) buffer, m_event_queue);
+ 
+-    wl_buffer_add_listener(buffer, &buffer_listener, NULL);
++    AddBufferToList(m_buffer);
++    wl_buffer_add_listener(buffer, &buffer_listener, this);
+     m_pending_frame=1;
+     if (m_perf_mode)
+         m_callback = wl_display_sync(m_display);
+@@ -365,6 +377,8 @@ Wayland::~Wayland()
+         wl_compositor_destroy(m_compositor);
+     if(NULL != m_event_queue)
+         wl_event_queue_destroy(m_event_queue);
++    if(0 != m_buffers_list.size())
++        DestroyBufferList();
+     if(NULL != m_registry)
+         wl_registry_destroy(m_registry);
+     if(NULL != m_display)
+@@ -428,6 +442,50 @@ void Wayland::DrmHandleAuthenticated()
+     m_bufmgr = drm_intel_bufmgr_gem_init(m_fd, BATCH_SIZE);
+ }
+ 
++void Wayland::AddBufferToList(wld_buffer *buffer)
++{
++   if (buffer == NULL)
++     return;
++
++   if (buffer->pInSurface) {
++     msdkFrameSurface *surface = FindUsedSurface(buffer->pInSurface);
++     msdk_atomic_inc16(&(surface->render_lock));
++     m_buffers_list.push_back(buffer);
++   }
++}
++
++void Wayland::RemoveBufferFromList(struct wl_buffer *buffer)
++{
++   wld_buffer *m_buffer = NULL;
++   m_buffer = m_buffers_list.front();
++   if (NULL != m_buffer && (m_buffer->buffer == buffer)) {
++     if (m_buffer->pInSurface) {
++       msdkFrameSurface *surface = FindUsedSurface(m_buffer->pInSurface);
++       msdk_atomic_dec16(&(surface->render_lock));
++     }
++     m_buffer->buffer = NULL;
++     m_buffer->pInSurface = NULL;
++     m_buffers_list.pop_front();
++     delete m_buffer;
++   }
++}
++
++void Wayland::DestroyBufferList()
++{
++   wld_buffer *m_buffer = NULL;
++   while (!m_buffers_list.empty())
++   {
++      m_buffer = m_buffers_list.front();
++      if (m_buffer->pInSurface)
++      {
++        msdkFrameSurface *surface = FindUsedSurface(m_buffer->pInSurface);
++        msdk_atomic_dec16(&(surface->render_lock));
++      }
++      m_buffers_list.pop_front();
++      delete m_buffer;
++   }
++}
++
+ Wayland* WaylandCreate()
+ {
+     return new Wayland;
+@@ -437,4 +495,3 @@ void WaylandDestroy(Wayland *pWld)
+ {
+     delete pWld;
+ }
+-
+diff --git a/samples/sample_misc/wayland/src/listener_wayland.cpp 
b/samples/sample_misc/wayland/src/listener_wayland.cpp
+index dc68c1d5..90f582a7 100644
+--- a/samples/sample_misc/wayland/src/listener_wayland.cpp
++++ b/samples/sample_misc/wayland/src/listener_wayland.cpp
+@@ -98,6 +98,8 @@ void handle_done(void *data, struct wl_callback *callback, 
uint32_t time)
+ 
+ void buffer_release(void *data, struct wl_buffer *buffer)
+ {
++    Wayland *wayland = static_cast<Wayland*>(data);
++    wayland->RemoveBufferFromList(buffer);
+     wl_buffer_destroy(buffer);
+     buffer = NULL;
+ }
+-- 
+2.17.1
+
diff --git a/recipes-multimedia/mediasdk/intel-mediasdk_20.3.0.bb 
b/recipes-multimedia/mediasdk/intel-mediasdk_20.3.0.bb
index 62cc2a5c..871b63fa 100644
--- a/recipes-multimedia/mediasdk/intel-mediasdk_20.3.0.bb
+++ b/recipes-multimedia/mediasdk/intel-mediasdk_20.3.0.bb
@@ -34,6 +34,7 @@ PACKAGECONFIG[wayland]        = "-DENABLE_WAYLAND=ON, 
-DENABLE_WAYLAND=OFF, wayland way
 SRC_URI = 
"git://github.com/Intel-Media-SDK/MediaSDK.git;protocol=https;branch=${BPN}-20.3;lfs=0
 \
            
file://0001-FindOpenCL.cmake-don-t-look-for-driver-at-build-time.patch \
            file://0001-FindITT.cmake-fix-detection-of-header-library.patch \
+           file://0001-Fix-video-stuttering-during-wayland-rendering.patch \
            "
 SRCREV = "34c7cbbb3775bd547a16ea37576297b290b603a4"
 S = "${WORKDIR}/git"
-- 
2.17.1

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#6833): 
https://lists.yoctoproject.org/g/meta-intel/message/6833
Mute This Topic: https://lists.yoctoproject.org/mt/78515725/21656
Group Owner: [email protected]
Unsubscribe: https://lists.yoctoproject.org/g/meta-intel/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to