File fix-ffmpeg.patch of Package indi-3rdparty-drivers

From 6e5cbe4ee876c1159796555ffdd171f1146e96ff Mon Sep 17 00:00:00 2001
From: Jasem Mutlaq <mutlaqja@ikarustech.com>
Date: Sun, 12 Oct 2025 19:21:01 +0300
Subject: [PATCH] Fix compiling with recent ffmpeg

---
 debian/indi-webcam/changelog |  6 +++
 indi-webcam/CMakeLists.txt   |  6 +--
 indi-webcam/indi_webcam.cpp  | 95 +++++++++++++++++++++---------------
 3 files changed, 66 insertions(+), 41 deletions(-)

diff --git a/debian/indi-webcam/changelog b/debian/indi-webcam/changelog
index 2be40f9bd..e7467b795 100644
--- a/debian/indi-webcam/changelog
+++ b/debian/indi-webcam/changelog
@@ -1,3 +1,9 @@
+indi-webcam (1.1) bionic; urgency=low
+
+  * Compile on recent FFMPEG 5+
+
+ -- Jasem Mutlaq <mutlaqja@ikarustech.com>  Sun, 12 Oct 2025 21:00:00 +0300
+
 indi-webcam (1.0) bionic; urgency=low
 
   * Initial Release.
diff --git a/indi-webcam/CMakeLists.txt b/indi-webcam/CMakeLists.txt
index f436afcad..d4e39750d 100644
--- a/indi-webcam/CMakeLists.txt
+++ b/indi-webcam/CMakeLists.txt
@@ -1,8 +1,8 @@
-PROJECT(indi_webcam C CXX)
 cmake_minimum_required(VERSION 3.16)
+PROJECT(indi_webcam C CXX)
 
-set (WEBCAM_VERSION_MAJOR 0)
-set (WEBCAM_VERSION_MINOR 2)
+set (WEBCAM_VERSION_MAJOR 1)
+set (WEBCAM_VERSION_MINOR 1)
 
 LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/")
 LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake_modules/")
diff --git a/indi-webcam/indi_webcam.cpp b/indi-webcam/indi_webcam.cpp
index ac75050c2..9b2979740 100644
--- a/indi-webcam/indi_webcam.cpp
+++ b/indi-webcam/indi_webcam.cpp
@@ -101,8 +101,12 @@ void indi_webcam::findAVFoundationVideoSources()
     //Need to disconnect the source to probe the streams
     if(isConnected())
     {
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 0, 0) // FFmpeg 4.x and older
         avcodec_close(pCodecCtx);
         avcodec_free_context(&pCodecCtx);
+#else // FFmpeg 5.0 and newer
+        avcodec_free_context(&pCodecCtx);
+#endif
         avformat_close_input(&pFormatCtx);
     }
     else
@@ -116,8 +120,12 @@ void indi_webcam::findAVFoundationVideoSources()
             DEBUG(INDI::Logger::DBG_SESSION, "Briefly connecting to avfoundation to update the source list");
             if(ConnectToSource("avfoundation", "default", frameRate, videoSize, inputPixelFormat, "Not using IP Camera"))
                 DEBUG(INDI::Logger::DBG_SESSION, "Source List Updated");
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 0, 0) // FFmpeg 4.x and older
             avcodec_close(pCodecCtx);
             avcodec_free_context(&pCodecCtx);
+#else // FFmpeg 5.0 and newer
+            avcodec_free_context(&pCodecCtx);
+#endif
             avformat_close_input(&pFormatCtx);
         }
     }
@@ -242,7 +250,8 @@ bool indi_webcam::Connect()
 }
 
 //This is the code that we use for FFMpeg to set up an input, connect to it, and set up the correct codecs.
