Skip to content

Commit

Permalink
Replace FFMS2 with native ffmpeg libav* audio/video decoder.
Browse files Browse the repository at this point in the history
Improve MediaClip start/end handling - clamp to frame boundary.
CI on ubuntu jammy and noble, macos ffmpeg 4 and 6
Better fuzzy audio tests.
  • Loading branch information
rectalogic committed Mar 12, 2024
1 parent 4ef25cd commit 89bad12
Show file tree
Hide file tree
Showing 57 changed files with 1,715 additions and 949 deletions.
2 changes: 1 addition & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Checks: 'clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,'
Checks: 'clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,bugprone-*'
WarningsAsErrors: true
HeaderFilterRegex: '.*\.h'
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"source.organizeImports": true,
"editor.formatOnSave": true,
"git.ignoreLimitWarning": true,
"clang-format.executable": "/usr/bin/clang-format-15",
"clang-format.executable": "/usr/bin/clang-format",
// https: //github.com/microsoft/vscode-remote-release/issues/8169
"extensions.verifySignature": false
}
Expand Down
41 changes: 33 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ jobs:

docker:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
ubuntu: ["jammy", "noble"]
permissions:
contents: read
packages: write
Expand All @@ -21,6 +25,7 @@ jobs:
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
flavor: prefix=${{ matrix.ubuntu }}-
- name: Setup buildx
uses: docker/setup-buildx-action@v3
- name: Log into registry ghcr.io
Expand All @@ -42,36 +47,54 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
push: true
target: mediafx
build-args: QT_VER=${{ env.QT_VER }}
build-args: |
"QT_VER=${{ env.QT_VER }}"
"UBUNTU=${{ matrix.ubuntu }}"
cache-from: type=registry,ref=ghcr.io/${{ github.repository }}:buildcache
cache-to: type=registry,ref=ghcr.io/${{ github.repository }}:buildcache,mode=max

linux:
runs-on: ubuntu-22.04
needs: docker
strategy:
fail-fast: false
matrix:
ubuntu: ["jammy", "noble"]
include:
- ubuntu: "noble"
test: "-e MEDIAFX_TEST=--verbose"
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
- name: Build/test mediaFX
run: DOCKER_OPTS="-e MEDIAFX_TEST=--verbose" TARGET=opengl builders/Linux/docker-run.sh
run: DOCKER_OPTS="${{ matrix.test }}" TARGET=opengl UBUNTU=${{ matrix.ubuntu }} builders/Linux/docker-run.sh
- name: Build/test mediaFX vulkan
run: DOCKER_OPTS="-e MEDIAFX_TEST=--verbose" TARGET=vulkan builders/Linux/docker-run.sh
if: matrix.ubuntu == 'noble'
run: DOCKER_OPTS="${{ matrix.test }}" TARGET=vulkan UBUNTU=${{ matrix.ubuntu }} builders/Linux/docker-run.sh
- name: Upload Failed Artifacts
if: failure()
uses: actions/upload-artifact@v4
with:
name: failed-output-linux
name: failed-output-linux-${{ matrix.ubuntu }}
path: build/Linux/output

macos:
runs-on: macos-14
strategy:
fail-fast: false
matrix:
ffmpeg: ["ffmpeg@4", "ffmpeg@6"]
include:
- ffmpeg: "ffmpeg@6"
test: "MEDIAFX_TEST=--verbose"
env:
XCODE_VER: "15.2"
steps:
- name: Brew
run: brew install bash ffmpeg@4 ffmpeg@6 ffms2
- name: Brew ffmpeg
run: |
brew install bash ${{ matrix.ffmpeg }}
- name: Checkout
uses: actions/checkout@v4
with:
Expand All @@ -97,12 +120,14 @@ jobs:
key: ${{ steps.restore-cache.outputs.cache-primary-key }}
- name: Build/test mediaFX
run: |
PATH="$(brew --prefix ffmpeg@4)/bin:$PATH" MEDIAFX_TEST=--verbose builders/mediafx-build.sh
export PATH="$(brew --prefix ${{ matrix.ffmpeg }})/bin:$PATH"
export PKG_CONFIG_PATH="$(brew --prefix ${{ matrix.ffmpeg }})/lib/pkgconfig"
${{ matrix.test }} builders/mediafx-build.sh
- name: Upload Failed Artifacts
if: failure()
uses: actions/upload-artifact@v4
with:
name: failed-output-darwin
name: failed-output-darwin-${{ matrix.ffmpeg }}
path: build/Darwin/output

