git: cf95c7f7bf4c - main - multimedia/kodi: fix ac3 encoding for ffmpeg6

From: Fernando Apesteguía <fernape_at_FreeBSD.org>
Date: Wed, 21 Jun 2023 05:50:44 UTC
The branch main has been updated by fernape:

URL: https://cgit.FreeBSD.org/ports/commit/?id=cf95c7f7bf4c3b465f77629f3da2532f24c4034f

commit cf95c7f7bf4c3b465f77629f3da2532f24c4034f
Author:     yzrh <yzrh@noema.org>
AuthorDate: 2023-06-20 13:07:32 +0000
Commit:     Fernando Apesteguía <fernape@FreeBSD.org>
CommitDate: 2023-06-21 05:45:27 +0000

    multimedia/kodi: fix ac3 encoding for ffmpeg6
    
    Add patch to fix the reported issue.
    
    PR:             272046
    Reported by:    yzrh@noema.org (maintainer)
---
 multimedia/kodi/Makefile                    |  2 +-
 multimedia/kodi/files/patch-ffmpeg6-support | 67 ++++++++++++++++-------------
 2 files changed, 37 insertions(+), 32 deletions(-)

diff --git a/multimedia/kodi/Makefile b/multimedia/kodi/Makefile
index e1bddf9a55d6..83753da338ac 100644
--- a/multimedia/kodi/Makefile
+++ b/multimedia/kodi/Makefile
@@ -1,6 +1,6 @@
 PORTNAME=	kodi
 DISTVERSION=	20.1
-PORTREVISION=	3
+PORTREVISION=	4
 CATEGORIES=	multimedia java
 # do not forget to fix devel/kodi-platform when updating kodi
 
diff --git a/multimedia/kodi/files/patch-ffmpeg6-support b/multimedia/kodi/files/patch-ffmpeg6-support
index 2ab9cbc27a3d..f337f73931b2 100644
--- a/multimedia/kodi/files/patch-ffmpeg6-support
+++ b/multimedia/kodi/files/patch-ffmpeg6-support
@@ -536,7 +536,7 @@ diff -urN xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp.orig xbmc/cores/Au
        avcodec_free_context(&m_CodecCtx);
        return false;
      }
-@@ -242,62 +261,78 @@
+@@ -242,62 +261,83 @@
  
  int CAEEncoderFFmpeg::Encode(uint8_t *in, int in_size, uint8_t *out, int out_size)
  {
@@ -588,51 +588,56 @@ diff -urN xbmc/cores/AudioEngine/Encoders/AEEncoderFFmpeg.cpp.orig xbmc/cores/Au
 -  /* initialize the output packet */
 -  AVPacket* pkt = av_packet_alloc();
 -  if (!pkt)
--  {
--    CLog::Log(LOGERROR, "CAEEncoderFFmpeg::{} - av_packet_alloc failed: {}", __FUNCTION__,
--              strerror(errno));
--    av_frame_free(&frame);
--    return 0;
--  }
-+    pkt->size = out_size;
-+    pkt->data = out;
- 
--  pkt->size = out_size;
--  pkt->data = out;
 +    /* encode it */
 +    err = avcodec_send_frame(m_CodecCtx, frame);
 +    if (err < 0)
 +      throw FFMpegException("Error sending a frame for encoding (error '{}')",
 +                            FFMpegErrorToString(err));
- 
--  /* encode it */
--  int ret = avcodec_encode_audio2(m_CodecCtx, pkt, frame, &got_output);
-+    while (err >= 0)
++
++    err = avcodec_receive_packet(m_CodecCtx, pkt);
++    //! @TODO: This is a workaround for our current design. The caller should be made
++    // aware of the potential error values to use the ffmpeg API in a proper way, which means
++    // copying with EAGAIN and multiple packet output.
++    // For the current situation there is a relationship implicitely assumed of:
++    // 1 frame in - 1 packet out. This holds true in practice but the API does not guarantee it.
++    if (err >= 0)
 +    {
-+      err = avcodec_receive_packet(m_CodecCtx, pkt);
-+      if (err == AVERROR(EAGAIN) || err == AVERROR_EOF)
++      if (pkt->size <= out_size)
 +      {
-+        av_channel_layout_uninit(&frame->ch_layout);
-+        av_frame_free(&frame);
-+        av_packet_free(&pkt);
-+        return (err == AVERROR(EAGAIN)) ? -1 : 0;
++        memset(out, 0, out_size);
++        memcpy(out, pkt->data, pkt->size);
++        size = pkt->size;
 +      }
-+      else if (err < 0)
++      else
 +      {
-+        throw FFMpegException("Error during encoding (error '{}')", FFMpegErrorToString(err));
++        CLog::LogF(LOGERROR, "Encoded pkt size ({}) is bigger than buffer ({})", pkt->size,
++                   out_size);
 +      }
- 
--  int size = pkt->size;
 +      av_packet_unref(pkt);
 +    }
- 
-+    size = pkt->size;
++    else
++    {
++      CLog::LogF(LOGERROR, "Error receiving encoded paket ({})", err);
++    }
 +  }
 +  catch (const FFMpegException& caught)
-+  {
+   {
+-    CLog::Log(LOGERROR, "CAEEncoderFFmpeg::{} - av_packet_alloc failed: {}", __FUNCTION__,
+-              strerror(errno));
+-    av_frame_free(&frame);
+-    return 0;
 +    CLog::Log(LOGERROR, "CAEEncoderFFmpeg::{} - {}", __func__, caught.what());
-+  }
-+
+   }
+ 
+-  pkt->size = out_size;
+-  pkt->data = out;
++  av_channel_layout_uninit(&frame->ch_layout);
+ 
+-  /* encode it */
+-  int ret = avcodec_encode_audio2(m_CodecCtx, pkt, frame, &got_output);
+-
+-  int size = pkt->size;
+-
    /* free temporary data */
    av_frame_free(&frame);