Add multi build setup

This commit is contained in:
Jan Stabenow
2022-05-12 21:51:49 +02:00
parent 9f9ede357c
commit 53027e82e8
14 changed files with 1196 additions and 290 deletions

11
.editorconfig Normal file
View File

@@ -0,0 +1,11 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = false

View File

@@ -0,0 +1,79 @@
name: 'Build base:alpine-ffmpeg-rpi'
on:
workflow_dispatch:
push:
branches-ignore:
- '**'
jobs:
docker:
runs-on: [self-hosted]
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: cardinalby/export-env-action@v1
with:
envFile: 'Build.alpine.env'
export: 'true'
expandWithJobEnv: 'true'
expand: 'true'
- uses: cardinalby/export-env-action@v1
with:
envFile: 'Build.alpine.rpi.env'
export: 'true'
expandWithJobEnv: 'true'
expand: 'true'
- name: Set up QEMU
uses: docker/setup-qemu-action@master
with:
platforms: linux/arm/v7
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@master
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build Multi-Arch
uses: docker/build-push-action@v2
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
file: ./Dockerfile.alpine.rpi
build-args: |
ALPINE_IMAGE=${{ env.OS_NAME }}:${{ env.OS_VERSION }}
FREETYPE_VERSION=${{ env.FREETYPE_VERSION }}
XML2_VERSION=${{ env.XML2_VERSION }}
SRT_VERSION=${{ env.SRT_VERSION }}
X264_VERSION=${{ env.X264_VERSION }}
X265_VERSION=${{ env.X265_VERSION }}
VPX_VERSION=${{ env.VPX_VERSION }}
LAME_VERSION=${{ env.LAME_VERSION }}
OPUS_VERSION=${{ env.OPUS_VERSION }}
VORBIS_VERSION=${{ env.VORBIS_VERSION }}
FFMPEG_VERSION=${{ env.FFMPEG_VERSION }}
RPI_VERSION=${{ env.RPI_VERSION }}
platforms: linux/arm/v7
push: true
tags: |
datarhei/base:${{ env.OS_NAME }}-ffmpeg-rpi-${{ env.OS_VERSION }}-${{ env.FFMPEG_VERSION }}
datarhei/base:${{ env.OS_NAME }}-ffmpeg-rpi-latest
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new

View File

@@ -0,0 +1,88 @@
name: 'Build base:alpine-ffmpeg-vvapi'
on:
workflow_dispatch:
push:
branches-ignore:
- '**'
jobs:
docker:
runs-on: [self-hosted]
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: cardinalby/export-env-action@v1
with:
envFile: 'Build.alpine.env'
export: 'true'
expandWithJobEnv: 'true'
expand: 'true'
- uses: cardinalby/export-env-action@v1
with:
envFile: 'Build.alpine.vaapi.env'
export: 'true'
expandWithJobEnv: 'true'
expand: 'true'
- name: Set up QEMU
uses: docker/setup-qemu-action@master
with:
platforms: all
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@master
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build Multi-Arch
uses: docker/build-push-action@v2
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
file: ./Dockerfile.alpine.vaapi
build-args: |
ALPINE_IMAGE=${{ env.OS_NAME }}:${{ env.OS_VERSION }}
FREETYPE_VERSION=${{ env.FREETYPE_VERSION }}
XML2_VERSION=${{ env.XML2_VERSION }}
SRT_VERSION=${{ env.SRT_VERSION }}
X264_VERSION=${{ env.X264_VERSION }}
X265_VERSION=${{ env.X265_VERSION }}
VPX_VERSION=${{ env.VPX_VERSION }}
LAME_VERSION=${{ env.LAME_VERSION }}
OPUS_VERSION=${{ env.OPUS_VERSION }}
VORBIS_VERSION=${{ env.VORBIS_VERSION }}
FFMPEG_VERSION=${{ env.FFMPEG_VERSION }}
LIBAV_VERSION=${{ env.LIBAV_VERSION }}
LIBVDPAU_VERSION=${{ env.LIBVDPAU_VERSION }}
MESA_VA_GALLIUM_VERSION=${{ env.MESA_VA_GALLIUM_VERSION }}
MESA_VDPAU_GALLIUM_VERSION=${{ env.MESA_VDPAU_GALLIUM_VERSION }}
LIBVA_VDPAU_DRIVER_VERSION=${{ env.LIBVA_VDPAU_DRIVER_VERSION }}
INTEL_GMMLIB_VERSION=${{ env.INTEL_GMMLIB_VERSION }}
INTEL_MEDIA_DRIVER_VERSION=${{ env.INTEL_MEDIA_DRIVER_VERSION }}
INTEL_MEDIA_SDK_VERSION=${{ env.INTEL_MEDIA_SDK_VERSION }}
INTEL_VAAPI_DRIVER=${{ env.INTEL_VAAPI_DRIVER }}
platforms: linux/amd64
push: true
tags: |
datarhei/base:${{ env.OS_NAME }}-ffmpeg-vaapi-${{ env.OS_VERSION }}-${{ env.FFMPEG_VERSION }}
datarhei/base:${{ env.OS_NAME }}-ffmpeg-vaapi-latest
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new

View File

@@ -0,0 +1,71 @@
name: 'Build base:alpine-ffmpeg'
on:
workflow_dispatch:
push:
branches-ignore:
- '**'
jobs:
docker:
runs-on: [self-hosted]
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: cardinalby/export-env-action@v1
with:
envFile: 'Build.alpine.env'
export: 'true'
expandWithJobEnv: 'true'
expand: 'true'
- name: Set up QEMU
uses: docker/setup-qemu-action@master
with:
platforms: all
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@master
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build Multi-Arch
uses: docker/build-push-action@v2
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
file: ./Dockerfile.alpine
build-args: |
ALPINE_IMAGE=${{ env.OS_NAME }}:${{ env.OS_VERSION }}
FREETYPE_VERSION=${{ env.FREETYPE_VERSION }}
XML2_VERSION=${{ env.XML2_VERSION }}
SRT_VERSION=${{ env.SRT_VERSION }}
X264_VERSION=${{ env.X264_VERSION }}
X265_VERSION=${{ env.X265_VERSION }}
VPX_VERSION=${{ env.VPX_VERSION }}
LAME_VERSION=${{ env.LAME_VERSION }}
OPUS_VERSION=${{ env.OPUS_VERSION }}
VORBIS_VERSION=${{ env.VORBIS_VERSION }}
FFMPEG_VERSION=${{ env.FFMPEG_VERSION }}
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: |
datarhei/base:${{ env.OS_NAME }}-ffmpeg-${{ env.OS_VERSION }}-${{ env.FFMPEG_VERSION }}
datarhei/base:${{ env.OS_NAME }}-ffmpeg-latest
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new

13
Build.alpine.env Normal file
View File

