From ce22296d0ebb306bae4bd822ac2ccea7743341bd Mon Sep 17 00:00:00 2001
From: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
Date: Tue, 8 Aug 2023 09:34:35 -0400
Subject: [PATCH] video: fix video cropping

This patch transfers hardware-decoded frames to main memory
if cropping is required.

Change-Id: I3b06868a744eb3a72340ce6f90e3c89564f49ace
---
 src/media/video/sinkclient.cpp | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/src/media/video/sinkclient.cpp b/src/media/video/sinkclient.cpp
index 8a333e5817..db0c29001f 100644
--- a/src/media/video/sinkclient.cpp
+++ b/src/media/video/sinkclient.cpp
@@ -342,7 +342,33 @@ SinkClient::sendFrameDirect(const std::shared_ptr<jami::MediaFrame>& frame_p)
 
     libjami::FrameBuffer outFrame(av_frame_alloc());
     av_frame_ref(outFrame.get(), std::static_pointer_cast<VideoFrame>(frame_p)->pointer());
+
     if (crop_.w || crop_.h) {
+#ifdef RING_ACCEL
+        auto desc = av_pix_fmt_desc_get(
+            (AVPixelFormat) std::static_pointer_cast<VideoFrame>(frame_p)->format());
+        /*
+         Cropping does not work for hardware-decoded frames.
+         They need to be transferred to main memory.
+         */
+        if (desc && (desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
+            std::shared_ptr<VideoFrame> frame = std::make_shared<VideoFrame>();
+            try {
+                frame = HardwareAccel::transferToMainMemory(*std::static_pointer_cast<VideoFrame>(
+                                                                frame_p),
+                                                            AV_PIX_FMT_NV12);
+            } catch (const std::runtime_error& e) {
+                JAMI_ERR("[Sink:%p] Transfert to hardware acceleration memory failed: %s",
+                         this,
+                         e.what());
+                return;
+            }
+            if (not frame)
+                return;
+            av_frame_unref(outFrame.get());
+            av_frame_ref(outFrame.get(), frame->pointer());
+        }
+#endif
         outFrame->crop_top = crop_.y;
         outFrame->crop_bottom = (size_t) outFrame->height - crop_.y - crop_.h;
         outFrame->crop_left = crop_.x;
@@ -474,7 +500,11 @@ SinkClient::setFrameSize(int width, int height)
                  width,
                  height,
                  mixer_ ? "Yes" : "No");
-        emitSignal<libjami::VideoSignal::DecodingStarted>(getId(), openedName(), width, height, mixer_);
+        emitSignal<libjami::VideoSignal::DecodingStarted>(getId(),
+                                                          openedName(),
+                                                          width,
+                                                          height,
+                                                          mixer_);
         started_ = true;
     } else if (started_) {
         JAMI_DBG("[Sink:%p] Stopped - size=%dx%d, mixer=%s",
-- 
GitLab