lint:
Expand Down
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ if(NOT "${isSystemDir}" STREQUAL "-1")
set(CMAKE_INSTALL_RPATH "")
endif()

add_compile_options($<$<CONFIG:Debug>:-fsanitize=address>)
add_link_options($<$<CONFIG:Debug>:-fsanitize=address>)

add_subdirectory(src/MediaFX)
add_subdirectory(tests)
add_subdirectory(tools/viewer)
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ for the QML elements and modules.
## Dependencies

MediaFX use [Qt 6.6](https://doc.qt.io/qt-6/),
the [FFMS2](https://github.com/FFMS/ffms2) decoding library,
and [FFmpeg](https://ffmpeg.org/).

## Example
Expand Down
80 changes: 62 additions & 18 deletions builders/Linux/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,88 @@
# SPDX-License-Identifier: GPL-3.0-or-later

# syntax = docker/dockerfile:1.2

ARG UBUNTU=noble

# linux arm64 not supported by Qt https://doc.qt.io/qt-6/supported-platforms.html
FROM --platform=linux/amd64 ubuntu:jammy as build
FROM --platform=linux/amd64 ubuntu:jammy as qt

ARG QT_VER
ENV container docker
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG=en_US.UTF-8
ENV LC_ALL=C.UTF-8
RUN apt-get -y update \
&& apt-get -y install python3 python3-pip
&& apt-get -y install python3 python3-pip python3-venv

COPY aqtinstall-requirements.txt /tmp/aqtinstall-requirements.txt
RUN pip3 install --requirement /tmp/aqtinstall-requirements.txt \
&& python3 -m aqt install-qt linux desktop ${QT_VER} --modules qtmultimedia qtquick3d qtshadertools qtquicktimeline debug_info --archives qtbase icu qttools qtdeclarative qtmultimedia qtquick3d qtquicktimeline --outputdir /usr/local/Qt \
&& python3 -m aqt install-doc linux ${QT_VER} --modules qtmultimedia --archives qtquick qtmultimedia --outputdir /usr/local/Qt \
RUN python3 -m venv venv && venv/bin/pip3 install --requirement /tmp/aqtinstall-requirements.txt \
&& venv/bin/python3 -m aqt install-qt linux desktop ${QT_VER} --modules qtmultimedia qtquick3d qtshadertools qtquicktimeline debug_info --archives qtbase icu qttools qtdeclarative qtmultimedia qtquick3d qtquicktimeline --outputdir /usr/local/Qt \
&& venv/bin/python3 -m aqt install-doc linux ${QT_VER} --modules qtmultimedia --archives qtquick qtmultimedia --outputdir /usr/local/Qt \
&& find /usr/local/Qt/Docs/Qt-${QT_VER} -type f -and -not -name '*.index' -delete


FROM --platform=linux/amd64 ubuntu:jammy as mediafx
FROM --platform=linux/amd64 ubuntu:jammy as jammy


FROM --platform=linux/amd64 ubuntu:noble as noble
RUN apt-get -y update && apt-get -y install \
clang-format \
clang-tidy \
clazy \
iwyu


FROM --platform=linux/amd64 ${UBUNTU} as mediafx
LABEL maintainer=rectalogic
ARG QT_VER

ENV GALLIUM_DRIVER=softpipe
ENV LIBGL_ALWAYS_SOFTWARE=1
ENV DRI_NO_MSAA=1

ENV container docker
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG=en_US.UTF-8
ENV LC_ALL=C.UTF-8
# iwyu & clazy needs clang-13
RUN apt-get -y update \
&& apt-get -y install sudo gosu build-essential cmake ninja-build git \
clang-15 clang-format-15 clang-tidy-15 clang-13 iwyu clazy \
libglx-mesa0 libglvnd-dev libxkbcommon-dev libxkbcommon-x11-0 libpulse-dev libxcb1 libx11-xcb1 libxcb-glx0 libxcb-cursor0 \
libxcb-icccm4 libxcb-image0 libxcb-render-util0 libxcb-keysyms1 libicu70 \
libvulkan-dev mesa-vulkan-drivers \
python3 python3-pip \
curl xz-utils xvfb pkg-config libavutil-dev libswresample-dev libffms2-dev ffmpeg \
fontconfig fonts-liberation bc

COPY --from=build /usr/local/Qt /usr/local/Qt/
RUN apt-get -y update && apt-get -y install \
bc \
build-essential \
cmake \
curl \
ffmpeg \
fontconfig \
fonts-liberation \
git \
gosu \
libavcodec-dev \
libavfilter-dev \
libavformat-dev \
libavutil-dev \
libglvnd-dev \
libglx-mesa0 \
libpulse-dev \
libvulkan-dev \
libx11-xcb1 \
libxcb-cursor0 \
libxcb-glx0 \
libxcb-icccm4 \
libxcb-image0 \
libxcb-keysyms1 \
libxcb-render-util0 \
libxcb1 \
libxkbcommon-dev \
libxkbcommon-x11-0 \
mesa-vulkan-drivers \
ninja-build \
pkg-config \
python3 \
python3-pip \
sudo \
xvfb \
xz-utils

COPY --from=qt /usr/local/Qt /usr/local/Qt/
ENV QTDIR /usr/local/Qt/${QT_VER}/gcc_64
ENV PATH /usr/local/Qt/${QT_VER}/gcc_64/bin:$PATH
ENV QT_VER=${QT_VER}
Expand Down
2 changes: 1 addition & 1 deletion builders/Linux/docker-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

CURRENT=${BASH_SOURCE%/*}
source "$CURRENT/../versions"
docker buildx build --build-arg QT_VER=${QT_VER:?} --platform linux/amd64 --memory-swap -1 --load --tag ghcr.io/rectalogic/mediafx:$(git branch --show-current) --file "${CURRENT}/Dockerfile" "${CURRENT}/.."
docker buildx build --build-arg UBUNTU=${UBUNTU:-noble} --build-arg QT_VER=${QT_VER:?} --platform linux/amd64 --memory-swap -1 --load --tag ghcr.io/rectalogic/mediafx:${UBUNTU:-noble}-$(git branch --show-current) --file "${CURRENT}/Dockerfile" "${CURRENT}/.."
2 changes: 1 addition & 1 deletion builders/Linux/docker-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ MOUNT="$(cd "${BASH_SOURCE%/*}/../.."; pwd)"
# opengl or vulkan
TARGET=${TARGET:-opengl}
docker run ${DOCKER_OPTS} -e QSG_RHI_BACKEND=${TARGET} --platform linux/amd64 --rm --init \
--mount="type=bind,src=${MOUNT},dst=/mediafx,consistency=cached" ghcr.io/rectalogic/mediafx:$(git branch --show-current) "$@"
--mount="type=bind,src=${MOUNT},dst=/mediafx,consistency=cached" ghcr.io/rectalogic/mediafx:${UBUNTU:-noble}-$(git branch --show-current) "$@"
3 changes: 0 additions & 3 deletions builders/Linux/env
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
# Copyright (C) 2024 Andrew Wason
# SPDX-License-Identifier: GPL-3.0-or-later

export GALLIUM_DRIVER=softpipe
export LIBGL_ALWAYS_SOFTWARE=1
export DRI_NO_MSAA=1
export SUDO=sudo
4 changes: 4 additions & 0 deletions builders/Linux/iwyu.imp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[
# https://github.com/include-what-you-use/include-what-you-use/issues/1277
{ include: ["<bits/chrono.h>", "private", "<chrono>", "public"] }
]
7 changes: 4 additions & 3 deletions builders/Linux/iwyu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@

set -e

mkdir -p /mediafx/build/Linux
cd /mediafx/build/Linux
BUILD_TYPE=${BUILD_TYPE:-Debug}
mkdir -p /mediafx/build/Linux/${BUILD_TYPE}
cd /mediafx/build/Linux/${BUILD_TYPE}
if [ ! -f "qt${QT_VER}.imp" ]; then
curl -O https://raw.githubusercontent.com/include-what-you-use/include-what-you-use/clang_13/mapgen/iwyu-mapgen-qt.py
python3 iwyu-mapgen-qt.py ${QTDIR}/include > qt${QT_VER}.imp
fi
CC="clang-13" CXX="clang++-13" cmake -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE="/usr/bin/iwyu;-Xiwyu;--mapping_file=/mediafx/build/Linux/qt${QT_VER}.imp;-Xiwyu;--cxx17ns;-Xiwyu;--no_comments" --install-prefix ${QTDIR} ../.. && exec cmake --build . --parallel 4
CC="clang" CXX="clang++" cmake -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE="/usr/bin/iwyu;-Xiwyu;--mapping_file=/mediafx/build/Linux/${BUILD_TYPE}/qt${QT_VER}.imp;-Xiwyu;--mapping_file=/mediafx/builders/Linux/iwyu.imp;-Xiwyu;--cxx17ns;-Xiwyu;--no_comments" --install-prefix ${QTDIR} ../../.. && exec cmake --build . --parallel 4
16 changes: 8 additions & 8 deletions builders/Linux/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
# Copyright (C) 2024 Andrew Wason
# SPDX-License-Identifier: GPL-3.0-or-later

set -e

mkdir -p /mediafx/build/Linux
cd /mediafx/build/Linux
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON --install-prefix ${QTDIR} ../..
BUILD_TYPE=${BUILD_TYPE:-Debug}
mkdir -p /mediafx/build/Linux/${BUILD_TYPE}
cd /mediafx/build/Linux/${BUILD_TYPE}
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=${BUILD_TYPE} --install-prefix ${QTDIR} ../../.. || exit 1
# Generate *.moc include files for tests
make tst_encoder_autogen/fast tst_interval_autogen/fast
make tst_encoder_autogen/fast tst_decoder_autogen/fast tst_interval_autogen/fast || exit 1
cd /mediafx
git config --global --add safe.directory /mediafx
FILES=$(git ls-files '**/*.cpp' '**/*.h')
/usr/bin/clang-tidy-15 -p /mediafx/build/Linux $FILES
/usr/bin/clazy-standalone -p /mediafx/build/Linux/compile_commands.json $FILES
/usr/bin/clang-tidy -p /mediafx/build/Linux/${BUILD_TYPE} $FILES || exit 1
/usr/bin/clazy-standalone -p /mediafx/build/Linux/${BUILD_TYPE}/compile_commands.json $FILES || exit 1
10 changes: 5 additions & 5 deletions builders/aqtinstall-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
aqtinstall==3.1.11
aqtinstall==3.1.12
beautifulsoup4==4.12.3
Brotli==1.1.0
bs4==0.0.2
certifi==2023.11.17
certifi==2024.2.2
charset-normalizer==3.3.2
defusedxml==0.7.1
humanize==4.9.0
idna==3.6
inflate64==1.0.0
multivolumefile==0.2.3
patch==1.16
psutil==5.9.7
py7zr==0.20.8
psutil==5.9.8
py7zr==0.21.0
pybcj==1.0.2
pycryptodomex==3.20.0
pyppmd==1.1.0
Expand All @@ -20,4 +20,4 @@ requests==2.31.0
semantic-version==2.10.0
soupsieve==2.5
texttable==1.7.0
urllib3==2.1.0
urllib3==2.2.1
23 changes: 12 additions & 11 deletions src/MediaFX/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,32 @@
# SPDX-License-Identifier: GPL-3.0-or-later

find_package(PkgConfig)
pkg_search_module(ffms2 REQUIRED IMPORTED_TARGET ffms2)
pkg_search_module(libavformat REQUIRED IMPORTED_TARGET libavformat)
pkg_search_module(libavcodec REQUIRED IMPORTED_TARGET libavcodec)
pkg_search_module(libavutil REQUIRED IMPORTED_TARGET libavutil)
pkg_search_module(libswresample REQUIRED IMPORTED_TARGET libswresample)
pkg_search_module(libavformat REQUIRED IMPORTED_TARGET libavformat>=58.76.100)
pkg_search_module(libavcodec REQUIRED IMPORTED_TARGET libavcodec>=58.134.100)
pkg_search_module(libavfilter REQUIRED IMPORTED_TARGET libavfilter>=7.110.100)
pkg_search_module(libavutil REQUIRED IMPORTED_TARGET libavutil>=56.70.100)

option(EVENT_LOGGER "Enable event logger" OFF)

qt_add_library(mediafx STATIC
application.cpp
session.cpp
media_manager.cpp
decoder.cpp
stream.cpp
audio_stream.cpp
video_stream.cpp
encoder.cpp
render_control.cpp
media_clip.cpp
track.cpp
video_track.cpp
audio_track.cpp
audio_renderer.cpp
interval.cpp
)

target_include_directories(mediafx PUBLIC ./)
target_include_directories(mediafx PRIVATE ${FFMS2_INCLUDE_DIRS} ${LIBAVFORMAT_INCLUDE_DIRS} ${LIBAVCODEC_INCLUDE_DIRS} ${LIBAVUTIL_INCLUDE_DIRS} ${LIBSWRESAMPLE_INCLUDE_DIRS})
target_compile_options(mediafx PUBLIC ${FFMS2_CFLAGS} ${LIBAVFORMAT_CFLAGS} ${LIBAVCODEC_CFLAGS} ${LIBAVUTIL_CFLAGS} ${LIBSWRESAMPLE_CFLAGS})
target_include_directories(mediafx PRIVATE ${LIBAVFORMAT_INCLUDE_DIRS} ${LIBAVCODEC_INCLUDE_DIRS} ${LIBAVFILTER_INCLUDE_DIRS})
target_include_directories(mediafx PUBLIC ${LIBAVUTIL_INCLUDE_DIRS})
target_compile_options(mediafx PRIVATE ${LIBAVFORMAT_CFLAGS} ${LIBAVCODEC_CFLAGS} ${LIBAVFILTER_CFLAGS} ${LIBAVUTIL_CFLAGS})

qt_add_executable(mediafxtool
main.cpp
Expand All @@ -49,7 +50,7 @@ qt_add_qml_module(mediafx
ShaderEffectState.qml
)

target_link_libraries(mediafx PUBLIC PkgConfig::ffms2 PkgConfig::libswresample PkgConfig::libavformat PkgConfig::libavcodec PkgConfig::libavutil Qt6::Core Qt6::Gui Qt6::GuiPrivate Qt6::Multimedia Qt6::Qml Qt6::Quick)
target_link_libraries(mediafx PUBLIC PkgConfig::libavformat PkgConfig::libavcodec PkgConfig::libavfilter PkgConfig::libavutil Qt6::Core Qt6::Gui Qt6::GuiPrivate Qt6::Multimedia Qt6::Qml Qt6::Quick)
target_link_libraries(mediafx PRIVATE mediafxplugin mixersplugin)

if(${Qt6Quick3D_FOUND})
Expand Down
1 change: 0 additions & 1 deletion src/MediaFX/MediaSequence.qml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later

import QtQuick
import MediaFX
import MediaFX.Mixers
import "sequence.js" as Sequence

Expand Down
Loading

0 comments on commit 89bad12

Please sign in to comment.