name: CI

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  linux:
    strategy:
      matrix:
        compiler: ['gcc-9']
        qt_version: ["5.15.2", "6.11.1"]
        include:
          - compiler: gcc-9
            packages: gcc-9 g++-9
            env: { 'CC': 'gcc-9', 'CXX': 'g++-9' }
          - qt_version: "6.11.1"
            qt_modules: "qtmultimedia"
            qt_packages: "libxkbcommon-dev libgstreamer-plugins-base1.0-0 libgstreamer-gl1.0-0"

    runs-on: ubuntu-latest

    env: ${{ matrix.env }}

    steps:
      - uses: actions/checkout@v3

      - name: Install compiler and FFmpeg dependencies
        run: |
          sudo apt-get update &&
          sudo apt-get install -y ${{ matrix.packages }} ${{ matrix.qt_packages }} \
                                  libavcodec-dev \
                                  libavformat-dev \
                                  libavdevice-dev \
                                  libavfilter-dev \
                                  libavformat-dev \
                                  libavutil-dev \
                                  libswresample-dev \
                                  libswscale-dev \
                                  libva-x11-2 \
                                  libva-drm2 \
                                  libass-dev

      - name: Install Qt
        uses: jurplel/install-qt-action@v3
        with:
          version: ${{ matrix.qt_version }}
          modules: ${{ matrix.qt_modules }}

      - name: libQtAVPlayer
        run: |
          mkdir build
          cd build
          cmake ../src/QtAVPlayer -DCMAKE_INSTALL_PREFIX=../install -DQT_AVPLAYER_MULTIMEDIA=ON
          make CC=$CC CXX=$CXX CXXFLAGS='-std=c++17' VERBOSE=1
          make install
          cd ../examples/qml_video
          mkdir build
          cd build
          cmake ../ -DCMAKE_PREFIX_PATH="$PWD/../../../install/lib/cmake" -DQT_AVPLAYER_LIB=ON
          make CC=$CC CXX=$CXX CXXFLAGS='-std=c++17' VERBOSE=1

      - name: QMake Test
        run: |
          export QT_LOGGING_RULES="qt.QtAVPlayer.debug=true"
          cd tests/auto/integration/qavdemuxer
          qmake DEFINES+="QT_AVPLAYER_LIBASS"
          make CC=$CC CXX=$CXX
          ./tst_qavdemuxer -platform offscreen
          cd ../qavplayer
          qmake
          make CC=$CC CXX=$CXX
          ./tst_qavplayer --platform minimal -maxwarnings 100000

      - name: QMake Examples
        run: |
          cd examples/qml_video
          qmake
          make CC=$CC CXX=$CXX
          cd ../widget_video_opengl
          qmake
          make CC=$CC CXX=$CXX
          cd ../muxer
          qmake
          make CC=$CC CXX=$CXX

      - name: CMake Examples
        run: |
          cd examples/qml_video
          cmake . -DQT_AVPLAYER_MULTIMEDIA=ON
          make CC=$CC CXX=$CXX CXXFLAGS='-std=c++17' VERBOSE=1
          cd ../widget_video
          cmake . -DQT_AVPLAYER_MULTIMEDIA=ON
          make CC=$CC CXX=$CXX CXXFLAGS='-std=c++17' VERBOSE=1
          cd ../widget_video_opengl
          cmake . -DQT_AVPLAYER_MULTIMEDIA=ON
          make CC=$CC CXX=$CXX CXXFLAGS='-std=c++17' VERBOSE=1

      - name: CMake Examples
        if: ${{ matrix.qt_version == '6.11.1' }}
        run: |
          cd examples/qml_player
          cmake . -DQT_AVPLAYER_MULTIMEDIA=ON -DQT_AVPLAYER_LIBASS=ON
          make CC=$CC CXX=$CXX CXXFLAGS='-std=c++17' VERBOSE=1

  macos:
    strategy:
      matrix:
        compiler: ['clang-9']
        include:
          - compiler: clang-9
            packages: llvm@14
            env: { 'CC': 'clang', 'CXX': 'clang++', 'CXXFLAGS': '-DNS_FORMAT_ARGUMENT\(A\)= -fapplication-extension -std=c++17' }

    runs-on: macos-latest

    env: ${{ matrix.env }}

    steps:
      - uses: actions/checkout@v3

      - name: Install dependencies
        run: |
          brew install ${{ matrix.packages }} ffmpeg qt@5

      - name: Set environment path
        run: |
          brew --prefix ffmpeg
          brew --prefix qt@5
          echo `brew --prefix qt@5`/bin >> $GITHUB_PATH
          echo "/usr/local/opt/llvm@9/bin" >> $GITHUB_PATH

      - name: libQtAVPlayer
        run: |
          export FFMPEG=`brew --prefix ffmpeg`
          ls -l $FFMPEG
          mkdir build
          cd build
          cmake ../src/QtAVPlayer -DCMAKE_INSTALL_PREFIX=../install -DQT_AVPLAYER_MULTIMEDIA=ON -DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES=$FFMPEG/include -DCMAKE_LIBRARY_PATH=$FFMPEG/lib
          make CC=$CC CXX=$CXX CXXFLAGS='-std=c++17' VERBOSE=1
          make install
          cd ../examples/qml_video
          mkdir build
          cd build
          cmake ../ -DCMAKE_PREFIX_PATH="$PWD/../../../install/lib/cmake" -DQT_AVPLAYER_LIB=ON -DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES=$FFMPEG/include -DCMAKE_LIBRARY_PATH=$FFMPEG/lib
          make CC=$CC CXX=$CXX CXXFLAGS='-std=c++17' VERBOSE=1

      - name: QMake Test
        run: |
          export FFMPEG=`brew --prefix ffmpeg`
          ls -l $FFMPEG
          export QT_LOGGING_RULES="qt.QtAVPlayer.debug=true"
          cd tests/auto/integration/qavdemuxer
          qmake INCLUDEPATH+="$FFMPEG/include" LIBS="-L$FFMPEG/lib"
          make CC=$CC CXX=$CXX
          tst_qavdemuxer.app/Contents/MacOS/tst_qavdemuxer
          cd ../qavplayer
          qmake INCLUDEPATH+="$FFMPEG/include" LIBS="-L$FFMPEG/lib"
          make CC=$CC CXX=$CXX
          tst_qavplayer.app/Contents/MacOS/tst_qavplayer --platform minimal -maxwarnings 100000

      - name: QMake Examples
        run: |
          export FFMPEG=`brew --prefix ffmpeg`
          cd examples/qml_video
          qmake INCLUDEPATH+="$FFMPEG/include" LIBS+="-L$FFMPEG/lib"
          make CC=$CC CXX=$CXX
          cd ../muxer
          qmake INCLUDEPATH+="$FFMPEG/include" LIBS+="-L$FFMPEG/lib"
          make CC=$CC CXX=$CXX

      - name: CMake Examples
        run: |
          export FFMPEG=`brew --prefix ffmpeg`
          cd examples/qml_video
          cmake . -DQT_AVPLAYER_MULTIMEDIA=ON -DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES=$FFMPEG/include -DCMAKE_LIBRARY_PATH=$FFMPEG/lib
          make CC=$CC CXX=$CXX CXXFLAGS='-std=c++17' VERBOSE=1
          cd ../widget_video
          cmake . -DQT_AVPLAYER_MULTIMEDIA=ON -DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES=$FFMPEG/include -DCMAKE_LIBRARY_PATH=$FFMPEG/lib
          make CC=$CC CXX=$CXX CXXFLAGS='-std=c++17' VERBOSE=1

  windows:
    strategy:
      matrix:
        qt_version: ["5.15.2", "6.8.2"]
        type: ["MSVC", "MINGW"]
        include:
          - qt_version: "6.8.2"
            qt_modules: "qtmultimedia"

    runs-on: windows-latest

    steps:
      - uses: actions/checkout@v3

      - name: Init vs environment
        if: ${{ matrix.type == 'MSVC' }}
        uses: egor-tensin/vs-shell@v2
        with:
          arch: x64

      - name: Install wget & unzip
        run: |
          choco install wget unzip xidel

      - name: Install Qt
        if: ${{ matrix.type == 'MINGW' && matrix.qt_version == '5.15.2' }}
        uses: jurplel/install-qt-action@v3
        with:
          arch: win64_mingw81
          version: ${{ matrix.qt_version }}

      - name: Install Qt
        if: ${{ matrix.type == 'MINGW' && matrix.qt_version == '6.8.2' }}
        uses: jurplel/install-qt-action@v3
        with:
          arch: win64_mingw
          version: ${{ matrix.qt_version }}
          modules: ${{ matrix.qt_modules }}

      - name: Install Qt
        if: ${{ matrix.type == 'MSVC' && matrix.qt_version == '5.15.2' }}
        uses: jurplel/install-qt-action@v3
        with:
          version: ${{ matrix.qt_version }}
          modules: ${{ matrix.qt_modules }}

      - name: Install Qt
        if: ${{ matrix.type == 'MSVC' && matrix.qt_version == '6.8.2' }}
        uses: jurplel/install-qt-action@v4
        with:
          target: 'desktop'
          arch: win64_msvc2022_64
          version: ${{ matrix.qt_version }}
          modules: ${{ matrix.qt_modules }}

      - name: Install FFmpeg
        shell: cmd
        run: |
          cd ..
          xidel https://github.com/BtbN/FFmpeg-Builds/releases -e "//include-fragment[contains(@src, '/expanded_assets/autobuild')]/@src[1]" --silent > ffmpeg-expand.url
          set /P FFMPEG_RELEASES=< ffmpeg-expand.url
          xidel %FFMPEG_RELEASES% -e "//a[contains(@href, '-gpl-shared.zip')]/@href[1]" --silent > ffmpeg.url
          xidel %FFMPEG_RELEASES% -e "(//a[contains(@href, '-gpl-shared.zip')])[1]/substring(., 0, string-length(.) - 3)" --silent > ffmpeg.name
          set /P FFMPEG_URL=< ffmpeg.url
          set /P FFMPEG_NAME=< ffmpeg.name
          type ffmpeg.url
          type ffmpeg.name
          wget https://github.com%FFMPEG_URL%
          unzip %FFMPEG_NAME%.zip
          ren %FFMPEG_NAME% ffmpeg
          dir ffmpeg
          dir ffmpeg\include
          dir ffmpeg\bin
          SET FFMPEG=%CD%\ffmpeg
          echo FFMPEG=%FFMPEG%>>%GITHUB_ENV%
          echo LIBRARY_PATH=C:\mingw64\bin;%FFMPEG%\lib;%FFMPEG%\bin;>>%GITHUB_ENV%
          echo %FFMPEG%\lib;%FFMPEG%\bin;C:\mingw64\bin>>%GITHUB_PATH%
          echo INCLUDE=%FFMPEG%\include;%INCLUDE%>>%GITHUB_ENV%
          echo CPLUS_INCLUDE_PATH=%FFMPEG%\include;%CPLUS_INCLUDE_PATH%>>%GITHUB_ENV%
          echo LIB=%FFMPEG%\lib;%FFMPEG%\bin;%LIB%>>%GITHUB_ENV%

      - name: QMake Test
        if: ${{ matrix.type == 'MSVC' }}
        shell: cmd
        run: |
          set QT_LOGGING_RULES=qt.QtAVPlayer.debug=true
          set QT_FORCE_STDERR_LOGGING=1
          set QT_ASSUME_STDERR_HAS_CONSOLE=1
          cd tests\auto\integration\qavdemuxer
          dir
          qmake
          nmake
          dir release
          release\tst_qavdemuxer.exe
          cd ..\qavplayer
          cd qavplayer
          qmake
          nmake
          release\tst_qavplayer.exe -maxwarnings 100000

      - name: libQtAVPlayer
        if: ${{ matrix.type == 'MSVC' }}
        run: |
          mkdir build
          cd build
          cmake ../src/QtAVPlayer -DCMAKE_INSTALL_PREFIX=../install -DQT_AVPLAYER_MULTIMEDIA=ON -DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES=D:\a\QtAVPlayer\ffmpeg\include -DCMAKE_LIBRARY_PATH=D:\a\QtAVPlayer\ffmpeg\lib
          cmake --build . -v
          cmake --install .
          cd ../examples/qml_video
          mkdir build
          cd build
          cmake ../ -DCMAKE_PREFIX_PATH="D:\a\QtAVPlayer\install\lib\cmake" -DQT_AVPLAYER_MULTIMEDIA=ON -DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES=D:\a\QtAVPlayer\ffmpeg\include -DCMAKE_LIBRARY_PATH=D:\a\QtAVPlayer\ffmpeg\lib
          cmake --build . -v

      - name: QMake Test
        if: ${{ matrix.type == 'MINGW' && matrix.qt_version == '5.15.2' }}
        shell: cmd
        run: |
          set QT_LOGGING_RULES=qt.QtAVPlayer.debug=true
          set QT_FORCE_STDERR_LOGGING=1
          set QT_ASSUME_STDERR_HAS_CONSOLE=1
          cd tests/auto/integration/qavdemuxer
          where g++
          qmake
          mingw32-make
          release\tst_qavdemuxer.exe
          cd ../qavplayer
          qmake
          mingw32-make
          release\tst_qavplayer.exe -maxwarnings 100000

      - name: QMake Examples
        if: ${{ matrix.type == 'MSVC' }}
        run: |
          cd examples/qml_video
          qmake
          nmake
          cd ../muxer
          qmake
          nmake

      - name: CMake Examples
        if: ${{ matrix.type == 'MSVC' }}
        run: |
          cd examples/qml_video
          cmake . -DQT_AVPLAYER_MULTIMEDIA=ON -DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES=D:\a\QtAVPlayer\ffmpeg\include -DCMAKE_LIBRARY_PATH=D:\a\QtAVPlayer\ffmpeg\lib
          cmake --build . -v
          cd ../widget_video
          cmake . -DQT_AVPLAYER_MULTIMEDIA=ON -DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES=D:\a\QtAVPlayer\ffmpeg\include -DCMAKE_LIBRARY_PATH=D:\a\QtAVPlayer\ffmpeg\lib
          cmake --build . -v

      - name: CMake Examples
        if: ${{ matrix.type == 'MSVC' && matrix.qt_version == '6.8.2' }}
        run: |
          cd examples/qml_player
          cmake . -DQT_AVPLAYER_MULTIMEDIA=ON -DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES=D:\a\QtAVPlayer\ffmpeg\include -DCMAKE_LIBRARY_PATH=D:\a\QtAVPlayer\ffmpeg\lib
          cmake --build . -v

      - name: QMake Examples
        if: ${{ matrix.type == 'MINGW' }}
        run: |
          cd examples/qml_video
          qmake
          mingw32-make
          cd ../muxer
          qmake
          mingw32-make

  sailfish:
    runs-on: ubuntu-latest
    container: coderus/sailfishos-platform-sdk:5.0.0.43

    env:
      RELEASE: 5.0.0.43
      ARCH: armv7hl

    steps:
      - name: Checkout
        # can't use actions/checkout (no node.js)
        run: |
          git clone "https://github.com/$GITHUB_REPOSITORY.git" /home/mersdk/build
          cd /home/mersdk/build
          git fetch origin "$GITHUB_REF"
          git checkout FETCH_HEAD

      - name: Install dependencies & libQtAVPlayer
        run: |
          export HOME=/home/mersdk
          cd $HOME/build
          TARGET=SailfishOS-$RELEASE-$ARCH
          alias mb2="mb2 -t $TARGET"

          mkdir build
          cd build
          mb2 build-init
          mb2 build-shell --maintain zypper install -y qt5-qtopengl-devel qt5-qtmultimedia-devel ffmpeg-devel
          mb2 build-shell cmake ../src/QtAVPlayer -DCMAKE_INSTALL_PREFIX=../install -DQT_AVPLAYER_MULTIMEDIA=ON
          mb2 build-shell make CXXFLAGS='-std=c++17' VERBOSE=1
          mb2 build-shell make install
          cd ../examples/qml_video
          mkdir build
          cd build
          mb2 build-init
          mb2 build-shell cmake ../ -DCMAKE_PREFIX_PATH="$PWD/../../../install/lib/cmake" -DQT_AVPLAYER_LIB=ON
          mb2 build-shell make CXXFLAGS='-std=c++17' VERBOSE=1

  android:
    strategy:
      matrix:
        qt_version: ["6.6.3"]
        arch: ["armv7"]

    runs-on: ubuntu-latest
    permissions:
      contents: read

    steps:
      - uses: actions/checkout@v3

      - name: Install Qt host (desktop)
        uses: jurplel/install-qt-action@v3
        with:
          version: ${{ matrix.qt_version }}
          target: 'desktop'
          arch: 'gcc_64'
          modules: 'qtmultimedia'

      - name: Install Qt for Android
        uses: jurplel/install-qt-action@v3
        with:
          version: ${{ matrix.qt_version }}
          target: 'android'
          arch: ${{ format('android_{0}', matrix.arch) }}
          modules: 'qtmultimedia'

      - name: Set up Android NDK
        uses: nttld/setup-ndk@v1
        with:
          ndk-version: r27b
          add-to-path: true

      - name: Set up Android build variables
        run: |
          echo "ANDROID_ABI=armeabi-v7a" >> $GITHUB_ENV
          if [ -f "$Qt6_DIR/Qt6Config.cmake" ]; then
            QT6_CMAKE_DIR="$Qt6_DIR"
            QT_ANDROID_PATH="$(dirname "$(dirname "$(dirname "$QT6_CMAKE_DIR")")")"
          elif [ -f "$Qt6_DIR/lib/cmake/Qt6/Qt6Config.cmake" ]; then
            QT_ANDROID_PATH="$Qt6_DIR"
            QT6_CMAKE_DIR="$Qt6_DIR/lib/cmake/Qt6"
          else
            echo "Qt6 config was not found under Qt6_DIR=$Qt6_DIR"
            exit 1
          fi

          QT_HOST_PATH="$(dirname "$QT_ANDROID_PATH")/gcc_64"
          if [ ! -d "$QT_HOST_PATH" ]; then
            echo "Qt host path was not found: $QT_HOST_PATH"
            exit 1
          fi
          QT_HOST_PATH_CMAKE_DIR="$QT_HOST_PATH/lib/cmake"
          if [ ! -d "$QT_HOST_PATH_CMAKE_DIR" ]; then
            echo "Qt host CMake path was not found: $QT_HOST_PATH_CMAKE_DIR"
            exit 1
          fi

          echo "QT_ANDROID_PATH=$QT_ANDROID_PATH" >> $GITHUB_ENV
          echo "QT6_CMAKE_DIR=$QT6_CMAKE_DIR" >> $GITHUB_ENV
          echo "QT_HOST_PATH=$QT_HOST_PATH" >> $GITHUB_ENV

      - name: Build FFmpeg for Android ${{ matrix.arch }}
        run: |
          FFMPEG_VERSION=7.1
          TOOLCHAIN=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64
          API=21
          FFMPEG_INSTALL=$GITHUB_WORKSPACE/ffmpeg-android

          if [ "$ANDROID_ABI" = "armeabi-v7a" ]; then
            FFMPEG_ARCH=arm
            FFMPEG_CPU=armv7-a
            FFMPEG_CROSS_PREFIX=arm-linux-androideabi-
            FFMPEG_CC=armv7a-linux-androideabi${API}-clang
          elif [ "$ANDROID_ABI" = "arm64-v8a" ]; then
            FFMPEG_ARCH=aarch64
            FFMPEG_CPU=armv8-a
            FFMPEG_CROSS_PREFIX=aarch64-linux-android-
            FFMPEG_CC=aarch64-linux-android${API}-clang
          else
            echo "Unsupported Android ABI: $ANDROID_ABI (supported: armeabi-v7a, arm64-v8a)"
            exit 1
          fi

          wget -q "https://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.gz"
          tar xf "ffmpeg-${FFMPEG_VERSION}.tar.gz"
          cd "ffmpeg-${FFMPEG_VERSION}"

          ./configure \
            --target-os=android \
            --arch=$FFMPEG_ARCH \
            --cpu=$FFMPEG_CPU \
            --enable-cross-compile \
            --cross-prefix=$TOOLCHAIN/bin/$FFMPEG_CROSS_PREFIX \
            --cc=$TOOLCHAIN/bin/$FFMPEG_CC \
            --nm=$TOOLCHAIN/bin/llvm-nm \
            --ar=$TOOLCHAIN/bin/llvm-ar \
            --as=$TOOLCHAIN/bin/$FFMPEG_CC \
            --strip=$TOOLCHAIN/bin/llvm-strip \
            --ranlib=$TOOLCHAIN/bin/llvm-ranlib \
            --disable-asm \
            --disable-doc \
            --disable-programs \
            --disable-everything \
            --enable-shared \
            --disable-static \
            --prefix=$FFMPEG_INSTALL

          make -j$(nproc)
          make install
          echo "FFMPEG_ANDROID=$FFMPEG_INSTALL" >> $GITHUB_ENV

      - name: Build libQtAVPlayer for Android
        run: |
          mkdir build
          cd build
          # Include both Android target Qt and desktop host Qt CMake roots so Qt6 Quick host tools are found.
          cmake ../src/QtAVPlayer \
            -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
            -DANDROID_STL="c++_shared" \
            -DCMAKE_INSTALL_PREFIX=../install \
            -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake \
            -DANDROID_ABI=$ANDROID_ABI \
            -DANDROID_PLATFORM=android-23 \
            -DCMAKE_PREFIX_PATH=$QT6_CMAKE_DIR \
            -DQt6_DIR=$QT6_CMAKE_DIR \
            -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH \
            -DCMAKE_LIBRARY_PATH=$FFMPEG_ANDROID/lib \
            -DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES=$FFMPEG_ANDROID/include \
            -DQT_AVPLAYER_MULTIMEDIA=ON

          cmake --build . --verbose
          cmake --install .

      - name: Build qml_video for Android
        run: |
          cd examples/qml_video
          mkdir build
          cd build
          # Include both Android target Qt and desktop host Qt CMake roots so Qt6 Quick host tools are found.
          cmake ../ \
            -DANDROID_SDK_ROOT="$ANDROID_SDK_ROOT" \
            -DANDROID_NDK="$ANDROID_NDK_ROOT" \
            -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
            -DANDROID_STL="c++_shared" \
            -DQT_DEBUG_FIND_PACKAGE=ON \
            -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake \
            -DANDROID_ABI=$ANDROID_ABI \
            -DANDROID_PLATFORM=android-23 \
            -DCMAKE_PREFIX_PATH="$PWD/../../../install/lib/cmake;$QT6_CMAKE_DIR" \
            -DQt6_DIR=$QT6_CMAKE_DIR \
            -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH \
            -DCMAKE_LIBRARY_PATH=$FFMPEG_ANDROID/lib \
            -DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES=$FFMPEG_ANDROID/include \
            -DQT_AVPLAYER_LIB=ON -DQT_AVPLAYER_MULTIMEDIA=ON
          cmake --build . --verbose
