summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-09-22 01:40:05 +0000
committerCoprDistGit <infra@openeuler.org>2023-09-22 01:40:05 +0000
commit4b12cf36d38a6c7a8e9bac94f8e7431aaa6b2480 (patch)
tree98f3fd045b63a9cfbbba44b7da6deb1a4306017c
parent2a7be7ef27b0549e7d466e5db2deaddc1f11e955 (diff)
automatic import of gstreamer1openeuler23.03
-rw-r--r--.gitignore1
-rw-r--r--ci.patch2225
-rw-r--r--gstreamer-inspect-rpm-format.patch400
-rw-r--r--gstreamer1.attr2
-rw-r--r--gstreamer1.prov44
-rw-r--r--gstreamer1.spec141
-rw-r--r--sources1
7 files changed, 2814 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..c47e71e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/gstreamer-1.20.4.tar.xz
diff --git a/ci.patch b/ci.patch
new file mode 100644
index 0000000..53e867c
--- /dev/null
+++ b/ci.patch
@@ -0,0 +1,2225 @@
+diff -urN gstreamer-1.20.4/ci/README.txt gstreamer-1.20.4-1/ci/README.txt
+--- gstreamer-1.20.4/ci/README.txt 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/README.txt 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,11 @@
++GStreamer Continuous Integration
++================================
++
++This repository contains all material relevant to the GStreamer
++Continuous Integration system.
++
++* Jenkins scripts
++
++* Docker images
++
++* Build scripts and code
+diff -urN gstreamer-1.20.4/ci/docker/README gstreamer-1.20.4-1/ci/docker/README
+--- gstreamer-1.20.4/ci/docker/README 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/docker/README 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,2 @@
++GStreamer Docker images
++
+diff -urN gstreamer-1.20.4/ci/docker/fedora/prepare.sh gstreamer-1.20.4-1/ci/docker/fedora/prepare.sh
+--- gstreamer-1.20.4/ci/docker/fedora/prepare.sh 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/docker/fedora/prepare.sh 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,259 @@
++set -eux
++
++# Fedora base image disable installing documentation files. See https://pagure.io/atomic-wg/issue/308
++# We need them to cleanly build our doc.
++sed -i "s/tsflags=nodocs//g" /etc/dnf/dnf.conf
++
++dnf install -y git-core ninja-build dnf-plugins-core python3-pip
++
++# Configure git for various usage
++git config --global user.email "gstreamer@gstreamer.net"
++git config --global user.name "Gstbuild Runner"
++
++# Add rpm fusion repositories in order to access all of the gst plugins
++sudo dnf install -y \
++ "https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm" \
++ "https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm"
++
++dnf upgrade -y
++
++# install rest of the extra deps
++dnf install -y \
++ aalib-devel \
++ aom \
++ bat \
++ intel-mediasdk-devel \
++ libaom \
++ libaom-devel \
++ libcaca-devel \
++ libdav1d \
++ libdav1d-devel \
++ ccache \
++ cmake \
++ clang-devel \
++ elfutils \
++ elfutils-libs \
++ elfutils-devel \
++ gcc \
++ gcc-c++ \
++ gdb \
++ git-lfs \
++ glslc \
++ gtk3 \
++ gtk3-devel \
++ gtest \
++ gtest-devel \
++ graphene \
++ graphene-devel \
++ gsl \
++ gsl-devel \
++ gupnp \
++ gupnp-devel \
++ gupnp-igd \
++ gupnp-igd-devel \
++ gssdp \
++ gssdp-devel \
++ faac-devel \
++ ffmpeg \
++ ffmpeg-libs \
++ ffmpeg-devel \
++ flex \
++ flite \
++ flite-devel \
++ mono-devel \
++ procps-ng \
++ patch \
++ qt5-devel \
++ redhat-rpm-config \
++ json-glib \
++ json-glib-devel \
++ libnice \
++ libnice-devel \
++ libsodium-devel \
++ libunwind \
++ libunwind-devel \
++ libyaml-devel \
++ libxml2-devel \
++ libxslt-devel \
++ llvm-devel \
++ log4c-devel \
++ make \
++ nasm \
++ neon \
++ neon-devel \
++ nunit \
++ npm \
++ opencv \
++ opencv-devel \
++ openjpeg2 \
++ openjpeg2-devel \
++ SDL2 \
++ SDL2-devel \
++ sbc \
++ sbc-devel \
++ x264 \
++ x264-libs \
++ x264-devel \
++ python3 \
++ python3-devel \
++ python3-libs \
++ python3-gobject \
++ python3-cairo \
++ python3-cairo-devel \
++ valgrind \
++ vulkan \
++ vulkan-devel \
++ mesa-omx-drivers \
++ mesa-libGL \
++ mesa-libGL-devel \
++ mesa-libGLU \
++ mesa-libGLU-devel \
++ mesa-libGLES \
++ mesa-libGLES-devel \
++ mesa-libOpenCL \
++ mesa-libOpenCL-devel \
++ mesa-libgbm \
++ mesa-libgbm-devel \
++ mesa-libd3d \
++ mesa-libd3d-devel \
++ mesa-libOSMesa \
++ mesa-libOSMesa-devel \
++ mesa-vulkan-drivers \
++ wpewebkit \
++ wpewebkit-devel \
++ xorg-x11-server-utils \
++ xorg-x11-server-Xvfb
++
++# Install common debug symbols
++dnf debuginfo-install -y gtk3 \
++ glib2 \
++ glibc \
++ gupnp \
++ gupnp-igd \
++ gssdp \
++ freetype \
++ openjpeg \
++ gobject-introspection \
++ python3 \
++ python3-libs \
++ python3-gobject \
++ libappstream-glib-devel \
++ libjpeg-turbo \
++ glib-networking \
++ libcurl \
++ libsoup \
++ nss \
++ nss-softokn \
++ nss-softokn-freebl \
++ nss-sysinit \
++ nss-util \
++ openssl \
++ openssl-libs \
++ openssl-pkcs11 \
++ brotli \
++ bzip2-libs \
++ gpm-libs \
++ harfbuzz \
++ harfbuzz-icu \
++ json-c \
++ json-glib \
++ libbabeltrace \
++ libffi \
++ libsrtp \
++ libunwind \
++ mpg123-libs \
++ neon \
++ orc-compiler \
++ orc \
++ pixman \
++ pulseaudio-libs \
++ pulseaudio-libs-glib2 \
++ wavpack \
++ webrtc-audio-processing \
++ ffmpeg \
++ ffmpeg-libs \
++ faad2-libs \
++ libavdevice \
++ libmpeg2 \
++ faac \
++ fdk-aac \
++ x264 \
++ x264-libs \
++ x265 \
++ x265-libs \
++ xz \
++ xz-libs \
++ zip \
++ zlib
++
++# Install the dependencies of gstreamer
++dnf builddep -y gstreamer1 \
++ gstreamer1-plugins-base \
++ gstreamer1-plugins-good \
++ gstreamer1-plugins-good-extras \
++ gstreamer1-plugins-ugly \
++ gstreamer1-plugins-ugly-free \
++ gstreamer1-plugins-bad-free \
++ gstreamer1-plugins-bad-free-extras \
++ gstreamer1-plugins-bad-freeworld \
++ gstreamer1-libav \
++ gstreamer1-rtsp-server \
++ gstreamer1-vaapi \
++ python3-gstreamer1
++
++dnf remove -y meson
++pip3 install meson==0.59.1 hotdoc python-gitlab
++
++
++# Remove gst-devel packages installed by builddep above
++dnf remove -y "gstreamer1*devel"
++
++# FIXME: Why does installing directly with dnf doesn't actually install
++# the documentation files?
++dnf download glib2-doc gdk-pixbuf2-devel*x86_64* gtk3-devel-docs
++rpm -i --reinstall *.rpm
++rm -f *.rpm
++
++# Install Rust
++RUSTUP_VERSION=1.24.3
++RUST_VERSION=1.55.0
++RUST_ARCH="x86_64-unknown-linux-gnu"
++
++dnf install -y wget
++RUSTUP_URL=https://static.rust-lang.org/rustup/archive/$RUSTUP_VERSION/$RUST_ARCH/rustup-init
++wget $RUSTUP_URL
++dnf remove -y wget
++
++export RUSTUP_HOME="/usr/local/rustup"
++export CARGO_HOME="/usr/local/cargo"
++export PATH="/usr/local/cargo/bin:$PATH"
++
++chmod +x rustup-init;
++./rustup-init -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION;
++rm rustup-init;
++chmod -R a+w $RUSTUP_HOME $CARGO_HOME
++
++rustup --version
++cargo --version
++rustc --version
++
++# get gstreamer and make all subprojects available
++git clone -b ${GIT_BRANCH} ${GIT_URL} /gstreamer
++git -C /gstreamer submodule update --init --depth=1
++meson subprojects download --sourcedir /gstreamer
++/gstreamer/ci/scripts/handle-subprojects-cache.py --build /gstreamer/subprojects/
++
++# Run git gc to prune unwanted refs and reduce the size of the image
++for i in $(find /subprojects/ -mindepth 1 -maxdepth 1 -type d);
++do
++ git -C $i gc --aggressive || true;
++done
++
++# Now remove the gstreamer clone
++rm -rf /gstreamer
++
++echo "Removing DNF cache"
++dnf clean all
++
++rm -R /root/*
++rm -rf /var/cache/dnf /var/log/dnf*
+diff -urN gstreamer-1.20.4/ci/docker/windows/.dockerignore gstreamer-1.20.4-1/ci/docker/windows/.dockerignore
+--- gstreamer-1.20.4/ci/docker/windows/.dockerignore 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/docker/windows/.dockerignore 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1 @@
++build_image.ps1
+diff -urN gstreamer-1.20.4/ci/docker/windows/Dockerfile gstreamer-1.20.4-1/ci/docker/windows/Dockerfile
+--- gstreamer-1.20.4/ci/docker/windows/Dockerfile 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/docker/windows/Dockerfile 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,66 @@
++# escape=`
++
++FROM 'mcr.microsoft.com/windows/server:ltsc2022'
++
++# Make sure any failure in PowerShell is fatal
++ENV ErrorActionPreference='Stop'
++SHELL ["powershell","-NoLogo", "-NonInteractive", "-Command"]
++
++RUN Install-WindowsFeature -Name Server-Media-Foundation
++
++# Install Chocolatey
++RUN iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
++# Install required packages
++RUN choco install -y vcredist140
++RUN choco install -y cmake --installargs 'ADD_CMAKE_TO_PATH=System'
++RUN choco install -y git --params '/NoAutoCrlf /NoCredentialManager /NoShellHereIntegration /NoGuiHereIntegration /NoShellIntegration'
++RUN choco install -y git-lfs
++RUN choco install -y 7zip
++RUN choco install -y python3
++RUN choco install -y msys2 --params '/NoPath /NoUpdate /InstallDir:C:\\msys64'
++
++# Remove MAX_PATH limit of 260 characters
++RUN New-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\FileSystem' `
++ -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
++RUN git config --system core.longpaths true
++
++RUN c:\msys64\usr\bin\bash -lc 'pacman -S --noconfirm mingw-w64-ucrt-x86_64-toolchain ninja'
++# Visual Studio can't be installed with choco.
++# It depends on dotnetfx v4.8.0.20190930, which requires a reboot: dotnetfx (exit code 3010)
++# https://github.com/microsoft/vs-dockerfiles/blob/main/native-desktop/
++# Set up environment to collect install errors.
++COPY Install.cmd C:\TEMP\
++RUN Invoke-WebRequest -Uri https://aka.ms/vscollect.exe -OutFile C:\TEMP\collect.exe
++# Download channel for fixed install.
++RUN Invoke-WebRequest -Uri https://aka.ms/vs/16/release/channel -OutFile C:\TEMP\VisualStudio.chman
++# Download and install Build Tools for Visual Studio 2017 for native desktop workload.
++RUN Invoke-WebRequest -Uri https://aka.ms/vs/16/release/vs_buildtools.exe -OutFile C:\TEMP\vs_buildtools.exe
++RUN C:\TEMP\Install.cmd C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache `
++ --channelUri C:\TEMP\VisualStudio.chman `
++ --installChannelUri C:\TEMP\VisualStudio.chman `
++ --add Microsoft.VisualStudio.Workload.VCTools `
++ --add Microsoft.VisualStudio.Workload.UniversalBuildTools `
++ --add Microsoft.VisualStudio.Component.VC.Tools.ARM64 `
++ --add Microsoft.VisualStudio.Component.VC.Tools.ARM `
++ --add Microsoft.VisualStudio.Component.UWP.VC.ARM64 `
++ --includeRecommended `
++ --installPath C:\BuildTools
++
++RUN Get-ChildItem C:\BuildTools
++RUN Get-ChildItem C:\BuildTools\VC\Tools\MSVC
++RUN Get-ChildItem 'C:\Program Files (x86)\Windows Kits\10\lib'
++
++RUN pip3 install meson==0.62.2
++
++RUN 'git config --global user.email "cirunner@gstreamer.freedesktop.org"; git config --global user.name "GStreamer CI system"'
++
++COPY install_mingw.ps1 C:\
++RUN C:\install_mingw.ps1
++
++ARG DEFAULT_BRANCH="main"
++
++COPY prepare_gst_env.ps1 C:\
++RUN C:\prepare_gst_env.ps1
++
++COPY prepare_cerbero_env.sh C:\
++RUN C:\MinGW\msys\1.0\bin\bash.exe --login -c "C:/prepare_cerbero_env.sh"
+diff -urN gstreamer-1.20.4/ci/docker/windows/Install.cmd gstreamer-1.20.4-1/ci/docker/windows/Install.cmd
+--- gstreamer-1.20.4/ci/docker/windows/Install.cmd 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/docker/windows/Install.cmd 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,35 @@
++@REM The MIT License (MIT)
++@REM Copyright (c) Microsoft Corporation
++
++@REM Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
++@REM associated documentation files (the "Software"), to deal in the Software without restriction,
++@REM including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
++@REM and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
++@REM subject to the following conditions:
++
++@REM The above copyright notice and this permission notice shall be included in all copies or substantial
++@REM portions of the Software.
++
++@REM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
++@REM NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++@REM IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
++@REM WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
++@REM SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++
++@if not defined _echo echo off
++setlocal enabledelayedexpansion
++
++call %*
++if "%ERRORLEVEL%"=="3010" (
++ exit /b 0
++) else (
++ if not "%ERRORLEVEL%"=="0" (
++ set ERR=%ERRORLEVEL%
++ if "%CI_PROJECT_PATH%"=="" (
++ call C:\TEMP\collect.exe -zip:C:\vslogs.zip
++ ) else (
++ call C:\TEMP\collect.exe -zip:%CI_PROJECT_PATH%\vslogs.zip
++ )
++ exit /b !ERR!
++ )
++)
+diff -urN gstreamer-1.20.4/ci/docker/windows/build_image.ps1 gstreamer-1.20.4-1/ci/docker/windows/build_image.ps1
+--- gstreamer-1.20.4/ci/docker/windows/build_image.ps1 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/docker/windows/build_image.ps1 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,18 @@
++$env:ErrorActionPreference='Stop'
++
++$env:DEFAULT_BRANCH='main'
++$env:VERSION='test'
++$env:tag ="registry.freedesktop.org/gstreamer/gst-ci/amd64/windows:$env:VERSION-$env:DEFAULT_BRANCH"
++
++Set-Location './docker/windows/'
++
++Get-Date
++Write-Output "Building $env:tag"
++docker build --isolation=hyperv -m 12g --build-arg DEFAULT_BRANCH=$env:DEFAULT_BRANCH -f Dockerfile -t $env:tag .
++if (!$?) {
++ Write-Host "Failed to build docker image $env:tag"
++ Exit 1
++}
++
++Get-Date
++Write-Output "Build Finished"
+\ No newline at end of file
+diff -urN gstreamer-1.20.4/ci/docker/windows/container.ps1 gstreamer-1.20.4-1/ci/docker/windows/container.ps1
+--- gstreamer-1.20.4/ci/docker/windows/container.ps1 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/docker/windows/container.ps1 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,60 @@
++# Copied from mesa, big kudos
++#
++# https://gitlab.freedesktop.org/mesa/mesa/-/blob/master/.gitlab-ci/windows/mesa_container.ps1
++# https://gitlab.freedesktop.org/mesa/mesa/-/blob/34e3e164936d1d3cef267da7780e87f062fedf39/.gitlab-ci/windows/mesa_container.ps1
++
++# Implements the equivalent of ci-templates container-ifnot-exists, using
++# Docker directly as we don't have buildah/podman/skopeo available under
++# Windows, nor can we execute Docker-in-Docker
++$registry_uri = $args[0]
++$registry_username = $args[1]
++$registry_password = $args[2]
++$registry_user_image = $args[3]
++$registry_central_image = $args[4]
++$dockerfile = $args[5]
++
++docker --config "windows-docker.conf" login -u "$registry_username" -p "$registry_password" "$registry_uri"
++if (!$?) {
++ Write-Host "docker login failed to $registry_uri"
++ Exit 1
++}
++
++# if the image already exists, don't rebuild it
++docker --config "windows-docker.conf" pull "$registry_user_image"
++if ($?) {
++ Write-Host "User image $registry_user_image already exists; not rebuilding"
++ docker --config "windows-docker.conf" logout "$registry_uri"
++ Exit 0
++}
++
++# if the image already exists upstream, copy it
++docker --config "windows-docker.conf" pull "$registry_central_image"
++if ($?) {
++ Write-Host "Copying central image $registry_central_image to user image $registry_user_image"
++ docker --config "windows-docker.conf" tag "$registry_central_image" "$registry_user_image"
++ docker --config "windows-docker.conf" push "$registry_user_image"
++ $pushstatus = $?
++ docker --config "windows-docker.conf" logout "$registry_uri"
++ if (!$pushstatus) {
++ Write-Host "Pushing image to $registry_user_image failed"
++ Exit 1
++ }
++ Exit 0
++}
++
++Write-Host "No image found at $registry_user_image or $registry_central_image; rebuilding"
++docker --config "windows-docker.conf" build $DOCKER_BUILD_ARGS --no-cache -t "$registry_user_image" -f "$dockerfile" "./ci/docker/windows"
++if (!$?) {
++ Write-Host "Container build failed"
++ docker --config "windows-docker.conf" logout "$registry_uri"
++ Exit 1
++}
++Get-Date
++
++docker --config "windows-docker.conf" push "$registry_user_image"
++$pushstatus = $?
++docker --config "windows-docker.conf" logout "$registry_uri"
++if (!$pushstatus) {
++ Write-Host "Pushing image to $registry_user_image failed"
++ Exit 1
++}
+diff -urN gstreamer-1.20.4/ci/docker/windows/install_gst.ps1 gstreamer-1.20.4-1/ci/docker/windows/install_gst.ps1
+--- gstreamer-1.20.4/ci/docker/windows/install_gst.ps1 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/docker/windows/install_gst.ps1 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,72 @@
++[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;
++
++# Download gst-build and all its subprojects
++# git clone -b $env:DEFAULT_BRANCH https://gitlab.freedesktop.org/gstreamer/gst-build.git C:\gst-build
++# FIXME: need 1.19+ for cairo subproject :/
++# Should use a stable branch instead
++git clone -b master --depth 1 https://gitlab.freedesktop.org/gstreamer/gst-build.git C:\gst-build
++if (!$?) {
++ Write-Host "Failed to clone gst-build"
++ Exit 1
++}
++
++Set-Location C:\gst-build
++
++# Copy the cache we already have in the image to avoid massive redownloads
++Move-Item C:/subprojects/* C:\gst-build\subprojects
++
++if (!$?) {
++ Write-Host "Failed to copy subprojects cache"
++ Exit 1
++}
++
++# Update the subprojects cache
++Write-Output "Running meson subproject reset"
++meson subprojects update --reset
++
++if (!$?) {
++ Write-Host "Failed to reset subprojects state"
++ Exit 1
++}
++
++Write-Output "Running git update"
++python git-update --no-interaction
++
++if (!$?) {
++ Write-Host "Failed to run git-update"
++ Exit 1
++}
++
++$env:MESON_ARGS = "-Dglib:installed_tests=false " +
++ "-Dlibnice:tests=disabled " +
++ "-Dlibnice:examples=disabled " +
++ "-Dffmpeg:tests=disabled " +
++ "-Dopenh264:tests=disabled " +
++ "-Dpygobject:tests=false " +
++ "-Dugly=enabled " +
++ "-Dbad=enabled " +
++ "-Dges=enabled " +
++ "-Drtsp_server=enabled " +
++ "-Ddevtools=enabled " +
++ "-Dsharp=disabled " +
++ "-Dpython=disabled " +
++ "-Dlibav=disabled " +
++ "-Dvaapi=disabled " +
++ "-Dgst-plugins-base:pango=enabled " +
++ "-Dgst-plugins-good:cairo=enabled " +
++ "-Dgpl=enabled "
++
++Write-Output "Building gst"
++cmd.exe /C "C:\BuildTools\Common7\Tools\VsDevCmd.bat -host_arch=amd64 -arch=amd64 && meson _build $env:MESON_ARGS && meson compile -C _build && ninja -C _build install"
++
++if (!$?) {
++ Write-Host "Failed to build and install gst"
++ Exit 1
++}
++
++git clean -fdxx
++
++if (!$?) {
++ Write-Host "Failed to git clean"
++ Exit 1
++}
+diff -urN gstreamer-1.20.4/ci/docker/windows/install_mingw.ps1 gstreamer-1.20.4-1/ci/docker/windows/install_mingw.ps1
+--- gstreamer-1.20.4/ci/docker/windows/install_mingw.ps1 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/docker/windows/install_mingw.ps1 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,29 @@
++[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;
++
++$msys_mingw_get_url = 'https://dotsrc.dl.osdn.net/osdn/mingw/68260/mingw-get-0.6.3-mingw32-pre-20170905-1-bin.tar.xz'
++
++Get-Date
++Write-Host "Downloading and extracting mingw-get for MSYS"
++Invoke-WebRequest -Uri $msys_mingw_get_url -OutFile C:\mingw-get.tar.xz
++7z e C:\mingw-get.tar.xz -o"C:\\"
++$res1 = $?
++7z x C:\mingw-get.tar -o"C:\\MinGW"
++$res2 = $?
++
++if (!($res1 -and $res2)) {
++ Write-Host "Failed to extract mingw-get"
++ Exit 1
++}
++
++Remove-Item C:\mingw-get.tar.xz -Force
++Remove-Item C:\mingw-get.tar -Force
++
++Get-Date
++Write-Host "Installing MSYS for Cerbero into C:/MinGW using mingw-get"
++Start-Process -Wait C:\MinGW\bin\mingw-get.exe -ArgumentList 'install msys-base mingw32-base mingw-developer-toolkit'
++if (!$?) {
++ Write-Host "Failed to install Msys for cerbero using MinGW"
++ Exit 1
++}
++
++Write-Host "MSYS/MinGW Install Complete"
+diff -urN gstreamer-1.20.4/ci/docker/windows/prepare_cerbero_env.sh gstreamer-1.20.4-1/ci/docker/windows/prepare_cerbero_env.sh
+--- gstreamer-1.20.4/ci/docker/windows/prepare_cerbero_env.sh 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/docker/windows/prepare_cerbero_env.sh 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,27 @@
++#! /bin/bash
++
++set -eux
++
++cd C:/
++git clone -b ${DEFAULT_BRANCH} https://gitlab.freedesktop.org/gstreamer/cerbero.git
++cd cerbero
++
++echo 'local_sources="C:/cerbero/cerbero-sources"' > localconf.cbc
++echo 'home_dir="C:/cerbero/cerbero-build"' >> localconf.cbc
++echo 'vs_install_path = "C:/BuildTools"' >> localconf.cbc
++echo 'vs_install_version = "vs16"' >> localconf.cbc
++
++# Fetch all bootstrap requirements
++./cerbero-uninstalled -t -c localconf.cbc -c config/win64.cbc fetch-bootstrap --jobs=4
++# Fetch all package requirements for a mingw gstreamer build
++./cerbero-uninstalled -t -c localconf.cbc -c config/win64.cbc fetch-package --jobs=4 gstreamer-1.0
++# Fetch all package requirements for a visualstudio gstreamer build
++./cerbero-uninstalled -t -v visualstudio -c localconf.cbc -c config/win64.cbc fetch-package --jobs=4 gstreamer-1.0
++
++# Fixup the MSYS installation
++./cerbero-uninstalled -t -c localconf.cbc -c config/win64.cbc bootstrap -y --build-tools=no --toolchains=no --offline
++
++# Wipe visualstudio package dist, sources, logs, and the build tools recipes
++./cerbero-uninstalled -t -v visualstudio -c localconf.cbc -c config/win64.cbc wipe --force --build-tools
++# clean the localconf
++rm /c/cerbero/localconf.cbc
+diff -urN gstreamer-1.20.4/ci/docker/windows/prepare_gst_env.ps1 gstreamer-1.20.4-1/ci/docker/windows/prepare_gst_env.ps1
+--- gstreamer-1.20.4/ci/docker/windows/prepare_gst_env.ps1 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/docker/windows/prepare_gst_env.ps1 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,17 @@
++[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;
++
++# FIXME: Python fails to validate github.com SSL certificate, unless we first
++# run a dummy download to force refreshing Windows' CA database.
++# See: https://bugs.python.org/issue36137
++(New-Object System.Net.WebClient).DownloadString("https://github.com") >$null
++
++Write-Host "Cloning GStreamer"
++git clone -b $env:DEFAULT_BRANCH https://gitlab.freedesktop.org/gstreamer/gstreamer.git C:\gstreamer
++
++# download the subprojects to try and cache them
++Write-Host "Downloading subprojects"
++meson subprojects download --sourcedir C:\gstreamer
++
++Write-Host "Caching subprojects into /subprojects/"
++python C:\gstreamer/ci/scripts/handle-subprojects-cache.py --build C:\gstreamer/subprojects/
++Remove-Item -Recurse -Force C:\gstreamer
+diff -urN gstreamer-1.20.4/ci/fuzzing/README.txt gstreamer-1.20.4-1/ci/fuzzing/README.txt
+--- gstreamer-1.20.4/ci/fuzzing/README.txt 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/fuzzing/README.txt 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,80 @@
++Fuzzing GStreamer
++=================
++
++ This directory contains the various fuzzing targets and helper
++ scripts.
++
++* Fuzzing targets
++
++ Fuzzing targets as small applications where we can test a specific
++ element or API. The goal is to have them be as small/targetted as
++ possible.
++
++ ex: appsrc ! <some_element> ! fakesink num-buffers=<small>
++
++ Not all components can be tested directly and therefore will be
++ indirectly tested via other targets (ex: libgstaudio will be tested
++ by targets/elements requiring it)
++
++ Anything that can process externally-provided data should be
++ covered, but there are cases where it might not make sense to use a
++ fuzzer (such as most elements processing raw audio/video).
++
++* build-oss-fuzz.sh
++
++ This is the script executed by the oss-fuzz project.
++
++ It builds glib, GStreamer, plugins and the fuzzing targets.
++
++* *.c
++
++ The fuzzing targets where the data to test will be provided to a
++ function whose signature follows the LibFuzzer signature:
++ https://llvm.org/docs/LibFuzzer.html
++
++* TODO
++
++ * Add a standalone build script
++
++ We need to be able to build and test the fuzzing targets outside
++ of the oss-fuzz infrastructure, and do that in our continous
++ integration system.
++
++ We need:
++
++ * A dummy fuzzing engine (given a directory, it opens all files and
++ calls the fuzzing targets with the content of those files.
++ * A script to be able to build those targets with that dummy engine
++ * A corpus of files to test those targets with.
++
++ * Build targets with dummy engine and run with existing tests.
++
++ * Create pull-based variants
++
++ Currently the existing targets are push-based only. Where
++ applicable we should make pull-based variants to test the other
++ code paths.
++
++ * Add more targets
++
++ core:
++ gst_parse fuzzer ?
++ base:
++ ext/
++ ogg
++ opus
++ pango
++ theora
++ vorbis
++ gst/
++ subparse
++ typefind : already covered in typefind target
++ gst-libs/gst/
++ sdp
++ other ones easily testable directly ?
++
++
++
++
++
++
+diff -urN gstreamer-1.20.4/ci/fuzzing/build-oss-fuzz.sh gstreamer-1.20.4-1/ci/fuzzing/build-oss-fuzz.sh
+--- gstreamer-1.20.4/ci/fuzzing/build-oss-fuzz.sh 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/fuzzing/build-oss-fuzz.sh 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,207 @@
++#!/bin/bash -eu
++
++# build-oss-fuzz.sh
++#
++# Build script which is executed by oss-fuzz build.sh
++#
++# $SRC: location of code checkouts
++# $OUT: location to put fuzzing targets and corpus
++# $WORK: writable directory where all compilation should be executed
++#
++# /!\ Do not override any CC, CXX, CFLAGS, ... variables
++#
++
++# This script is divided in two parts
++#
++# 1) Build all the dependencies statically
++#
++# 2) Build the fuzzing targets
++
++# Prefix where we will temporarily install everything
++PREFIX=$WORK/prefix
++mkdir -p $PREFIX
++# always try getting the arguments for static compilation/linking
++# Fixes GModule not being picked when gstreamer-1.0.pc is looked up by meson
++# more or less https://github.com/mesonbuild/meson/pull/6629
++export PKG_CONFIG="`which pkg-config` --static"
++export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig
++export PATH=$PREFIX/bin:$PATH
++
++# Minimize gst-debug level/code
++export CFLAGS="$CFLAGS -DGST_LEVEL_MAX=2"
++
++#
++echo "CFLAGS : " $CFLAGS
++echo "CXXFLAGS : " $CXXFLAGS
++PLUGIN_DIR=$PREFIX/lib/gstreamer-1.0
++
++rm -rf $WORK/*
++
++# Switch to work directory
++cd $WORK
++
++# 1) BUILD GLIB AND GSTREAMER
++# Note: we build glib ourselves so that we get proper malloc/free backtraces
++tar xvJf $SRC/glib-2.64.2.tar.xz
++cd glib-2.64.2
++# options taken from glib's oss-fuzz build definition
++meson \
++ --prefix=$PREFIX \
++ --libdir=lib \
++ --default-library=static \
++ -Db_lundef=false \
++ -Doss_fuzz=enabled \
++ -Dlibmount=disabled \
++ -Dinternal_pcre=true \
++ _builddir
++ninja -C _builddir
++ninja -C _builddir install
++cd ..
++
++# Note: We don't use/build orc since it still seems to be problematic
++# with clang and the various sanitizers.
++
++# For now we only build core and base. Add other modules when/if needed
++for i in gstreamer;
++do
++ mkdir -p $i
++ cd $i
++ meson \
++ --prefix=$PREFIX \
++ --libdir=lib \
++ --default-library=static \
++ -Db_lundef=false \
++ -Ddoc=disabled \
++ -Dexamples=disabled \
++ -Dintrospection=disabled \
++ -Dgood=disabled \
++ -Dugly=disabled \
++ -Dbad=disabled \
++ -Dlibav=disabled \
++ -Dges=disabled \
++ -Domx=disabled \
++ -Dvaapi=disabled \
++ -Dsharp=disabled \
++ -Drs=disabled \
++ -Dpython=disabled \
++ -Dlibnice=disabled \
++ -Ddevtools=disabled \
++ -Drtsp_server=disabled \
++ -Dgst-examples=disabled \
++ -Dqt5=disabled \
++ -Dorc=disabled \
++ -Dgtk_doc=disabled \
++ -Dgstreamer:tracer_hooks=false \
++ -Dgstreamer:registry=false \
++ -Dgst-plugins-base:cairo=disabled \
++ -Dgst-plugins-base:opus=disabled \
++ -Dgst-plugins-base:pango=disabled \
++ _builddir \
++ $SRC/$i
++ ninja -C _builddir
++ ninja -C _builddir install
++ cd ..
++done
++
++
++
++# 2) Build the target fuzzers
++
++# All targets will be linked in with $LIB_FUZZING_ENGINE which contains the
++# actual fuzzing runner. Anything fuzzing engine can be used provided it calls
++# the same function as libfuzzer.
++
++# Note: The fuzzer .o needs to be first compiled with CC and then linked with CXX
++
++# We want to statically link everything, except for shared libraries
++# that are present on the base image. Those need to be specified
++# beforehand and explicitely linked dynamically If any of the static
++# dependencies require a pre-installed shared library, you need to add
++# that library to the following list
++PREDEPS_LDFLAGS="-Wl,-Bdynamic -ldl -lm -pthread -lrt -lpthread"
++
++# These are the basic .pc dependencies required to build any of the fuzzing targets
++# That is : glib, gstreamer core and gst-app
++# The extra target-specific dependencies are to be specified later
++COMMON_DEPS="glib-2.0 gio-2.0 gstreamer-1.0 gstreamer-app-1.0"
++
++# For each target, defined the following:
++# TARGET_DEPS : Extra .pc dependencies for the target (in addition to $COMMON_DEPS)
++# All dependencies (including sub-dependencies) must be speecified
++# PLUGINS : .a of the plugins to link
++# They must match the static plugins declared/registered in the target
++
++#
++# TARGET : push-based ogg/theora/vorbis discoverer
++#
++# FIXME : Rename to discoverer_push_oggtheoravorbis
++
++TARGET_DEPS=" gstreamer-pbutils-1.0 \
++ gstreamer-video-1.0 \
++ gstreamer-audio-1.0 \
++ gstreamer-riff-1.0 \
++ gstreamer-tag-1.0 \
++ zlib ogg vorbis vorbisenc \
++ theoraenc theoradec theora cairo"
++
++PLUGINS="$PLUGIN_DIR/libgstcoreelements.a \
++ $PLUGIN_DIR/libgsttypefindfunctions.a \
++ $PLUGIN_DIR/libgstplayback.a \
++ $PLUGIN_DIR/libgstapp.a \
++ $PLUGIN_DIR/libgstvorbis.a \
++ $PLUGIN_DIR/libgsttheora.a \
++ $PLUGIN_DIR/libgstogg.a"
++
++echo
++echo ">>>> BUILDING gst-discoverer"
++echo
++BUILD_CFLAGS="$CFLAGS `pkg-config --static --cflags $COMMON_DEPS $TARGET_DEPS`"
++BUILD_LDFLAGS="-Wl,-static `pkg-config --static --libs $COMMON_DEPS $TARGET_DEPS`"
++
++$CC $CFLAGS $BUILD_CFLAGS -c $SRC/gstreamer/ci/fuzzing/gst-discoverer.c -o $SRC/gstreamer/ci/fuzzing/gst-discoverer.o
++$CXX $CXXFLAGS \
++ -o $OUT/gst-discoverer \
++ $PREDEPS_LDFLAGS \
++ $SRC/gstreamer/ci/fuzzing/gst-discoverer.o \
++ $PLUGINS \
++ $BUILD_LDFLAGS \
++ $LIB_FUZZING_ENGINE \
++ -Wl,-Bdynamic
++
++#
++# TARGET : push-based typefind
++#
++
++# typefindfunction depends on pbutils which depends on gst{audio|video|tag}
++TARGET_DEPS=" gstreamer-pbutils-1.0 \
++ gstreamer-video-1.0 \
++ gstreamer-audio-1.0 \
++ gstreamer-tag-1.0"
++
++PLUGINS="$PLUGIN_DIR/libgstcoreelements.a \
++ $PLUGIN_DIR/libgsttypefindfunctions.a \
++ $PLUGIN_DIR/libgstapp.a"
++
++echo
++echo ">>>> BUILDING typefind"
++echo
++BUILD_CFLAGS="$CFLAGS `pkg-config --static --cflags $COMMON_DEPS $TARGET_DEPS`"
++BUILD_LDFLAGS="-Wl,-static `pkg-config --static --libs $COMMON_DEPS $TARGET_DEPS`"
++
++$CC $CFLAGS $BUILD_CFLAGS -c $SRC/gstreamer/ci/fuzzing/typefind.c -o $SRC/gstreamer/ci/fuzzing/typefind.o
++$CXX $CXXFLAGS \
++ -o $OUT/typefind \
++ $PREDEPS_LDFLAGS \
++ $SRC/gstreamer/ci/fuzzing/typefind.o \
++ $PLUGINS \
++ $BUILD_LDFLAGS \
++ $LIB_FUZZING_ENGINE \
++ -Wl,-Bdynamic
++
++echo
++echo ">>>> Installing seed corpus"
++echo
++# FIXME : Sadly we apparently need to have the corpus downloaded in the
++# Dockerfile and not here.
++
++cp $SRC/*_seed_corpus.zip $OUT
+diff -urN gstreamer-1.20.4/ci/fuzzing/gst-discoverer.c gstreamer-1.20.4-1/ci/fuzzing/gst-discoverer.c
+--- gstreamer-1.20.4/ci/fuzzing/gst-discoverer.c 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/fuzzing/gst-discoverer.c 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,137 @@
++/*
++ * Copyright 2016 Google Inc.
++ * author: Edward Hervey <bilboed@bilboed.com>
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include <locale.h>
++
++#include <stdlib.h>
++#include <glib.h>
++#include <gst/gst.h>
++#include <gst/pbutils/pbutils.h>
++
++#ifndef LOCAL_FUZZ_BUILD
++GST_PLUGIN_STATIC_DECLARE (coreelements);
++GST_PLUGIN_STATIC_DECLARE (playback);
++GST_PLUGIN_STATIC_DECLARE (typefindfunctions);
++GST_PLUGIN_STATIC_DECLARE (app);
++GST_PLUGIN_STATIC_DECLARE (ogg);
++GST_PLUGIN_STATIC_DECLARE (theora);
++GST_PLUGIN_STATIC_DECLARE (vorbis);
++#endif
++
++/* push-based discoverer fuzzing target
++ *
++ * This application can be compiled with libFuzzer to simulate
++ * a push-based discoverer execution.
++ *
++ * To reproduce the failing behaviour, use:
++ * $ gst-discoverer-1.0 pushfile:///...
++ *
++ * The goal is to cover basic usage of demuxers, parsers and
++ * base decoder elements.
++ *
++ * When compiling, only link the required demuxer/parser/decoder
++ * plugins and keep it to a limited range (ex: ogg/theora/vorbis)
++ *
++ **/
++
++const guint8 *fuzztesting_data;
++size_t fuzztesting_size;
++
++static void
++appsrc_configuration (GstDiscoverer * dc, GstElement * source, gpointer data)
++{
++ GstBuffer *buf;
++ GstFlowReturn ret;
++
++ /* Create buffer from fuzztesting_data which shouldn't be freed */
++ buf =
++ gst_buffer_new_wrapped_full (0, (gpointer) fuzztesting_data,
++ fuzztesting_size, 0, fuzztesting_size, NULL, NULL);
++ g_object_set (G_OBJECT (source), "size", fuzztesting_size, NULL);
++ g_signal_emit_by_name (G_OBJECT (source), "push-buffer", buf, &ret);
++ gst_buffer_unref (buf);
++}
++
++static void
++custom_logger (const gchar * log_domain,
++ GLogLevelFlags log_level, const gchar * message, gpointer unused_data)
++{
++ if (log_level & G_LOG_LEVEL_CRITICAL) {
++ g_printerr ("CRITICAL ERROR : %s\n", message);
++ abort ();
++ } else if (log_level & G_LOG_LEVEL_WARNING) {
++ g_printerr ("WARNING : %s\n", message);
++ }
++}
++
++int
++LLVMFuzzerTestOneInput (const guint8 * data, size_t size)
++{
++ GError *err = NULL;
++ GstDiscoverer *dc;
++ gint timeout = 10;
++ GstDiscovererInfo *info;
++ static gboolean initialized = FALSE;
++
++ if (!initialized) {
++ /* We want critical warnings to assert so we can fix them */
++ g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL);
++ g_log_set_default_handler (custom_logger, NULL);
++
++ /* Only initialize and register plugins once */
++ gst_init (NULL, NULL);
++
++#ifndef LOCAL_FUZZ_BUILD
++ GST_PLUGIN_STATIC_REGISTER (coreelements);
++ GST_PLUGIN_STATIC_REGISTER (playback);
++ GST_PLUGIN_STATIC_REGISTER (typefindfunctions);
++ GST_PLUGIN_STATIC_REGISTER (app);
++ GST_PLUGIN_STATIC_REGISTER (ogg);
++ GST_PLUGIN_STATIC_REGISTER (theora);
++ GST_PLUGIN_STATIC_REGISTER (vorbis);
++#endif
++
++ initialized = TRUE;
++ }
++
++ dc = gst_discoverer_new (timeout * GST_SECOND, &err);
++ if (G_UNLIKELY (dc == NULL)) {
++ g_print ("Error initializing: %s\n", err->message);
++ g_clear_error (&err);
++ exit (1);
++ }
++
++ fuzztesting_data = data;
++ fuzztesting_size = size;
++
++ /* Connect to source-setup signal to give the data */
++ g_signal_connect (dc, "source-setup", (GCallback) appsrc_configuration, NULL);
++
++ info = gst_discoverer_discover_uri (dc, "appsrc://", &err);
++ g_clear_error (&err);
++ if (info)
++ gst_discoverer_info_unref (info);
++
++ g_object_unref (dc);
++
++ return 0;
++}
+diff -urN gstreamer-1.20.4/ci/fuzzing/localfuzzer.c gstreamer-1.20.4-1/ci/fuzzing/localfuzzer.c
+--- gstreamer-1.20.4/ci/fuzzing/localfuzzer.c 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/fuzzing/localfuzzer.c 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,78 @@
++/* GStreamer
++ * Copyright (C) 2017 Edward Hervey <bilboed@bilboed.com>
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
++ * Boston, MA 02110-1301, USA.
++ */
++
++/* Local fuzzer runner */
++#include <glib.h>
++
++extern int LLVMFuzzerTestOneInput (const guint8 * data, size_t size);
++
++static void
++test_file (gchar * filename)
++{
++ GDir *dir;
++ gchar *path;
++ gchar *contents;
++ gsize length;
++
++ /* if filename is a directory, process the contents */
++ if ((dir = g_dir_open (filename, 0, NULL))) {
++ const gchar *entry;
++
++ while ((entry = g_dir_read_name (dir))) {
++ gchar *spath;
++
++ spath = g_strconcat (filename, G_DIR_SEPARATOR_S, entry, NULL);
++ test_file (spath);
++ g_free (spath);
++ }
++
++ g_dir_close (dir);
++ return;
++ }
++
++ /* Make sure path is absolute */
++ if (!g_path_is_absolute (filename)) {
++ gchar *curdir;
++
++ curdir = g_get_current_dir ();
++ path = g_build_filename (curdir, filename, NULL);
++ g_free (curdir);
++ } else
++ path = g_strdup (filename);
++
++ /* Check if path exists */
++ if (g_file_get_contents (path, &contents, &length, NULL)) {
++ g_print (">>> %s (%" G_GSIZE_FORMAT " bytes)\n", path, length);
++ LLVMFuzzerTestOneInput ((const guint8 *) contents, length);
++ g_free (contents);
++ }
++
++ g_free (path);
++}
++
++int
++main (int argc, gchar ** argv)
++{
++ gint i;
++
++ for (i = 1; i < argc; i++)
++ test_file (argv[i]);
++
++ return 0;
++}
+diff -urN gstreamer-1.20.4/ci/fuzzing/typefind.c gstreamer-1.20.4-1/ci/fuzzing/typefind.c
+--- gstreamer-1.20.4/ci/fuzzing/typefind.c 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/fuzzing/typefind.c 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,115 @@
++/*
++ * Copyright 2016 Google Inc.
++ * author: Edward Hervey <bilboed@bilboed.com>
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include <locale.h>
++
++#include <stdlib.h>
++#include <glib.h>
++#include <gst/gst.h>
++
++#ifndef LOCAL_FUZZ_BUILD
++GST_PLUGIN_STATIC_DECLARE (coreelements);
++GST_PLUGIN_STATIC_DECLARE (typefindfunctions);
++GST_PLUGIN_STATIC_DECLARE (app);
++#endif
++
++/* push-based typefind fuzzing target
++ *
++ * This application can be compiled with libFuzzer to simulate
++ * a push-based typefind execution.
++ *
++ * To reproduce the failing behaviour, use:
++ * $ gst-launch-1.0 pushfile:///.. ! typefind ! fakesink
++ *
++ * The goal is to cover typefind code and implementation.
++ *
++ **/
++static void
++custom_logger (const gchar * log_domain,
++ GLogLevelFlags log_level, const gchar * message, gpointer unused_data)
++{
++ if (log_level & G_LOG_LEVEL_CRITICAL) {
++ g_printerr ("CRITICAL ERROR : %s\n", message);
++ abort ();
++ } else if (log_level & G_LOG_LEVEL_WARNING) {
++ g_printerr ("WARNING : %s\n", message);
++ }
++}
++
++int
++LLVMFuzzerTestOneInput (const guint8 * data, size_t size)
++{
++ GError *err = NULL;
++ static gboolean initialized = FALSE;
++ GstElement *pipeline, *source, *typefind, *fakesink;
++ GstBuffer *buf;
++ GstFlowReturn flowret;
++ GstState state;
++
++ if (!initialized) {
++ /* We want critical warnings to assert so we can fix them */
++ g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL);
++ g_log_set_default_handler (custom_logger, NULL);
++
++ /* Only initialize and register plugins once */
++ gst_init (NULL, NULL);
++
++#ifndef LOCAL_FUZZ_BUILD
++ GST_PLUGIN_STATIC_REGISTER (coreelements);
++ GST_PLUGIN_STATIC_REGISTER (typefindfunctions);
++ GST_PLUGIN_STATIC_REGISTER (app);
++#endif
++
++ initialized = TRUE;
++ }
++
++ /* Create the pipeline */
++ pipeline = gst_pipeline_new ("pipeline");
++ source = gst_element_factory_make ("appsrc", "source");
++ typefind = gst_element_factory_make ("typefind", "typefind");
++ fakesink = gst_element_factory_make ("fakesink", "fakesink");
++
++ gst_bin_add_many (GST_BIN (pipeline), source, typefind, fakesink, NULL);
++ gst_element_link_many (source, typefind, fakesink, NULL);
++
++ /* Set pipeline to READY so we can provide data to appsrc */
++ gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY);
++ buf = gst_buffer_new_wrapped_full (0, (gpointer) data, size,
++ 0, size, NULL, NULL);
++ g_object_set (G_OBJECT (source), "size", size, NULL);
++ g_signal_emit_by_name (G_OBJECT (source), "push-buffer", buf, &flowret);
++ gst_buffer_unref (buf);
++
++ /* Set pipeline to PAUSED and wait (typefind will either fail or succeed) */
++ gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
++
++ /* wait until state change either completes or fails */
++ gst_element_get_state (GST_ELEMENT (pipeline), &state, NULL, -1);
++
++ /* Go back to NULL */
++ gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
++
++ /* And release the pipeline */
++ gst_object_unref (pipeline);
++
++ return 0;
++}
+diff -urN gstreamer-1.20.4/ci/gitlab/build_manifest.py gstreamer-1.20.4-1/ci/gitlab/build_manifest.py
+--- gstreamer-1.20.4/ci/gitlab/build_manifest.py 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/gitlab/build_manifest.py 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,270 @@
++#!/usr/bin/env python3
++
++import argparse
++import os
++import sys
++import subprocess
++import urllib.error
++import urllib.parse
++import urllib.request
++import json
++
++from typing import Dict, Tuple, List
++# from pprint import pprint
++
++if sys.version_info < (3, 6):
++ raise SystemExit('Need Python 3.6 or newer')
++
++GSTREAMER_MODULES: List[str] = [
++ 'orc',
++ 'cerbero',
++ 'gst-build',
++ 'gstreamer',
++ 'gst-plugins-base',
++ 'gst-plugins-good',
++ 'gst-plugins-bad',
++ 'gst-plugins-ugly',
++ 'gst-libav',
++ 'gst-devtools',
++ 'gst-docs',
++ 'gst-editing-services',
++ 'gst-omx',
++ 'gst-python',
++ 'gst-rtsp-server',
++ 'gstreamer-sharp',
++ 'gstreamer-vaapi',
++ 'gst-integration-testsuites',
++ 'gst-examples',
++]
++
++MANIFEST_TEMPLATE: str = """<?xml version="1.0" encoding="UTF-8"?>
++<manifest>
++ <remote fetch="{}" name="user"/>
++ <remote fetch="https://gitlab.freedesktop.org/gstreamer/" name="origin"/>
++{}
++</manifest>"""
++
++
++CERBERO_DEPS_LOGS_TARGETS = (
++ ('cross-ios', 'universal'),
++ ('cross-windows-mingw', 'x86'),
++ ('cross-windows-mingw', 'x86_64'),
++ ('cross-android', 'universal'),
++ ('fedora', 'x86_64'),
++ ('macos', 'x86_64'),
++ ('windows-msvc', 'x86_64'),
++)
++
++# Disallow git prompting for a username/password
++os.environ['GIT_TERMINAL_PROMPT'] = '0'
++def git(*args, repository_path='.'):
++ return subprocess.check_output(["git"] + list(args), cwd=repository_path).decode()
++
++def get_cerbero_last_build_info (branch : str):
++ # Fetch the deps log for all (distro, arch) targets
++ all_commits = {}
++ for distro, arch in CERBERO_DEPS_LOGS_TARGETS:
++ url = f'https://artifacts.gstreamer-foundation.net/cerbero-deps/{branch}/{distro}/{arch}/cerbero-deps.log'
++ print(f'Fetching {url}')
++ try:
++ req = urllib.request.Request(url)
++ resp = urllib.request.urlopen(req);
++ deps = json.loads(resp.read())
++ except urllib.error.URLError as e:
++ print(f'WARNING: Failed to GET {url}: {e!s}')
++ continue
++
++ for dep in deps:
++ commit = dep['commit']
++ if commit not in all_commits:
++ all_commits[commit] = []
++ all_commits[commit].append((distro, arch))
++
++ # Fetch the cerbero commit that has the most number of caches
++ best_commit = None
++ newest_commit = None
++ max_caches = 0
++ total_caches = len(CERBERO_DEPS_LOGS_TARGETS)
++ for commit, targets in all_commits.items():
++ if newest_commit is None:
++ newest_commit = commit
++ have_caches = len(targets)
++ # If this commit has caches for all targets, just use it
++ if have_caches == total_caches:
++ best_commit = commit
++ break
++ # Else, try to find the commit with the most caches
++ if have_caches > max_caches:
++ max_caches = have_caches
++ best_commit = commit
++ if newest_commit is None:
++ print('WARNING: No deps logs were found, will build from scratch')
++ if best_commit != newest_commit:
++ print(f'WARNING: Cache is not up-to-date for commit {newest_commit}, using commit {best_commit} instead')
++ return best_commit
++
++
++def get_branch_info(module: str, namespace: str, branch: str) -> Tuple[str, str]:
++ try:
++ res = git('ls-remote', f'https://gitlab.freedesktop.org/{namespace}/{module}.git', branch)
++ except subprocess.CalledProcessError:
++ return None, None
++
++ if not res:
++ return None, None
++
++ # Special case cerbero to avoid cache misses
++ if module == 'cerbero':
++ sha = get_cerbero_last_build_info(branch)
++ if sha is not None:
++ return sha, sha
++
++ lines = res.split('\n')
++ for line in lines:
++ if line.endswith('/' + branch):
++ try:
++ sha, refname = line.split('\t')
++ except ValueError:
++ continue
++ return refname.strip(), sha
++
++ return None, None
++
++
++def find_repository_sha(module: str, branchname: str) -> Tuple[str, str, str]:
++ namespace: str = os.environ["CI_PROJECT_NAMESPACE"]
++ ups_branch: str = os.getenv('GST_UPSTREAM_BRANCH', default='master')
++
++ if module == "orc":
++ ups_branch = os.getenv('ORC_UPSTREAM_BRANCH', default='master')
++
++ if module == os.environ['CI_PROJECT_NAME']:
++ return 'user', branchname, os.environ['CI_COMMIT_SHA']
++
++ if branchname != ups_branch:
++ remote_refname, sha = get_branch_info(module, namespace, branchname)
++ if sha is not None:
++ return 'user', remote_refname, sha
++
++ # Check upstream project for a branch
++ remote_refname, sha = get_branch_info(module, 'gstreamer', ups_branch)
++ if sha is not None:
++ return 'origin', remote_refname, sha
++
++ # This should never occur given the upstream fallback above
++ print(f"Could not find anything for {module}:{branchname}")
++ print("If something reaches that point, please file a bug")
++ print("https://gitlab.freedesktop.org/gstreamer/gst-ci/issues")
++ assert False
++
++
++# --- Unit tests --- #
++# Basically, pytest will happily let a test mutate a variable, and then run
++# the next tests one the same environment without reset the vars.
++def preserve_ci_vars(func):
++ """Preserve the original CI Variable values"""
++ def wrapper():
++ try:
++ url = os.environ["CI_PROJECT_URL"]
++ user = os.environ["CI_PROJECT_NAMESPACE"]
++ except KeyError:
++ url = "invalid"
++ user = ""
++
++ private = os.getenv("READ_PROJECTS_TOKEN", default=None)
++ if not private:
++ os.environ["READ_PROJECTS_TOKEN"] = "FOO"
++
++ func()
++
++ os.environ["CI_PROJECT_URL"] = url
++ os.environ["CI_PROJECT_NAMESPACE"] = user
++
++ if private:
++ os.environ["READ_PROJECTS_TOKEN"] = private
++ # if it was set after
++ elif os.getenv("READ_PROJECTS_TOKEN", default=None):
++ del os.environ["READ_PROJECTS_TOKEN"]
++
++ return wrapper
++
++@preserve_ci_vars
++def test_find_repository_sha():
++ os.environ["CI_PROJECT_NAME"] = "some-random-project"
++ os.environ["CI_PROJECT_URL"] = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-good"
++ os.environ["CI_PROJECT_NAMESPACE"] = "alatiera"
++ os.environ["GST_UPSTREAM_BRANCH"] = "master"
++ del os.environ["READ_PROJECTS_TOKEN"]
++
++ # This should find the repository in the user namespace
++ remote, refname, git_ref = find_repository_sha("gst-plugins-good", "1.2")
++ assert remote == "user"
++ assert git_ref == "08ab260b8a39791e7e62c95f4b64fd5b69959325"
++ assert refname == "refs/heads/1.2"
++
++ # This should fallback to upstream master branch since no matching branch was found
++ remote, refname, git_ref = find_repository_sha("gst-plugins-good", "totally-valid-branch-name")
++ assert remote == "origin"
++ assert refname == "refs/heads/master"
++
++ os.environ["CI_PROJECT_NAME"] = "the_project"
++ os.environ["CI_COMMIT_SHA"] = "MySha"
++
++ remote, refname, git_ref = find_repository_sha("the_project", "whatever")
++ assert remote == "user"
++ assert git_ref == "MySha"
++ assert refname == "whatever"
++
++
++@preserve_ci_vars
++def test_get_project_branch():
++ os.environ["CI_PROJECT_NAME"] = "some-random-project"
++ os.environ["CI_COMMIT_SHA"] = "dwbuiw"
++ os.environ["CI_PROJECT_URL"] = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-good"
++ os.environ["CI_PROJECT_NAMESPACE"] = "nowaythisnamespaceexists_"
++ del os.environ["READ_PROJECTS_TOKEN"]
++
++ os.environ['GST_UPSTREAM_BRANCH'] = '1.12'
++ remote, refname, twelve = find_repository_sha('gst-plugins-good', '1.12')
++ assert twelve is not None
++ assert remote == 'origin'
++ assert refname == "refs/heads/1.12"
++
++ os.environ['GST_UPSTREAM_BRANCH'] = '1.14'
++ remote, refname, fourteen = find_repository_sha('gst-plugins-good', '1.14')
++ assert fourteen is not None
++ assert remote == 'origin'
++ assert refname == "refs/heads/1.14"
++
++
++if __name__ == "__main__":
++ parser = argparse.ArgumentParser()
++ parser.add_argument("--self-update", action="store_true", default=False)
++ parser.add_argument(dest="output", default='manifest.xml', nargs='?')
++ options = parser.parse_args()
++
++ current_branch: str = os.environ['CI_COMMIT_REF_NAME']
++ user_remote_url: str = os.path.dirname(os.environ['CI_PROJECT_URL'])
++ if not user_remote_url.endswith('/'):
++ user_remote_url += '/'
++
++ if options.self_update:
++ remote, remote_refname, sha = find_repository_sha("gst-ci", current_branch)
++ if remote == 'user':
++ remote = user_remote_url + 'gst-ci'
++ else:
++ remote = "https://gitlab.freedesktop.org/gstreamer/gst-ci"
++
++ git('fetch', remote, remote_refname)
++ git('checkout', '--detach', sha)
++ sys.exit(0)
++
++ projects: str = ''
++ for module in GSTREAMER_MODULES:
++ print(f"Checking {module}:", end=' ')
++ remote, refname, revision = find_repository_sha(module, current_branch)
++ print(f"remote '{remote}', refname: '{refname}', revision: '{revision}'")
++ projects += f" <project path=\"{module}\" name=\"{module}.git\" remote=\"{remote}\" revision=\"{revision}\" refname=\"{refname}\" />\n"
++
++ with open(options.output, mode='w') as manifest:
++ print(MANIFEST_TEMPLATE.format(user_remote_url, projects), file=manifest)
+diff -urN gstreamer-1.20.4/ci/gitlab/clone_manifest_ref.py gstreamer-1.20.4-1/ci/gitlab/clone_manifest_ref.py
+--- gstreamer-1.20.4/ci/gitlab/clone_manifest_ref.py 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/gitlab/clone_manifest_ref.py 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,92 @@
++#!/usr/bin/env python3
++
++import argparse
++import os
++import subprocess
++
++from collections import namedtuple
++import xml.etree.ElementTree as ET
++
++# Disallow git prompting for a username/password
++os.environ['GIT_TERMINAL_PROMPT'] = '0'
++def git(*args, repository_path='.'):
++ return subprocess.check_output(["git"] + list(args), cwd=repository_path).decode()
++
++class Manifest(object):
++ '''
++ Parse and store the content of a manifest file
++ '''
++
++ remotes = {}
++ projects = {}
++ default_remote = 'origin'
++ default_revision = 'refs/heads/master'
++
++ def __init__(self, manifest_path):
++ self.manifest_path = manifest_path
++
++ def parse(self):
++ try:
++ tree = ET.parse(self.manifest_path)
++ except Exception as ex:
++ raise Exception("Error loading manifest %s in file %s" % (self.manifest_path, ex))
++
++ root = tree.getroot()
++
++ for child in root:
++ if child.tag == 'remote':
++ self.remotes[child.attrib['name']] = child.attrib['fetch']
++ if child.tag == 'default':
++ self.default_remote = child.attrib['remote'] or self.default_remote
++ self.default_revision = child.attrib['revision'] or self.default_revision
++ if child.tag == 'project':
++ project = namedtuple('Project', ['name', 'remote',
++ 'revision', 'fetch_uri'])
++
++ project.name = child.attrib['name']
++ if project.name.endswith('.git'):
++ project.name = project.name[:-4]
++ project.remote = child.attrib.get('remote') or self.default_remote
++ project.revision = child.attrib.get('revision') or self.default_revision
++ project.fetch_uri = self.remotes[project.remote] + project.name + '.git'
++
++ self.projects[project.name] = project
++
++ def find_project(self, name):
++ try:
++ return self.projects[name]
++ except KeyError as ex:
++ raise Exception("Could not find project %s in manifest %s" % (name, self.manifest_path))
++
++ def get_fetch_uri(self, project, remote):
++ fetch = self.remotes[remote]
++ return fetch + project.name + '.git'
++
++if __name__ == "__main__":
++ parser = argparse.ArgumentParser()
++ parser.add_argument("--project", action="store", type=str)
++ parser.add_argument("--destination", action="store", type=str, default='.')
++ parser.add_argument("--manifest", action="store", type=str)
++ parser.add_argument("--fetch", action="store_true", default=False)
++ options = parser.parse_args()
++
++ if not options.project:
++ raise ValueError("--project argument not provided")
++ if not options.manifest:
++ raise ValueError("--manifest argument not provided")
++
++ manifest = Manifest(options.manifest)
++ manifest.parse()
++ project = manifest.find_project(options.project)
++
++ dest = options.destination
++ if dest == '.':
++ dest = os.path.join (os.getcwd(), project.name)
++
++ if options.fetch:
++ assert os.path.exists(dest) == True
++ git('fetch', project.fetch_uri, project.revision, repository_path=dest)
++ else:
++ git('clone', project.fetch_uri, dest)
++
++ git('checkout', '--detach', project.revision, repository_path=dest)
+diff -urN gstreamer-1.20.4/ci/gitlab/freedesktop_doc_importer.py gstreamer-1.20.4-1/ci/gitlab/freedesktop_doc_importer.py
+--- gstreamer-1.20.4/ci/gitlab/freedesktop_doc_importer.py 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/gitlab/freedesktop_doc_importer.py 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,39 @@
++#!/usr/bin/python3
++import os
++import gitlab
++from datetime import datetime
++import tempfile
++from subprocess import check_call, call, check_output
++
++BRANCH="main"
++NAMESPACE="gstreamer"
++JOB="documentation"
++DOC_BASE="/srv/gstreamer.freedesktop.org/public_html/documentation"
++
++print(f"Running at {datetime.now()}")
++with tempfile.TemporaryDirectory() as tmpdir:
++ os.chdir(tmpdir)
++
++ gl = gitlab.Gitlab("https://gitlab.freedesktop.org/")
++ project = gl.projects.get(1357)
++ pipelines = project.pipelines.list()
++ for pipeline in pipelines:
++ if pipeline.ref != BRANCH:
++ continue
++
++ job, = [j for j in pipeline.jobs.list() if j.name == "documentation"]
++ if job.status != "success":
++ continue
++
++ url = f"https://gitlab.freedesktop.org/gstreamer/gstreamer/-/jobs/{job.id}/artifacts/download"
++ print("============================================================================================================================")
++ print(f"Updating documentation from: {url}\n\n")
++ check_call(f"wget {url} -O gstdocs.zip", shell=True)
++ print("Unziping file.")
++ check_output("unzip gstdocs.zip", shell=True)
++ print("Running rsync.")
++ call(f"rsync -rvaz --links --delete documentation/ {DOC_BASE}", shell=True)
++ call(f"chmod -R g+w {DOC_BASE}; chgrp -R gstreamer {DOC_BASE}", shell=True)
++
++ print(f"Done updating doc")
++ break
+diff -urN gstreamer-1.20.4/ci/gitlab/trigger_cerbero_pipeline.py gstreamer-1.20.4-1/ci/gitlab/trigger_cerbero_pipeline.py
+--- gstreamer-1.20.4/ci/gitlab/trigger_cerbero_pipeline.py 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/gitlab/trigger_cerbero_pipeline.py 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,75 @@
++#!/usr/bin/python3
++
++import time
++import os
++import sys
++import gitlab
++
++CERBERO_PROJECT = 'gstreamer/cerbero'
++
++
++class Status:
++ FAILED = 'failed'
++ MANUAL = 'manual'
++ CANCELED = 'canceled'
++ SUCCESS = 'success'
++ SKIPPED = 'skipped'
++ CREATED = 'created'
++
++ @classmethod
++ def is_finished(cls, state):
++ return state in [
++ cls.FAILED,
++ cls.MANUAL,
++ cls.CANCELED,
++ cls.SUCCESS,
++ cls.SKIPPED,
++ ]
++
++
++def fprint(msg):
++ print(msg, end="")
++ sys.stdout.flush()
++
++
++if __name__ == "__main__":
++ server = os.environ['CI_SERVER_URL']
++ gl = gitlab.Gitlab(server,
++ private_token=os.environ.get('GITLAB_API_TOKEN'),
++ job_token=os.environ.get('CI_JOB_TOKEN'))
++
++ cerbero = gl.projects.get(CERBERO_PROJECT)
++
++ # CI_PROJECT_URL is not necessarily the project where the branch we need to
++ # build resides, for instance merge request pipelines can be run on
++ # 'gstreamer' namespace. Fetch the branch name in the same way, just in
++ # case it breaks in the future.
++ if 'CI_MERGE_REQUEST_SOURCE_PROJECT_URL' in os.environ:
++ project_url = os.environ['CI_MERGE_REQUEST_SOURCE_PROJECT_URL']
++ project_branch = os.environ['CI_MERGE_REQUEST_SOURCE_BRANCH_NAME']
++ else:
++ project_url = os.environ['CI_PROJECT_URL']
++ project_branch = os.environ['CI_COMMIT_REF_NAME']
++
++ pipe = cerbero.trigger_pipeline(
++ token=os.environ['CI_JOB_TOKEN'],
++ ref=os.environ["GST_UPSTREAM_BRANCH"],
++ variables={
++ "CI_GSTREAMER_URL": project_url,
++ "CI_GSTREAMER_REF_NAME": project_branch,
++ # This tells cerbero CI that this is a pipeline started via the
++ # trigger API, which means it can use a deps cache instead of
++ # building from scratch.
++ "CI_GSTREAMER_TRIGGERED": "true",
++ }
++ )
++
++ fprint(f'Cerbero pipeline running at {pipe.web_url} ')
++ while True:
++ time.sleep(15)
++ pipe.refresh()
++ if Status.is_finished(pipe.status):
++ fprint(f": {pipe.status}\n")
++ sys.exit(0 if pipe.status == Status.SUCCESS else 1)
++ else:
++ fprint(".")
+diff -urN gstreamer-1.20.4/ci/jenkins/Jenkinsfile-cerbero-debian gstreamer-1.20.4-1/ci/jenkins/Jenkinsfile-cerbero-debian
+--- gstreamer-1.20.4/ci/jenkins/Jenkinsfile-cerbero-debian 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/jenkins/Jenkinsfile-cerbero-debian 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,51 @@
++node("docker") {
++ docker.image('gstreamer/build-base-ubuntu:latest').inside {
++
++ env.OUTPREFIX="${env.WORKSPACE}/../output/${params.build_tag}/linux_x86_64/"
++
++ stage('Checkout') {
++ // FIXME: Only checkout the manifest and not all dependencies ?
++ checkout([$class: 'RepoScm',
++ manifestRepositoryUrl:'git+ssh://git.arracacha.collabora.co.uk/git/gst-manifest.git',
++ manifestBranch:"refs/tags/${params.build_tag}",
++ jobs:4,
++ currentBranch:true,
++ quiet:true,
++ depth:0])
++ }
++
++ stage('Setup') {
++ sh "find ../output -maxdepth 1 -ctime +1 | xargs rm -Rf"
++ sh "cd .repo/manifests/; git checkout ${params.build_tag}; cd ../.."
++ sh "rm -Rf ./workdir/sources/linux_x86_64/"
++ sh "rm -f *.rpm"
++ sh "rm -Rf ./workdir/temp; mkdir -p ./workdir/temp"
++ sh "rm -Rf ./workdir/tmp*"
++
++ // Create custom configuration file
++ sh "./gst-ci-scripts/manifest2cerbero.py .repo/manifests/default.xml ./cerbero/config/linux.config --output localconf.cbc"
++ sh '''echo "home_dir = \\"$WORKSPACE/workdir\\"" >> localconf.cbc'''
++ sh '''echo "logs = \\"$OUTPREFIX/logs\\"" >> localconf.cbc'''
++ sh './cerbero/cerbero-uninstalled -c localconf.cbc show-config'
++ }
++
++ stage('bootstrap') {
++ sh './cerbero/cerbero-uninstalled -c localconf.cbc bootstrap'
++ sh 'rm -Rf ./workdir/sources/build-tools/'
++ }
++
++ stage('fetch') {
++ sh './cerbero/cerbero-uninstalled -c localconf.cbc fetch-package --reset-rdeps --full-reset gstreamer-1.0'
++ }
++
++ stage('package') {
++ sh './cerbero/cerbero-uninstalled -c localconf.cbc package gstreamer-1.0'
++ }
++
++ stage('Cleanup') {
++ sh 'rm -f *.rpm'
++ sh 'find ../output -maxdepth 1 -ctime +1 | xargs rm -Rf'
++ }
++ // FIXME: IRC Notification
++ }
++}
+diff -urN gstreamer-1.20.4/ci/jenkins/Jenkinsfile-master-fedora gstreamer-1.20.4-1/ci/jenkins/Jenkinsfile-master-fedora
+--- gstreamer-1.20.4/ci/jenkins/Jenkinsfile-master-fedora 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/jenkins/Jenkinsfile-master-fedora 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,66 @@
++node('docker') {
++ docker.image('gstreamer/build-base-fedora:latest').inside {
++
++ env.CCACHE_DIR = "${env.WORKSPACE}/.ccache"
++ env.CCACHE_MAXSIZE = "2G"
++ env.CC = "ccache gcc"
++ env.CXX = "ccache g++"
++ env.MAKEFLAGS = "-j6"
++ env.PATH = "${env.WORKSPACE}:${env.PATH}"
++ env.GST_UNINSTALLED_ROOT="${env.WORKSPACE}"
++ env.HOME="${env.WORKSPACE}"
++ env.DISPLAY=":0"
++
++ stage('Checkout') {
++ if (params.wipe) {
++ sh 'rm -Rf *'
++ }
++ checkout([$class: 'RepoScm',
++ manifestRepositoryUrl:'https://git.arracacha.collabora.co.uk/git/gst-manifest.git',
++ manifestBranch:"refs/tags/${params.build_tag}",
++ jobs:4,
++ currentBranch:true,
++ quiet:true,
++ depth:0,
++ mirrorDir:'/repositories'])
++ }
++
++ stage('Cleanup') {
++ sh 'rm -f **/tests/check/*/*.xml'
++ }
++
++ stage ('Build') {
++ sh "uname -a"
++ sh "./gstreamer/scripts/gst-uninstalled ./gst-ci-scripts/ci-build.sh fast-build-only"
++ }
++
++ withEnv(['DISPLAY=:0']) {
++ stage ('Check') {
++ env.GST_CHECKS_IGNORE="test_allocate_udp_ports_multicast,test_allocate_udp_ports_client_settings,test_reorder_buffer,test_redirect_yes"
++ env.GST_CHECK_XML=1
++ sh 'Xvfb :0 -screen 0 1024x768x24 -fbdir /tmp &'
++ sh 'env'
++ sh "./gstreamer/scripts/gst-uninstalled ./gst-ci-scripts/ci-build.sh check"
++
++ step([$class: 'XUnitBuilder',
++ testTimeMargin: '3000', thresholdMode: 1,
++ thresholds: [[$class: 'FailedThreshold',
++ failureNewThreshold: '',
++ failureThreshold: '400',
++ unstableNewThreshold: '',
++ unstableThreshold: '1'],
++ [$class: 'SkippedThreshold',
++ failureNewThreshold: '',
++ failureThreshold: '',
++ unstableNewThreshold: '',
++ unstableThreshold: '']],
++ tools: [[$class: 'CheckType',
++ deleteOutputFiles: true,
++ failIfNotNew: true,
++ pattern: '**/tests/check/*/*.xml',
++ skipNoTestFiles: true,
++ stopProcessingIfError: true]]])
++ }
++ }
++ }
++}
+diff -urN gstreamer-1.20.4/ci/jenkins/Jenkinsfile-master-ubuntu gstreamer-1.20.4-1/ci/jenkins/Jenkinsfile-master-ubuntu
+--- gstreamer-1.20.4/ci/jenkins/Jenkinsfile-master-ubuntu 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/jenkins/Jenkinsfile-master-ubuntu 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,66 @@
++node('docker') {
++ docker.image('gstreamer/build-base-ubuntu:latest').inside {
++
++ env.CCACHE_DIR = "${env.WORKSPACE}/.ccache"
++ env.CCACHE_MAXSIZE = "2G"
++ env.CC = "ccache gcc"
++ env.CXX = "ccache g++"
++ env.MAKEFLAGS = "-j6"
++ env.PATH = "${env.WORKSPACE}:${env.PATH}"
++ env.GST_UNINSTALLED_ROOT="${env.WORKSPACE}"
++ env.HOME="${env.WORKSPACE}"
++ env.DISPLAY=":0"
++
++ stage('Checkout') {
++ if (params.wipe) {
++ sh 'rm -Rf *'
++ }
++ checkout([$class: 'RepoScm',
++ manifestRepositoryUrl:'https://git.arracacha.collabora.co.uk/git/gst-manifest.git',
++ manifestBranch:"refs/tags/${params.build_tag}",
++ jobs:4,
++ currentBranch:true,
++ quiet:true,
++ depth:0,
++ mirrorDir:'/repositories'])
++ }
++
++ stage('Cleanup') {
++ sh 'rm -f **/tests/check/*/*.xml'
++ }
++
++ stage ('Build') {
++ sh "uname -a"
++ sh "./gstreamer/scripts/gst-uninstalled ./gst-ci-scripts/ci-build.sh fast-build-only"
++ }
++
++ withEnv(['DISPLAY=:0']) {
++ stage ('Check') {
++ env.GST_CHECKS_IGNORE="test_allocate_udp_ports_multicast,test_allocate_udp_ports_client_settings,test_reorder_buffer,test_redirect_yes"
++ env.GST_CHECK_XML=1
++ sh 'Xvfb :0 -screen 0 1024x768x24 -fbdir /tmp &'
++ sh 'env'
++ sh "./gstreamer/scripts/gst-uninstalled ./gst-ci-scripts/ci-build.sh check"
++
++ step([$class: 'XUnitBuilder',
++ testTimeMargin: '3000', thresholdMode: 1,
++ thresholds: [[$class: 'FailedThreshold',
++ failureNewThreshold: '',
++ failureThreshold: '400',
++ unstableNewThreshold: '',
++ unstableThreshold: '1'],
++ [$class: 'SkippedThreshold',
++ failureNewThreshold: '',
++ failureThreshold: '',
++ unstableNewThreshold: '',
++ unstableThreshold: '']],
++ tools: [[$class: 'CheckType',
++ deleteOutputFiles: true,
++ failIfNotNew: true,
++ pattern: '**/tests/check/*/*.xml',
++ skipNoTestFiles: true,
++ stopProcessingIfError: true]]])
++ }
++ }
++ }
++}
+diff -urN gstreamer-1.20.4/ci/jenkins/Jenkinsfile-meson-fedora gstreamer-1.20.4-1/ci/jenkins/Jenkinsfile-meson-fedora
+--- gstreamer-1.20.4/ci/jenkins/Jenkinsfile-meson-fedora 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/jenkins/Jenkinsfile-meson-fedora 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,71 @@
++node('docker') {
++ docker.image('gstreamer/build-meson-fedora:latest').inside {
++
++ env.CCACHE_DIR = "${env.WORKSPACE}/.ccache"
++ env.CCACHE_MAXSIZE = "2G"
++ env.CC = "ccache gcc"
++ env.CXX = "ccache g++"
++ env.MAKEFLAGS = "-j6"
++ env.PATH = "${env.WORKSPACE}:${env.PATH}"
++ env.HOME="${env.WORKSPACE}"
++ env.DISPLAY=":0"
++
++ stage('Checkout') {
++ if (params.wipe) {
++ sh 'rm -Rf build/'
++ }
++ checkout([$class: 'GitSCM', branches: [[name: '*/master']],
++ doGenerateSubmoduleConfigurations: false,
++ extensions: [[$class: 'CloneOption',
++ depth: 0,
++ noTags: false,
++ reference: '/gstbuild/gst-build/',
++ shallow: false]],
++ submoduleCfg: [],
++ userRemoteConfigs: [[url: 'git://anongit.freedesktop.org/gstreamer/gst-build']]]
++ )
++ sh 'git checkout master && git reset --hard origin/master'
++ sh 'curl "https://git.arracacha.collabora.co.uk/cgit/gst-manifest.git/plain/default.xml?id=$BUILD_TAG" -k -o manifest.xml'
++ }
++
++ stage('Setup') {
++ sh './git-update --no-color --manifest=manifest.xml --no-interaction'
++ sh './setup.py -Ddisable_gstreamer_vaapi=true'
++ }
++
++ stage ('Build') {
++ sh "ninja -C build"
++ }
++
++ stage ('Check') {
++ sh "./gst-uninstalled.py gst-validate-launcher --check-bugs --no-display --mute -n check --xunit-file $WORKSPACE/xunit.xml -M $WORKSPACE/validate-output --ignore-numfailures"
++
++ step([$class: 'XUnitBuilder',
++ testTimeMargin: '3000', thresholdMode: 1,
++ thresholds: [[$class: 'FailedThreshold',
++ failureNewThreshold: '',
++ failureThreshold: '5',
++ unstableNewThreshold: '',
++ unstableThreshold: '1'],
++ [$class: 'SkippedThreshold',
++ failureNewThreshold: '',
++ failureThreshold: '',
++ unstableNewThreshold: '',
++ unstableThreshold: '']],
++ tools: [[$class: 'JUnitType',
++ deleteOutputFiles: true,
++ failIfNotNew: true,
++ pattern: 'xunit.xml',
++ skipNoTestFiles: true,
++ stopProcessingIfError: true]]])
++ }
++
++ stage('install') {
++ sh 'mkdir -p dest'
++ sh 'DESTDIR=$PWD/dest ninja -C build install'
++ }
++ stage('package') {
++ sh 'cd dest && tar caJf gstreamer-$BUILD_TAG.tar.xz usr'
++ }
++ }
++}
+diff -urN gstreamer-1.20.4/ci/meson/vs2019-arm64-cross-file.txt gstreamer-1.20.4-1/ci/meson/vs2019-arm64-cross-file.txt
+--- gstreamer-1.20.4/ci/meson/vs2019-arm64-cross-file.txt 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/meson/vs2019-arm64-cross-file.txt 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,23 @@
++[constants]
++vs_path = 'C:\BuildTools'
++msvc_version = '14.29.30133'
++msvc_version_dir = vs_path / 'VC\Tools\MSVC' / msvc_version
++msvc_arm64_bindir = msvc_version_dir / 'bin\Hostx64\arm64'
++msvc_arm64_libdir = msvc_version_dir / 'lib\arm64'
++
++[host_machine]
++system = 'windows'
++cpu_family = 'aarch64'
++cpu = 'aarch64'
++endian = 'little'
++
++[properties]
++needs_exe_wrapper = true
++
++[binaries]
++lib = msvc_arm64_bindir / 'lib.exe'
++c = msvc_arm64_bindir / 'cl.exe'
++c_ld = msvc_arm64_bindir / 'link.exe'
++cpp = msvc_arm64_bindir / 'cl.exe'
++cpp_ld = msvc_arm64_bindir / 'link.exe'
++pkgconfig = 'false'
+diff -urN gstreamer-1.20.4/ci/meson/vs2019-x64-native-file.txt gstreamer-1.20.4-1/ci/meson/vs2019-x64-native-file.txt
+--- gstreamer-1.20.4/ci/meson/vs2019-x64-native-file.txt 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/meson/vs2019-x64-native-file.txt 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,38 @@
++[constants]
++vs_path = 'C:\BuildTools'
++msvc_version = '14.29.30133'
++msvc_version_dir = vs_path / 'VC\Tools\MSVC' / msvc_version
++msvc_x64_bindir = msvc_version_dir / 'bin\Hostx64\x64'
++msvc_x64_libdir = msvc_version_dir / 'lib\x64'
++wk_path = 'C:\Program Files (x86)\Windows Kits'
++wk_version = '10.0.19041.0'
++wk_x64_libdir = wk_path / '10\lib' / wk_version / 'um\x64'
++wk_x64_crt_libdir = wk_path / '10\lib' / wk_version / 'ucrt\x64'
++# Forcibly link to x64 libs when using native linker, otherwise the LIB
++# variable in the env will cause link.exe to pick up libs from the cross
++# msvc libdir. A better fix might be to use a wrapper script that calls
++# link.exe inside the correct VS environment for x64.
++msvc_x64_libs = [msvc_x64_libdir / 'msvcrt.lib', msvc_x64_libdir / 'msvcrtd.lib', msvc_x64_libdir / 'vcruntime.lib', msvc_x64_libdir / 'oldnames.lib', wk_x64_crt_libdir / 'ucrt.lib']
++
++[host_machine]
++system = 'windows'
++cpu_family = 'x86_64'
++cpu = 'x86_64'
++endian = 'little'
++
++[properties]
++needs_exe_wrapper = true
++
++[built-in options]
++# Ensure that x64 libs are used for linking even when we're inside, say, an
++# arm64 VS environment
++c_link_args = ['/LIBPATH:' + wk_x64_libdir] + msvc_x64_libs
++cpp_link_args = ['/LIBPATH:' + wk_x64_libdir] + msvc_x64_libs
++
++[binaries]
++lib = msvc_x64_bindir / 'lib.exe'
++c = msvc_x64_bindir / 'cl.exe'
++c_ld = msvc_x64_bindir / 'link.exe'
++cpp = msvc_x64_bindir / 'cl.exe'
++cpp_ld = msvc_x64_bindir / 'link.exe'
++pkgconfig = 'false'
+diff -urN gstreamer-1.20.4/ci/scripts/check-documentation-diff.py gstreamer-1.20.4-1/ci/scripts/check-documentation-diff.py
+--- gstreamer-1.20.4/ci/scripts/check-documentation-diff.py 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/scripts/check-documentation-diff.py 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,20 @@
++#!/usr/bin/python3
++import os, subprocess, sys
++
++if __name__ == "__main__":
++ diffsdir = 'plugins-cache-diffs'
++ os.makedirs(diffsdir, exist_ok=True)
++ res = 0
++ try:
++ subprocess.check_call(['git', 'diff', '--quiet'] )
++ except subprocess.CalledProcessError:
++ diffname = os.path.join(diffsdir, 'plugins_cache.diff')
++ res += 1
++ with open(diffname, 'w') as diff:
++ subprocess.check_call(['git', 'diff'], stdout=diff)
++ print('\033[91mYou have a diff in the documentation cache. Please update with:\033[0m')
++ print(' $ curl %s/%s | git apply -' % (os.environ['CI_ARTIFACTS_URL'], diffname.replace('../', '')))
++
++ if res != 0:
++ print('(note that it might take a few minutes for artefacts to be available on the server)\n')
++ sys.exit(res)
+\ No newline at end of file
+diff -urN gstreamer-1.20.4/ci/scripts/handle-subprojects-cache.py gstreamer-1.20.4-1/ci/scripts/handle-subprojects-cache.py
+--- gstreamer-1.20.4/ci/scripts/handle-subprojects-cache.py 1970-01-01 00:00:00.000000000 +0000
++++ gstreamer-1.20.4-1/ci/scripts/handle-subprojects-cache.py 2022-10-12 15:39:51.000000000 +0000
+@@ -0,0 +1,82 @@
++#!/usr/bin/env python3
++
++"""
++Copies current subproject git repository to create a cache
++"""
++
++import shutil
++import os
++import sys
++import argparse
++import subprocess
++
++DEST = "/subprojects"
++PARSER = argparse.ArgumentParser()
++PARSER.add_argument('subprojects_dir')
++PARSER.add_argument('--build', action="store_true", default=False)
++
++
++def create_cache_in_image(options):
++ os.makedirs(DEST, exist_ok=True)
++ print("Creating cache from %s" % options.subprojects_dir)
++ for project_name in os.listdir(options.subprojects_dir):
++ project_path = os.path.join(options.subprojects_dir, project_name)
++
++ if project_name != "packagecache" and not os.path.exists(os.path.join(project_path, '.git')):
++ continue
++
++ if os.path.exists(os.path.join(DEST, project_name)):
++ continue
++
++ print("Copying %s" % project_name)
++ shutil.copytree(project_path, os.path.join(DEST, project_name))
++
++ media_path = os.path.join(options.subprojects_dir, '..', '.git',
++ 'modules', 'subprojects', 'gst-integration-testsuites', 'medias')
++ if os.path.exists(os.path.join(DEST, 'medias.git')):
++ return
++
++ if os.path.exists(media_path):
++ print("Creating media cache")
++ shutil.copytree(media_path, os.path.join(DEST, 'medias.git'))
++ else:
++ print("Did not find medias in %s" % media_path)
++
++
++def copy_cache(options):
++ # FIXME Remove when not needed anymore.
++ for path in [DEST, "/gst-build/subprojects", r"C:\gst-build\subprojects"]:
++ if not os.path.exists(path):
++ print("%s doesn't exist." % path)
++ continue
++
++ for project_name in os.listdir(path):
++ project_path = os.path.join(options.subprojects_dir, project_name)
++ cache_dir = os.path.join(path, project_name)
++
++ if project_name == 'medias.git':
++ project_path = os.path.join(options.subprojects_dir, '..', '.git', 'modules',
++ 'subprojects', 'gst-integration-testsuites')
++ os.makedirs(project_path, exist_ok=True)
++ project_path = os.path.join(project_path, 'medias')
++
++ if os.path.exists(project_path):
++ print("- Ignoring %s" % cache_dir)
++ continue
++
++ if not os.path.isdir(cache_dir):
++ print("- Ignoring %s" % cache_dir)
++ continue
++
++ print("Copying from %s -> %s" % (cache_dir, project_path))
++ shutil.copytree(cache_dir, project_path)
++ subprocess.check_call(['meson', 'subprojects', 'update', '--reset'])
++
++
++if __name__ == "__main__":
++ options = PARSER.parse_args()
++
++ if options.build:
++ create_cache_in_image(options)
++ else:
++ copy_cache(options)
diff --git a/gstreamer-inspect-rpm-format.patch b/gstreamer-inspect-rpm-format.patch
new file mode 100644
index 0000000..0114c06
--- /dev/null
+++ b/gstreamer-inspect-rpm-format.patch
@@ -0,0 +1,400 @@
+From 642d0d6fef226fb89eaecf0016f8e5e333b9023e Mon Sep 17 00:00:00 2001
+From: Wim Taymans <wtaymans@redhat.com>
+Date: Tue, 23 Jun 2015 10:28:29 +0200
+Subject: [PATCH] gst-inspect: add mode to output RPM requires format
+
+---
+ tools/gst-inspect.c | 279 +++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 263 insertions(+), 16 deletions(-)
+
+diff --git a/tools/gst-inspect.c b/tools/gst-inspect.c
+index 8da042946..a057cba09 100644
+--- a/tools/gst-inspect.c
++++ b/tools/gst-inspect.c
+@@ -394,7 +394,7 @@ print_object_properties_info (GObject * obj, GObjectClass * obj_class,
+
+ first_flag = TRUE;
+ n_print ("%sflags%s: ", PROP_ATTR_NAME_COLOR, RESET_COLOR);
+- readable = ! !(param->flags & G_PARAM_READABLE);
++ readable = !!(param->flags & G_PARAM_READABLE);
+ if (readable && obj != NULL) {
+ g_object_get_property (obj, param->name, &value);
+ } else {
+@@ -1739,11 +1739,228 @@ print_tracer_info (GstPluginFeature * feature, gboolean print_names)
+ return 0;
+ }
+
++static void
++print_gst_structure_append_field (GList * strings, const char *field)
++{
++ GList *s;
++
++ //g_message ("adding '%s' to the string", field);
++
++ for (s = strings; s != NULL; s = s->next) {
++ g_string_append (s->data, field);
++ }
++}
++
++static void
++print_gst_structure_append_field_index (GList * strings, const char *field,
++ guint num_items, guint offset)
++{
++ GList *s;
++ guint i;
++
++ //g_message ("adding '%s' to the string (num: %d offset: %d)", field, num_items, offset);
++
++ for (s = strings, i = 0; s != NULL; s = s->next, i++) {
++ if (i == offset) {
++ //g_message ("adding '%s' at '%d'", field, i);
++ g_string_append (s->data, field);
++ }
++ if (i == num_items)
++ i = 0;
++ }
++
++}
++
++static GList *
++print_gst_structure_dup_fields (GList * strings, guint num_items)
++{
++ guint new_items, i;
++
++ if (num_items == 1)
++ return strings;
++
++ //g_message ("creating %d new items", num_items);
++
++ new_items = g_list_length (strings) * (num_items - 1);
++ for (i = 0; i < new_items; i++) {
++ GString *s, *first;
++
++ first = strings->data;
++ s = g_string_new_len (first->str, first->len);
++ strings = g_list_prepend (strings, s);
++ }
++
++ return strings;
++}
++
++enum
++{
++ FIELD_VERSION = 0,
++ FIELD_LAYER,
++ FIELD_VARIANT,
++ FIELD_SYSTEMSTREAM
++};
++
++static int
++field_get_type (const char *field_name)
++{
++ if (strstr (field_name, "version") != NULL)
++ return FIELD_VERSION;
++ if (strcmp (field_name, "layer") == 0)
++ return FIELD_LAYER;
++ if (strcmp (field_name, "systemstream") == 0)
++ return FIELD_SYSTEMSTREAM;
++ if (strcmp (field_name, "variant") == 0)
++ return FIELD_VARIANT;
++
++ return -1;
++}
++
++static gint
++fields_type_compare (const char *a, const char *b)
++{
++ gint a_type, b_type;
++
++ a_type = field_get_type (a);
++ b_type = field_get_type (b);
++ if (a_type < b_type)
++ return -1;
++ if (b_type < a_type)
++ return 1;
++ return 0;
++}
++
++static void
++print_gst_structure_for_rpm (const char *type_name, GstStructure * s)
++{
++ guint i, num_fields;
++ const char *name;
++ GList *fields, *l, *strings;
++ GString *string;
++
++ name = gst_structure_get_name (s);
++ strings = NULL;
++ num_fields = gst_structure_n_fields (s);
++ fields = NULL;
++
++ for (i = 0; i < num_fields; i++) {
++ const char *field_name;
++
++ field_name = gst_structure_nth_field_name (s, i);
++ if (field_get_type (field_name) < 0) {
++ //g_message ("ignoring field named %s", field_name);
++ continue;
++ }
++
++ fields =
++ g_list_insert_sorted (fields, g_strdup (field_name),
++ (GCompareFunc) fields_type_compare);
++ }
++
++ /* Example:
++ * gstreamer1(decoder-video/mpeg)(mpegversion=1)()(64bit) */
++ string = g_string_new ("gstreamer1");
++ g_string_append_c (string, '(');
++ g_string_append (string, type_name);
++ g_string_append_c (string, '-');
++ g_string_append (string, name);
++ g_string_append_c (string, ')');
++
++ strings = g_list_append (strings, string);
++
++ for (l = fields; l != NULL; l = l->next) {
++ char *field_name;
++ GType type;
++
++ field_name = l->data;
++
++ type = gst_structure_get_field_type (s, field_name);
++ //g_message ("field is: %s, type: %s", field_name, g_type_name (type));
++
++ if (type == G_TYPE_INT) {
++ char *field;
++ int value;
++
++ gst_structure_get_int (s, field_name, &value);
++ field = g_strdup_printf ("(%s=%d)", field_name, value);
++ print_gst_structure_append_field (strings, field);
++ g_free (field);
++ } else if (type == G_TYPE_BOOLEAN) {
++ char *field;
++ int value;
++
++ gst_structure_get_boolean (s, field_name, &value);
++ field = g_strdup_printf ("(%s=%s)", field_name, value ? "true" : "false");
++ print_gst_structure_append_field (strings, field);
++ g_free (field);
++ } else if (type == GST_TYPE_INT_RANGE) {
++ const GValue *value;
++ int min, max;
++
++ value = gst_structure_get_value (s, field_name);
++ min = gst_value_get_int_range_min (value);
++ max = gst_value_get_int_range_max (value);
++
++ strings = print_gst_structure_dup_fields (strings, max - min + 1);
++
++ for (i = min; i <= max; i++) {
++ char *field;
++
++ field = g_strdup_printf ("(%s=%d)", field_name, i);
++ print_gst_structure_append_field_index (strings, field, max - min + 1,
++ i - min);
++ g_free (field);
++ }
++ } else if (type == GST_TYPE_LIST) {
++ const GValue *value;
++ int num_items;
++
++ value = gst_structure_get_value (s, field_name);
++ num_items = gst_value_list_get_size (value);
++
++ strings = print_gst_structure_dup_fields (strings, num_items);
++
++ for (i = 0; i < num_items; i++) {
++ char *field;
++ const GValue *item_value;
++
++ item_value = gst_value_list_get_value (value, i);
++ field = g_strdup_printf ("(%s=%d)", field_name,
++ g_value_get_int (item_value));
++ print_gst_structure_append_field_index (strings, field, num_items, i);
++ g_free (field);
++ }
++ } else if (type == G_TYPE_STRING) {
++ char *field;
++ const char *value;
++
++ value = gst_structure_get_string (s, field_name);
++ field = g_strdup_printf ("(%s=%s)", field_name, value);
++ print_gst_structure_append_field (strings, field);
++ g_free (field);
++ } else {
++ g_warning ("unhandled type! %s", g_type_name (type));
++ }
++
++ g_free (field_name);
++ }
++
++ g_list_free (fields);
++
++ for (l = strings; l != NULL; l = l->next) {
++ string = l->data;
++ g_print ("%s\n", string->str);
++ g_string_free (string, TRUE);
++ }
++ g_list_free (strings);
++}
++
+ /* NOTE: Not coloring output from automatic install functions, as their output
+ * is meant for machines, not humans.
+ */
+ static void
+-print_plugin_automatic_install_info_codecs (GstElementFactory * factory)
++print_plugin_automatic_install_info_codecs (GstElementFactory * factory,
++ gboolean rpm_format)
+ {
+ GstPadDirection direction;
+ const gchar *type_name;
+@@ -1769,6 +1986,13 @@ print_plugin_automatic_install_info_codecs (GstElementFactory * factory)
+ return;
+ }
+
++ if (rpm_format) {
++ /* Ignore NONE ranked plugins */
++ if ((gst_plugin_feature_get_rank (GST_PLUGIN_FEATURE (factory))) ==
++ GST_RANK_NONE)
++ return;
++ }
++
+ /* decoder/demuxer sink pads should always be static and there should only
+ * be one, the same applies to encoders/muxers and source pads */
+ static_templates = gst_element_factory_get_static_pad_templates (factory);
+@@ -1805,15 +2029,20 @@ print_plugin_automatic_install_info_codecs (GstElementFactory * factory)
+ gst_structure_remove_field (s, "rate");
+ gst_structure_remove_field (s, "depth");
+ gst_structure_remove_field (s, "clock-rate");
+- s_str = gst_structure_to_string (s);
+- g_print ("%s-%s\n", type_name, s_str);
+- g_free (s_str);
++ if (!rpm_format) {
++ s_str = gst_structure_to_string (s);
++ g_print ("%s-%s\n", type_name, s_str);
++ g_free (s_str);
++ } else {
++ print_gst_structure_for_rpm (type_name, s);
++ }
+ }
+ gst_caps_unref (caps);
+ }
+
+ static void
+-print_plugin_automatic_install_info_protocols (GstElementFactory * factory)
++print_plugin_automatic_install_info_protocols (GstElementFactory * factory,
++ gboolean rpm_format)
+ {
+ const gchar *const *protocols;
+
+@@ -1822,13 +2051,19 @@ print_plugin_automatic_install_info_protocols (GstElementFactory * factory)
+ switch (gst_element_factory_get_uri_type (factory)) {
+ case GST_URI_SINK:
+ while (*protocols != NULL) {
+- g_print ("urisink-%s\n", *protocols);
++ if (!rpm_format)
++ g_print ("urisink-%s\n", *protocols);
++ else
++ g_print ("gstreamer1(urisink-%s)\n", *protocols);
+ ++protocols;
+ }
+ break;
+ case GST_URI_SRC:
+ while (*protocols != NULL) {
+- g_print ("urisource-%s\n", *protocols);
++ if (!rpm_format)
++ g_print ("urisource-%s\n", *protocols);
++ else
++ g_print ("gstreamer1(urisource-%s)\n", *protocols);
+ ++protocols;
+ }
+ break;
+@@ -1839,7 +2074,7 @@ print_plugin_automatic_install_info_protocols (GstElementFactory * factory)
+ }
+
+ static void
+-print_plugin_automatic_install_info (GstPlugin * plugin)
++print_plugin_automatic_install_info (GstPlugin * plugin, gboolean rpm_format)
+ {
+ GList *features, *l;
+
+@@ -1858,11 +2093,15 @@ print_plugin_automatic_install_info (GstPlugin * plugin)
+ if (feature_plugin == plugin) {
+ GstElementFactory *factory;
+
+- g_print ("element-%s\n", gst_plugin_feature_get_name (feature));
++ if (!rpm_format)
++ g_print ("element-%s\n", gst_plugin_feature_get_name (feature));
++ else
++ g_print ("gstreamer1(element-%s)\n",
++ gst_plugin_feature_get_name (feature));
+
+ factory = GST_ELEMENT_FACTORY (feature);
+- print_plugin_automatic_install_info_protocols (factory);
+- print_plugin_automatic_install_info_codecs (factory);
++ print_plugin_automatic_install_info_protocols (factory, rpm_format);
++ print_plugin_automatic_install_info_codecs (factory, rpm_format);
+ }
+ if (feature_plugin)
+ gst_object_unref (feature_plugin);
+@@ -1884,7 +2123,7 @@ print_all_plugin_automatic_install_info (void)
+ plugin = (GstPlugin *) (plugins->data);
+ plugins = g_list_next (plugins);
+
+- print_plugin_automatic_install_info (plugin);
++ print_plugin_automatic_install_info (plugin, FALSE);
+ }
+ gst_plugin_list_free (orig_plugins);
+ }
+@@ -1951,6 +2190,7 @@ main (int argc, char *argv[])
+ gboolean do_print_blacklist = FALSE;
+ gboolean plugin_name = FALSE;
+ gboolean print_aii = FALSE;
++ gboolean print_aii_rpm = FALSE;
+ gboolean uri_handlers = FALSE;
+ gboolean check_exists = FALSE;
+ gboolean color_always = FALSE;
+@@ -1972,6 +2212,9 @@ main (int argc, char *argv[])
+ "or all plugins provide.\n "
+ "Useful in connection with external automatic plugin "
+ "installation mechanisms"), NULL},
++ {"rpm", '\0', 0, G_OPTION_ARG_NONE, &print_aii_rpm,
++ N_("Print the machine-parsable list of features of a plugin in RPM "
++ "Provides compatible-format"), NULL},
+ {"plugin", '\0', 0, G_OPTION_ARG_NONE, &plugin_name,
+ N_("List the plugin contents"), NULL},
+ {"types", 't', 0, G_OPTION_ARG_STRING, &types,
+@@ -2135,7 +2378,7 @@ main (int argc, char *argv[])
+ /* if there is such a plugin, print out info */
+ if (plugin) {
+ if (print_aii) {
+- print_plugin_automatic_install_info (plugin);
++ print_plugin_automatic_install_info (plugin, print_aii_rpm);
+ } else {
+ print_plugin_info (plugin);
+ print_plugin_features (plugin);
+@@ -2148,13 +2391,17 @@ main (int argc, char *argv[])
+
+ if (plugin) {
+ if (print_aii) {
+- print_plugin_automatic_install_info (plugin);
++ print_plugin_automatic_install_info (plugin, print_aii_rpm);
+ } else {
+ print_plugin_info (plugin);
+ print_plugin_features (plugin);
+ }
+ } else {
+- g_printerr (_("Could not load plugin file: %s\n"), error->message);
++ if (!print_aii_rpm)
++ g_print (_("Could not load plugin file: %s\n"), error->message);
++ else
++ g_printerr (_("Could not load plugin file: %s\n"),
++ error->message);
+ g_clear_error (&error);
+ exit_code = -1;
+ goto done;
+--
+2.26.2
+
diff --git a/gstreamer1.attr b/gstreamer1.attr
new file mode 100644
index 0000000..2d134ff
--- /dev/null
+++ b/gstreamer1.attr
@@ -0,0 +1,2 @@
+%__gstreamer1_provides %{_rpmconfigdir}/gstreamer1.prov
+%__gstreamer1_path ^%{_libdir}/gstreamer-1.*/.*\.so$
diff --git a/gstreamer1.prov b/gstreamer1.prov
new file mode 100644
index 0000000..a3e901e
--- /dev/null
+++ b/gstreamer1.prov
@@ -0,0 +1,44 @@
+#!/bin/sh
+#
+# Script to install in:
+# /usr/lib/rpm/redhat/find-provides.d
+#
+# Transform GStreamer auto install info into RPM provides
+#
+# Author: Bastien Nocera <hadess@hadess.net>
+# Based on other provides scripts from RPM
+#
+
+filelist=`grep -e '^.*/gstreamer-1.0/lib.*.so$' | sed "s/['\"]/\\\&/g"`
+
+# --- Alpha does not mark 64bit dependencies•
+case `uname -m` in
+ alpha*) mark64="" ;;
+ *) mark64="()(64bit)" ;;
+esac
+
+solist=$(echo $filelist | \
+ xargs file -L 2>/dev/null | grep "ELF" | cut -d: -f1 )
+
+function getmark()
+{
+ lib64=`if file -L $1 2>/dev/null | \
+ grep "ELF 64-bit" >/dev/null; then echo -n "$mark64"; fi`
+}
+
+function libdir()
+{
+ buildlibdir=`dirname $1`
+ buildlibdir=`dirname $buildlibdir`
+}
+
+for so in $solist ; do
+ getmark $so
+ libdir $so
+ LD_LIBRARY_PATH=$buildlibdir gst-inspect-1.0 --print-plugin-auto-install-info --rpm $so 2> /dev/null | while read line ; do
+ echo -n "$line";
+ echo -n "$lib64"
+ echo
+ done
+done
+
diff --git a/gstreamer1.spec b/gstreamer1.spec
new file mode 100644
index 0000000..7bae17b
--- /dev/null
+++ b/gstreamer1.spec
@@ -0,0 +1,141 @@
+Name: gstreamer1
+Version: 1.20.4
+Release: 1
+Summary: Bindings for GStreamer 1.0, the open source multimedia framework
+License: LGPLv2+
+URL: https://gstreamer.freedesktop.org/
+Source0: https://github.com/GStreamer/gstreamer/archive/refs/tags/gstreamer-%{version}.tar.xz
+Source1: gstreamer1.attr
+Source2: gstreamer1.prov
+
+
+Patch0001: ci.patch
+Patch0002: gstreamer-inspect-rpm-format.patch
+
+BuildRequires: bison check-devel chrpath meson >= 0.59.0 gcc
+BuildRequires: flex gettext gettext-devel glib2-devel >= 2.32.0
+BuildRequires: gobject-introspection-devel >= 1.31.1 libtool
+BuildRequires: libxml2-devel >= 2.4.0 pkgconfig libcap-devel
+BuildRequires: libunwind-devel elfutils-devel bash-completion
+
+%description
+GStreamer1 implements a framework that allows for processing and encoding of
+multimedia sources in a manner similar to a shell pipeline.
+
+Because it's introspection-based, most of the classes follow directly from the
+C API. Therefore, most of the documentation is by example rather than a full
+breakdown of the class structure.
+
+%package devel
+Summary: Development files for GStreamer streaming media framework
+Requires: %{name} = %{version}-%{release}
+Requires: glib2-devel libxml2-devel check-devel
+
+%description devel
+The %{name}-devel package includes the libraries, header files, etc.,
+that you'll need to develop applications that are linked with the
+gstreamer1 extensibility library.
+
+
+%package help
+Summary: Documents for %{name}
+Buildarch: noarch
+Requires: man info %{name} = %{version}-%{release}
+Provides: %{name}-devel-docs
+
+%description help
+Man pages and other related documents for %{name}.
+
+%prep
+%autosetup -n gstreamer-%{version} -p1
+
+
+
+%build
+
+%meson \
+ -D tests=disabled -D examples=disabled \
+ -D ptp-helper-permissions=capabilities -D dbghelp=disabled \
+ -D doc=disabled
+%meson_build
+
+%install
+%meson_install
+%find_lang gstreamer-1.0
+%delete_la
+install -m0644 -D %{SOURCE1} %{buildroot}%{_rpmconfigdir}/fileattrs/gstreamer1.attr
+install -m0755 -D %{SOURCE2} %{buildroot}%{_rpmconfigdir}/gstreamer1.prov
+%ldconfig_scriptlets
+
+%files -f gstreamer-1.0.lang
+%doc AUTHORS NEWS
+%license COPYING
+%{_bindir}/gst-*-1.0
+%{_rpmconfigdir}/gstreamer1.prov
+%{_rpmconfigdir}/fileattrs/gstreamer1.attr
+%{_libdir}/*.so.*
+%{_libdir}/gstreamer-1.0/*.so
+%{_libdir}/girepository-1.0/*.typelib
+%{_libexecdir}/gstreamer-1.0/*
+%{_datadir}/bash-completion/helpers/gst
+%{_datadir}/bash-completion/completions/gst-*
+
+%files devel
+%{_datadir}/aclocal/gst-element-check-1.0.m4
+%{_datadir}/gir-1.0/*.gir
+%{_libdir}/*.so
+%{_libdir}/pkgconfig/*.pc
+%{_includedir}/gstreamer-1.0/gst/*.h
+%{_includedir}/gstreamer-1.0/gst/net/*.h
+%{_includedir}/gstreamer-1.0/gst/controller/*.h
+%{_includedir}/gstreamer-1.0/gst/check/*.h
+%{_includedir}/gstreamer-1.0/gst/base/*.h
+
+%{_datadir}/gstreamer-1.0/gdb/*
+%{_datadir}/gdb/auto-load/*
+
+%files help
+%doc RELEASE
+%{_mandir}/man1/*.gz
+
+%changelog
+* Tue Nov 1 2022 huyab<1229981468@qq.com> - 1.20.4-1
+- update to 1.20.4
+
+* Sat Jun 25 2022 lin zhang <lin.zhang@turbolinux.com.cn> - 1.20.3-1
+- update to 1.20.3
+
+* Mon Jun 20 2022 lin zhang <lin.zhang@turbolinux.com.cn> - 1.19.3-2
+- fix build when Meson >= 0.61.5
+- remove meson option gtk_doc
+
+* Fri Dec 3 2021 hanhui <hanhui15@huawei.com> - 1.19.3-1
+- Upgrade to gstreamer-1.19.3
+
+* Wed Jun 23 2021 weijin deng <weijin.deng@turbolinux.com.cn> - 1.18.4-1
+- Upgrade to 1.18.4
+- Delete Adapt-to-backwards-incompatible-change-in-GUN.patch whose target
+ patch file doesn't exist in this version 1.18.4
+- Add gstreamer-inspect-rpm-format.patch
+- Use meson rebuild
+
+* Wed Mar 3 2021 yanan <yanan@huawei.com> - 1.16.2-3
+- remove buildrequires for gtk-doc
+
+* Tue Aug 4 2020 wangye <wangye70@huawei.com> - 1.16.2-2
+- fix 1.16.2 make error
+
+* Sat Jul 25 2020 hanhui <hanhui15@huawei.com> - 1.16.2-1
+- update 1.16.2
+
+* Tue Jan 7 2020 openEuler Buildteam <buildteam@openeuler.org> - 1.14.4-4
+- update software package
+
+* Sun Dec 29 2019 openEuler Buildteam <buildteam@openeuler.org> - 1.14.4-3
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:optimization the spec
+
+* Tue Aug 27 2019 openEuler Buildteam <buildteam@openeuler.org> - 1.14.4-2
+- Package Init
diff --git a/sources b/sources
new file mode 100644
index 0000000..dc7b6ed
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+7c53246ab7a51401876866ca54e07b34 gstreamer-1.20.4.tar.xz