@@ -0,0 +1,13 @@
# FFMPEG BASE PACKAGES
OS_NAME=alpine
OS_VERSION=3.15
FREETYPE_VERSION=2.11.1-r1
XML2_VERSION=2.9.13-r0
SRT_VERSION=1.4.2-r1
X264_VERSION=20210613-r0
X265_VERSION=3.5-r0
VPX_VERSION=1.10.0-r0
LAME_VERSION=3.100-r0
OPUS_VERSION=1.3.1-r1
VORBIS_VERSION=1.3.7-r0
FFMPEG_VERSION=4.4.2

2
Build.alpine.rpi.env Normal file
View File

@@ -0,0 +1,2 @@
# FFMPEG RPI PACKAGES
RPI_VERSION=0.20200813-r0

10
Build.alpine.vaapi.env Normal file
View File

@@ -0,0 +1,10 @@
# FFMPEG VAAPI PACKAGES
LIBAV_VERSION=2.14.0-r0
LIBVDPAU_VERSION=1.5-r0
MESA_VA_GALLIUM_VERSION=21.3.8-r1
MESA_VDPAU_GALLIUM_VERSION=21.3.8-r1
LIBVA_VDPAU_DRIVER_VERSION=0.7.4-r2
INTEL_GMMLIB_VERSION=22.1.2-r0
INTEL_MEDIA_DRIVER_VERSION=22.4.1-r0
INTEL_MEDIA_SDK_VERSION=22.4.1-r0
INTEL_VAAPI_DRIVER=2.4.1-r0

128
Dockerfile.alpine Normal file
View File

