mirror of
https://github.com/datarhei/ffmpeg
synced 2025-12-24 13:08:07 +08:00
Add ff v5.1.2
This commit is contained in:
3
.github/workflows/build_base_alpine-rpi.yaml
vendored
3
.github/workflows/build_base_alpine-rpi.yaml
vendored
@@ -58,7 +58,7 @@ jobs:
|
||||
context: .
|
||||
file: ./Dockerfile.alpine.rpi
|
||||
build-args: |
|
||||
ALPINE_IMAGE=${{ env.OS_NAME }}:${{ env.OS_VERSION }}
|
||||
BUILD_IMAGE=${{ env.OS_NAME }}:${{ env.OS_VERSION }}
|
||||
FREETYPE_VERSION=${{ env.FREETYPE_VERSION }}
|
||||
XML2_VERSION=${{ env.XML2_VERSION }}
|
||||
SRT_VERSION=${{ env.SRT_VERSION }}
|
||||
@@ -70,6 +70,7 @@ jobs:
|
||||
VORBIS_VERSION=${{ env.VORBIS_VERSION }}
|
||||
FFMPEG_VERSION=${{ env.FFMPEG_VERSION }}
|
||||
RPI_VERSION=${{ env.RPI_VERSION }}
|
||||
ALSA_VERSION=${{ env.ALSA_VERSION }}
|
||||
platforms: linux/arm64, linux/arm/v7
|
||||
push: true
|
||||
tags: |
|
||||
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
context: .
|
||||
file: ./Dockerfile.alpine.vaapi
|
||||
build-args: |
|
||||
ALPINE_IMAGE=${{ env.OS_NAME }}:${{ env.OS_VERSION }}
|
||||
BUILD_IMAGE=${{ env.OS_NAME }}:${{ env.OS_VERSION }}
|
||||
FREETYPE_VERSION=${{ env.FREETYPE_VERSION }}
|
||||
XML2_VERSION=${{ env.XML2_VERSION }}
|
||||
SRT_VERSION=${{ env.SRT_VERSION }}
|
||||
|
||||
2
.github/workflows/build_base_alpine.yaml
vendored
2
.github/workflows/build_base_alpine.yaml
vendored
@@ -51,7 +51,7 @@ jobs:
|
||||
context: .
|
||||
file: ./Dockerfile.alpine
|
||||
build-args: |
|
||||
ALPINE_IMAGE=${{ env.OS_NAME }}:${{ env.OS_VERSION }}
|
||||
BUILD_IMAGE=${{ env.OS_NAME }}:${{ env.OS_VERSION }}
|
||||
FREETYPE_VERSION=${{ env.FREETYPE_VERSION }}
|
||||
XML2_VERSION=${{ env.XML2_VERSION }}
|
||||
SRT_VERSION=${{ env.SRT_VERSION }}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# FFMPEG BASE PACKAGES
|
||||
OS_NAME=alpine
|
||||
OS_VERSION=3.15
|
||||
FREETYPE_VERSION=2.11.1-r2
|
||||
XML2_VERSION=2.9.14-r0
|
||||
SRT_VERSION=1.4.2-r1
|
||||
X264_VERSION=20210613-r0
|
||||
X265_VERSION=3.5-r0
|
||||
VPX_VERSION=1.10.0-r0
|
||||
OS_VERSION=3.16
|
||||
FREETYPE_VERSION=2.12.1-r0
|
||||
XML2_VERSION=2.9.14-r2
|
||||
SRT_VERSION=1.4.4-r0
|
||||
X264_VERSION=0.163_git20210613-r0
|
||||
X265_VERSION=3.5-r3
|
||||
VPX_VERSION=1.11.0-r1
|
||||
LAME_VERSION=3.100-r0
|
||||
OPUS_VERSION=1.3.1-r1
|
||||
VORBIS_VERSION=1.3.7-r0
|
||||
FBDEV_VERSION=0.5.0-r3
|
||||
V4L_VERSION=1.22.1-r1
|
||||
FFMPEG_VERSION=5.0.1
|
||||
FFMPEG_VERSION=5.1.2
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
# FFMPEG RPI PACKAGES
|
||||
RPI_VERSION=0.20200813-r0
|
||||
RPI_VERSION=0.20200813-r1
|
||||
ALSA_VERSION=1.2.7.2-r0
|
||||
|
||||
|
||||
@@ -1,10 +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
|
||||
MESA_VA_GALLIUM_VERSION=22.2.2-r2
|
||||
MESA_VDPAU_GALLIUM_VERSION=22.2.2-r2
|
||||
LIBVA_VDPAU_DRIVER_VERSION=0.7.4-r2
|
||||
INTEL_GMMLIB_VERSION=22.1.3-r0
|
||||
INTEL_MEDIA_DRIVER_VERSION=22.4.2-r0
|
||||
INTEL_MEDIA_SDK_VERSION=22.4.2-r0
|
||||
INTEL_MEDIA_DRIVER_VERSION=22.6.1-r0
|
||||
INTEL_MEDIA_SDK_VERSION=22.5.4-r0
|
||||
INTEL_VAAPI_DRIVER=2.4.1-r0
|
||||
132
Build.sh
Executable file
132
Build.sh
Executable file
@@ -0,0 +1,132 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -au
|
||||
|
||||
function source_env() {
|
||||
env=${1:-.env}
|
||||
[ ! -f "${env}" ] && { echo "Env file ${env} doesn't exist"; return 1; }
|
||||
eval $(sed -e '/^\s*$/d' -e '/^\s*#/d' -e 's/=/="/' -e 's/$/"/' -e 's/^/export /' "${env}")
|
||||
}
|
||||
|
||||
function build_default() {
|
||||
source_env ./Build.alpine.env
|
||||
# "--load" does not support multiple platforms
|
||||
# use "--push" to publish
|
||||
# --platform linux/amd64,linux/arm64,linux/arm/v7
|
||||
docker buildx build \
|
||||
--load \
|
||||
--build-arg BUILD_IMAGE=$OS_NAME:$OS_VERSION \
|
||||
--build-arg FREETYPE_VERSION=$FREETYPE_VERSION \
|
||||
--build-arg XML2_VERSION=$XML2_VERSION \
|
||||
--build-arg SRT_VERSION=$SRT_VERSION \
|
||||
--build-arg X264_VERSION=$X264_VERSION \
|
||||
--build-arg X265_VERSION=$X265_VERSION \
|
||||
--build-arg VPX_VERSION=$VPX_VERSION \
|
||||
--build-arg LAME_VERSION=$LAME_VERSION \
|
||||
--build-arg OPUS_VERSION=$OPUS_VERSION \
|
||||
--build-arg VORBIS_VERSION=$VORBIS_VERSION \
|
||||
--build-arg FFMPEG_VERSION=$FFMPEG_VERSION \
|
||||
--platform linux/amd64 \
|
||||
-f Dockerfile.alpine \
|
||||
-t datarhei/base:$OS_NAME-ffmpeg-$OS_VERSION-$FFMPEG_VERSION .
|
||||
}
|
||||
|
||||
function build_rpi() {
|
||||
source_env ./Build.alpine.env
|
||||
source_env ./Build.alpine.rpi.env
|
||||
# "--load" does not support multiple platforms
|
||||
# use "--push" to publish
|
||||
# --platform linux/arm64,linux/arm/v7
|
||||
docker buildx build \
|
||||
--load \
|
||||
--build-arg BUILD_IMAGE=$OS_NAME:$OS_VERSION \
|
||||
--build-arg FREETYPE_VERSION=$FREETYPE_VERSION \
|
||||
--build-arg XML2_VERSION=$XML2_VERSION \
|
||||
--build-arg SRT_VERSION=$SRT_VERSION \
|
||||
--build-arg X264_VERSION=$X264_VERSION \
|
||||
--build-arg X265_VERSION=$X265_VERSION \
|
||||
--build-arg VPX_VERSION=$VPX_VERSION \
|
||||
--build-arg LAME_VERSION=$LAME_VERSION \
|
||||
--build-arg OPUS_VERSION=$OPUS_VERSION \
|
||||
--build-arg VORBIS_VERSION=$VORBIS_VERSION \
|
||||
--build-arg FFMPEG_VERSION=$FFMPEG_VERSION \
|
||||
--build-arg RPI_VERSION=$RPI_VERSION \
|
||||
--build-arg ALSA_VERSION=$ALSA_VERSION \
|
||||
--platform linux/arm64 \
|
||||
-f Dockerfile.alpine.rpi \
|
||||
-t datarhei/base:$OS_NAME-ffmpeg-rpi-$OS_VERSION-$FFMPEG_VERSION .
|
||||
}
|
||||
|
||||
function build_cuda() {
|
||||
source_env ./Build.ubuntu.env
|
||||
source_env ./Build.ubuntu.cuda.env
|
||||
docker buildx build \
|
||||
--load \
|
||||
--build-arg BUILD_IMAGE=nvidia/cuda:$CUDA_VERSION-devel-$OS_NAME$OS_VERSION \
|
||||
--build-arg DEPLOY_IMAGE=nvidia/cuda:$CUDA_VERSION-runtime-$OS_NAME$OS_VERSION \
|
||||
--build-arg FFNVCODEC_VERSION=$FFNVCODEC_VERSION \
|
||||
--build-arg FREETYPE_VERSION=$FREETYPE_VERSION \
|
||||
--build-arg XML2_VERSION=$XML2_VERSION \
|
||||
--build-arg SRT_VERSION=$SRT_VERSION \
|
||||
--build-arg X264_VERSION=$X264_VERSION \
|
||||
--build-arg X265_VERSION=$X265_VERSION \
|
||||
--build-arg VPX_VERSION=$VPX_VERSION \
|
||||
--build-arg LAME_VERSION=$LAME_VERSION \
|
||||
--build-arg OPUS_VERSION=$OPUS_VERSION \
|
||||
--build-arg VORBIS_VERSION=$VORBIS_VERSION \
|
||||
--build-arg FFMPEG_VERSION=$FFMPEG_VERSION \
|
||||
--platform linux/amd64 \
|
||||
-f Dockerfile.ubuntu.cuda \
|
||||
-t datarhei/base:$OS_NAME-ffmpeg-cuda-$OS_VERSION-$FFMPEG_VERSION-$CUDA_VERSION .
|
||||
}
|
||||
|
||||
function build_vaapi() {
|
||||
source_env ./Build.alpine.env
|
||||
source_env ./Build.alpine.vaapi.env
|
||||
docker buildx build \
|
||||
--load \
|
||||
--build-arg BUILD_IMAGE=$OS_NAME:$OS_VERSION \
|
||||
--build-arg FREETYPE_VERSION=$FREETYPE_VERSION \
|
||||
--build-arg XML2_VERSION=$XML2_VERSION \
|
||||
--build-arg SRT_VERSION=$SRT_VERSION \
|
||||
--build-arg X264_VERSION=$X264_VERSION \
|
||||
--build-arg X265_VERSION=$X265_VERSION \
|
||||
--build-arg VPX_VERSION=$VPX_VERSION \
|
||||
--build-arg LAME_VERSION=$LAME_VERSION \
|
||||
--build-arg OPUS_VERSION=$OPUS_VERSION \
|
||||
--build-arg VORBIS_VERSION=$VORBIS_VERSION \
|
||||
--build-arg FFMPEG_VERSION=$FFMPEG_VERSION \
|
||||
--build-arg LIBAV_VERSION=$LIBAV_VERSION \
|
||||
--build-arg LIBVDPAU_VERSION=$LIBVDPAU_VERSION \
|
||||
--build-arg MESA_VA_GALLIUM_VERSION=$MESA_VA_GALLIUM_VERSION \
|
||||
--build-arg MESA_VDPAU_GALLIUM_VERSION=$MESA_VDPAU_GALLIUM_VERSION \
|
||||
--build-arg LIBVA_VDPAU_DRIVER_VERSION=$LIBVA_VDPAU_DRIVER_VERSION \
|
||||
--build-arg INTEL_GMMLIB_VERSION=$INTEL_GMMLIB_VERSION \
|
||||
--build-arg INTEL_MEDIA_DRIVER_VERSION=$INTEL_MEDIA_DRIVER_VERSION \
|
||||
--build-arg INTEL_MEDIA_SDK_VERSION=$INTEL_MEDIA_SDK_VERSION \
|
||||
--build-arg INTEL_VAAPI_DRIVER=$INTEL_VAAPI_DRIVER \
|
||||
--platform linux/amd64 \
|
||||
-f Dockerfile.alpine.vaapi \
|
||||
-t datarhei/base:$OS_NAME-ffmpeg-vaapi-$OS_VERSION-$FFMPEG_VERSION .
|
||||
}
|
||||
|
||||
main() {
|
||||
if [[ $# == 0 ]]; then
|
||||
echo "Options available: default, rpi, cuda, vaapi"
|
||||
exit 0
|
||||
else
|
||||
if [[ $1 == "default" ]]; then
|
||||
build_default
|
||||
elif [[ $1 == "rpi" ]]; then
|
||||
build_rpi
|
||||
elif [[ $1 == "cuda" ]]; then
|
||||
build_cuda
|
||||
elif [[ $1 == "vaapi" ]]; then
|
||||
build_vaapi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
main $@
|
||||
|
||||
exit 0
|
||||
@@ -1,3 +1,3 @@
|
||||
# FFMPEG CUDA PACKAGES
|
||||
CUDA_VERSION=11.4.2
|
||||
FFNVCODEC_VERSION=11.1.5.1
|
||||
CUDA_VERSION=11.7.1
|
||||
FFNVCODEC_VERSION=11.1.5.2
|
||||
@@ -1,14 +1,14 @@
|
||||
# FFMPEG BASE PACKAGES
|
||||
OS_NAME=ubuntu
|
||||
OS_VERSION=20.04
|
||||
FREETYPE_VERSION=2.10.4
|
||||
ENV LIBXML2_VERSION=2.9.14
|
||||
FREETYPE_VERSION=2.12.1
|
||||
XML2_VERSION=2.9.14
|
||||
SRT_VERSION=1.4.4
|
||||
X264_VERSION=stable
|
||||
X265_VERSION=3.4
|
||||
VPX_VERSION=1.11.0
|
||||
VPX_VERSION=1.12.0
|
||||
LAME_VERSION=3.100
|
||||
OPUS_VERSION=1.3.1
|
||||
OGG_VERSION=1.3.5
|
||||
VORBIS_VERSION=1.3.7
|
||||
FFMPEG_VERSION=5.0.1
|
||||
FFMPEG_VERSION=5.1.2
|
||||
@@ -1,6 +1,6 @@
|
||||
ARG ALPINE_IMAGE=alpine:3.15
|
||||
ARG BUILD_IMAGE=alpine:3.15
|
||||
|
||||
FROM $ALPINE_IMAGE as builder
|
||||
FROM $BUILD_IMAGE as builder
|
||||
|
||||
ARG FREETYPE_VERSION=2.11.1-r2
|
||||
ARG XML2_VERSION=2.9.14-r0
|
||||
@@ -106,10 +106,11 @@ RUN mkdir -p /ffmpeg/lib && \
|
||||
/usr/lib/libpng16.so.16 \
|
||||
/usr/lib/libxml2.so.2 \
|
||||
/usr/lib/liblzma.so.5 \
|
||||
/usr/lib/libsrt.so.1 \
|
||||
/usr/lib/libsrt.so.1.4 \
|
||||
/usr/lib/libx264.so.163 \
|
||||
/usr/lib/libx265.so.199 \
|
||||
/usr/lib/libvpx.so.6 \
|
||||
/usr/lib/libnuma.so.1 \
|
||||
/usr/lib/libvpx.so.7 \
|
||||
/usr/lib/libmp3lame.so.0 \
|
||||
/usr/lib/libopus.so.0 \
|
||||
/usr/lib/libvorbis.so.0 \
|
||||
@@ -119,7 +120,7 @@ RUN mkdir -p /ffmpeg/lib && \
|
||||
/usr/lib/libstdc++.so.6 \
|
||||
/ffmpeg/lib
|
||||
|
||||
FROM $ALPINE_IMAGE as final
|
||||
FROM $BUILD_IMAGE as final
|
||||
|
||||
COPY --from=builder /usr/bin/ffmpeg /usr/bin/ffmpeg
|
||||
COPY --from=builder /ffmpeg/lib/* /usr/lib/
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
ARG ALPINE_IMAGE=alpine:3.15
|
||||
ARG BUILD_IMAGE=alpine:3.15
|
||||
|
||||
FROM $ALPINE_IMAGE as builder
|
||||
FROM $BUILD_IMAGE as builder
|
||||
|
||||
ARG RPI_VERSION=0.20200813-r0
|
||||
ARG ALSA_VERSION=1.2.5.1-r1
|
||||
|
||||
ARG FREETYPE_VERSION=2.11.1-r1
|
||||
ARG XML2_VERSION=2.9.13-r0
|
||||
@@ -13,7 +14,6 @@ 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 FBDEV_VERSION=0.5.0-r3
|
||||
ARG V4L_VERSION=1.22.1-r1
|
||||
ARG FFMPEG_VERSION=4.4.2
|
||||
@@ -120,10 +120,11 @@ RUN mkdir -p /ffmpeg/lib && \
|
||||
/usr/lib/libpng16.so.16 \
|
||||
/usr/lib/libxml2.so.2 \
|
||||
/usr/lib/liblzma.so.5 \
|
||||
/usr/lib/libsrt.so.1 \
|
||||
/usr/lib/libsrt.so.1.4 \
|
||||
/usr/lib/libx264.so.163 \
|
||||
/usr/lib/libx265.so.199 \
|
||||
/usr/lib/libvpx.so.6 \
|
||||
/usr/lib/libnuma.so.1 \
|
||||
/usr/lib/libvpx.so.7 \
|
||||
/usr/lib/libmp3lame.so.0 \
|
||||
/usr/lib/libopus.so.0 \
|
||||
/usr/lib/libvorbis.so.0 \
|
||||
@@ -133,7 +134,7 @@ RUN mkdir -p /ffmpeg/lib && \
|
||||
/usr/lib/libstdc++.so.6 \
|
||||
/ffmpeg/lib
|
||||
|
||||
FROM $ALPINE_IMAGE as final
|
||||
FROM $BUILD_IMAGE as final
|
||||
|
||||
COPY --from=builder /usr/bin/ffmpeg /usr/bin/ffmpeg
|
||||
COPY --from=builder /ffmpeg/lib/* /usr/lib/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
ARG ALPINE_IMAGE=alpine:3.15
|
||||
ARG BUILD_IMAGE=alpine:3.15
|
||||
|
||||
FROM $ALPINE_IMAGE as builder
|
||||
FROM $BUILD_IMAGE as builder
|
||||
|
||||
ARG LIBAV_VERSION=2.14.0-r0
|
||||
ARG LIBVDPAU_VERSION=1.5-r0
|
||||
@@ -135,10 +135,11 @@ RUN mkdir -p /ffmpeg/lib && \
|
||||
/usr/lib/libbrotlicommon.so.1 \
|
||||
/usr/lib/libbz2.so.1 \
|
||||
/usr/lib/libpng16.so.16 \
|
||||
/usr/lib/libsrt.so.1 \
|
||||
/usr/lib/libsrt.so.1.4 \
|
||||
/usr/lib/libx264.so.163 \
|
||||
/usr/lib/libx265.so.199 \
|
||||
/usr/lib/libvpx.so.6 \
|
||||
/usr/lib/libnuma.so.1 \
|
||||
/usr/lib/libvpx.so.7 \
|
||||
/usr/lib/libmp3lame.so.0 \
|
||||
/usr/lib/libopus.so.0 \
|
||||
/usr/lib/libvorbis.so.0 \
|
||||
@@ -164,7 +165,7 @@ RUN mkdir -p /ffmpeg/lib && \
|
||||
/usr/lib/libva-x11.so.2 \
|
||||
/ffmpeg/lib
|
||||
|
||||
FROM $ALPINE_IMAGE as final
|
||||
FROM $BUILD_IMAGE as final
|
||||
|
||||
COPY --from=builder /usr/bin/ffmpeg /usr/bin/ffmpeg
|
||||
COPY --from=builder /ffmpeg/lib/* /usr/lib/
|
||||
|
||||
25
README.md
25
README.md
@@ -2,7 +2,7 @@
|
||||
|
||||
FFmpeg base image for [datarhei/core](https://github.com/datarhei/core).
|
||||
|
||||
Branch: 5.0
|
||||
Branch: 5.1
|
||||
|
||||
## Config:
|
||||
|
||||
@@ -29,23 +29,26 @@ _Additional informations can be found in the Dockerfiles._
|
||||
|
||||
| Dockerimage | OS | Plattform | GPU |
|
||||
| -------------------------------------------------- | ------------ | ---------------------------------------- | ------------------------------------------- |
|
||||
| docker.io/datarhei/base:alpine-ffmpeg-latest | Alpine 3.15 | linux/amd64, linux/arm64, linux/arm/v7 | - |
|
||||
| docker.io/datarhei/base:alpine-ffmpeg-rpi-latest | Alpine 3.15 | Raspberry Pi (linux/arm/v7, linux/arm64) | MMAL/OMX/V4L2-M2M (32bit), V4L2-M2M (64bit) |
|
||||
| docker.io/datarhei/base:alpine-ffmpeg-vaapi-latest | Alpine 3.15 | linux/amd64 | Intel VAAPI |
|
||||
| docker.io/datarhei/base:ubuntu-ffmpeg-cuda-latest | Ubuntu 20.03 | linux/amd64 | Nvidia Cuda |
|
||||
| docker.io/datarhei/base:alpine-ffmpeg-5.1.2 | Alpine 3.16 | linux/amd64, linux/arm64, linux/arm/v7 | - |
|
||||
| docker.io/datarhei/base:alpine-ffmpeg-rpi-5.1.2 | Alpine 3.16 | Raspberry Pi (linux/arm/v7, linux/arm64) | MMAL/OMX/V4L2-M2M (32bit), V4L2-M2M (64bit) |
|
||||
| docker.io/datarhei/base:alpine-ffmpeg-vaapi-5.1.2 | Alpine 3.16 | linux/amd64 | Intel VAAPI |
|
||||
| docker.io/datarhei/base:ubuntu-ffmpeg-cuda-5.1.2 | Ubuntu 20.03 | linux/amd64 | Nvidia Cuda |
|
||||
|
||||
More tags: https://hub.docker.com/repository/docker/datarhei/base/general
|
||||
|
||||
## Testing
|
||||
## Build & test
|
||||
|
||||
```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
|
||||
$ git clone github.com/datarhei/ffmpeg
|
||||
$ ./Build.sh {arg}
|
||||
```
|
||||
|
||||
Args:
|
||||
- default (alpine-ffmpeg-latest)
|
||||
- rpi (alpine-ffmpeg-rpi-latest)
|
||||
- vaapi (alpine-ffmpeg-vaapi-latest)
|
||||
- cuda (ubuntu-ffmpeg-cuda-latest)
|
||||
|
||||
## Known problems:
|
||||
|
||||
The libraries are currently not compiled due to errors caused by Docker virtualisation.
|
||||
|
||||
98
contrib/README.md
Normal file
98
contrib/README.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# Patches
|
||||
FFmpeg patches.
|
||||
|
||||
|
||||
## HLS bitrate
|
||||
Calculate bandwidth estimate for the hls master manifest.
|
||||
|
||||
|
||||
## JSON stats
|
||||
This repository contains a patch for the FFmpeg program to provide detailed progress information. With this patch, FFmpeg will output
|
||||
the progress information in a JSON string that contains the data for each input and output stream individually. The JSON output is enabled
|
||||
by default. It can be enabled with the global `-jsonstats` switch on the command line. Use the `-stats` switch
|
||||
on the command line for the standard progress output.
|
||||
|
||||
Example output with `-stats`:
|
||||
|
||||
```
|
||||
frame= 143 fps= 25 q=-1.0 Lsize= 941kB time=00:00:05.68 bitrate=1357.0kbits/s speed=0.995x
|
||||
```
|
||||
|
||||
Example output with `-jsonstats`:
|
||||
|
||||
```
|
||||
JSONProgress:{"inputs":[{"id":0, "stream":0, "type":"video", "codec":"rawvideo", "coder":"rawvideo", "pix_fmt":"rgb24", "frame":188, "fps":24.95, "width":1280, "height":720, "size_kb":507600, "bitrate_kbps":552960.0},{"id":1, "stream":0, "type":"audio", "codec":"pcm_u8", "coder":"pcm_u8", "frame":314, "sampling_hz":44100, "layout":"stereo", "size_kb":628, "bitrate_kbps":705.6}], "outputs":[{"id":0, "stream":0, "type":"video", "codec":"h264", "coder":"libx264", "pix_fmt":"yuv420p", "frame":188, "fps":24.95, "q":-1.0, "width":1280, "height":720, "size_kb":1247, "bitrate_kbps":1365.6},{"id":0, "stream":1, "type":"audio", "codec":"aac", "coder":"aac", "frame":315, "sampling_hz":44100, "layout":"stereo", "size_kb":2, "bitrate_kbps":2.1}], "frame":188, "fps":24.95, "q":-1.0, "size_kb":1249, "bitrate_kbps":1367.7, "time":"0h0m7.48s", "speed":0.993, "dup":0, "drop":0}
|
||||
```
|
||||
|
||||
The same output but nicely formatted:
|
||||
|
||||
```json
|
||||
{
|
||||
"bitrate_kbps": 1367.7,
|
||||
"drop": 0,
|
||||
"dup": 0,
|
||||
"fps": 24.95,
|
||||
"frame": 188,
|
||||
"inputs": [
|
||||
{
|
||||
"bitrate_kbps": 552960.0,
|
||||
"codec": "rawvideo",
|
||||
"coder": "rawvideo",
|
||||
"fps": 24.95,
|
||||
"frame": 188,
|
||||
"height": 720,
|
||||
"id": 0,
|
||||
"pix_fmt": "rgb24",
|
||||
"size_kb": 507600,
|
||||
"stream": 0,
|
||||
"type": "video",
|
||||
"width": 1280
|
||||
},
|
||||
{
|
||||
"bitrate_kbps": 705.6,
|
||||
"codec": "pcm_u8",
|
||||
"coder": "pcm_u8",
|
||||
"frame": 314,
|
||||
"id": 1,
|
||||
"layout": "stereo",
|
||||
"sampling_hz": 44100,
|
||||
"size_kb": 628,
|
||||
"stream": 0,
|
||||
"type": "audio"
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"bitrate_kbps": 1365.6,
|
||||
"codec": "h264",
|
||||
"coder": "libx264",
|
||||
"fps": 24.95,
|
||||
"frame": 188,
|
||||
"height": 720,
|
||||
"id": 0,
|
||||
"pix_fmt": "yuv420p",
|
||||
"q": -1.0,
|
||||
"size_kb": 1247,
|
||||
"stream": 0,
|
||||
"type": "video",
|
||||
"width": 1280
|
||||
},
|
||||
{
|
||||
"bitrate_kbps": 2.1,
|
||||
"codec": "aac",
|
||||
"coder": "aac",
|
||||
"frame": 315,
|
||||
"id": 0,
|
||||
"layout": "stereo",
|
||||
"sampling_hz": 44100,
|
||||
"size_kb": 2,
|
||||
"stream": 1,
|
||||
"type": "audio"
|
||||
}
|
||||
],
|
||||
"q": -1.0,
|
||||
"size_kb": 1249,
|
||||
"speed": 0.993,
|
||||
"time": "0h0m7.48s"
|
||||
}
|
||||
```
|
||||
@@ -1,17 +1,17 @@
|
||||
From 85870fdb0530c8d12faa682bd571060b0fa8fb73 Mon Sep 17 00:00:00 2001
|
||||
From df74cdced975a6f13fdc24e43e75a7f9b571c661 Mon Sep 17 00:00:00 2001
|
||||
From: Ingo Oppermann <ingo@datarhei.com>
|
||||
Date: Wed, 13 Jul 2022 14:26:24 +0200
|
||||
Subject: [PATCH v1] Calculate bandwidth estimate (ffmpeg 5.0)
|
||||
Date: Tue, 25 Oct 2022 10:43:45 +0200
|
||||
Subject: [PATCH v2] Calculate bandwidth estimate (ffmpeg 5.1)
|
||||
|
||||
---
|
||||
libavformat/hlsenc.c | 29 +++++++++++++++++++++++++++++
|
||||
1 file changed, 29 insertions(+)
|
||||
|
||||
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
|
||||
index ef8973c..8e437de 100644
|
||||
index 6f49ae1a..da7c3f21 100644
|
||||
--- a/libavformat/hlsenc.c
|
||||
+++ b/libavformat/hlsenc.c
|
||||
@@ -125,6 +125,7 @@ typedef struct VariantStream {
|
||||
@@ -124,6 +124,7 @@ typedef struct VariantStream {
|
||||
AVIOContext *out;
|
||||
AVIOContext *out_single_file;
|
||||
int packets_written;
|
||||
@@ -19,7 +19,7 @@ index ef8973c..8e437de 100644
|
||||
int init_range_length;
|
||||
uint8_t *temp_buffer;
|
||||
uint8_t *init_buffer;
|
||||
@@ -139,6 +140,8 @@ typedef struct VariantStream {
|
||||
@@ -138,6 +139,8 @@ typedef struct VariantStream {
|
||||
double dpp; // duration per packet
|
||||
int64_t start_pts;
|
||||
int64_t end_pts;
|
||||
@@ -45,7 +45,7 @@ index ef8973c..8e437de 100644
|
||||
bandwidth += bandwidth / 10;
|
||||
|
||||
ccgroup = NULL;
|
||||
@@ -2439,6 +2452,19 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
@@ -2443,6 +2456,19 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ index ef8973c..8e437de 100644
|
||||
end_pts = hls->recording_time * vs->number;
|
||||
|
||||
if (vs->sequence - vs->nb_entries > hls->start_sequence && hls->init_time > 0) {
|
||||
@@ -2656,6 +2682,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
@@ -2663,6 +2689,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
}
|
||||
|
||||
vs->packets_written++;
|
||||
@@ -73,7 +73,7 @@ index ef8973c..8e437de 100644
|
||||
if (oc->pb) {
|
||||
ret = ff_write_chained(oc, stream_index, pkt, s, 0);
|
||||
vs->video_keyframe_size += pkt->size;
|
||||
@@ -2949,6 +2976,8 @@ static int hls_init(AVFormatContext *s)
|
||||
@@ -2956,6 +2983,8 @@ static int hls_init(AVFormatContext *s)
|
||||
vs->sequence = hls->start_sequence;
|
||||
vs->start_pts = AV_NOPTS_VALUE;
|
||||
vs->end_pts = AV_NOPTS_VALUE;
|
||||
@@ -83,7 +83,7 @@ index ef8973c..8e437de 100644
|
||||
vs->initial_prog_date_time = initial_program_date_time;
|
||||
|
||||
|
||||
base-commit: 82c775a733a6b3a1a951b7cb1d4fd965bfd2b4dc
|
||||
base-commit: 2bca71f4986725d7cf0d441e2f82a790d0a0c717
|
||||
--
|
||||
2.32.1 (Apple Git-133)
|
||||
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
From 815dc4ce1931ab11baf2fd68986974eafcdd76f1 Mon Sep 17 00:00:00 2001
|
||||
From ae76cd00ce561f8a22179ffa56e8b1a04afdfae8 Mon Sep 17 00:00:00 2001
|
||||
From: Ingo Oppermann <ingo@datarhei.com>
|
||||
Date: Wed, 18 May 2022 21:40:50 +0200
|
||||
Subject: [PATCH v21] JSON progress report (ffmpeg 5.0)
|
||||
Date: Tue, 25 Oct 2022 10:45:42 +0200
|
||||
Subject: [PATCH v23] JSON progress report (ffmpeg 5.1)
|
||||
|
||||
---
|
||||
fftools/ffmpeg.c | 262 +++++++++++++++++++++++++++++++++++++++++--
|
||||
fftools/ffmpeg.c | 205 ++++++++++++++++++++++++++++--
|
||||
fftools/ffmpeg.h | 1 +
|
||||
fftools/ffmpeg_opt.c | 69 ++++++++++++
|
||||
3 files changed, 322 insertions(+), 10 deletions(-)
|
||||
fftools/ffmpeg_mux.c | 294 +++++++++++++++++++++++++++++++++++++++++++
|
||||
fftools/ffmpeg_opt.c | 107 ++++++++++++++++
|
||||
4 files changed, 597 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
|
||||
index bdeff9a..f8821e1 100644
|
||||
index e7384f05..f52ff4f1 100644
|
||||
--- a/fftools/ffmpeg.c
|
||||
+++ b/fftools/ffmpeg.c
|
||||
@@ -1673,12 +1673,11 @@ static void print_final_stats(int64_t total_size)
|
||||
@@ -1504,12 +1504,11 @@ static void print_final_stats(int64_t total_size)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +27,9 @@ index bdeff9a..f8821e1 100644
|
||||
- int64_t total_size;
|
||||
+ int64_t total_size = 0;
|
||||
AVCodecContext *enc;
|
||||
int frame_number, vid, i;
|
||||
int vid, i;
|
||||
double bitrate;
|
||||
@@ -1707,13 +1706,6 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
||||
@@ -1538,13 +1537,6 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
||||
|
||||
t = (cur_time-timer_start) / 1000000.0;
|
||||
|
||||
@@ -42,7 +43,7 @@ index bdeff9a..f8821e1 100644
|
||||
vid = 0;
|
||||
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
|
||||
av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
|
||||
@@ -1796,6 +1788,9 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
||||
@@ -1627,6 +1619,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;
|
||||
@@ -52,17 +53,24 @@ index bdeff9a..f8821e1 100644
|
||||
}
|
||||
|
||||
secs = FFABS(pts) / AV_TIME_BASE;
|
||||
@@ -1883,6 +1878,251 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
||||
@@ -1714,6 +1709,196 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
||||
print_final_stats(total_size);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * Print progress report in JSON format
|
||||
+ *
|
||||
+ * @param is_last_report Whether this is the last report
|
||||
+ * @param timer_start Time when the processing started
|
||||
+ * @param cur_time Current processing time of the stream
|
||||
+ */
|
||||
+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;
|
||||
+ AVCodecContext *enc;
|
||||
+ int i, j;
|
||||
+ uint64_t first_vid, first_frame_number = 0, first_packet_number = 0;
|
||||
+ double speed;
|
||||
@@ -73,45 +81,47 @@ index bdeff9a..f8821e1 100644
|
||||
+ float t, q;
|
||||
+ float first_q = -1;
|
||||
+
|
||||
+ if (!print_jsonstats && !is_last_report && !progress_avio) {
|
||||
+ if(!print_jsonstats && !is_last_report && !progress_avio) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_last_report) {
|
||||
+ if (last_time == -1) {
|
||||
+ if(!is_last_report) {
|
||||
+ if(last_time == -1) {
|
||||
+ last_time = cur_time;
|
||||
+ return;
|
||||
+ }
|
||||
+ if ((cur_time - last_time) < 500000) {
|
||||
+ if((cur_time - last_time) < 500000) {
|
||||
+ return;
|
||||
+ }
|
||||
+ last_time = cur_time;
|
||||
+ }
|
||||
+
|
||||
+ t = (cur_time-timer_start) / 1000000.0;
|
||||
+ 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++) {
|
||||
+ for(i = 0; i < nb_input_files; i++) {
|
||||
+ InputFile *f = input_files[i];
|
||||
+
|
||||
+ for (j = 0; j < f->nb_streams; j++) {
|
||||
+ 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,
|
||||
+ "\"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 {
|
||||
+ } else {
|
||||
+ av_bprintf(&buf, "},");
|
||||
+ }
|
||||
+ }
|
||||
@@ -119,35 +129,34 @@ index bdeff9a..f8821e1 100644
|
||||
+
|
||||
+ 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;
|
||||
+ for(i = 0; i < nb_output_streams; i++) {
|
||||
+ 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;
|
||||
+ 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, "\"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);
|
||||
+ 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_frame_number = ost->frames_encoded == 0
|
||||
+ ? ost->packets_written
|
||||
+ : ost->frames_encoded;
|
||||
+ first_packet_number = ost->packets_written;
|
||||
+ first_q = q;
|
||||
+
|
||||
@@ -157,12 +166,18 @@ index bdeff9a..f8821e1 100644
|
||||
+
|
||||
+ /* 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(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) {
|
||||
+ if(is_last_report) {
|
||||
+ nb_frames_drop += ost->last_dropped;
|
||||
+ }
|
||||
+
|
||||
@@ -173,15 +188,18 @@ index bdeff9a..f8821e1 100644
|
||||
+
|
||||
+ if(i == (nb_output_streams - 1)) {
|
||||
+ av_bprintf(&buf, "}");
|
||||
+ }
|
||||
+ else {
|
||||
+ } 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,
|
||||
+ "\"frame\":%" PRIu64 ",\"packet\":%" PRIu64 ",\"q\":%.1f,",
|
||||
+ first_frame_number,
|
||||
+ first_packet_number,
|
||||
+ first_q);
|
||||
+
|
||||
+ av_bprintf(&buf, "\"size_kb\":%.0f,", total_size / 1024.0);
|
||||
+
|
||||
@@ -194,16 +212,22 @@ index bdeff9a..f8821e1 100644
|
||||
+ 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);
|
||||
+ 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, "\"dup\":%"PRId64",\"drop\":%"PRId64, nb_frames_dup, nb_frames_drop);
|
||||
+ av_bprintf(&buf, "}");
|
||||
+
|
||||
+ if (print_jsonstats || is_last_report) {
|
||||
+ if(print_jsonstats || is_last_report) {
|
||||
+ fprintf(stderr, "%s\n", buf.str);
|
||||
+ fflush(stderr);
|
||||
+ }
|
||||
@@ -211,113 +235,26 @@ index bdeff9a..f8821e1 100644
|
||||
+ 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)
|
||||
+ 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 {
|
||||
+ if(print_jsonstats == 1) {
|
||||
+ print_json_report(is_last_report, timer_start, cur_time);
|
||||
+ } else {
|
||||
+ print_default_report(is_last_report, timer_start, cur_time);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par)
|
||||
static int ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par)
|
||||
{
|
||||
// We never got any input. Set a fake format, which will
|
||||
@@ -2967,6 +3207,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) {
|
||||
ret = print_sdp();
|
||||
if (ret < 0) {
|
||||
int ret;
|
||||
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
|
||||
index 9b200b8..bd053f4 100644
|
||||
index 391a35cf..179f2d22 100644
|
||||
--- a/fftools/ffmpeg.h
|
||||
+++ b/fftools/ffmpeg.h
|
||||
@@ -622,6 +622,7 @@ extern int debug_ts;
|
||||
@@ -636,6 +636,7 @@ extern int debug_ts;
|
||||
extern int exit_on_error;
|
||||
extern int abort_on_flags;
|
||||
extern int print_stats;
|
||||
@@ -325,11 +262,330 @@ index 9b200b8..bd053f4 100644
|
||||
extern int64_t stats_period;
|
||||
extern int qp_hist;
|
||||
extern int stdin_interaction;
|
||||
diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c
|
||||
index a55fd18f..3a09ba08 100644
|
||||
--- a/fftools/ffmpeg_mux.c
|
||||
+++ b/fftools/ffmpeg_mux.c
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "libavutil/log.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/timestamp.h"
|
||||
+#include "libavutil/bprint.h"
|
||||
+#include "libavutil/pixdesc.h"
|
||||
|
||||
#include "libavcodec/packet.h"
|
||||
|
||||
@@ -226,6 +228,296 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * Write a graph as JSON to an initialized buffer
|
||||
+ *
|
||||
+ * @param buf Pointer to an initialized AVBPrint buffer
|
||||
+ * @param graph Pointer to a AVFilterGraph
|
||||
+ */
|
||||
+static void print_json_graph(AVBPrint *buf, AVFilterGraph *graph)
|
||||
+{
|
||||
+ int i, j;
|
||||
+
|
||||
+ if(graph == NULL) {
|
||||
+ av_bprintf(buf, "null\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ av_bprintf(buf, "[");
|
||||
+
|
||||
+ for(i = 0; i < graph->nb_filters; i++) {
|
||||
+ const AVFilterContext *filter_ctx = graph->filters[i];
|
||||
+
|
||||
+ for(j = 0; j < filter_ctx->nb_outputs; j++) {
|
||||
+ AVFilterLink *link = filter_ctx->outputs[j];
|
||||
+ if(link) {
|
||||
+ const AVFilterContext *dst_filter_ctx = link->dst;
|
||||
+
|
||||
+ av_bprintf(buf,
|
||||
+ "{\"src_name\":\"%s\",\"src_filter\":\"%s\",\"dst_name\":\"%s\",\"dst_filter\":\"%s\",",
|
||||
+ filter_ctx->name,
|
||||
+ filter_ctx->filter->name,
|
||||
+ dst_filter_ctx->name,
|
||||
+ dst_filter_ctx->filter->name);
|
||||
+ av_bprintf(buf,
|
||||
+ "\"inpad\":\"%s\",\"outpad\":\"%s\",",
|
||||
+ avfilter_pad_get_name(link->srcpad, 0),
|
||||
+ avfilter_pad_get_name(link->dstpad, 0));
|
||||
+ av_bprintf(buf,
|
||||
+ "\"timebase\": \"%d/%d\",",
|
||||
+ link->time_base.num,
|
||||
+ link->time_base.den);
|
||||
+
|
||||
+ if(link->type == AVMEDIA_TYPE_VIDEO) {
|
||||
+ const AVPixFmtDescriptor *desc =
|
||||
+ av_pix_fmt_desc_get(link->format);
|
||||
+ av_bprintf(buf,
|
||||
+ "\"type\":\"video\",\"format\":\"%s\",\"width\":%d,\"height\":%d",
|
||||
+ desc->name,
|
||||
+ link->w,
|
||||
+ link->h);
|
||||
+ } else if(link->type == AVMEDIA_TYPE_AUDIO) {
|
||||
+ char layout[255];
|
||||
+ av_channel_layout_describe(&link->ch_layout, layout, sizeof(layout));
|
||||
+ av_bprintf(buf,
|
||||
+ "\"type\":\"audio\",\"format\":\"%s\",\"sampling_hz\":%d,\"layout\":\"%s\"",
|
||||
+ av_get_sample_fmt_name(link->format),
|
||||
+ link->sample_rate,
|
||||
+ layout);
|
||||
+ }
|
||||
+
|
||||
+ if(i == (graph->nb_filters - 1)) {
|
||||
+ av_bprintf(buf, "}");
|
||||
+ } else {
|
||||
+ av_bprintf(buf, "},");
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ av_bprintf(buf, "]");
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Print all outputs in JSON format
|
||||
+ */
|
||||
+static void print_json_outputs()
|
||||
+{
|
||||
+ static int ost_all_initialized = 0;
|
||||
+ int i, j, k;
|
||||
+ int nb_initialized = 0;
|
||||
+ AVBPrint buf;
|
||||
+
|
||||
+ if(print_jsonstats != 1) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if(ost_all_initialized == 1) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // count how many outputs are initialized
|
||||
+ for(i = 0; i < nb_output_streams; i++) {
|
||||
+ OutputStream *ost = output_streams[i];
|
||||
+ if(ost->initialized) {
|
||||
+ nb_initialized++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // only when all outputs are initialized, dump the outputs
|
||||
+ if(nb_initialized == nb_output_streams) {
|
||||
+ ost_all_initialized = 1;
|
||||
+ }
|
||||
+
|
||||
+ if(ost_all_initialized != 1) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ 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;
|
||||
+ char *url = NULL;
|
||||
+
|
||||
+ if(av_escape(&url,
|
||||
+ ctx->url,
|
||||
+ "\\\"",
|
||||
+ AV_ESCAPE_MODE_BACKSLASH,
|
||||
+ AV_UTF8_FLAG_ACCEPT_ALL) < 0) {
|
||||
+ url = av_strdup("-");
|
||||
+ }
|
||||
+
|
||||
+ av_bprintf(&buf, "{");
|
||||
+ av_bprintf(&buf,
|
||||
+ "\"url\":\"%s\",\"format\":\"%s\",\"index\":%d,\"stream\":%d,",
|
||||
+ url,
|
||||
+ ctx->oformat->name,
|
||||
+ ost->file_index,
|
||||
+ ost->index);
|
||||
+ av_bprintf(&buf,
|
||||
+ "\"type\":\"%s\",\"codec\":\"%s\",\"coder\":\"%s\",\"bitrate_kbps\":%" PRId64
|
||||
+ ",",
|
||||
+ av_get_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");
|
||||
+
|
||||
+ av_free(url);
|
||||
+
|
||||
+ 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_channel_layout_describe(&enc->ch_layout, layout, sizeof(layout));
|
||||
+
|
||||
+ av_bprintf(&buf,
|
||||
+ ",\"sampling_hz\":%d,\"layout\":\"%s\",\"channels\":%d",
|
||||
+ enc->sample_rate,
|
||||
+ layout,
|
||||
+ enc->ch_layout.nb_channels);
|
||||
+ }
|
||||
+
|
||||
+ if(i == (nb_output_streams - 1)) {
|
||||
+ av_bprintf(&buf, "}");
|
||||
+ } else {
|
||||
+ av_bprintf(&buf, "},");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ av_bprintf(&buf, "]");
|
||||
+
|
||||
+ av_log(NULL, AV_LOG_INFO, "%s\n", buf.str);
|
||||
+
|
||||
+ av_bprint_clear(&buf);
|
||||
+
|
||||
+ av_bprintf(&buf, "ffmpeg.mapping:{");
|
||||
+ av_bprintf(&buf, "\"graphs\":[");
|
||||
+
|
||||
+ for(i = 0; i < nb_filtergraphs; i++) {
|
||||
+ av_bprintf(&buf, "{\"index\":%d,\"graph\":", i);
|
||||
+ print_json_graph(&buf, filtergraphs[i]->graph);
|
||||
+
|
||||
+ if(i == (nb_filtergraphs - 1)) {
|
||||
+ av_bprintf(&buf, "}");
|
||||
+ } else {
|
||||
+ av_bprintf(&buf, "},");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ av_bprintf(&buf, "],");
|
||||
+
|
||||
+ // The following is inspired by tools/graph2dot.c
|
||||
+
|
||||
+ av_bprintf(&buf, "\"mapping\":[");
|
||||
+
|
||||
+ for(i = 0; i < nb_input_streams; i++) {
|
||||
+ InputStream *ist = input_streams[i];
|
||||
+
|
||||
+ for(j = 0; j < ist->nb_filters; j++) {
|
||||
+ if(ist->filters[j]->graph) {
|
||||
+ char *name = NULL;
|
||||
+ for(k = 0; k < ist->filters[j]->graph->nb_inputs; k++) {
|
||||
+ if(ist->filters[j]->graph->inputs[k]->ist == ist) {
|
||||
+ name = ist->filters[j]->graph->inputs[k]->filter->name;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ av_bprintf(&buf,
|
||||
+ "{\"input\":{\"index\":%d,\"stream\":%d},\"graph\":{\"index\":%d,\"name\":\"%s\"},\"output\":null},",
|
||||
+ ist->file_index,
|
||||
+ ist->st->index,
|
||||
+ ist->filters[j]->graph->index,
|
||||
+ name);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for(i = 0; i < nb_output_streams; i++) {
|
||||
+ OutputStream *ost = output_streams[i];
|
||||
+
|
||||
+ if(ost->attachment_filename) {
|
||||
+ av_bprintf(&buf,
|
||||
+ "{\"input\":null,\"file\":\"%s\",\"output\":{\"index\":%d,\"stream\":%d}},",
|
||||
+ ost->attachment_filename,
|
||||
+ ost->file_index,
|
||||
+ ost->index);
|
||||
+ goto next_output;
|
||||
+ }
|
||||
+
|
||||
+ if(ost->filter && ost->filter->graph) {
|
||||
+ char *name = NULL;
|
||||
+ for(j = 0; j < ost->filter->graph->nb_outputs; j++) {
|
||||
+ if(ost->filter->graph->outputs[j]->ost == ost) {
|
||||
+ name = ost->filter->graph->outputs[j]->filter->name;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ av_bprintf(&buf,
|
||||
+ "{\"input\":null,\"graph\":{\"index\":%d,\"name\":\"%s\"},\"output\":{\"index\":%d,\"stream\":%d}}",
|
||||
+ ost->filter->graph->index,
|
||||
+ name,
|
||||
+ ost->file_index,
|
||||
+ ost->index);
|
||||
+ goto next_output;
|
||||
+ }
|
||||
+
|
||||
+ av_bprintf(&buf,
|
||||
+ "{\"input\":{\"index\":%d,\"stream\":%d},\"output\":{\"index\":%d,\"stream\":%d}",
|
||||
+ input_streams[ost->source_index]->file_index,
|
||||
+ input_streams[ost->source_index]->st->index,
|
||||
+ ost->file_index,
|
||||
+ ost->index);
|
||||
+ av_bprintf(&buf, ",\"copy\":%s", ost->stream_copy ? "true" : "false");
|
||||
+
|
||||
+ if(ost->sync_ist != input_streams[ost->source_index]) {
|
||||
+ av_bprintf(&buf,
|
||||
+ ",\"sync\":{\"index\":%d,\"stream\":%d}",
|
||||
+ ost->sync_ist->file_index,
|
||||
+ ost->sync_ist->st->index);
|
||||
+ }
|
||||
+
|
||||
+ av_bprintf(&buf, "}");
|
||||
+
|
||||
+ next_output:
|
||||
+ if(i != (nb_output_streams - 1)) {
|
||||
+ av_bprintf(&buf, ",");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ av_bprintf(&buf, "]}");
|
||||
+
|
||||
+ av_log(NULL, AV_LOG_INFO, "%s\n", buf.str);
|
||||
+
|
||||
+ av_bprint_finalize(&buf, NULL);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
/* open the muxer when all the streams are initialized */
|
||||
int of_check_init(OutputFile *of)
|
||||
{
|
||||
@@ -251,6 +543,8 @@ int of_check_init(OutputFile *of)
|
||||
av_dump_format(of->ctx, of->index, of->ctx->url, 1);
|
||||
nb_output_dumped++;
|
||||
|
||||
+ print_json_outputs();
|
||||
+
|
||||
if (sdp_filename || want_sdp) {
|
||||
ret = print_sdp();
|
||||
if (ret < 0) {
|
||||
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
|
||||
index 9c820ab..8471dc9 100644
|
||||
index 6e18a4a2..94064947 100644
|
||||
--- a/fftools/ffmpeg_opt.c
|
||||
+++ b/fftools/ffmpeg_opt.c
|
||||
@@ -43,6 +43,7 @@
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "libavutil/parseutils.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/pixfmt.h"
|
||||
@@ -337,20 +593,24 @@ index 9c820ab..8471dc9 100644
|
||||
|
||||
#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
|
||||
|
||||
@@ -160,6 +161,7 @@ int debug_ts = 0;
|
||||
@@ -171,6 +172,7 @@ int debug_ts = 0;
|
||||
int exit_on_error = 0;
|
||||
int abort_on_flags = 0;
|
||||
int print_stats = -1;
|
||||
+int print_jsonstats = -1;
|
||||
+int print_jsonstats = 1;
|
||||
int qp_hist = 0;
|
||||
int stdin_interaction = 1;
|
||||
float max_error_rate = 2.0/3;
|
||||
@@ -3433,6 +3435,69 @@ static int open_files(OptionGroupList *l, const char *inout,
|
||||
@@ -3547,6 +3549,108 @@ static int open_files(OptionGroupList *l, const char *inout,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void print_json_inputs() {
|
||||
+ if(print_jsonstats != 1 && print_stats != -1) {
|
||||
+/**
|
||||
+ * Print all inputs in JSON format
|
||||
+ */
|
||||
+static void print_json_inputs()
|
||||
+{
|
||||
+ if(print_jsonstats != 1) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
@@ -360,25 +620,53 @@ index 9c820ab..8471dc9 100644
|
||||
+ av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
|
||||
+
|
||||
+ av_bprintf(&buf, "ffmpeg.inputs:[");
|
||||
+ for (i = 0; i < nb_input_files; i++) {
|
||||
+ 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;
|
||||
+ 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++) {
|
||||
+ 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);
|
||||
+ AVDictionaryEntry *lang =
|
||||
+ av_dict_get(st->metadata, "language", NULL, 0);
|
||||
+ char *url = NULL;
|
||||
+
|
||||
+ if(av_escape(&url,
|
||||
+ ctx->url,
|
||||
+ "\\\"",
|
||||
+ AV_ESCAPE_MODE_BACKSLASH,
|
||||
+ AV_UTF8_FLAG_ACCEPT_ALL) < 0) {
|
||||
+ url = av_strdup("-");
|
||||
+ }
|
||||
+
|
||||
+ 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");
|
||||
+ av_bprintf(&buf,
|
||||
+ "\"url\":\"%s\",\"format\":\"%s\",\"index\":%d,\"stream\":%d,",
|
||||
+ url,
|
||||
+ ctx->iformat->name,
|
||||
+ i,
|
||||
+ j);
|
||||
+ av_bprintf(&buf,
|
||||
+ "\"type\":\"%s\",\"codec\":\"%s\",\"coder\":\"%s\",\"bitrate_kbps\":%" PRId64
|
||||
+ ",",
|
||||
+ av_get_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");
|
||||
+
|
||||
+ av_free(url);
|
||||
+
|
||||
+ if(dec->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
+ float fps = 0;
|
||||
@@ -386,45 +674,51 @@ index 9c820ab..8471dc9 100644
|
||||
+ 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) {
|
||||
+ 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_channel_layout_describe(&dec->ch_layout, layout, sizeof(layout));
|
||||
+
|
||||
+ av_bprintf(&buf, ",\"sampling_hz\":%d,\"layout\":\"%s\",\"channels\":%d", dec->sample_rate, layout, dec->channels);
|
||||
+ av_bprintf(&buf,
|
||||
+ ",\"sampling_hz\":%d,\"layout\":\"%s\",\"channels\":%d",
|
||||
+ dec->sample_rate,
|
||||
+ layout,
|
||||
+ dec->ch_layout.nb_channels);
|
||||
+ }
|
||||
+
|
||||
+ if(i == (nb_input_files - 1) && j == (f->nb_streams - 1)) {
|
||||
+ av_bprintf(&buf, "}");
|
||||
+ }
|
||||
+ else {
|
||||
+ } else {
|
||||
+ av_bprintf(&buf, "},");
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ av_bprintf(&buf, "]");
|
||||
+
|
||||
+ fprintf(stderr, "%s\n", buf.str);
|
||||
+
|
||||
+ return;
|
||||
+ av_log(NULL, AV_LOG_INFO, "%s\n", buf.str);
|
||||
+}
|
||||
+
|
||||
int ffmpeg_parse_options(int argc, char **argv)
|
||||
{
|
||||
OptionParseContext octx;
|
||||
@@ -3466,6 +3531,8 @@ int ffmpeg_parse_options(int argc, char **argv)
|
||||
@@ -3580,6 +3684,7 @@ int ffmpeg_parse_options(int argc, char **argv)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ print_json_inputs();
|
||||
+
|
||||
apply_sync_offsets();
|
||||
|
||||
/* create the complex filtergraphs */
|
||||
ret = init_complex_filters();
|
||||
if (ret < 0) {
|
||||
@@ -3674,6 +3741,8 @@ const OptionDef options[] = {
|
||||
@@ -3806,6 +3911,8 @@ const OptionDef options[] = {
|
||||
"enable automatic conversion filters globally" },
|
||||
{ "stats", OPT_BOOL, { &print_stats },
|
||||
"print progress report during encoding", },
|
||||
@@ -434,7 +728,7 @@ index 9c820ab..8471dc9 100644
|
||||
"set the period at which ffmpeg updates stats and -progress output", "time" },
|
||||
{ "attach", HAS_ARG | OPT_PERFILE | OPT_EXPERT |
|
||||
|
||||
base-commit: 71650a0ab9193298b29c86db433f43b2feb62b93
|
||||
base-commit: 2bca71f4986725d7cf0d441e2f82a790d0a0c717
|
||||
--
|
||||
2.32.0 (Apple Git-132)
|
||||
2.32.1 (Apple Git-133)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user