diff --git a/media-libs/opencv/opencv-4.5.5.recipe b/media-libs/opencv/opencv-4.5.5.recipe new file mode 100644 index 000000000..75342f38c --- /dev/null +++ b/media-libs/opencv/opencv-4.5.5.recipe @@ -0,0 +1,481 @@ +SUMMARY="Open Source Computer Vision Library" +DESCRIPTION="A collection of algorithms and sample code for various \ +computer vision problems." +HOMEPAGE="https://opencv.org/" +COPYRIGHT="2000-2020, Intel Corporation + 2009-2011, Willow Garage Inc. + 2009-2016, NVIDIA Corporation + 2010-2013, Advanced Micro Devices, Inc. + 2015-2016, OpenCV Foundation + 2015-2016, Itseez Inc. + 2019-2020, Xperience AI" +LICENSE="BSD (3-clause)" +REVISION="1" +SOURCE_URI="https://github.com/opencv/opencv/archive/$portVersion.tar.gz" +SOURCE_FILENAME="opencv-$portVersion.tar.gz" +CHECKSUM_SHA256="a1cfdcf6619387ca9e232687504da996aaa9f7b5689986b8331ec02cb61d28ad" +SOURCE_URI_2="https://github.com/opencv/opencv_contrib/archive/$portVersion.tar.gz" +SOURCE_FILENAME_2="opencv_contrib-$portVersion.tar.gz" +CHECKSUM_SHA256_2="a97c2eaecf7a23c6dbd119a609c6d7fae903e5f9ff5f1fe678933e01c67a6c11" +PATCHES="opencv-4.5.5.patchset" + +ARCHITECTURES="all !x86_gcc2 ?x86" +SECONDARY_ARCHITECTURES="x86" + +# On x86_gcc2 we don't want to install the commands in bin//, but in bin/. +commandSuffix=$secondaryArchSuffix +commandBinDir=$binDir +if [ "$targetArchitecture" = x86_gcc2 ]; then + commandSuffix= + commandBinDir=$prefix/bin +fi + +portVersionCompat="$portVersion compat >= ${portVersion%%.*}" +libVersion="$portVersion" +libVersionCompat="$libVersion compat >= ${libVersion%.*}" + +PROVIDES=" + opencv$secondaryArchSuffix = $portVersionCompat + lib:libopencv_alphamat$secondaryArchSuffix = $libVersionCompat + lib:libopencv_aruco$secondaryArchSuffix = $libVersionCompat + lib:libopencv_barcode$secondaryArchSuffix = $libVersionCompat + lib:libopencv_bgsegm$secondaryArchSuffix = $libVersionCompat + lib:libopencv_bioinspired$secondaryArchSuffix = $libVersionCompat + lib:libopencv_calib3d$secondaryArchSuffix = $libVersionCompat + lib:libopencv_ccalib$secondaryArchSuffix = $libVersionCompat + lib:libopencv_core$secondaryArchSuffix = $libVersionCompat + lib:libopencv_cvv$secondaryArchSuffix = $libVersionCompat + lib:libopencv_datasets$secondaryArchSuffix = $libVersionCompat + lib:libopencv_dnn_objdetect$secondaryArchSuffix = $libVersionCompat + lib:libopencv_dnn_superres$secondaryArchSuffix = $libVersionCompat + lib:libopencv_dnn$secondaryArchSuffix = $libVersionCompat + lib:libopencv_dpm$secondaryArchSuffix = $libVersionCompat + lib:libopencv_face$secondaryArchSuffix = $libVersionCompat + lib:libopencv_features2d$secondaryArchSuffix = $libVersionCompat + lib:libopencv_flann$secondaryArchSuffix = $libVersionCompat + lib:libopencv_freetype$secondaryArchSuffix = $libVersionCompat + lib:libopencv_fuzzy$secondaryArchSuffix = $libVersionCompat + lib:libopencv_gapi$secondaryArchSuffix = $libVersionCompat + lib:libopencv_hdf$secondaryArchSuffix = $libVersionCompat + lib:libopencv_hfs$secondaryArchSuffix = $libVersionCompat + lib:libopencv_highgui$secondaryArchSuffix = $libVersionCompat + lib:libopencv_img_hash$secondaryArchSuffix = $libVersionCompat + lib:libopencv_imgcodecs$secondaryArchSuffix = $libVersionCompat + lib:libopencv_imgproc$secondaryArchSuffix = $libVersionCompat + lib:libopencv_intensity_transform$secondaryArchSuffix = $libVersionCompat + lib:libopencv_line_descriptor$secondaryArchSuffix = $libVersionCompat + lib:libopencv_mcc$secondaryArchSuffix = $libVersionCompat + lib:libopencv_ml$secondaryArchSuffix = $libVersionCompat + lib:libopencv_objdetect$secondaryArchSuffix = $libVersionCompat + lib:libopencv_optflow$secondaryArchSuffix = $libVersionCompat + lib:libopencv_phase_unwrapping$secondaryArchSuffix = $libVersionCompat + lib:libopencv_photo$secondaryArchSuffix = $libVersionCompat + lib:libopencv_plot$secondaryArchSuffix = $libVersionCompat + lib:libopencv_quality$secondaryArchSuffix = $libVersionCompat + lib:libopencv_rapid$secondaryArchSuffix = $libVersionCompat + lib:libopencv_reg$secondaryArchSuffix = $libVersionCompat + lib:libopencv_rgbd$secondaryArchSuffix = $libVersionCompat + lib:libopencv_saliency$secondaryArchSuffix = $libVersionCompat + lib:libopencv_shape$secondaryArchSuffix = $libVersionCompat + lib:libopencv_stereo$secondaryArchSuffix = $libVersionCompat + lib:libopencv_stitching$secondaryArchSuffix = $libVersionCompat + lib:libopencv_structured_light$secondaryArchSuffix = $libVersionCompat + lib:libopencv_superres$secondaryArchSuffix = $libVersionCompat + lib:libopencv_surface_matching$secondaryArchSuffix = $libVersionCompat + lib:libopencv_text$secondaryArchSuffix = $libVersionCompat + lib:libopencv_tracking$secondaryArchSuffix = $libVersionCompat + lib:libopencv_video$secondaryArchSuffix = $libVersionCompat + lib:libopencv_videoio$secondaryArchSuffix = $libVersionCompat + lib:libopencv_videostab$secondaryArchSuffix = $libVersionCompat + lib:libopencv_xfeatures2d$secondaryArchSuffix = $libVersionCompat + lib:libopencv_ximgproc$secondaryArchSuffix = $libVersionCompat + lib:libopencv_xobjdetect$secondaryArchSuffix = $libVersionCompat + lib:libopencv_xphoto$secondaryArchSuffix = $libVersionCompat + lib:libopencv_wechat_qrcode$secondaryArchSuffix = $libVersionCompat + " +REQUIRES=" + haiku$secondaryArchSuffix + lib:libavcodec$secondaryArchSuffix + lib:libavformat$secondaryArchSuffix + lib:libavutil$secondaryArchSuffix +# lib:libceres$secondaryArchSuffix + lib:libfreetype$secondaryArchSuffix + lib:libgdal$secondaryArchSuffix + lib:libGL$secondaryArchSuffix + lib:libglib_2.0$secondaryArchSuffix + lib:libglog$secondaryArchSuffix + lib:libGLU$secondaryArchSuffix + lib:libgphoto2$secondaryArchSuffix + lib:libgstapp_1.0$secondaryArchSuffix + lib:libgstreamer_1.0$secondaryArchSuffix + lib:libgstvideo_1.0$secondaryArchSuffix + lib:libharfbuzz$secondaryArchSuffix + lib:libhdf5$secondaryArchSuffix + lib:libiconv$secondaryArchSuffix +# lib:libilmimf$secondaryArchSuffix #openexr + lib:libintl$secondaryArchSuffix + lib:libjasper$secondaryArchSuffix + lib:libjpeg$secondaryArchSuffix + lib:liblapack$secondaryArchSuffix + lib:libopenblas$secondaryArchSuffix + lib:libopenjp2$secondaryArchSuffix + lib:libpng16$secondaryArchSuffix + lib:libQt5Concurrent$secondaryArchSuffix + lib:libQt5Core$secondaryArchSuffix + lib:libQt5Gui$secondaryArchSuffix + lib:libQt5Test$secondaryArchSuffix + lib:libQt5Widgets$secondaryArchSuffix + lib:libswscale$secondaryArchSuffix + lib:libtesseract$secondaryArchSuffix + lib:libtiff$secondaryArchSuffix + lib:libwebp$secondaryArchSuffix + lib:libz$secondaryArchSuffix + " + +PROVIDES_devel=" + opencv${secondaryArchSuffix}_devel = $portVersionCompat + devel:libopencv_alphamat$secondaryArchSuffix = $libVersionCompat + devel:libopencv_aruco$secondaryArchSuffix = $libVersionCompat + devel:libopencv_barcode$secondaryArchSuffix = $libVersionCompat + devel:libopencv_bgsegm$secondaryArchSuffix = $libVersionCompat + devel:libopencv_bioinspired$secondaryArchSuffix = $libVersionCompat + devel:libopencv_calib3d$secondaryArchSuffix = $libVersionCompat + devel:libopencv_ccalib$secondaryArchSuffix = $libVersionCompat + devel:libopencv_core$secondaryArchSuffix = $libVersionCompat + devel:libopencv_cvv$secondaryArchSuffix = $libVersionCompat + devel:libopencv_datasets$secondaryArchSuffix = $libVersionCompat + devel:libopencv_dnn_objdetect$secondaryArchSuffix = $libVersionCompat + devel:libopencv_dnn_superres$secondaryArchSuffix = $libVersionCompat + devel:libopencv_dnn$secondaryArchSuffix = $libVersionCompat + devel:libopencv_dpm$secondaryArchSuffix = $libVersionCompat + devel:libopencv_face$secondaryArchSuffix = $libVersionCompat + devel:libopencv_features2d$secondaryArchSuffix = $libVersionCompat + devel:libopencv_flann$secondaryArchSuffix = $libVersionCompat + devel:libopencv_freetype$secondaryArchSuffix = $libVersionCompat + devel:libopencv_fuzzy$secondaryArchSuffix = $libVersionCompat + devel:libopencv_gapi$secondaryArchSuffix = $libVersionCompat + devel:libopencv_hdf$secondaryArchSuffix = $libVersionCompat + devel:libopencv_hfs$secondaryArchSuffix = $libVersionCompat + devel:libopencv_highgui$secondaryArchSuffix = $libVersionCompat + devel:libopencv_img_hash$secondaryArchSuffix = $libVersionCompat + devel:libopencv_imgcodecs$secondaryArchSuffix = $libVersionCompat + devel:libopencv_imgproc$secondaryArchSuffix = $libVersionCompat + devel:libopencv_intensity_transform$secondaryArchSuffix = $libVersionCompat + devel:libopencv_line_descriptor$secondaryArchSuffix = $libVersionCompat + devel:libopencv_mcc$secondaryArchSuffix = $libVersionCompat + devel:libopencv_ml$secondaryArchSuffix = $libVersionCompat + devel:libopencv_objdetect$secondaryArchSuffix = $libVersionCompat + devel:libopencv_optflow$secondaryArchSuffix = $libVersionCompat + devel:libopencv_phase_unwrapping$secondaryArchSuffix = $libVersionCompat + devel:libopencv_photo$secondaryArchSuffix = $libVersionCompat + devel:libopencv_plot$secondaryArchSuffix = $libVersionCompat + devel:libopencv_quality$secondaryArchSuffix = $libVersionCompat + devel:libopencv_rapid$secondaryArchSuffix = $libVersionCompat + devel:libopencv_reg$secondaryArchSuffix = $libVersionCompat + devel:libopencv_rgbd$secondaryArchSuffix = $libVersionCompat + devel:libopencv_saliency$secondaryArchSuffix = $libVersionCompat + devel:libopencv_shape$secondaryArchSuffix = $libVersionCompat + devel:libopencv_stereo$secondaryArchSuffix = $libVersionCompat + devel:libopencv_stitching$secondaryArchSuffix = $libVersionCompat + devel:libopencv_structured_light$secondaryArchSuffix = $libVersionCompat + devel:libopencv_superres$secondaryArchSuffix = $libVersionCompat + devel:libopencv_surface_matching$secondaryArchSuffix = $libVersionCompat + devel:libopencv_text$secondaryArchSuffix = $libVersionCompat + devel:libopencv_tracking$secondaryArchSuffix = $libVersionCompat + devel:libopencv_video$secondaryArchSuffix = $libVersionCompat + devel:libopencv_videoio$secondaryArchSuffix = $libVersionCompat + devel:libopencv_videostab$secondaryArchSuffix = $libVersionCompat + devel:libopencv_xfeatures2d$secondaryArchSuffix = $libVersionCompat + devel:libopencv_ximgproc$secondaryArchSuffix = $libVersionCompat + devel:libopencv_xobjdetect$secondaryArchSuffix = $libVersionCompat + devel:libopencv_xphoto$secondaryArchSuffix = $libVersionCompat + devel:libopencv_wechat_qrcode$secondaryArchSuffix = $libVersionCompat + " +REQUIRES_devel=" + opencv$secondaryArchSuffix == $portVersion base + " + +PROVIDES_python=" + opencv${secondaryArchSuffix}_python = $portVersionCompat + " +REQUIRES_python=" + haiku$secondaryArchSuffix + opencv$secondaryArchSuffix == $portVersion base + " + +PROVIDES_tools=" + opencv${secondaryArchSuffix}_tools = $portVersionCompat + cmd:opencv_annotation$commandSuffix = $portVersion + cmd:opencv_interactive_calibration$commandSuffix = $portVersion + cmd:opencv_model_diagnostics$secondaryArchSuffix = $portVersion + cmd:opencv_version$commandSuffix = $portVersion + cmd:opencv_visualisation$commandSuffix = $portVersion + cmd:opencv_waldboost_detector$commandSuffix = $portVersion + cmd:setup_vars_opencv4.sh$commandSuffix = $portVersion + " +REQUIRES_tools=" + haiku$secondaryArchSuffix + opencv$secondaryArchSuffix == $portVersion base + numpy${secondaryArchSuffix}_python3 + cmd:python3 + " + +BUILD_REQUIRES=" + haiku${secondaryArchSuffix}_devel + devel:cblas$secondaryArchSuffix + devel:eigen$secondaryArchSuffix + devel:libavcodec$secondaryArchSuffix + devel:libavcodec$secondaryArchSuffix + devel:libavformat$secondaryArchSuffix + devel:libavutil$secondaryArchSuffix +# devel:libcaffe$secondaryArchSuffix +# devel:libceres$secondaryArchSuffix + devel:libexif$secondaryArchSuffix + devel:libfreetype$secondaryArchSuffix + devel:libgdal$secondaryArchSuffix +# devel:libgflags$secondaryArchSuffix + devel:libGL$secondaryArchSuffix + devel:libglib_2.0$secondaryArchSuffix + devel:libglog$secondaryArchSuffix + devel:libGLU$secondaryArchSuffix + devel:libgphoto2$secondaryArchSuffix + devel:libgstapp_1.0$secondaryArchSuffix + devel:libgstreamer_1.0$secondaryArchSuffix + devel:libgstvideo_1.0$secondaryArchSuffix + devel:libharfbuzz$secondaryArchSuffix + devel:libhdf5$secondaryArchSuffix + devel:libiconv$secondaryArchSuffix +# devel:libilmimf$secondaryArchSuffix #openexr + devel:libintl$secondaryArchSuffix + devel:libjasper$secondaryArchSuffix + devel:libjpeg$secondaryArchSuffix + devel:liblapack$secondaryArchSuffix + devel:liblept$secondaryArchSuffix + devel:libopenblas$secondaryArchSuffix + devel:libopencl_headers$secondaryArchSuffix + devel:libopenjp2$secondaryArchSuffix + devel:liborc_0.4$secondaryArchSuffix + devel:libpng16$secondaryArchSuffix +# devel:libprotobuf$secondaryArchSuffix + devel:libQt5Concurrent$secondaryArchSuffix + devel:libQt5Core$secondaryArchSuffix + devel:libQt5Gui$secondaryArchSuffix + devel:libQt5Test$secondaryArchSuffix + devel:libQt5Widgets$secondaryArchSuffix + devel:libswscale$secondaryArchSuffix + devel:libtesseract$secondaryArchSuffix + devel:libtiff$secondaryArchSuffix + devel:libwebp$secondaryArchSuffix + devel:libz$secondaryArchSuffix + " +BUILD_PREREQUIRES=" +# cmd:ant + cmd:cmake + cmd:doxygen + numpy${secondaryArchSuffix}_python3 + cmd:gcc$secondaryArchSuffix +# cmd:javac +# cmd:jni + cmd:ld$secondaryArchSuffix + cmd:make +# cmd:matlab # maybe later + cmd:pkg_config$secondaryArchSuffix + cmd:python3 + " + +defineDebugInfoPackage opencv$secondaryArchSuffix \ + $libDir/libopencv_alphamat.so.$libVersion \ + $libDir/libopencv_aruco.so.$libVersion \ + $libDir/libopencv_bgsegm.so.$libVersion \ + $libDir/libopencv_barcode.so.$libVersion \ + $libDir/libopencv_bioinspired.so.$libVersion \ + $libDir/libopencv_calib3d.so.$libVersion \ + $libDir/libopencv_ccalib.so.$libVersion \ + $libDir/libopencv_core.so.$libVersion \ + $libDir/libopencv_cvv.so.$libVersion \ + $libDir/libopencv_datasets.so.$libVersion \ + $libDir/libopencv_dnn_objdetect.so.$libVersion \ + $libDir/libopencv_dnn_superres.so.$libVersion \ + $libDir/libopencv_dnn.so.$libVersion \ + $libDir/libopencv_dpm.so.$libVersion \ + $libDir/libopencv_face.so.$libVersion \ + $libDir/libopencv_features2d.so.$libVersion \ + $libDir/libopencv_flann.so.$libVersion \ + $libDir/libopencv_freetype.so.$libVersion \ + $libDir/libopencv_fuzzy.so.$libVersion \ + $libDir/libopencv_gapi.so.$libVersion \ + $libDir/libopencv_hdf.so.$libVersion \ + $libDir/libopencv_hfs.so.$libVersion \ + $libDir/libopencv_highgui.so.$libVersion \ + $libDir/libopencv_img_hash.so.$libVersion \ + $libDir/libopencv_imgcodecs.so.$libVersion \ + $libDir/libopencv_imgproc.so.$libVersion \ + $libDir/libopencv_intensity_transform.so.$libVersion \ + $libDir/libopencv_line_descriptor.so.$libVersion \ + $libDir/libopencv_mcc.so.$libVersion \ + $libDir/libopencv_ml.so.$libVersion \ + $libDir/libopencv_objdetect.so.$libVersion \ + $libDir/libopencv_optflow.so.$libVersion \ + $libDir/libopencv_phase_unwrapping.so.$libVersion \ + $libDir/libopencv_photo.so.$libVersion \ + $libDir/libopencv_plot.so.$libVersion \ + $libDir/libopencv_quality.so.$libVersion \ + $libDir/libopencv_rapid.so.$libVersion \ + $libDir/libopencv_reg.so.$libVersion \ + $libDir/libopencv_rgbd.so.$libVersion \ + $libDir/libopencv_saliency.so.$libVersion \ + $libDir/libopencv_shape.so.$libVersion \ + $libDir/libopencv_stereo.so.$libVersion \ + $libDir/libopencv_stitching.so.$libVersion \ + $libDir/libopencv_structured_light.so.$libVersion \ + $libDir/libopencv_superres.so.$libVersion \ + $libDir/libopencv_surface_matching.so.$libVersion \ + $libDir/libopencv_text.so.$libVersion \ + $libDir/libopencv_tracking.so.$libVersion \ + $libDir/libopencv_video.so.$libVersion \ + $libDir/libopencv_videoio.so.$libVersion \ + $libDir/libopencv_videostab.so.$libVersion \ + $libDir/libopencv_xfeatures2d.so.$libVersion \ + $libDir/libopencv_ximgproc.so.$libVersion \ + $libDir/libopencv_xobjdetect.so.$libVersion \ + $libDir/libopencv_xphoto.so.$libVersion \ + $libDir/libopencv_wechat_qrcode.so.$libVersion + +BUILD() +{ + mkdir -p build_haiku && cd build_haiku + + local ARCH_SUBDIR= + if [ -n "$secondaryArchSuffix" ]; then + ARCH_SUBDIR="$secondaryArchSuffix/" + fi + + pythonVersion=$(python3 --version 2>&1 | sed 's/Python //' | head -c3) + + cmake .. \ + -DCMAKE_BUILD_TYPE=Release \ + $cmakeDirArgs \ + -DBUILD_TESTS=OFF \ + -DBUILD_PERF_TESTS=OFF \ + -DCMAKE_INSTALL_BINDIR=$commandBinDir \ + -DCMAKE_INSTALL_LIBEXECDIR=$libDir \ + -DWITH_GDAL=ON \ + -DWITH_IPP=OFF \ + -DWITH_OPENGL=OFF \ + -DWITH_QT=ON \ + -DWITH_EIGEN=ON \ + -DWITH_OPENEXR=ON \ + -DWITH_FFMPEG=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_SKIP_RPATH=ON \ + -DENABLE_PIC=OFF \ + -DOPENCV_GENERATE_PKGCONFIG=YES \ + -DCMAKE_INSTALL_PREFIX:PATH="$prefix" \ + -DOPENCV_OTHER_INSTALL_PATH:PATH="$dataDir" \ + -DOpenBLAS_INCLUDE_DIR="$portPackageLinksDir/openblas${secondaryArchSuffix}_devel/develop/headers/$ARCH_SUBDIR" \ + -DOpenBLAS_LIB="$portPackageLinksDir/openblas${secondaryArchSuffix}_devel/develop/lib/$ARCH_SUBDIR" \ + -DOPENCV_PYTHON3_INSTALL_PATH="$prefix/lib/python$pythonVersion/vendor-packages" \ + -DPYTHON3_NUMPY_INCLUDE_DIRS:PATH="`finddir B_SYSTEM_LIB_DIRECTORY`/python${pythonVersion}/vendor-packages/numpy/core/include" \ + -DOPENCV_EXTRA_MODULES_PATH="$sourceDir2/opencv_contrib-$portVersion/modules" \ + -DEigen3_DIR=`finddir B_SYSTEM_DATA_DIRECTORY`/eigen3/cmake + + make $jobArgs +} + +INSTALL() +{ + cd build_haiku + + make install + + prepareInstalledDevelLibs libopencv_alphamat \ + libopencv_aruco \ + libopencv_barcode \ + libopencv_bgsegm \ + libopencv_bioinspired \ + libopencv_calib3d \ + libopencv_ccalib \ + libopencv_core \ + libopencv_cvv \ + libopencv_datasets \ + libopencv_dnn_objdetect \ + libopencv_dnn_superres \ + libopencv_dnn \ + libopencv_dpm \ + libopencv_face \ + libopencv_features2d \ + libopencv_flann \ + libopencv_freetype \ + libopencv_fuzzy \ + libopencv_gapi \ + libopencv_hdf \ + libopencv_hfs \ + libopencv_highgui \ + libopencv_img_hash \ + libopencv_imgcodecs \ + libopencv_imgproc \ + libopencv_intensity_transform \ + libopencv_line_descriptor \ + libopencv_mcc \ + libopencv_ml \ + libopencv_objdetect \ + libopencv_optflow \ + libopencv_phase_unwrapping \ + libopencv_photo \ + libopencv_plot \ + libopencv_quality \ + libopencv_rapid \ + libopencv_reg \ + libopencv_rgbd \ + libopencv_saliency \ + libopencv_shape \ + libopencv_stereo \ + libopencv_stitching \ + libopencv_structured_light \ + libopencv_superres \ + libopencv_surface_matching \ + libopencv_text \ + libopencv_tracking \ + libopencv_video \ + libopencv_videoio \ + libopencv_videostab \ + libopencv_xfeatures2d \ + libopencv_ximgproc \ + libopencv_xobjdetect \ + libopencv_xphoto \ + libopencv_wechat_qrcode + + # fixCmake + sed -i 's,\/include,/'${relativeIncludeDir}',g' \ + $libDir/cmake/opencv4/OpenCVConfig.cmake + + fixPkgconfig + + # fixPkgconfig + if [ -n "$secondaryArchSuffix" ]; then + sed -i 's,\/headers/x86,\/headers/x86/opencv4,g' \ + $prefix/$relativeDevelopLibDir/pkgconfig/opencv4.pc + else + sed -i 's,\/headers,\/headers/opencv4,g' \ + $prefix/$relativeDevelopLibDir/pkgconfig/opencv4.pc + fi + + # devel package + packageEntries devel \ + $developDir \ + $libDir/cmake + + # python package + packageEntries python \ + $prefix/lib/python* + + # tools package + packageEntries tools \ + $commandBinDir +} + +TEST() +{ + LIBRARY_PATH="$sourceDir/build_haiku/lib${LIBRARY_PATH:+:$LIBRARY_PATH}" \ + make -C build_haiku test $jobArgs +} diff --git a/media-libs/opencv/patches/opencv-4.5.5.patchset b/media-libs/opencv/patches/opencv-4.5.5.patchset new file mode 100644 index 000000000..9d7be787b --- /dev/null +++ b/media-libs/opencv/patches/opencv-4.5.5.patchset @@ -0,0 +1,1001 @@ +From 5440fd6cb43ea65a056c46b691fcdab1a425e92d Mon Sep 17 00:00:00 2001 +From: Maksim Shabunin +Date: Sat, 19 Mar 2022 20:06:50 +0300 +Subject: [PATCH] videoio: initial FFmpeg 5.0 support + +--- + modules/videoio/src/cap_ffmpeg_impl.hpp | 442 ++++++++++++++++-------- + 1 file changed, 304 insertions(+), 138 deletions(-) + +diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp +index 43c555309b9d..91a0f710aa63 100644 +--- a/modules/videoio/src/cap_ffmpeg_impl.hpp ++++ b/modules/videoio/src/cap_ffmpeg_impl.hpp +@@ -41,6 +41,8 @@ + //M*/ + + #include "cap_ffmpeg_legacy_api.hpp" ++#include "opencv2/core/utils/logger.hpp" ++#include "cap_interface.hpp" + + using namespace cv; + +@@ -49,6 +51,7 @@ using namespace cv; + #endif + #include + #include ++#include + + #ifndef __OPENCV_BUILD + #define CV_FOURCC(c1, c2, c3, c4) (((c1) & 255) + (((c2) & 255) << 8) + (((c3) & 255) << 16) + (((c4) & 255) << 24)) +@@ -79,6 +82,7 @@ extern "C" { + + #include + #include ++#include + + #if LIBAVUTIL_BUILD >= (LIBAVUTIL_VERSION_MICRO >= 100 \ + ? CALC_FFMPEG_VERSION(51, 63, 100) : CALC_FFMPEG_VERSION(54, 6, 0)) +@@ -88,6 +92,62 @@ extern "C" { + #include + #include + ++// https://github.com/FFmpeg/FFmpeg/blob/b6af56c034759b81985f8ea094e41cbd5f7fecfb/doc/APIchanges#L602-L605 ++#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(58, 9, 100) ++# define CV_FFMPEG_REGISTER ++#endif ++ ++// https://github.com/FFmpeg/FFmpeg/blob/b6af56c034759b81985f8ea094e41cbd5f7fecfb/doc/APIchanges#L654-L657 ++#if LIBAVCODEC_BUILD < CALC_FFMPEG_VERSION(58, 9, 100) ++# define CV_FFMPEG_LOCKMGR ++#endif ++ ++// https://github.com/FFmpeg/FFmpeg/blob/b6af56c034759b81985f8ea094e41cbd5f7fecfb/doc/APIchanges#L390-L392 ++#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(58, 87, 100) ++#include ++#endif ++ ++// https://github.com/FFmpeg/FFmpeg/blob/b6af56c034759b81985f8ea094e41cbd5f7fecfb/doc/APIchanges#L208-L210 ++#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(59, 0, 100) ++# define CV_FFMPEG_FMT_CONST const ++#else ++# define CV_FFMPEG_FMT_CONST ++#endif ++ ++// https://github.com/FFmpeg/FFmpeg/blob/b6af56c034759b81985f8ea094e41cbd5f7fecfb/doc/APIchanges#L623-L624 ++#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(58, 7, 100) ++# define CV_FFMPEG_URL ++#endif ++ ++// AVStream.codec deprecated in favor of AVStream.codecpar ++// https://github.com/FFmpeg/FFmpeg/blob/b6af56c034759b81985f8ea094e41cbd5f7fecfb/doc/APIchanges#L1039-L1040 ++#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(59, 16, 100) ++//#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(57, 33, 100) ++# define CV_FFMPEG_CODECPAR ++# define CV_FFMPEG_CODEC_FIELD codecpar ++#else ++# define CV_FFMPEG_CODEC_FIELD codec ++#endif ++ ++#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(59, 16, 100) ++# define CV_FFMPEG_PTS_FIELD pts ++#else ++# define CV_FFMPEG_PTS_FIELD pkt_pts ++#endif ++ ++// https://github.com/FFmpeg/FFmpeg/blob/b6af56c034759b81985f8ea094e41cbd5f7fecfb/doc/APIchanges#L1757-L1758 ++#if LIBAVUTIL_BUILD < CALC_FFMPEG_VERSION(52, 63, 100) ++inline static AVRational av_make_q(int num, int den) ++{ ++ AVRational res; ++ res.num = num; ++ res.den = den; ++ return res; ++} ++#endif ++ ++ ++ + #ifdef __cplusplus + } + #endif +@@ -471,6 +531,15 @@ static AVRational _opencv_ffmpeg_get_sample_aspect_ratio(AVStream *stream) + #endif + } + ++inline static std::string _opencv_ffmpeg_get_error_string(int error_code) ++{ ++ char buf[255] = {0}; ++ const int err = av_strerror(error_code, buf, 254); ++ if (err == 0) ++ return std::string(buf); ++ else ++ return std::string("Unknown error"); ++} + + struct CvCapture_FFMPEG + { +@@ -502,6 +571,7 @@ struct CvCapture_FFMPEG + + AVFormatContext * ic; + AVCodec * avcodec; ++ AVCodecContext * context; + int video_stream; + AVStream * video_st; + AVFrame * picture; +@@ -565,6 +635,7 @@ void CvCapture_FFMPEG::init() + img_convert_ctx = 0; + + avcodec = 0; ++ context = 0; + frame_number = 0; + eps_zero = 0.000025; + +@@ -617,10 +688,19 @@ void CvCapture_FFMPEG::close() + + if( video_st ) + { +- avcodec_close( video_st->codec ); ++#ifdef CV_FFMPEG_CODECPAR ++ avcodec_close( context ); ++#endif + video_st = NULL; + } + ++ if (context) ++ { ++#ifdef CV_FFMPEG_CODECPAR ++ avcodec_free_context(&context); ++#endif ++ } ++ + if( ic ) + { + avformat_close_input(&ic); +@@ -798,8 +878,10 @@ class AutoLock + }; + #endif + ++ + static ImplMutex _mutex; + ++#ifdef CV_FFMPEG_LOCKMGR + static int LockCallBack(void **mutex, AVLockOp op) + { + ImplMutex* localMutex = reinterpret_cast(*mutex); +@@ -830,7 +912,7 @@ static int LockCallBack(void **mutex, AVLockOp op) + } + return 0; + } +- ++#endif + + static void ffmpeg_log_callback(void *ptr, int level, const char *fmt, va_list vargs) + { +@@ -881,19 +963,59 @@ class InternalFFMpegRegister + { + avformat_network_init(); + ++#ifdef CV_FFMPEG_REGISTER + /* register all codecs, demux and protocols */ + av_register_all(); ++#endif + ++#ifdef CV_FFMPEG_LOCKMGR + /* register a callback function for synchronization */ + av_lockmgr_register(&LockCallBack); ++#endif + } + ~InternalFFMpegRegister() + { ++#ifdef CV_FFMPEG_LOCKMGR + av_lockmgr_register(NULL); ++#endif + av_log_set_callback(NULL); + } + }; + ++inline void fill_codec_context(AVCodecContext * enc, AVDictionary * dict) ++{ ++//#ifdef FF_API_THREAD_INIT ++// avcodec_thread_init(enc, get_number_of_cpus()); ++//#else ++ enc->thread_count = get_number_of_cpus(); ++//#endif ++ ++ AVDictionaryEntry* avdiscard_entry = av_dict_get(dict, "avdiscard", NULL, 0); ++ ++ if (avdiscard_entry) ++ { ++ if(strcmp(avdiscard_entry->value, "all") == 0) ++ enc->skip_frame = AVDISCARD_ALL; ++ else if (strcmp(avdiscard_entry->value, "bidir") == 0) ++ enc->skip_frame = AVDISCARD_BIDIR; ++ else if (strcmp(avdiscard_entry->value, "default") == 0) ++ enc->skip_frame = AVDISCARD_DEFAULT; ++ else if (strcmp(avdiscard_entry->value, "none") == 0) ++ enc->skip_frame = AVDISCARD_NONE; ++ // NONINTRA flag was introduced with version bump at revision: ++ // https://github.com/FFmpeg/FFmpeg/commit/b152152df3b778d0a86dcda5d4f5d065b4175a7b ++ // This key is supported only for FFMPEG version ++#if LIBAVCODEC_VERSION_MICRO >= 100 && LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(55, 67, 100) ++ else if (strcmp(avdiscard_entry->value, "nonintra") == 0) ++ enc->skip_frame = AVDISCARD_NONINTRA; ++#endif ++ else if (strcmp(avdiscard_entry->value, "nonkey") == 0) ++ enc->skip_frame = AVDISCARD_NONKEY; ++ else if (strcmp(avdiscard_entry->value, "nonref") == 0) ++ enc->skip_frame = AVDISCARD_NONREF; ++ } ++} ++ + bool CvCapture_FFMPEG::open(const char* _filename, const VideoCaptureParameters& params) + { + InternalFFMpegRegister::init(); +@@ -997,7 +1119,7 @@ bool CvCapture_FFMPEG::open(const char* _filename, const VideoCaptureParameters& + #else + av_dict_set(&dict, "rtsp_transport", "tcp", 0); + #endif +- AVInputFormat* input_format = NULL; ++ CV_FFMPEG_FMT_CONST AVInputFormat* input_format = NULL; + AVDictionaryEntry* entry = av_dict_get(dict, "input_format", NULL, 0); + if (entry != 0) + { +@@ -1015,60 +1137,44 @@ bool CvCapture_FFMPEG::open(const char* _filename, const VideoCaptureParameters& + err = avformat_find_stream_info(ic, NULL); + if (err < 0) + { +- CV_WARN("Could not find codec parameters"); ++ CV_LOG_WARNING(NULL, "Unable to read codec parameters from stream (" << _opencv_ffmpeg_get_error_string(err) << ")"); + goto exit_func; + } + for(i = 0; i < ic->nb_streams; i++) + { +- AVCodecContext* enc = ic->streams[i]->codec; +- +-//#ifdef FF_API_THREAD_INIT +-// avcodec_thread_init(enc, get_number_of_cpus()); +-//#else +- enc->thread_count = get_number_of_cpus(); +-//#endif +- +- AVDictionaryEntry* avdiscard_entry = av_dict_get(dict, "avdiscard", NULL, 0); +- +- if (avdiscard_entry) { +- if(strcmp(avdiscard_entry->value, "all") == 0) +- enc->skip_frame = AVDISCARD_ALL; +- else if (strcmp(avdiscard_entry->value, "bidir") == 0) +- enc->skip_frame = AVDISCARD_BIDIR; +- else if (strcmp(avdiscard_entry->value, "default") == 0) +- enc->skip_frame = AVDISCARD_DEFAULT; +- else if (strcmp(avdiscard_entry->value, "none") == 0) +- enc->skip_frame = AVDISCARD_NONE; +- // NONINTRA flag was introduced with version bump at revision: +- // https://github.com/FFmpeg/FFmpeg/commit/b152152df3b778d0a86dcda5d4f5d065b4175a7b +- // This key is supported only for FFMPEG version +-#if LIBAVCODEC_VERSION_MICRO >= 100 && LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(55, 67, 100) +- else if (strcmp(avdiscard_entry->value, "nonintra") == 0) +- enc->skip_frame = AVDISCARD_NONINTRA; ++#ifndef CV_FFMPEG_CODECPAR ++ context = ic->streams[i]->codec; ++ AVCodecID codec_id = context->codec_id; ++ AVMediaType codec_type = context->codec_type; ++#else ++ AVCodecParameters* par = ic->streams[i]->codecpar; ++ AVCodecID codec_id = par->codec_id; ++ AVMediaType codec_type = par->codec_type; + #endif +- else if (strcmp(avdiscard_entry->value, "nonkey") == 0) +- enc->skip_frame = AVDISCARD_NONKEY; +- else if (strcmp(avdiscard_entry->value, "nonref") == 0) +- enc->skip_frame = AVDISCARD_NONREF; +- } + +- if( AVMEDIA_TYPE_VIDEO == enc->codec_type && video_stream < 0) ++ if( AVMEDIA_TYPE_VIDEO == codec_type && video_stream < 0) + { +- CV_LOG_DEBUG(NULL, "FFMPEG: stream[" << i << "] is video stream with codecID=" << (int)enc->codec_id +- << " width=" << enc->width +- << " height=" << enc->height ++ // backup encoder' width/height ++#ifndef CV_FFMPEG_CODECPAR ++ int enc_width = context->width; ++ int enc_height = context->height; ++#else ++ int enc_width = par->width; ++ int enc_height = par->height; ++#endif ++ ++ CV_LOG_DEBUG(NULL, "FFMPEG: stream[" << i << "] is video stream with codecID=" << (int)codec_id ++ << " width=" << enc_width ++ << " height=" << enc_height + ); + +- // backup encoder' width/height +- int enc_width = enc->width; +- int enc_height = enc->height; + + #if !USE_AV_HW_CODECS + va_type = VIDEO_ACCELERATION_NONE; + #endif + + // find and open decoder, try HW acceleration types specified in 'hw_acceleration' list (in order) +- AVCodec *codec = NULL; ++ const AVCodec *codec = NULL; + err = -1; + #if USE_AV_HW_CODECS + HWAccelIterator accel_iter(va_type, false/*isEncoder*/, dict); +@@ -1080,21 +1186,27 @@ bool CvCapture_FFMPEG::open(const char* _filename, const VideoCaptureParameters& + #if USE_AV_HW_CODECS + accel_iter.parse_next(); + AVHWDeviceType hw_type = accel_iter.hw_type(); +- enc->get_format = avcodec_default_get_format; +- if (enc->hw_device_ctx) { +- av_buffer_unref(&enc->hw_device_ctx); +- } + if (hw_type != AV_HWDEVICE_TYPE_NONE) + { + CV_LOG_DEBUG(NULL, "FFMPEG: trying to configure H/W acceleration: '" << accel_iter.hw_type_device_string() << "'"); + AVPixelFormat hw_pix_fmt = AV_PIX_FMT_NONE; +- codec = hw_find_codec(enc->codec_id, hw_type, av_codec_is_decoder, accel_iter.disabled_codecs().c_str(), &hw_pix_fmt); +- if (codec) { ++ codec = hw_find_codec(codec_id, hw_type, av_codec_is_decoder, accel_iter.disabled_codecs().c_str(), &hw_pix_fmt); ++ if (codec) ++ { ++#ifdef CV_FFMPEG_CODECPAR ++ context = avcodec_alloc_context3(codec); ++#endif ++ CV_Assert(context); ++ context->get_format = avcodec_default_get_format; ++ if (context->hw_device_ctx) { ++ av_buffer_unref(&context->hw_device_ctx); ++ } + if (hw_pix_fmt != AV_PIX_FMT_NONE) +- enc->get_format = hw_get_format_callback; // set callback to select HW pixel format, not SW format +- enc->hw_device_ctx = hw_create_device(hw_type, hw_device, accel_iter.device_subname(), use_opencl != 0); +- if (!enc->hw_device_ctx) ++ context->get_format = hw_get_format_callback; // set callback to select HW pixel format, not SW format ++ context->hw_device_ctx = hw_create_device(hw_type, hw_device, accel_iter.device_subname(), use_opencl != 0); ++ if (!context->hw_device_ctx) + { ++ context->get_format = avcodec_default_get_format; + CV_LOG_DEBUG(NULL, "FFMPEG: ... can't create H/W device: '" << accel_iter.hw_type_device_string() << "'"); + codec = NULL; + } +@@ -1106,10 +1218,10 @@ bool CvCapture_FFMPEG::open(const char* _filename, const VideoCaptureParameters& + AVDictionaryEntry* video_codec_param = av_dict_get(dict, "video_codec", NULL, 0); + if (video_codec_param == NULL) + { +- codec = avcodec_find_decoder(enc->codec_id); ++ codec = avcodec_find_decoder(codec_id); + if (!codec) + { +- CV_LOG_ERROR(NULL, "Could not find decoder for codec_id=" << (int)enc->codec_id); ++ CV_LOG_ERROR(NULL, "Could not find decoder for codec_id=" << (int)codec_id); + } + } + else +@@ -1121,10 +1233,26 @@ bool CvCapture_FFMPEG::open(const char* _filename, const VideoCaptureParameters& + CV_LOG_ERROR(NULL, "Could not find decoder '" << video_codec_param->value << "'"); + } + } ++ if (codec) ++ { ++#ifdef CV_FFMPEG_CODECPAR ++ context = avcodec_alloc_context3(codec); ++#endif ++ CV_Assert(context); ++ } + } + if (!codec) ++ { ++#ifdef CV_FFMPEG_CODECPAR ++ avcodec_free_context(&context); ++#endif + continue; +- err = avcodec_open2(enc, codec, NULL); ++ } ++ fill_codec_context(context, dict); ++#ifdef CV_FFMPEG_CODECPAR ++ avcodec_parameters_to_context(context, par); ++#endif ++ err = avcodec_open2(context, codec, NULL); + if (err >= 0) { + #if USE_AV_HW_CODECS + va_type = hw_type_to_va_type(hw_type); +@@ -1146,10 +1274,10 @@ bool CvCapture_FFMPEG::open(const char* _filename, const VideoCaptureParameters& + } + + // checking width/height (since decoder can sometimes alter it, eg. vp6f) +- if (enc_width && (enc->width != enc_width)) +- enc->width = enc_width; +- if (enc_height && (enc->height != enc_height)) +- enc->height = enc_height; ++ if (enc_width && (context->width != enc_width)) ++ context->width = enc_width; ++ if (enc_height && (context->height != enc_height)) ++ context->height = enc_height; + + video_stream = i; + video_st = ic->streams[i]; +@@ -1160,8 +1288,8 @@ bool CvCapture_FFMPEG::open(const char* _filename, const VideoCaptureParameters& + picture = avcodec_alloc_frame(); + #endif + +- frame.width = enc->width; +- frame.height = enc->height; ++ frame.width = context->width; ++ frame.height = context->height; + frame.cn = 3; + frame.step = 0; + frame.data = NULL; +@@ -1306,7 +1434,7 @@ bool CvCapture_FFMPEG::grabFrame() + int count_errs = 0; + const int max_number_of_attempts = 1 << 9; + +- if( !ic || !video_st ) return false; ++ if( !ic || !video_st || !context ) return false; + + if( ic->streams[video_stream]->nb_frames > 0 && + frame_number > ic->streams[video_stream]->nb_frames ) +@@ -1322,7 +1450,7 @@ bool CvCapture_FFMPEG::grabFrame() + + #if USE_AV_SEND_FRAME_API + // check if we can receive frame from previously decoded packet +- valid = avcodec_receive_frame(video_st->codec, picture) >= 0; ++ valid = avcodec_receive_frame(context, picture) >= 0; + #endif + + // get the next frame +@@ -1372,19 +1500,19 @@ bool CvCapture_FFMPEG::grabFrame() + + // Decode video frame + #if USE_AV_SEND_FRAME_API +- if (avcodec_send_packet(video_st->codec, &packet) < 0) { ++ if (avcodec_send_packet(context, &packet) < 0) { + break; + } +- ret = avcodec_receive_frame(video_st->codec, picture); ++ ret = avcodec_receive_frame(context, picture); + #else + int got_picture = 0; +- avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet); ++ avcodec_decode_video2(context, picture, &got_picture, &packet); + ret = got_picture ? 0 : -1; + #endif + if (ret >= 0) { + //picture_pts = picture->best_effort_timestamp; + if( picture_pts == AV_NOPTS_VALUE_ ) +- picture_pts = picture->pkt_pts != AV_NOPTS_VALUE_ && picture->pkt_pts != 0 ? picture->pkt_pts : picture->pkt_dts; ++ picture_pts = picture->CV_FFMPEG_PTS_FIELD != AV_NOPTS_VALUE_ && picture->CV_FFMPEG_PTS_FIELD != 0 ? picture->CV_FFMPEG_PTS_FIELD : picture->pkt_dts; + + valid = true; + } else if (ret == AVERROR(EAGAIN)) { +@@ -1415,7 +1543,7 @@ bool CvCapture_FFMPEG::grabFrame() + + bool CvCapture_FFMPEG::retrieveFrame(int flag, unsigned char** data, int* step, int* width, int* height, int* cn) + { +- if (!video_st) ++ if (!video_st || !context) + return false; + + if (rawMode || flag == extraDataIdx) +@@ -1428,8 +1556,8 @@ bool CvCapture_FFMPEG::retrieveFrame(int flag, unsigned char** data, int* step, + ret = p.data != NULL; + } + else if (flag == extraDataIdx) { +- *data = ic->streams[video_stream]->codec->extradata; +- *step = ic->streams[video_stream]->codec->extradata_size; ++ *data = ic->streams[video_stream]->CV_FFMPEG_CODEC_FIELD->extradata; ++ *step = ic->streams[video_stream]->CV_FFMPEG_CODEC_FIELD->extradata_size; + } + *width = *step; + *height = 1; +@@ -1454,13 +1582,13 @@ bool CvCapture_FFMPEG::retrieveFrame(int flag, unsigned char** data, int* step, + return false; + + if( img_convert_ctx == NULL || +- frame.width != video_st->codec->width || +- frame.height != video_st->codec->height || ++ frame.width != video_st->CV_FFMPEG_CODEC_FIELD->width || ++ frame.height != video_st->CV_FFMPEG_CODEC_FIELD->height || + frame.data == NULL ) + { + // Some sws_scale optimizations have some assumptions about alignment of data/step/width/height + // Also we use coded_width/height to workaround problem with legacy ffmpeg versions (like n0.8) +- int buffer_width = video_st->codec->coded_width, buffer_height = video_st->codec->coded_height; ++ int buffer_width = context->coded_width, buffer_height = context->coded_height; + + img_convert_ctx = sws_getCachedContext( + img_convert_ctx, +@@ -1494,8 +1622,8 @@ bool CvCapture_FFMPEG::retrieveFrame(int flag, unsigned char** data, int* step, + _opencv_ffmpeg_av_image_fill_arrays(&rgb_picture, rgb_picture.data[0], + AV_PIX_FMT_BGR24, buffer_width, buffer_height ); + #endif +- frame.width = video_st->codec->width; +- frame.height = video_st->codec->height; ++ frame.width = video_st->CV_FFMPEG_CODEC_FIELD->width; ++ frame.height = video_st->CV_FFMPEG_CODEC_FIELD->height; + frame.cn = 3; + frame.data = rgb_picture.data[0]; + frame.step = rgb_picture.linesize[0]; +@@ -1505,7 +1633,7 @@ bool CvCapture_FFMPEG::retrieveFrame(int flag, unsigned char** data, int* step, + img_convert_ctx, + sw_picture->data, + sw_picture->linesize, +- 0, video_st->codec->coded_height, ++ 0, context->coded_height, + rgb_picture.data, + rgb_picture.linesize + ); +@@ -1529,12 +1657,12 @@ bool CvCapture_FFMPEG::retrieveHWFrame(cv::OutputArray output) + { + #if USE_AV_HW_CODECS + // check that we have HW frame in GPU memory +- if (!picture || !picture->hw_frames_ctx) { ++ if (!picture || !picture->hw_frames_ctx || !context) { + return false; + } + + // GPU color conversion NV12->BGRA, from GPU media buffer to GPU OpenCL buffer +- return hw_copy_frame_to_umat(video_st->codec->hw_device_ctx, picture, output); ++ return hw_copy_frame_to_umat(context->hw_device_ctx, picture, output); + #else + CV_UNUSED(output); + return false; +@@ -1543,7 +1671,7 @@ bool CvCapture_FFMPEG::retrieveHWFrame(cv::OutputArray output) + + double CvCapture_FFMPEG::getProperty( int property_id ) const + { +- if( !video_st ) return 0; ++ if( !video_st || !context ) return 0; + + double codec_tag = 0; + CV_CODEC_ID codec_id = AV_CODEC_ID_NONE; +@@ -1570,8 +1698,8 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const + case CAP_PROP_FPS: + return get_fps(); + case CAP_PROP_FOURCC: +- codec_id = video_st->codec->codec_id; +- codec_tag = (double) video_st->codec->codec_tag; ++ codec_id = video_st->CV_FFMPEG_CODEC_FIELD->codec_id; ++ codec_tag = (double) video_st->CV_FFMPEG_CODEC_FIELD->codec_tag; + + if(codec_tag || codec_id == AV_CODEC_ID_NONE) + { +@@ -1591,7 +1719,11 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const + return _opencv_ffmpeg_get_sample_aspect_ratio(ic->streams[video_stream]).den; + case CAP_PROP_CODEC_PIXEL_FORMAT: + { ++#ifdef CV_FFMPEG_CODECPAR ++ AVPixelFormat pix_fmt = (AVPixelFormat)video_st->codecpar->format; ++#else + AVPixelFormat pix_fmt = video_st->codec->pix_fmt; ++#endif + unsigned int fourcc_tag = avcodec_pix_fmt_to_codec_tag(pix_fmt); + return (fourcc_tag == 0) ? (double)-1 : (double)fourcc_tag; + } +@@ -1671,7 +1803,7 @@ double CvCapture_FFMPEG::get_fps() const + + if (fps < eps_zero) + { +- fps = 1.0 / r2d(ic->streams[video_stream]->codec->time_base); ++ fps = 1.0 / r2d(ic->streams[video_stream]->time_base); + } + #endif + return fps; +@@ -1703,7 +1835,16 @@ double CvCapture_FFMPEG::dts_to_sec(int64_t dts) const + void CvCapture_FFMPEG::get_rotation_angle() + { + rotation_angle = 0; +-#if LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 94, 100) ++#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(57, 68, 100) ++ const uint8_t *data = 0; ++ data = av_stream_get_side_data(video_st, AV_PKT_DATA_DISPLAYMATRIX, NULL); ++ if (data) ++ { ++ rotation_angle = cvRound(av_display_rotation_get((const int32_t*)data)); ++ if (rotation_angle < 0) ++ rotation_angle += 360; ++ } ++#elif LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(52, 94, 100) + AVDictionaryEntry *rotate_tag = av_dict_get(video_st->metadata, "rotate", NULL, 0); + if (rotate_tag != NULL) + rotation_angle = atoi(rotate_tag->value); +@@ -1712,6 +1853,7 @@ void CvCapture_FFMPEG::get_rotation_angle() + + void CvCapture_FFMPEG::seek(int64_t _frame_number) + { ++ CV_Assert(context); + _frame_number = std::min(_frame_number, get_total_frames()); + int delta = 16; + +@@ -1728,7 +1870,7 @@ void CvCapture_FFMPEG::seek(int64_t _frame_number) + double time_base = r2d(ic->streams[video_stream]->time_base); + time_stamp += (int64_t)(sec / time_base + 0.5); + if (get_total_frames() > 1) av_seek_frame(ic, video_stream, time_stamp, AVSEEK_FLAG_BACKWARD); +- avcodec_flush_buffers(ic->streams[video_stream]->codec); ++ avcodec_flush_buffers(context); + if( _frame_number > 0 ) + { + grabFrame(); +@@ -1833,7 +1975,7 @@ struct CvVideoWriter_FFMPEG + + void init(); + +- AVOutputFormat * fmt; ++ CV_FFMPEG_FMT_CONST AVOutputFormat * fmt; + AVFormatContext * oc; + uint8_t * outbuf; + uint32_t outbuf_size; +@@ -1842,6 +1984,7 @@ struct CvVideoWriter_FFMPEG + AVFrame * input_picture; + uint8_t * picbuf; + AVStream * video_st; ++ AVCodecContext * context; + AVPixelFormat input_pix_fmt; + unsigned char * aligned_input; + size_t aligned_input_size; +@@ -1906,6 +2049,7 @@ void CvVideoWriter_FFMPEG::init() + input_picture = 0; + picbuf = 0; + video_st = 0; ++ context = 0; + input_pix_fmt = AV_PIX_FMT_NONE; + aligned_input = NULL; + aligned_input_size = 0; +@@ -1957,23 +2101,32 @@ static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bo + } + + /* configure video stream */ +-static bool icv_configure_video_stream_FFMPEG(AVFormatContext *oc, ++static AVCodecContext * icv_configure_video_stream_FFMPEG(AVFormatContext *oc, + AVStream *st, + const AVCodec* codec, + int w, int h, int bitrate, +- double fps, AVPixelFormat pixel_format) ++ double fps, AVPixelFormat pixel_format, int fourcc) + { ++#ifdef CV_FFMPEG_CODECPAR ++ AVCodecContext *c = avcodec_alloc_context3(codec); ++#else + AVCodecContext *c = st->codec; ++#endif ++ CV_Assert(c); ++ + int frame_rate, frame_rate_base; + + c->codec_id = codec->id; + c->codec_type = AVMEDIA_TYPE_VIDEO; ++ c->codec_tag = fourcc; + ++#ifndef CV_FFMPEG_CODECPAR + // Set per-codec defaults + CV_CODEC_ID c_id = c->codec_id; + avcodec_get_context_defaults3(c, codec); + // avcodec_get_context_defaults3 erases codec_id for some reason + c->codec_id = c_id; ++#endif + + /* put sample parameters */ + int64_t lbit_rate = (int64_t)bitrate; +@@ -2016,7 +2169,12 @@ static bool icv_configure_video_stream_FFMPEG(AVFormatContext *oc, + } + } + if (best == NULL) +- return false; ++ { ++#ifdef CV_FFMPEG_CODECPAR ++ avcodec_free_context(&c); ++#endif ++ return NULL; ++ } + c->time_base.den= best->num; + c->time_base.num= best->den; + } +@@ -2059,26 +2217,20 @@ static bool icv_configure_video_stream_FFMPEG(AVFormatContext *oc, + #endif + } + +-#if defined(_MSC_VER) +- AVRational avg_frame_rate = {frame_rate, frame_rate_base}; +- st->avg_frame_rate = avg_frame_rate; +-#else +- st->avg_frame_rate = (AVRational){frame_rate, frame_rate_base}; +-#endif ++ st->avg_frame_rate = av_make_q(frame_rate, frame_rate_base); + #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(55, 20, 0) + st->time_base = c->time_base; + #endif + +- return true; ++ return c; + } + + static const int OPENCV_NO_FRAMES_WRITTEN_CODE = 1000; + +-static int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, ++static int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, AVCodecContext * c, + uint8_t *, uint32_t, + AVFrame * picture, int frame_idx) + { +- AVCodecContext* c = video_st->codec; + int ret = OPENCV_NO_FRAMES_WRITTEN_CODE; + + #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(57, 0, 0) +@@ -2176,9 +2328,6 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int + width = frame_width; + height = frame_height; + +- // typecast from opaque data type to implemented struct +- AVCodecContext* c = video_st->codec; +- + // FFmpeg contains SIMD optimizations which can sometimes read data past + // the supplied input buffer. + // Related info: https://trac.ffmpeg.org/ticket/6763 +@@ -2215,10 +2364,10 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int + step = aligned_step; + } + +- AVPixelFormat sw_pix_fmt = c->pix_fmt; ++ AVPixelFormat sw_pix_fmt = context->pix_fmt; + #if USE_AV_HW_CODECS +- if (c->hw_frames_ctx) +- sw_pix_fmt = ((AVHWFramesContext*)c->hw_frames_ctx->data)->sw_format; ++ if (context->hw_frames_ctx) ++ sw_pix_fmt = ((AVHWFramesContext*)context->hw_frames_ctx->data)->sw_format; + #endif + if ( sw_pix_fmt != input_pix_fmt ) { + CV_Assert( input_picture ); +@@ -2232,8 +2381,8 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int + img_convert_ctx = sws_getContext(width, + height, + (AVPixelFormat)input_pix_fmt, +- c->width, +- c->height, ++ context->width, ++ context->height, + sw_pix_fmt, + SWS_BICUBIC, + NULL, NULL, NULL); +@@ -2255,14 +2404,14 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int + + bool ret; + #if USE_AV_HW_CODECS +- if (video_st->codec->hw_device_ctx) { ++ if (context->hw_device_ctx) { + // copy data to HW frame + AVFrame* hw_frame = av_frame_alloc(); + if (!hw_frame) { + CV_LOG_ERROR(NULL, "Error allocating AVFrame (av_frame_alloc)"); + return false; + } +- if (av_hwframe_get_buffer(video_st->codec->hw_frames_ctx, hw_frame, 0) < 0) { ++ if (av_hwframe_get_buffer(context->hw_frames_ctx, hw_frame, 0) < 0) { + CV_LOG_ERROR(NULL, "Error obtaining HW frame (av_hwframe_get_buffer)"); + av_frame_free(&hw_frame); + return false; +@@ -2273,14 +2422,14 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int + return false; + } + hw_frame->pts = frame_idx; +- int ret_write = icv_av_write_frame_FFMPEG(oc, video_st, outbuf, outbuf_size, hw_frame, frame_idx); ++ int ret_write = icv_av_write_frame_FFMPEG(oc, video_st, context, outbuf, outbuf_size, hw_frame, frame_idx); + ret = ret_write >= 0 ? true : false; + av_frame_free(&hw_frame); + } else + #endif + { + picture->pts = frame_idx; +- int ret_write = icv_av_write_frame_FFMPEG(oc, video_st, outbuf, outbuf_size, picture, frame_idx); ++ int ret_write = icv_av_write_frame_FFMPEG(oc, video_st, context, outbuf, outbuf_size, picture, frame_idx); + ret = ret_write >= 0 ? true : false; + } + +@@ -2291,7 +2440,7 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int + + bool CvVideoWriter_FFMPEG::writeHWFrame(cv::InputArray input) { + #if USE_AV_HW_CODECS +- if (!video_st->codec->hw_frames_ctx) ++ if (!video_st || !context || !context->hw_frames_ctx || !context->hw_device_ctx) + return false; + + // Get hardware frame from frame pool +@@ -2299,20 +2448,20 @@ bool CvVideoWriter_FFMPEG::writeHWFrame(cv::InputArray input) { + if (!hw_frame) { + return false; + } +- if (av_hwframe_get_buffer(video_st->codec->hw_frames_ctx, hw_frame, 0) < 0) { ++ if (av_hwframe_get_buffer(context->hw_frames_ctx, hw_frame, 0) < 0) { + av_frame_free(&hw_frame); + return false; + } + + // GPU to GPU copy +- if (!hw_copy_umat_to_frame(video_st->codec->hw_device_ctx, input, hw_frame)) { ++ if (!hw_copy_umat_to_frame(context->hw_device_ctx, input, hw_frame)) { + av_frame_free(&hw_frame); + return false; + } + + // encode + hw_frame->pts = frame_idx; +- icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, hw_frame, frame_idx); ++ icv_av_write_frame_FFMPEG( oc, video_st, context, outbuf, outbuf_size, hw_frame, frame_idx); + frame_idx++; + + av_frame_free(&hw_frame); +@@ -2365,7 +2514,7 @@ void CvVideoWriter_FFMPEG::close() + { + for(;;) + { +- int ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, NULL, frame_idx); ++ int ret = icv_av_write_frame_FFMPEG( oc, video_st, context, outbuf, outbuf_size, NULL, frame_idx); + if( ret == OPENCV_NO_FRAMES_WRITTEN_CODE || ret < 0 ) + break; + } +@@ -2380,7 +2529,7 @@ void CvVideoWriter_FFMPEG::close() + } + + // free pictures +- if( video_st->codec->pix_fmt != input_pix_fmt) ++ if( context->pix_fmt != input_pix_fmt) + { + if(picture->data[0]) + free(picture->data[0]); +@@ -2392,7 +2541,7 @@ void CvVideoWriter_FFMPEG::close() + av_free(input_picture); + + /* close codec */ +- avcodec_close(video_st->codec); ++ avcodec_close(context); + + av_free(outbuf); + +@@ -2599,8 +2748,15 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, + + /* set file name */ + oc->oformat = fmt; ++#ifndef CV_FFMPEG_URL + snprintf(oc->filename, sizeof(oc->filename), "%s", filename); +- ++#else ++ size_t name_len = strlen(filename); ++ oc->url = (char*)av_malloc(name_len + 1); ++ CV_Assert(oc->url); ++ memcpy((void*)oc->url, filename, name_len + 1); ++ oc->url[name_len] = '\0'; ++#endif + /* set some options */ + oc->max_delay = (int)(0.7*AV_TIME_BASE); /* This reduces buffer underrun warnings with MPEG */ + +@@ -2715,7 +2871,7 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, + double bitrate = std::min(bitrate_scale*fps*width*height, (double)INT_MAX/2); + + if (codec_id == AV_CODEC_ID_NONE) { +- codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); ++ codec_id = av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO); + } + + // Add video stream to output file +@@ -2733,11 +2889,9 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, + } + #endif + +- AVCodecContext *c = video_st->codec; +- + // find and open encoder, try HW acceleration types specified in 'hw_acceleration' list (in order) + int err = -1; +- AVCodec* codec = NULL; ++ const AVCodec* codec = NULL; + #if USE_AV_HW_CODECS + AVBufferRef* hw_device_ctx = NULL; + HWAccelIterator accel_iter(va_type, true/*isEncoder*/, dict); +@@ -2780,9 +2934,17 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, + AVPixelFormat format = codec_pix_fmt; + #endif + +- if (!icv_configure_video_stream_FFMPEG(oc, video_st, codec, +- width, height, (int) (bitrate + 0.5), +- fps, format)) { ++#ifdef CV_FFMPEG_CODECPAR ++ if (context) ++ { ++ avcodec_free_context(&context); ++ } ++#endif ++ context = icv_configure_video_stream_FFMPEG(oc, video_st, codec, ++ width, height, (int) (bitrate + 0.5), ++ fps, format, fourcc); ++ if (!context) ++ { + continue; + } + +@@ -2794,27 +2956,25 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, + #endif + #endif + +- c->codec_tag = fourcc; +- + #if USE_AV_HW_CODECS + if (hw_device_ctx) { +- c->hw_device_ctx = av_buffer_ref(hw_device_ctx); ++ context->hw_device_ctx = av_buffer_ref(hw_device_ctx); + if (hw_format != AV_PIX_FMT_NONE) { +- c->hw_frames_ctx = hw_create_frames(NULL, hw_device_ctx, width, height, hw_format); +- if (!c->hw_frames_ctx) ++ context->hw_frames_ctx = hw_create_frames(NULL, hw_device_ctx, width, height, hw_format); ++ if (!context->hw_frames_ctx) + continue; + } + } + #endif + +- int64_t lbit_rate = (int64_t) c->bit_rate; ++ int64_t lbit_rate = (int64_t) context->bit_rate; + lbit_rate += (int64_t)(bitrate / 2); + lbit_rate = std::min(lbit_rate, (int64_t) INT_MAX); +- c->bit_rate_tolerance = (int) lbit_rate; +- c->bit_rate = (int) lbit_rate; ++ context->bit_rate_tolerance = (int) lbit_rate; ++ context->bit_rate = (int) lbit_rate; + + /* open the codec */ +- err = avcodec_open2(c, codec, NULL); ++ err = avcodec_open2(context, codec, NULL); + if (err >= 0) { + #if USE_AV_HW_CODECS + va_type = hw_type_to_va_type(hw_type); +@@ -2823,7 +2983,7 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, + #endif + break; + } else { +- CV_LOG_ERROR(NULL, "Could not open codec " << codec->name << ", error: " << icvFFMPEGErrStr(err)); ++ CV_LOG_ERROR(NULL, "Could not open codec " << codec->name << ", error: " << icvFFMPEGErrStr(err) << " (" << err << ")"); + } + #if USE_AV_HW_CODECS + } // while (accel_iter.good()) +@@ -2844,6 +3004,12 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, + return false; + } + ++#ifdef CV_FFMPEG_CODECPAR ++ // Copy all to codecpar... ++ // !!! https://stackoverflow.com/questions/15897849/c-ffmpeg-not-writing-avcc-box-information ++ avcodec_parameters_from_context(video_st->codecpar, context); ++#endif ++ + outbuf = NULL; + + +@@ -2858,16 +3024,16 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, + } + + bool need_color_convert; +- AVPixelFormat sw_pix_fmt = c->pix_fmt; ++ AVPixelFormat sw_pix_fmt = context->pix_fmt; + #if USE_AV_HW_CODECS +- if (c->hw_frames_ctx) +- sw_pix_fmt = ((AVHWFramesContext*)c->hw_frames_ctx->data)->sw_format; ++ if (context->hw_frames_ctx) ++ sw_pix_fmt = ((AVHWFramesContext*)context->hw_frames_ctx->data)->sw_format; + #endif + + need_color_convert = (sw_pix_fmt != input_pix_fmt); + + /* allocate the encoded raw picture */ +- picture = icv_alloc_picture_FFMPEG(sw_pix_fmt, c->width, c->height, need_color_convert); ++ picture = icv_alloc_picture_FFMPEG(sw_pix_fmt, context->width, context->height, need_color_convert); + if (!picture) { + return false; + } +@@ -2877,7 +3043,7 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, + to the required output format */ + input_picture = NULL; + if ( need_color_convert ) { +- input_picture = icv_alloc_picture_FFMPEG(input_pix_fmt, c->width, c->height, false); ++ input_picture = icv_alloc_picture_FFMPEG(input_pix_fmt, context->width, context->height, false); + if (!input_picture) { + return false; + }