@@ -0,0 +1,128 @@
ARG ALPINE_IMAGE=alpine:3.15
FROM $ALPINE_IMAGE as builder
ARG FREETYPE_VERSION=2.11.1-r1
ARG XML2_VERSION=2.9.13-r0
ARG SRT_VERSION=1.4.2-r1
ARG X264_VERSION=20210613-r0
ARG X265_VERSION=3.5-r0
ARG VPX_VERSION=1.10.0-r0
ARG LAME_VERSION=3.100-r0
ARG OPUS_VERSION=1.3.1-r1
ARG VORBIS_VERSION=1.3.7-r0
ARG FFMPEG_VERSION=4.4.2
ENV PKG_CONFIG_PATH=/usr/lib/pkgconfig \
SRC=/usr
# install build packages
RUN apk add --update \
autoconf \
automake \
bash \
binutils \
bzip2 \
ca-certificates \
cmake \
coreutils \
curl \
diffutils \
g++ \
gcc \
libgcc \
libssl1.1 \
libtool \
linux-headers \
make \
musl-dev \
nasm \
openssl-dev \
patch \
tar \
zlib-dev
# install shared ffmpeg libs
RUN apk add -U \
freetype-dev=${FREETYPE_VERSION} \
libxml2-dev=${XML2_VERSION} \
libsrt-dev=${SRT_VERSION} \
x264-dev=${X264_VERSION} \
x265-dev=${X265_VERSION} \
libvpx-dev=${VPX_VERSION} \
lame-dev=${LAME_VERSION} \
opus-dev=${OPUS_VERSION} \
libvorbis-dev=${VORBIS_VERSION}
# install and patch ffmpeg
RUN mkdir -p /dist && cd /dist && \
curl -OLk http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.gz && \
tar -xvz -f ffmpeg-${FFMPEG_VERSION}.tar.gz && \
rm ffmpeg-${FFMPEG_VERSION}.tar.gz
COPY ./contrib /contrib
RUN cd /dist/ffmpeg-${FFMPEG_VERSION} && \
patch -p1 < /contrib/ffmpeg-jsonstats.patch && \
./configure \
--extra-version=datarhei \
--prefix="${SRC}" \
--extra-libs="-lpthread -lxml2 -lm -lz -lsupc++ -lstdc++ -lssl -lcrypto -lz -lc -ldl" \
--enable-nonfree \
--enable-gpl \
--enable-version3 \
--enable-postproc \
--enable-static \
--enable-openssl \
--enable-libxml2 \
--enable-libfreetype \
--enable-libsrt \
--enable-libx264 \
--enable-libx265 \
--enable-libvpx \
--enable-libmp3lame \
--enable-libopus \
--enable-libvorbis \
--disable-ffplay \
--disable-debug \
--disable-doc \
--disable-shared && \
make -j$(nproc) && \
make install
# export shared ffmpeg libs
RUN mkdir -p /ffmpeg/lib && \
cp \
/usr/lib/libfreetype.so.6 \
/usr/lib/libbrotlidec.so.1 \
/usr/lib/libbrotlicommon.so.1 \
/usr/lib/libbz2.so.1 \
/usr/lib/libpng16.so.16 \
/usr/lib/libxml2.so.2 \
/usr/lib/liblzma.so.5 \
/usr/lib/libsrt.so.1 \
/usr/lib/libx264.so.163 \
/usr/lib/libx265.so.199 \
/usr/lib/libvpx.so.6 \
/usr/lib/libmp3lame.so.0 \
/usr/lib/libopus.so.0 \
/usr/lib/libvorbis.so.0 \
/usr/lib/libogg.so.0 \
/usr/lib/libvorbisenc.so.2 \
/usr/lib/libgcc_s.so.1 \
/usr/lib/libstdc++.so.6 \
/ffmpeg/lib
FROM $ALPINE_IMAGE as final
COPY --from=builder /usr/bin/ffmpeg /usr/bin/ffmpeg
COPY --from=builder /ffmpeg/lib/* /usr/lib/
RUN apk add --no-cache \
ca-certificates \
tzdata && \
ffmpeg -buildconf
WORKDIR /tmp
ENTRYPOINT ["/usr/bin/ffmpeg"]
CMD ["-version"]

145
Dockerfile.alpine.rpi Normal file
View File

@@ -0,0 +1,145 @@
ARG ALPINE_IMAGE=alpine:3.15
FROM $ALPINE_IMAGE as builder
ARG RPI_VERSION=0.20200813-r0
ARG FREETYPE_VERSION=2.11.1-r1
ARG XML2_VERSION=2.9.13-r0
ARG SRT_VERSION=1.4.2-r1
ARG X264_VERSION=20210613-r0
ARG X265_VERSION=3.5-r0
ARG VPX_VERSION=1.10.0-r0
ARG LAME_VERSION=3.100-r0
ARG OPUS_VERSION=1.3.1-r1
ARG VORBIS_VERSION=1.3.7-r0
ARG ALSA_VERSION=1.2.5.1-r1
ARG FFMPEG_VERSION=4.4.2
ENV PKG_CONFIG_PATH=/usr/lib/pkgconfig \
SRC=/usr
# install build packages
RUN apk add -U \
autoconf \
automake \
bash \
binutils \
bzip2 \
ca-certificates \
cmake \
coreutils \
curl \
diffutils \
g++ \
gcc \
libgcc \
libssl1.1 \
libtool \
linux-headers \
make \
musl-dev \
nasm \
openssl-dev \
patch \
tar \
zlib-dev
# install shared ffmpeg libs
RUN apk add \
raspberrypi-dev=${RPI_VERSION} \
raspberrypi-libs=${RPI_VERSION} \
libxml2-dev=${XML2_VERSION} \
freetype-dev=${FREETYPE_VERSION} \
libsrt-dev=${SRT_VERSION} \
x264-dev=${X264_VERSION} \
x265-dev=${X265_VERSION} \
libvpx-dev=${VPX_VERSION} \
lame-dev=${LAME_VERSION} \
opus-dev=${OPUS_VERSION} \
libvorbis-dev=${VORBIS_VERSION} \
alsa-lib-dev=${ALSA_VERSION}
# install and patch ffmpeg
RUN mkdir -p /dist && cd /dist && \
curl -OLk http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.gz && \
tar -xvz -f ffmpeg-${FFMPEG_VERSION}.tar.gz && \
rm ffmpeg-${FFMPEG_VERSION}.tar.gz
COPY ./contrib /contrib
RUN cd /dist/ffmpeg-${FFMPEG_VERSION} && \
patch -p1 < /contrib/ffmpeg-jsonstats.patch && \
./configure \
--extra-version=datarhei \
--prefix="${SRC}" \
--extra-libs="-lpthread -lxml2 -lm -lz -lsupc++ -lstdc++ -lssl -lcrypto -lz -lc -ldl" \
--enable-nonfree \
--enable-gpl \
--enable-version3 \
--enable-postproc \
--enable-static \
--enable-openssl \
--enable-libxml2 \
--enable-omx \
--enable-omx-rpi \
--enable-mmal \
--enable-v4l2_m2m \
--enable-alsa \
--enable-libfreetype \
--enable-libsrt \
--enable-libx264 \
--enable-libx265 \
--enable-libvpx \
--enable-libmp3lame \
--enable-libopus \
--enable-libvorbis \
--disable-ffplay \
--disable-debug \
--disable-doc \
--disable-shared && \
make -j$(nproc) && \
make install
# export shared ffmpeg libs
RUN mkdir -p /ffmpeg/lib && \
cp \
/usr/lib/libfreetype.so.6 \
/usr/lib/libbrotlidec.so.1 \
/usr/lib/libbrotlicommon.so.1 \
/usr/lib/libbz2.so.1 \
/usr/lib/libpng16.so.16 \
/usr/lib/libxml2.so.2 \
/usr/lib/liblzma.so.5 \
/usr/lib/libsrt.so.1 \
/usr/lib/libx264.so.163 \
/usr/lib/libx265.so.199 \
/usr/lib/libvpx.so.6 \
/usr/lib/libmp3lame.so.0 \
/usr/lib/libopus.so.0 \
/usr/lib/libvorbis.so.0 \
/usr/lib/libogg.so.0 \
/usr/lib/libvorbisenc.so.2 \
/usr/lib/libgcc_s.so.1 \
/usr/lib/libstdc++.so.6 \
/ffmpeg/lib
FROM $ALPINE_IMAGE as final
COPY --from=builder /usr/bin/ffmpeg /usr/bin/ffmpeg
COPY --from=builder /ffmpeg/lib/* /usr/lib/
ARG RPI_VERSION=0.20200813-r0
RUN apk add --no-cache \
ca-certificates \
tzdata \
alsa-lib \
raspberrypi-libs=${RPI_VERSION} && \
echo "/opt/vc/lib:/usr/local/lib:/usr/lib:/lib" > /etc/ld-musl-armhf.path && \
ffmpeg -buildconf
WORKDIR /tmp
ENTRYPOINT ["/usr/bin/ffmpeg"]
CMD ["-version"]

172
Dockerfile.alpine.vaapi Normal file
View File

@@ -0,0 +1,172 @@
ARG ALPINE_IMAGE=alpine:3.15
FROM $ALPINE_IMAGE as builder
ARG LIBAV_VERSION=2.14.0-r0
ARG LIBVDPAU_VERSION=1.5-r0
ARG MESA_VA_GALLIUM_VERSION=21.3.8-r1
ARG MESA_VDPAU_GALLIUM_VERSION=21.3.8-r1
ARG LIBVA_VDPAU_DRIVER_VERSION=0.7.4-r2
ARG INTEL_GMMLIB_VERSION=22.1.2-r0
ARG INTEL_MEDIA_DRIVER_VERSION=22.4.1-r0
ARG INTEL_MEDIA_SDK_VERSION=22.4.1-r0
ARG INTEL_VAAPI_DRIVER=2.4.1-r0
ARG FREETYPE_VERSION=2.11.1-r1
ARG SRT_VERSION=1.4.2-r1
ARG X264_VERSION=20210613-r0
ARG X265_VERSION=3.5-r0
ARG VPX_VERSION=1.10.0-r0
ARG LAME_VERSION=3.100-r0
ARG OPUS_VERSION=1.3.1-r1
ARG VORBIS_VERSION=1.3.7-r0
ARG FFMPEG_VERSION=4.4.1
ENV PKG_CONFIG_PATH=/usr/lib/pkgconfig \
SRC=/usr
# install build packages
RUN apk add --update \
autoconf \
automake \
bash \
binutils \
bzip2 \
ca-certificates \
cmake \
coreutils \
curl \
diffutils \
g++ \
gcc \
libgcc \
libssl1.1 \
libtool \
linux-headers \
make \
musl-dev \
nasm \
openssl-dev \
patch \
tar \
zlib-dev
# install shared ffmpeg libs
RUN apk add -U \
freetype-dev=${FREETYPE_VERSION} \
libsrt-dev=${SRT_VERSION} \
x264-dev=${X264_VERSION} \
x265-dev=${X265_VERSION} \
libvpx-dev=${VPX_VERSION} \
lame-dev=${LAME_VERSION} \
opus-dev=${OPUS_VERSION} \
libvorbis-dev=${VORBIS_VERSION}
# install shared ffmpeg libs
RUN echo http://dl-2.alpinelinux.org/alpine/edge/main >> /etc/apk/repositories
RUN apk add -U \
libva-dev=${LIBAV_VERSION} \
libvdpau-dev=${LIBVDPAU_VERSION} \
libva-intel-driver=${INTEL_VAAPI_DRIVER} \
mesa-va-gallium=${MESA_VA_GALLIUM_VERSION} \
mesa-vdpau-gallium=${MESA_VDPAU_GALLIUM_VERSION}
# install shared ffmpeg libs
RUN echo http://dl-2.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories
RUN apk add -U \
intel-gmmlib-dev=${INTEL_GMMLIB_VERSION} \
intel-media-driver-dev=${INTEL_MEDIA_DRIVER_VERSION} \
intel-media-sdk-dev=${INTEL_MEDIA_SDK_VERSION}
# install shared ffmpeg libs
RUN echo http://dl-2.alpinelinux.org/alpine/edge/testing >> /etc/apk/repositories
RUN apk add -U \
libva-vdpau-driver=${LIBVA_VDPAU_DRIVER_VERSION}
# install and patch ffmpeg
RUN mkdir -p /dist && cd /dist && \
curl -OLk http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.gz && \
tar -xvz -f ffmpeg-${FFMPEG_VERSION}.tar.gz && \
rm ffmpeg-${FFMPEG_VERSION}.tar.gz
COPY ./contrib /contrib
RUN cd /dist/ffmpeg-${FFMPEG_VERSION} && \
patch -p1 < /contrib/ffmpeg-jsonstats.patch && \
./configure \
--extra-version=datarhei \
--prefix="${SRC}" \
--extra-libs="-lpthread -lm -lz -lsupc++ -lstdc++ -lssl -lcrypto -lz -lc -ldl" \
--enable-nonfree \
--enable-gpl \
--enable-version3 \
--enable-static \
--enable-openssl \
--enable-libfreetype \
--enable-libsrt \
--enable-libx264 \
--enable-libx265 \
--enable-libvpx \
--enable-libmp3lame \
--enable-libopus \
--enable-libvorbis \
--enable-libmfx \
--enable-vaapi \
--enable-vdpau \
--disable-ffplay \
--disable-debug \
--disable-doc \
--disable-shared && \
make -j$(nproc) && \
make install
# export shared ffmpeg libs
RUN mkdir -p /ffmpeg/lib && \
cp \
/usr/lib/libfreetype.so.6 \
/usr/lib/libbrotlidec.so.1 \
/usr/lib/libbrotlicommon.so.1 \
/usr/lib/libbz2.so.1 \
/usr/lib/libpng16.so.16 \
/usr/lib/libsrt.so.1 \
/usr/lib/libx264.so.163 \
/usr/lib/libx265.so.199 \
/usr/lib/libvpx.so.6 \
/usr/lib/libmp3lame.so.0 \
/usr/lib/libopus.so.0 \
/usr/lib/libvorbis.so.0 \
/usr/lib/libogg.so.0 \
/usr/lib/libvorbisenc.so.2 \
/usr/lib/libgcc_s.so.1 \
/usr/lib/libstdc++.so.6 \
/usr/lib/libxcb.so.1 \
/usr/lib/libXau.so.6 \
/usr/lib/libXdmcp.so.6 \
/usr/lib/libbsd.so.0 \
/usr/lib/libmd.so.0 \
/usr/lib/libxcb-shm.so.0 \
/usr/lib/libxcb-shape.so.0 \
/usr/lib/libxcb-xfixes.so.0 \
/usr/lib/libva.so.2 \
/usr/lib/libmfx.so.1 \
/usr/lib/libva-drm.so.2 \
/usr/lib/libdrm.so.2 \
/usr/lib/libvdpau.so.1 \
/usr/lib/libXext.so.6 \
/usr/lib/libX11.so.6 \
/ffmpeg/lib
FROM $ALPINE_IMAGE as final
COPY --from=builder /usr/bin/ffmpeg /usr/bin/ffmpeg
COPY --from=builder /ffmpeg/lib/* /usr/lib/
RUN apk add --no-cache \
ca-certificates \
tzdata && \
ffmpeg -buildconf
WORKDIR /tmp
ENTRYPOINT ["/usr/bin/ffmpeg"]
CMD ["-version"]

View File

@@ -1,101 +0,0 @@
ARG ALPINE_IMAGE=alpine:latest
FROM $ALPINE_IMAGE as builder
ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig \
SRC=/usr/local
ARG FDKAAC_VERSION=0.1.5
ARG LAME_VERSION=3.99.5
ARG X264_VERSION=20180607-2245-stable
ARG FFMPEG_VERSION=2.8.14
RUN buildDeps="autoconf \
automake \
bash \
binutils \
bzip2 \
cmake \
curl \
coreutils \
g++ \
gcc \
gnupg \
libtool \
make \
python \
openssl-dev \
tar \
yasm \
zlib-dev" && \
export MAKEFLAGS="-j$(($(grep -c ^processor /proc/cpuinfo) + 1))" && \
apk update && \
apk upgrade && \
apk add --update ${buildDeps} libgcc libstdc++ ca-certificates libssl1.0
RUN DIR=$(mktemp -d) && cd ${DIR} && \
echo "http://ftp.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-${X264_VERSION}.tar.bz2" && \
curl -sL http://ftp.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-${X264_VERSION}.tar.bz2 | \
tar -jx --strip-components=1 && \
./configure --prefix="${SRC}" --bindir="${SRC}/bin" --enable-shared && \
make && \
make install
RUN DIR=$(mktemp -d) && cd ${DIR} && \
LAME_GIT_VERSION=$(echo ${LAME_VERSION} | tr '.' '_') && \
curl -sL https://github.com/rbrito/lame/archive/RELEASE__${LAME_GIT_VERSION}.tar.gz | \
tar -zx --strip-components=1 && \
cp /usr/share/automake-*/config.guess config.guess && \
./configure --prefix="${SRC}" --bindir="${SRC}/bin" --disable-static --enable-nasm --datarootdir="${DIR}" && \
make && \
make install
RUN DIR=$(mktemp -d) && cd ${DIR} && \
curl -sL https://github.com/mstorsjo/fdk-aac/archive/v${FDKAAC_VERSION}.tar.gz | \
tar -zx --strip-components=1 && \
autoreconf -fiv && \
./configure --prefix="${SRC}" --disable-static --datadir="${DIR}" && \
make && \
make install
RUN DIR=$(mktemp -d) && cd ${DIR} && \
curl -sLO http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.gz && \
tar -zx --strip-components=1 -f ffmpeg-${FFMPEG_VERSION}.tar.gz && \
./configure \
--bindir="${SRC}/bin" \
--extra-libs=-ldl \
--extra-cflags="-I${SRC}/include" \
--extra-ldflags="-L${SRC}/lib" \
--extra-libs=-ldl \
--prefix="${SRC}" \
--enable-nonfree \
--enable-gpl \
--enable-version3 \
--enable-avresample \
--enable-libmp3lame \
--enable-libx264 \
--enable-openssl \
--enable-postproc \
--enable-small \
--enable-libfdk_aac \
--enable-shared \
--disable-debug \
--disable-doc \
--disable-static \
--disable-ffserver && \
make && \
make install && \
hash -r
FROM $ALPINE_IMAGE
COPY --from=builder /usr/local/bin/ffmpeg /usr/local/bin/ffmpeg
COPY --from=builder /usr/local/bin/ffprobe /usr/local/bin/ffprobe
COPY --from=builder /usr/local/lib /usr/local/lib
RUN apk add --update --no-cache libssl1.0 && \
ffmpeg -buildconf
CMD ["--help"]
ENTRYPOINT ["ffmpeg"]
WORKDIR /tmp/ffmpeg

