A command-line and API-based video bitstream parser, using ffmpeg and other third party libraries.
- Overview
- History and Goals
- Installation
- Usage
- Output
- Available Metrics
- API Integration
- Building Manually
- Developer Guide
- Acknowledgements
- Contributing
- License
This project supplies two main components:
- A command-line tool for parsing video bitstreams (
video-parser) - A C++ API for parsing video bitstreams,
libvideoparser, which is used by the CLI program
The project is aimed at providing input for bitstream-based video (quality) assessment.
Internally, ffmpeg is used, and linked into the project. Currently, the project is built with FFmpeg 8.1-dev (3148 commits from latest release).
We strive to keep the project up to date with the latest ffmpeg version.
The actual ffmpeg changes are published in this ffmpeg fork in the videoparser branch.
For AV1 support, libaom is also vendored as a submodule. The code, including its changes, is mirrored at this libaom fork in the videoparser branch.
The project is using previous work from the bitstream_mode3_videoparser project. This project was written from the ground up to be faster. How fast?
╔══════════════════════════════════════════════════╗
Legacy parser ╢██████████████████████████████████████████████████╟ 21.161s
videoparser-ng ╢███░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░╟ 1.291s
╠══════════════════════════════════════════════════╣
Super fast – a 16⨉ speedup! This is on a 1920x1080 HEVC video file at 29.97 fps, parsing all frames and extracting all available metrics. For 3840x2160 (4K) videos, the speedup is even higher, around 70x as measured on a M1 Mac.
The overall goal is to provide bitstream statistics to be later used for calculating video quality metrics such as ITU-T Rec. P.1204.3, which has a reference implementation available.
There are some design docs about this project available here. It explains the rationale for the creation of the project, the detailed statistics available in the bitstream_mode3_videoparser project have ported over, and what we would like to add as features on top of that.
Go to releases and pick the right archive for your platform. Extract it, then run the video-parser binary.
Note
macOS Security Limitations: You might need to allow the binary to run. Try running it once from the Terminal, and you will be shown a security notice. Then, go to System Preferences > Security & Privacy > General, and allow the binary. After that, you can run it from the Terminal again. Another security popup will show, but this time you can allow it to run directly.
We provide pre-built Docker images on GitHub Container Registry. You can use them without building yourself.
To pull the image, you need to have a valid GitHub token with access to the repository. If you don't have a token, create one here, and make sure it has read:packages scope enabled.
docker login ghcr.ioYou will be prompted to enter your GitHub username, and as password, enter your personal access token. Once you have a token, you can pull the image:
# Standard build (recommended)
docker pull ghcr.io/aveq-research/videoparser-ng:latest
# Legacy build (for compatibility testing with bitstream_mode3_videoparser)
docker pull ghcr.io/aveq-research/videoparser-ng:latest-legacyThe latest tag will always point to the latest stable release. If you want to use a specific version, you can pull it by replacing latest with the version tag, e.g. 0.6.0:
docker pull ghcr.io/aveq-research/videoparser-ng:0.6.0
docker pull ghcr.io/aveq-research/videoparser-ng:0.6.0-legacyThe latest master branch build is also available under the master and master-legacy tags, but these are not guaranteed to be stable.
Pre-compiled static libraries and headers are available for building your own applications on top of the video parser. The SDK includes:
libvideoparser.a– VideoParser librarylibaom.a– AV1 decoder librarylibavcodec.a,libavformat.a,libavutil.a– FFmpeg libraries- Headers for VideoParser, libaom, and FFmpeg
Download the SDK archive for your platform from the releases page. Both standard and legacy variants are available.
To run the CLI, run:
build/VideoParserCli/video-parser <path-to-video-file>Or, for Docker, you must mount the video file into the container, e.g. to run it on test/test_video_h264.mkv, do:
docker run --rm -it -v $(pwd)/test/test_video_h264.mkv:/video.mkv videoparser-ng /video.mkvAdd the option -h for detailed usage.
The tool will print a set of line-delimited JSON records to STDOUT, either for per-sequence statistics (sequence_info), or per-frame statistics (frame_info). These are denoted with the type field.
Here is an example, but formatted with jq to make it more readable:
build/VideoParserCli/video-parser test/test_video_h264.mkv -n 1 | jqThis would print:
{
"type": "sequence_info",
"video_bit_depth": 8,
"video_bitrate": 37.0,
"video_codec": "h264",
"video_codec_level": 13,
"video_codec_profile": 100,
"video_duration": 10.0,
"video_frame_count": 300,
"video_framerate": 30.0,
"video_height": 240,
"video_pix_fmt": "yuv420p",
"video_width": 320
}
{
"coefs_bit_count": 1328,
"current_poc": 0,
"dts": 0.0,
"frame_idx": 0,
"frame_type": 1,
"is_idr": true,
"mb_mv_count": 0,
"motion_avg": 0.0,
"motion_bit_count": 0,
"motion_diff_avg": 0.0,
"motion_diff_stdev": 0.0,
"motion_stdev": 0.0,
"motion_x_avg": 0.0,
"motion_x_stdev": 0.0,
"motion_y_avg": 0.0,
"motion_y_stdev": 0.0,
"mv_coded_count": 0,
"poc_diff": -1,
"pts": 0.0,
"qp_avg": 16.196666666666665,
"qp_bb_avg": 16.196666666666665,
"qp_bb_stdev": 7.840790067900615,
"qp_init": 10,
"qp_max": 31,
"qp_min": 10,
"qp_stdev": 7.840790067900615,
"size": 87,
"type": "frame_info"
}The tool will also print various logs to STDERR which you can redirect to a file if you want to save them, or ignore with 2>/dev/null.
The following metadata/metrics are available:
| Metric | Description | Unit |
|---|---|---|
video_duration |
Duration of the video | seconds |
video_codec |
Codec name (h264, hevc, vp9, av1) | — |
video_bitrate |
Average bitrate | kbps |
video_framerate |
Frame rate | fps |
video_width |
Frame width | pixels |
video_height |
Frame height | pixels |
video_codec_profile |
Codec profile ID | — |
video_codec_level |
Codec level ID | — |
video_bit_depth |
Bit depth per sample | bits |
video_pix_fmt |
Pixel format (e.g., yuv420p) | — |
video_frame_count |
Total number of frames | count |
| Metric | Description | Unit |
|---|---|---|
frame_idx |
Zero-based frame index in decode order | count |
pts |
Presentation timestamp | seconds |
dts |
Decoding timestamp | seconds |
size |
Frame size | bytes |
frame_type |
Frame type (1=I, 2=P, 3=B) | enum |
is_idr |
Whether frame is an IDR/keyframe | boolean |
qp_avg |
Average QP of all coding units | QP index |
qp_stdev |
Standard deviation of QP values | QP index |
qp_min |
Minimum QP value in frame | QP index |
qp_max |
Maximum QP value in frame | QP index |
qp_init |
Initial QP from slice/frame header | QP index |
qp_bb_avg |
Average QP excluding black borders | QP index |
qp_bb_stdev |
Std. dev. of QP excluding black borders | QP index |
motion_avg |
Average motion vector length | sub-pel |
motion_stdev |
Std. dev. of motion vector lengths | sub-pel |
motion_x_avg |
Average of absolute X components | sub-pel |
motion_y_avg |
Average of absolute Y components | sub-pel |
motion_x_stdev |
Std. dev. of X components | sub-pel |
motion_y_stdev |
Std. dev. of Y components | sub-pel |
motion_diff_avg |
Average motion vector prediction residual | sub-pel |
motion_diff_stdev |
Std. dev. of motion vector residuals | sub-pel |
current_poc |
Picture Order Count of current frame | count |
poc_diff |
Minimum POC difference between frames | count |
motion_bit_count |
Bits used for motion information | bits |
coefs_bit_count |
Bits used for transform coefficients | bits |
mb_mv_count |
Number of blocks with motion vectors | count |
mv_coded_count |
Number of explicitly coded MVs | count |
A detailed description of all available metrics is available in METRICS.md.
For the implementation notes (i.e., what was modified to extract the metrics), see DEVELOPERS.md.
The project provides a C++ API in the libvideoparser library. See the VideoParserCli folder for an example of how to use the API.
API documentation is available in the docs folder. You can view it at this location.
Follow the instructions below to build the project from source.
- Ubuntu 22.04 or higher, or macOS 12.0 or higher
- CMake 3.15 or higher
- A C++17 compiler (GCC 9.3 or higher, Clang 10.0 or higher)
You also need:
pkg-configninja-build
Note that you can skip the build step by just using the pre-built Docker image.
Xcode is required to compile software on your Mac. Install Xcode by downloading it from the website or using the Mac App Store.
After installing Xcode, install the Command Line Tools from Preferences > Downloads > Components. You can also install the tools via your shell:
xcode-select --installThen, using Homebrew, install the required packages:
brew install \
cmake ninja pkg-config \
automake git libtool sdl shtool texi2html wget nasmsudo apt install \
autoconf \
automake \
build-essential \
cmake \
git-core \
libsdl2-dev \
libtool \
libunistring-dev \
meson \
ninja-build \
pkg-config \
texinfo \
wget \
yasm \
nasm \
zlib1g-dev \
libbz2-devTo enable "legacy" computation mode (replicating known bugs from the original bitstream_mode3_videoparser for compatibility testing), rebuild with:
VP_EXTRA_CFLAGS="-DVP_MV_POC_NORMALIZATION=1" util/build-ffmpeg.sh --clean && ./util/build-cmake.shThis enables POC-based motion vector normalization and other legacy behaviors. See DEVELOPERS.md for details on what this flag changes.
Warning
Legacy mode is only recommended for H.264 and HEVC compatibility testing. For VP9, the legacy parser had fundamental bugs making its output unreliable. See VP9_Parsing.md for details.
First clone all submodules:
git submodule update --init --recursiveThen build ffmpeg initially:
util/build-ffmpeg.shThen run the build script for the project:
util/build-cmake.shThis will create the library: build/VideoParser/libvideoparser.a
You can also run the CLI:
build/VideoParserCli/video-parser
If you get a warning like:
WARNING: libavcodec/allcodecs.c newer than config_components.h, rerun configure
Then run:
util/build-ffmpeg.sh --reconfigureThis will rebuild ffmpeg after which you can run the build script for the project again.
To build the project with Docker, run:
docker build -t videoparser-ng .This will build the project and create a Docker image named videoparser-ng.
To build in legacy mode (with POC-based motion vector normalization for compatibility with the original bitstream_mode3_videoparser), pass the LEGACY_MODE build argument:
docker build --build-arg LEGACY_MODE=1 -t videoparser-ng-legacy .For fully static Alpine-based builds (used for GitHub releases), use the Alpine Dockerfile:
# Standard build
docker build -f Dockerfile.alpine -t videoparser-ng-static .
# Legacy mode
docker build -f Dockerfile.alpine --build-arg LEGACY_MODE=1 -t videoparser-ng-static-legacy .We have a more detailed guide for testing and the specific features implemented. See DEVELOPERS.md.
If you use this project in your research, please reference this repository:
@misc{videoparser-ng,
author = {Werner Robitza and Jonatan Stenlund and others},
title = {VideoParser – The Next Generation},
year = {2024},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/aveq-research/videoparser-ng}}
}Contributions to this project were funded by AVEQ GmbH and Ericsson. Contributors:
- Werner Robitza (AVEQ GmbH)
- Jonatan Stenlund (Ericsson, Luleå University of Technology): initial motion vector analysis implementation, see
motion-vectorsbranch
This project would not have been possible without the major work that went into the original video parser. The main developers who have to be credited for this include Peter List (basic parser code, bulk of the implementation for H.264 and HEVC), Anton Schubert (VP9 implementation), Steve Göring (major code and build improvements), Werner Robitza (Python parser interface, debugging), and Rakesh Rao Ramachandra Rao (various code improvements and model training).
See CONTRIBUTING.md if you want to contribute.
Copyright (c) AVEQ GmbH, videoparser-ng contributors.
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, see https://www.gnu.org/licenses/.
Also, see the LICENSE.txt file for details on third-party licenses.