-bool indi_webcam::ConnectToSource(std::string device, std::string source, int framerate, std::string videosize, std::string inputpixelformat,
+bool indi_webcam::ConnectToSource(std::string device, std::string source, int framerate, std::string videosize,
+                                  std::string inputpixelformat,
                                   std::string urlSource)
 {
     char stringFrameRate[16];
@@ -251,8 +260,12 @@ bool indi_webcam::ConnectToSource(std::string device, std::string source, int fr
     snprintf(stringffmpegTimeout, 16, "%.0f", ffmpegTimeout);
     if(isConnected())
     {
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 0, 0) // FFmpeg 4.x and older
         avcodec_close(pCodecCtx);
         avcodec_free_context(&pCodecCtx);
+#else // FFmpeg 5.0 and newer
+        avcodec_free_context(&pCodecCtx);
+#endif
         avformat_close_input(&pFormatCtx);
     }
 
@@ -357,7 +370,8 @@ bool indi_webcam::reconnectSource()
 //This is the method that should be called to change the streaming device, source, framerate, or video size
 //If it was already connected, it will attempt a connection with the new settings and if it is not successful, it will revert to the old ones.
 //It should be safe to use while streaming or between image captures because it will pause them and return them to normal afterwards.
-bool indi_webcam::ChangeSource(std::string newDevice, std::string newSource, int newFramerate, std::string newInputPixelFormat, std::string newVideosize)
+bool indi_webcam::ChangeSource(std::string newDevice, std::string newSource, int newFramerate,
+                               std::string newInputPixelFormat, std::string newVideosize)
 {
     //This will pause the streaming while it attempts the new connection settings.
     bool was_streaming = false;
@@ -411,8 +425,9 @@ bool indi_webcam::ChangeSource(std::string newDevice, std::string newSource, int
 //This is the method that should be called to change the streaming device, source, framerate, or video size
 //If it was already connected, it will attempt a connection with the new settings and if it is not successful, it will revert to the old ones.
 //It should be safe to use while streaming or between image captures because it will pause them and return them to normal afterwards.
-bool indi_webcam::ChangeOnlineSource(std::string newProtocol, std::string newIPAddress, std::string newPort, std::string newUserName,
-                                   std::string newPassword)
+bool indi_webcam::ChangeOnlineSource(std::string newProtocol, std::string newIPAddress, std::string newPort,
+                                     std::string newUserName,
+                                     std::string newPassword)
 {
     std::string newURL;
 
@@ -493,8 +508,12 @@ bool indi_webcam::Disconnect()
     if (isConnected())
     {
         // Close the codecs
+#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 0, 0) // FFmpeg 4.x and older
         avcodec_close(pCodecCtx);
         avcodec_free_context(&pCodecCtx);
+#else // FFmpeg 5.0 and newer
+        avcodec_free_context(&pCodecCtx);
+#endif
 
         // Close the video file
         avformat_close_input(&pFormatCtx);
@@ -544,16 +563,16 @@ bool indi_webcam::initProperties()
                        MAIN_CONTROL_TAB, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
     defineProperty(&OutputFormatSelection);
 
-    IUFillNumber(&TimeoutOptionsT[0], "FFMPEG_TIMEOUT", "FFMPEG", "%.0f", 0 , 100000000, 1, ffmpegTimeout);
-    IUFillNumber(&TimeoutOptionsT[1], "BUFFER_TIMEOUT", "Buffer", "%.0f", 0 , 10000000, 1, bufferTimeout);
+    IUFillNumber(&TimeoutOptionsT[0], "FFMPEG_TIMEOUT", "FFMPEG", "%.0f", 0, 100000000, 1, ffmpegTimeout);
+    IUFillNumber(&TimeoutOptionsT[1], "BUFFER_TIMEOUT", "Buffer", "%.0f", 0, 10000000, 1, bufferTimeout);
     IUFillNumberVector(&TimeoutOptionsTP, TimeoutOptionsT, NARRAY(TimeoutOptionsT), getDeviceName(), "TIMEOUT_OPTIONS",
-                     "Timeouts (us)", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);
+                       "Timeouts (us)", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);
 
     defineProperty(&TimeoutOptionsTP);
 
-    IUFillNumber(&PixelSizeT[0], "PIXEL_SIZE_um", "Pixel Size (µm)", "%.3f", 0 , 50, 0.1, pixelSize);
+    IUFillNumber(&PixelSizeT[0], "PIXEL_SIZE_um", "Pixel Size (µm)", "%.3f", 0, 50, 0.1, pixelSize);
     IUFillNumberVector(&PixelSizeTP, PixelSizeT, NARRAY(PixelSizeT), getDeviceName(), "PIXEL_SIZE",
-                     "Pixel Size", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);
+                       "Pixel Size", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);
 
     defineProperty(&PixelSizeTP);
 
@@ -576,7 +595,7 @@ bool indi_webcam::initProperties()
 
     IUFillSwitchVector(&PixelSizeSelection, PixelSizes, 15, getDeviceName(), "PIXEL_SIZE_SELECTION", "Camera Pixel Sizes (µm)",
                        OPTIONS_TAB, IP_RW, ISR_1OFMANY, 60, IPS_IDLE);
-     defineProperty(&PixelSizeSelection);
+    defineProperty(&PixelSizeSelection);
 
     IUFillSwitch(&RefreshS[0], "Scan Ports", "Scan Sources", ISS_OFF);
     IUFillSwitchVector(&RefreshSP, RefreshS, 1, getDeviceName(), "INPUT_SCAN", "Refresh", CONNECTION_TAB, IP_RW, ISR_ATMOST1,
@@ -1355,7 +1374,7 @@ void indi_webcam::TimerHit()
 
         // The time left in the "exposure" is less than the time it takes to make an actual exposure
         // or the time left is less than the polling period, so get it now.
-        if (timeleft < (1 / frameRate) || timeleft < getCurrentPollingPeriod()/1000.0)
+        if (timeleft < (1 / frameRate) || timeleft < getCurrentPollingPeriod() / 1000.0)
         {
             if(webcamStacking)
                 copyFinalStackToPrimaryFrameBuffer();
@@ -1868,33 +1887,33 @@ bool indi_webcam::getStreamFrame()
 
 //This will clear out the frame buffer of any unread frames.
 //That way we are sure to get the latest frames when exposing
- bool indi_webcam::flush_frame_buffer()
- {
-     int packetReceiveTime = -1;
-     int num = 0;
-     while(packetReceiveTime < bufferTimeout)
-     {
-         num++;
-         struct timeval then;
-         gettimeofday(&then, nullptr);
-         AVPacket packet;
-         int ret = av_read_frame(pFormatCtx, &packet);
-         if(ret != 0) // Return value less than 0 means error
-         {
-             if(ret == -35) //Leave the loop since the device is not available to give frames.
-                 break;
-             char errbuff[200];
-             av_make_error_string(errbuff, 200, ret);
-             DEBUGF(INDI::Logger::DBG_SESSION, "FFMPEG Error while clearing buffer: %s.", errbuff);
-         }
-         struct timeval now;
-         gettimeofday(&now, nullptr);
-         packetReceiveTime = now.tv_usec - then.tv_usec;
-         av_packet_unref(&packet);
-     }
-     DEBUGF(INDI::Logger::DBG_SESSION, "Buffer Cleared of %u stale frames.", num);
-     return true;  //Buffer Cleared
- }
+bool indi_webcam::flush_frame_buffer()
+{
+    int packetReceiveTime = -1;
+    int num = 0;
+    while(packetReceiveTime < bufferTimeout)
+    {
+        num++;
+        struct timeval then;
+        gettimeofday(&then, nullptr);
+        AVPacket packet;
+        int ret = av_read_frame(pFormatCtx, &packet);
+        if(ret != 0) // Return value less than 0 means error
+        {
+            if(ret == -35) //Leave the loop since the device is not available to give frames.
+                break;
+            char errbuff[200];
+            av_make_error_string(errbuff, 200, ret);
+            DEBUGF(INDI::Logger::DBG_SESSION, "FFMPEG Error while clearing buffer: %s.", errbuff);
+        }
+        struct timeval now;
+        gettimeofday(&now, nullptr);
+        packetReceiveTime = now.tv_usec - then.tv_usec;
+        av_packet_unref(&packet);
+    }
+    DEBUGF(INDI::Logger::DBG_SESSION, "Buffer Cleared of %u stale frames.", num);
+    return true;  //Buffer Cleared
+}
 
 //This frees up the resources used for streaming/exposing
 void indi_webcam::freeMemory()

openSUSE Build Service is sponsored by