View File

@@ -1,100 +0,0 @@
ARG ALPINE_IMAGE=alpine:latest
FROM $ALPINE_IMAGE as builder
ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig \
SRC=/usr/local
ARG FDKAAC_VERSION=0.1.5
ARG LAME_VERSION=3.99.5
ARG X264_VERSION=20180607-2245-stable
ARG FFMPEG_VERSION=4.0
RUN buildDeps="autoconf \
automake \
bash \
binutils \
bzip2 \
cmake \
curl \
coreutils \
g++ \
gcc \
gnupg \
libtool \
make \
python \
openssl-dev \
tar \
yasm \
zlib-dev" && \
export MAKEFLAGS="-j$(($(grep -c ^processor /proc/cpuinfo) + 1))" && \
apk update && \
apk upgrade && \
apk add --update ${buildDeps} libgcc libstdc++ ca-certificates libssl1.0
RUN DIR=$(mktemp -d) && cd ${DIR} && \
echo "http://ftp.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-${X264_VERSION}.tar.bz2" && \
curl -sL http://ftp.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-${X264_VERSION}.tar.bz2 | \
tar -jx --strip-components=1 && \
./configure --prefix="${SRC}" --bindir="${SRC}/bin" --enable-shared && \
make && \
make install
RUN DIR=$(mktemp -d) && cd ${DIR} && \
LAME_GIT_VERSION=$(echo ${LAME_VERSION} | tr '.' '_') && \
curl -sL https://github.com/rbrito/lame/archive/RELEASE__${LAME_GIT_VERSION}.tar.gz | \
tar -zx --strip-components=1 && \
cp /usr/share/automake-*/config.guess config.guess && \
./configure --prefix="${SRC}" --bindir="${SRC}/bin" --disable-static --enable-nasm --datarootdir="${DIR}" && \
make && \
make install
RUN DIR=$(mktemp -d) && cd ${DIR} && \
curl -sL https://github.com/mstorsjo/fdk-aac/archive/v${FDKAAC_VERSION}.tar.gz | \
tar -zx --strip-components=1 && \
autoreconf -fiv && \
./configure --prefix="${SRC}" --disable-static --datadir="${DIR}" && \
make && \
make install
RUN DIR=$(mktemp -d) && cd ${DIR} && \
curl -sLO http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.gz && \
tar -zx --strip-components=1 -f ffmpeg-${FFMPEG_VERSION}.tar.gz && \
./configure \
--bindir="${SRC}/bin" \
--extra-libs=-ldl \
--extra-cflags="-I${SRC}/include" \
--extra-ldflags="-L${SRC}/lib" \
--extra-libs=-ldl \
--prefix="${SRC}" \
--enable-nonfree \
--enable-gpl \
--enable-version3 \
--enable-avresample \
--enable-libmp3lame \
--enable-libx264 \
--enable-openssl \
--enable-postproc \
--enable-small \
--enable-libfdk_aac \
--enable-shared \
--disable-debug \
--disable-doc \
--disable-static && \
make && \
make install && \
hash -r
FROM $ALPINE_IMAGE
COPY --from=builder /usr/local/bin/ffmpeg /usr/local/bin/ffmpeg
COPY --from=builder /usr/local/bin/ffprobe /usr/local/bin/ffprobe
COPY --from=builder /usr/local/lib /usr/local/lib
RUN apk add --update --no-cache libssl1.0 && \
ffmpeg -buildconf
CMD ["--help"]
ENTRYPOINT ["ffmpeg"]
WORKDIR /tmp/ffmpeg

126
README.md
View File

@@ -1,95 +1,43 @@
# FFmpeg
FFmpeg Development Image for H.264-Processing (e.g. RTMP, HLS)
* Alpine Linux (3.7)
* FFmpeg
* Docker-Images for AMD64/X86, ARMHF (e.g. Raspberry-Pi) and AARCH64 (e.g. Pine64)
# FFmpeg Base
FFmpeg base image for [datarhei/core](https://github.com/datarhei/core).
## Config:
```sh
./configure
--enable-nonfree
--enable-gpl
--enable-version3
--enable-avresample
--enable-libmp3lame
--enable-libx264
--enable-openssl
--enable-postproc
--enable-small
--enable-libfdk_aac
--enable-shared
--disable-debug
--disable-doc
--disable-static
--disable-ffserver (removed in v4)
--enable-libfreetype
--enable-libsrt
--enable-libx264
--enable-libx265
--enable-libvpx
--enable-libmp3lame
--enable-libopus
--enable-libvorbis
```
*Additional informations can be found in the Dockerfiles.*
## Patches:
- JSON-Stats (expands progress data per file in json format)
## Images and Plattforms:
Dockerimage | OS | Plattform | GPU
-----------|----|-----------|----
docker.io/datarhei/ffmpeg:latest | Alpine 3.15 | linux/amd64, linux/arm64, linux/arm/v7 | -
docker.io/datarhei/ffmpeg:rpi-latest | Alpine 3.15 | Raspberry Pi (linux/arm/v7) | MMAL/OMX
docker.io/datarhei/ffmpeg:vaapi-latest | Alpine 3.15 | linux/amd64 | Intel VAAPI
## Testing
```sh
$ docker buildx create builder
$ docker buildx use builder
$ docker buildx inspect builder --bootstrap
$ docker buildx build --platform linux/amd64 linux/arm64 linux/arm/v7 -f Dockerfile -t ffmpeg:dev --load .
$ docker buildx rm builder
```
* `4.0.1`, `4.0`, `4` (docker pull `datarhei/ffmpeg:4.0`)
* `4.0.1-armhf`, `4.0-armhf`, `4-armhf` (docker pull `datarhei/ffmpeg:4.0-armhf`)
* `4.0.1-aarch64`, `4.0-aarch64`, `4-aarch64` (docker pull `datarhei/ffmpeg:4.0-aarch64`)
* `3.4.2`, `3.4`, `3` (docker pull `datarhei/ffmpeg:3.4`)
* `3.3.7`, `3.3` (docker pull `datarhei/ffmpeg:3.3`)
* `3.3.7-armhf`, `3.3-armhf`, `3-armhf` (docker pull `datarhei/ffmpeg:3.3-armhf`)
* `3.3.7-aarch64`, `3.3-aarch64`, `3-aarch64` (docker pull `datarhei/ffmpeg:3.3-aarch64`)
* `3.2.10`, `3.2` (docker pull `datarhei/ffmpeg:3.2`)
* `3.2.10-armhf`, `3.2-armhf` (docker pull `datarhei/ffmpeg:3.2-armhf`)
* `3.2.10-aarch64`, `3.2-aarch64` (docker pull `datarhei/ffmpeg:3.2-aarch64`)
* `3.1.11`, `3.1` (docker pull `datarhei/ffmpeg:3.1`)
* `3.1.11-armhf`, `3.1-armhf` (docker pull `datarhei/ffmpeg:3.1-armhf`)
* `3.1.11-aarch64`, `3.1-aarch64` (docker pull `datarhei/ffmpeg:3.1-aarch64`)
* `3.0.11`, `3.0` (docker pull `datarhei/ffmpeg:3.0`)
* `3.0.11-armhf`, `3.0-armhf` (docker pull `datarhei/ffmpeg:3.0-armhf`)
* `3.0.11-aarch64`, `3.0-aarch64` (docker pull `datarhei/ffmpeg:3.0-aarch64`)
* `2.8.14`, `2.8`, `2` (docker pull `datarhei/ffmpeg:2.8`)
* `2.8.14-armhf`, `2.8-armhf`, `2-armhf` (docker pull `datarhei/ffmpeg:2.8-armhf`)
* `2.8.14-aarch64`, `2.8-aarch64`, `2-aarch64` (docker pull `datarhei/ffmpeg:2.8-aarch64`)
## Known problems:
The libraries are currently not compiled due to errors caused by Docker virtualisation.
## Build your own Image
## Feature requests:
Please create an issue with your use case and all the requirements.
#### FFmpeg 4+
```sh
docker build -f Dockerfile_FFmpeg_4 -t ffmpeg:amd64 \
--build-arg ALPINE_IMAGE=alpine:latest \
--build-arg FFMPEG_VERSION=4.0 \
--build-arg FDKAAC_VERSION=0.1.5 \
--build-arg LAME_VERSION=3.99.5 \
--build-arg X264_VERSION=20180607-2245-stable .
docker build -f Dockerfile_FFmpeg_4 -t ffmpeg:armhf \
--build-arg ALPINE_IMAGE=resin/armhf-alpine:latest \
--build-arg FFMPEG_VERSION=4.0 \
--build-arg FDKAAC_VERSION=0.1.5 \
--build-arg LAME_VERSION=3.99.5 \
--build-arg X264_VERSION=20180607-2245-stable .
docker build -f Dockerfile_FFmpeg_4 -t ffmpeg:aarch64 \
--build-arg ALPINE_IMAGE=resin/aarch64-alpine:latest \
--build-arg FFMPEG_VERSION=4.0 \
--build-arg FDKAAC_VERSION=0.1.5 \
--build-arg LAME_VERSION=3.99.5 \
--build-arg X264_VERSION=20180607-2245-stable .
```
#### FFmpeg 2-3
```sh
docker build -f Dockerfile_FFmpeg_2-3 -t ffmpeg:amd64 \
--build-arg ALPINE_IMAGE=alpine:latest \
--build-arg FFMPEG_VERSION=3.3.7 \
--build-arg FDKAAC_VERSION=0.1.5 \
--build-arg LAME_VERSION=3.99.5 \
--build-arg X264_VERSION=20180607-2245-stable .
docker build -f Dockerfile_FFmpeg_2-3 -t ffmpeg:armhf \
--build-arg ALPINE_IMAGE=resin/armhf-alpine:latest \
--build-arg FFMPEG_VERSION=3.3.7 \
--build-arg FDKAAC_VERSION=0.1.5 \
--build-arg LAME_VERSION=3.99.5 \
--build-arg X264_VERSION=20180607-2245-stable .
docker build -f Dockerfile_FFmpeg_2-3 -t ffmpeg:aarch64 \
--build-arg ALPINE_IMAGE=resin/aarch64-alpine:latest \
--build-arg FFMPEG_VERSION=3.3.7 \
--build-arg FDKAAC_VERSION=0.1.5 \
--build-arg LAME_VERSION=3.99.5 \
--build-arg X264_VERSION=20180607-2245-stable .
```
## Licence
LGPL-licensed with optional components licensed under GPL. Please refer to the LICENSE file for detailed information.

View File

@@ -0,0 +1,440 @@
From df7dfb5351f77a672de5a6d613678888f560afcb Mon Sep 17 00:00:00 2001
From: Ingo Oppermann <ingo@oppermann.ch>
Date: Tue, 1 Jun 2021 08:53:52 +0200
Subject: [PATCH v20] JSON progress report (ffmpeg 4.4)
---
fftools/ffmpeg.c | 262 +++++++++++++++++++++++++++++++++++++++++--
fftools/ffmpeg.h | 1 +
fftools/ffmpeg_opt.c | 69 ++++++++++++
3 files changed, 322 insertions(+), 10 deletions(-)
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 46bb014..e5e00c9 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -1699,12 +1699,11 @@ static void print_final_stats(int64_t total_size)
}
}
-static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time)
+static void print_default_report(int is_last_report, int64_t timer_start, int64_t cur_time)
{
AVBPrint buf, buf_script;
OutputStream *ost;
- AVFormatContext *oc;
- int64_t total_size;
+ int64_t total_size = 0;
AVCodecContext *enc;
int frame_number, vid, i;
double bitrate;
@@ -1733,13 +1732,6 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
t = (cur_time-timer_start) / 1000000.0;
-
- oc = output_files[0]->ctx;
-
- total_size = avio_size(oc->pb);
- if (total_size <= 0) // FIXME improve avio_size() so it works with non seekable output too
- total_size = avio_tell(oc->pb);
-
vid = 0;
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
@@ -1822,6 +1814,9 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
if (is_last_report)
nb_frames_drop += ost->last_dropped;
+
+ total_size += ost->data_size;
+ total_size += ost->enc_ctx->extradata_size;
}
secs = FFABS(pts) / AV_TIME_BASE;
@@ -1909,6 +1904,251 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
print_final_stats(total_size);
}
+static void print_json_report(int is_last_report, int64_t timer_start, int64_t cur_time)
+{
+ AVBPrint buf;
+ InputStream *ist;
+ OutputStream *ost;
+ uint64_t stream_size, total_size = 0;
+ AVCodecContext *enc, *dec;
+ int i, j;
+ uint64_t first_vid, first_frame_number = 0, first_packet_number = 0;
+ double speed;
+ int64_t min_pts = INT64_MIN + 1, pts = INT64_MIN + 1;
+ static int64_t last_time = -1;
+ int hours, mins, secs, us;
+ const char *hours_sign;
+ float t, q;
+ float first_q = -1;
+
+ if (!print_jsonstats && !is_last_report && !progress_avio) {
+ return;
+ }
+
+ if (!is_last_report) {
+ if (last_time == -1) {
+ last_time = cur_time;
+ return;
+ }
+ if ((cur_time - last_time) < 500000) {
+ return;
+ }
+ last_time = cur_time;
+ }
+
+ t = (cur_time-timer_start) / 1000000.0;
+
+ av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+
+ av_bprintf(&buf, "ffmpeg.progress:{");
+ av_bprintf(&buf, "\"inputs\":[");
+ for (i = 0; i < nb_input_files; i++) {
+ InputFile *f = input_files[i];
+
+ for (j = 0; j < f->nb_streams; j++) {
+ ist = input_streams[f->ist_index + j];
+ dec = ist->dec_ctx;
+
+ av_bprintf(&buf, "{");
+ av_bprintf(&buf, "\"index\":%d,\"stream\":%d,", i, j);
+
+ av_bprintf(&buf, "\"frame\":%"PRIu64",\"packet\":%"PRIu64",", ist->frames_decoded == 0 ? ist->nb_packets : ist->frames_decoded, ist->nb_packets);
+
+ av_bprintf(&buf, "\"size_kb\":%.0f", ist->data_size / 1024.0);
+
+ if(i == (nb_input_files - 1) && j == (f->nb_streams - 1)) {
+ av_bprintf(&buf, "}");
+ }
+ else {
+ av_bprintf(&buf, "},");
+ }
+ }
+ }
+
+ av_bprintf(&buf, "],");
+
+ // check libavcodec/utils.c:avcodec_string
+ // check libavformat/dump.c:av_dump_format
+ // check libavcodec/avcodec.h:struct AVCodec and struct AVCodecContext
+ // check libavformat/avformat.h:struct AVStream
+ // check fftools/ffmpeg.h:struct OutputStream
+
+ first_vid = 1;
+
+ av_bprintf(&buf, "\"outputs\":[");
+ for (i = 0; i < nb_output_streams; i++) {
+ OutputFile *f;
+ q = -1;
+ ost = output_streams[i];
+ f = output_files[ost->file_index];
+ enc = ost->enc_ctx;
+ if (!ost->stream_copy) {
+ q = ost->quality / (float) FF_QP2LAMBDA;
+ }
+
+ av_bprintf(&buf, "{");
+ av_bprintf(&buf, "\"index\":%d,\"stream\":%d,", ost->file_index, ost->index);
+
+ av_bprintf(&buf, "\"frame\":%"PRIu64",\"packet\":%"PRIu64",", ost->frames_encoded == 0 ? ost->packets_written : ost->frames_encoded, ost->packets_written);
+
+ if(enc->codec_type == AVMEDIA_TYPE_VIDEO) {
+ av_bprintf(&buf, "\"q\":%.1f,", q);
+
+ if(first_vid == 1) {
+ first_frame_number = ost->frames_encoded == 0 ? ost->packets_written : ost->frames_encoded;
+ first_packet_number = ost->packets_written;
+ first_q = q;
+
+ first_vid = 0;
+ }
+ }
+
+ /* compute min output value */
+ pts = INT64_MIN + 1;
+ if (av_stream_get_end_pts(ost->st) != AV_NOPTS_VALUE) {
+ pts = FFMAX(pts, av_rescale_q(av_stream_get_end_pts(ost->st), ost->st->time_base, AV_TIME_BASE_Q));
+ min_pts = FFMAX(min_pts, av_rescale_q(av_stream_get_end_pts(ost->st), ost->st->time_base, AV_TIME_BASE_Q));
+ }
+
+ if (is_last_report) {
+ nb_frames_drop += ost->last_dropped;
+ }
+
+ stream_size = ost->data_size + ost->enc_ctx->extradata_size;
+ total_size += stream_size;
+
+ av_bprintf(&buf, "\"size_kb\":%.0f", stream_size / 1024.0);
+
+ if(i == (nb_output_streams - 1)) {
+ av_bprintf(&buf, "}");
+ }
+ else {
+ av_bprintf(&buf, "},");
+ }
+ }
+
+ av_bprintf(&buf, "],");
+
+ av_bprintf(&buf, "\"frame\":%"PRIu64",\"packet\":%"PRIu64",\"q\":%.1f,", first_frame_number, first_packet_number, first_q);
+
+ av_bprintf(&buf, "\"size_kb\":%.0f,", total_size / 1024.0);
+
+ secs = FFABS(min_pts) / AV_TIME_BASE;
+ us = FFABS(min_pts) % AV_TIME_BASE;
+ mins = secs / 60;
+ secs %= 60;
+ hours = mins / 60;
+ mins %= 60;
+ hours_sign = (min_pts < 0) ? "-" : "";
+
+ if(min_pts != AV_NOPTS_VALUE) {
+ av_bprintf(&buf, "\"time\":\"%s%dh%dm%d.%ds\",", hours_sign, hours, mins, secs, (100 * us) / AV_TIME_BASE);
+ }
+
+ speed = t != 0.0 ? (double)min_pts / AV_TIME_BASE / t : -1;
+ av_bprintf(&buf, "\"speed\":%.3g,", speed);
+
+ av_bprintf(&buf, "\"dup\":%d,\"drop\":%d", nb_frames_dup, nb_frames_drop);
+ av_bprintf(&buf, "}");
+
+ if (print_jsonstats || is_last_report) {
+ fprintf(stderr, "%s\n", buf.str);
+ fflush(stderr);
+ }
+
+ av_bprint_finalize(&buf, NULL);
+}
+
+static void print_json_outputs() {
+ static int ost_all_initialized = 0;
+ int i;
+ int nb_initialized = 0;
+
+ if(print_jsonstats != 1 && print_stats != -1) {
+ return;
+ }
+
+ if(ost_all_initialized == 1) {
+ return;
+ }
+
+ // check if all outputs are initialized
+ for (i = 0; i < nb_output_streams; i++) {
+ OutputStream *ost = output_streams[i];
+ if (ost->initialized) {
+ nb_initialized++;
+ }
+ }
+
+ // only if all outputs are initialized, dump the outputs
+ if (nb_initialized == nb_output_streams) {
+ ost_all_initialized = 1;
+
+ AVBPrint buf;
+
+ av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+
+ av_bprintf(&buf, "ffmpeg.outputs:[");
+ for (i = 0; i < nb_output_streams; i++) {
+ OutputStream *ost = output_streams[i];
+ OutputFile *f = output_files[ost->file_index];
+ AVFormatContext *ctx = f->ctx;
+ AVStream *st = ost->st;
+ AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
+ AVCodecContext *enc = ost->enc_ctx;
+
+ av_bprintf(&buf, "{");
+ av_bprintf(&buf, "\"url\":\"%s\",\"format\":\"%s\",\"index\":%d,\"stream\":%d,", ctx->url, ctx->oformat->name, ost->file_index, ost->index);
+ av_bprintf(&buf, "\"type\":\"%s\",\"codec\":\"%s\",\"coder\":\"%s\",\"bitrate_kbps\":%"PRId64",", media_type_string(enc->codec_type), avcodec_get_name(enc->codec_id), ost->stream_copy ? "copy" : (enc->codec ? enc->codec->name : "unknown"), enc->bit_rate / 1000);
+ av_bprintf(&buf, "\"duration_sec\":%f,\"language\":\"%s\"", 0.0, lang != NULL ? lang->value : "und");
+
+ if(enc->codec_type == AVMEDIA_TYPE_VIDEO) {
+ float fps = 0;
+ if(st->avg_frame_rate.den && st->avg_frame_rate.num) {
+ fps = av_q2d(st->avg_frame_rate);
+ }
+
+ av_bprintf(&buf, ",\"fps\":%f,\"pix_fmt\":\"%s\",\"width\":%d,\"height\":%d", fps, st->codecpar->format == AV_PIX_FMT_NONE ? "none" : av_get_pix_fmt_name(st->codecpar->format), st->codecpar->width, st->codecpar->height);
+ }
+ else if(enc->codec_type == AVMEDIA_TYPE_AUDIO) {
+ char layout[128];
+
+ av_get_channel_layout_string(layout, sizeof(layout), enc->channels, enc->channel_layout);
+
+ av_bprintf(&buf, ",\"sampling_hz\":%d,\"layout\":\"%s\",\"channels\":%d", enc->sample_rate, layout, enc->channels);
+ }
+
+ if(i == (nb_output_streams - 1)) {
+ av_bprintf(&buf, "}");
+ }
+ else {
+ av_bprintf(&buf, "},");
+ }
+ }
+
+ av_bprintf(&buf, "]");
+
+ fprintf(stderr, "%s\n", buf.str);
+
+ av_bprint_clear(&buf);
+ }
+
+ return;
+}
+
+static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time)
+{
+ if (!print_stats && !print_jsonstats && !is_last_report && !progress_avio)
+ return;
+
+ if (print_stats == 1) {
+ print_default_report(is_last_report, timer_start, cur_time);
+ }
+ else {
+ print_json_report(is_last_report, timer_start, cur_time);
+ }
+}
+
static void ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par)
{
// We never got any input. Set a fake format, which will
@@ -3048,6 +3288,8 @@ static int check_init_output_file(OutputFile *of, int file_index)
av_dump_format(of->ctx, file_index, of->ctx->url, 1);
nb_output_dumped++;
+ print_json_outputs();
+
if (sdp_filename || want_sdp)
print_sdp();
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 606f2af..e7e9a46 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -621,6 +621,7 @@ extern int debug_ts;
extern int exit_on_error;
extern int abort_on_flags;
extern int print_stats;
+extern int print_jsonstats;
extern int64_t stats_period;
extern int qp_hist;
extern int stdin_interaction;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 807e783..d48c02a 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -41,6 +41,7 @@
#include "libavutil/parseutils.h"
#include "libavutil/pixdesc.h"
#include "libavutil/pixfmt.h"
+#include "libavutil/bprint.h"
#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
@@ -167,6 +168,7 @@ int debug_ts = 0;
int exit_on_error = 0;
int abort_on_flags = 0;
int print_stats = -1;
+int print_jsonstats = -1;
int qp_hist = 0;
int stdin_interaction = 1;
int frame_bits_per_raw_sample = 0;
@@ -3348,6 +3350,69 @@ static int open_files(OptionGroupList *l, const char *inout,
return 0;
}
+static void print_json_inputs() {
+ if(print_jsonstats != 1 && print_stats != -1) {
+ return;
+ }
+
+ AVBPrint buf;
+ int i, j;
+
+ av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+
+ av_bprintf(&buf, "ffmpeg.inputs:[");
+ for (i = 0; i < nb_input_files; i++) {
+ InputFile *f = input_files[i];
+ AVFormatContext *ctx = f->ctx;
+
+ float duration = 0;
+ if (ctx->duration != AV_NOPTS_VALUE) {
+ duration = (float)(ctx->duration + (ctx->duration <= INT64_MAX - 5000 ? 5000 : 0)) / (float)AV_TIME_BASE;
+ }
+
+ for (j = 0; j < f->nb_streams; j++) {
+ InputStream *ist = input_streams[f->ist_index + j];
+ AVCodecContext *dec = ist->dec_ctx;
+ AVStream *st = ist->st;
+ AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
+
+ av_bprintf(&buf, "{");
+ av_bprintf(&buf, "\"url\":\"%s\",\"format\":\"%s\",\"index\":%d,\"stream\":%d,", ctx->url, ctx->iformat->name, i, j);
+ av_bprintf(&buf, "\"type\":\"%s\",\"codec\":\"%s\",\"coder\":\"%s\",\"bitrate_kbps\":%"PRId64",", media_type_string(dec->codec_type), avcodec_get_name(dec->codec_id), dec->codec ? dec->codec->name : "unknown", dec->bit_rate / 1000);
+ av_bprintf(&buf, "\"duration_sec\":%f,\"language\":\"%s\"", duration, lang != NULL ? lang->value : "und");
+
+ if(dec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ float fps = 0;
+ if(st->avg_frame_rate.den && st->avg_frame_rate.num) {
+ fps = av_q2d(st->avg_frame_rate);
+ }
+
+ av_bprintf(&buf, ",\"fps\":%f,\"pix_fmt\":\"%s\",\"width\":%d,\"height\":%d", fps, st->codecpar->format == AV_PIX_FMT_NONE ? "none" : av_get_pix_fmt_name(st->codecpar->format), st->codecpar->width, st->codecpar->height);
+ }
+ else if(dec->codec_type == AVMEDIA_TYPE_AUDIO) {
+ char layout[128];
+
+ av_get_channel_layout_string(layout, sizeof(layout), dec->channels, dec->channel_layout);
+
+ av_bprintf(&buf, ",\"sampling_hz\":%d,\"layout\":\"%s\",\"channels\":%d", dec->sample_rate, layout, dec->channels);
+ }
+
+ if(i == (nb_input_files - 1) && j == (f->nb_streams - 1)) {
+ av_bprintf(&buf, "}");
+ }
+ else {
+ av_bprintf(&buf, "},");
+ }
+ }
+ }
+
+ av_bprintf(&buf, "]");
+
+ fprintf(stderr, "%s\n", buf.str);
+
+ return;
+}
+
int ffmpeg_parse_options(int argc, char **argv)
{
OptionParseContext octx;
@@ -3381,6 +3446,8 @@ int ffmpeg_parse_options(int argc, char **argv)
goto fail;
}
+ print_json_inputs();
+
/* create the complex filtergraphs */
ret = init_complex_filters();
if (ret < 0) {
@@ -3584,6 +3651,8 @@ const OptionDef options[] = {
"enable automatic conversion filters globally" },
{ "stats", OPT_BOOL, { &print_stats },
"print progress report during encoding", },
+ { "jsonstats", OPT_BOOL, { &print_jsonstats },
+ "print JSON progress report during encoding", },
{ "stats_period", HAS_ARG | OPT_EXPERT, { .func_arg = opt_stats_period },
"set the period at which ffmpeg updates stats and -progress output", "time" },
{ "attach", HAS_ARG | OPT_PERFILE | OPT_EXPERT |
base-commit: 9dcc10e319b3533e0cef975c013b5fdf02e67ea2
--
2.24.3 (Apple Git-128)