From cbe603398497a969a558477b82e1fbee002f20bf Mon Sep 17 00:00:00 2001 From: Josh Holmer Date: Mon, 23 Jan 2023 09:59:27 -0500 Subject: [PATCH] Add sys crate and rename things --- Cargo.toml | 158 +- README.md | 20 +- .../.github/workflows/build.yml | 41 + ffmpeg-sys-the-third/.gitignore | 3 + ffmpeg-sys-the-third/Cargo.toml | 119 ++ ffmpeg-sys-the-third/README.md | 31 + ffmpeg-sys-the-third/build.rs | 1301 +++++++++++++++++ ffmpeg-sys-the-third/channel_layout_fixed.h | 188 +++ ffmpeg-sys-the-third/src/avutil/error.rs | 68 + ffmpeg-sys-the-third/src/avutil/macros.rs | 13 + ffmpeg-sys-the-third/src/avutil/mod.rs | 14 + ffmpeg-sys-the-third/src/avutil/pixfmt.rs | 236 +++ ffmpeg-sys-the-third/src/avutil/rational.rs | 35 + ffmpeg-sys-the-third/src/avutil/util.rs | 8 + ffmpeg-sys-the-third/src/lib.rs | 16 + 15 files changed, 2165 insertions(+), 86 deletions(-) create mode 100644 ffmpeg-sys-the-third/.github/workflows/build.yml create mode 100644 ffmpeg-sys-the-third/.gitignore create mode 100644 ffmpeg-sys-the-third/Cargo.toml create mode 100644 ffmpeg-sys-the-third/README.md create mode 100644 ffmpeg-sys-the-third/build.rs create mode 100644 ffmpeg-sys-the-third/channel_layout_fixed.h create mode 100644 ffmpeg-sys-the-third/src/avutil/error.rs create mode 100644 ffmpeg-sys-the-third/src/avutil/macros.rs create mode 100644 ffmpeg-sys-the-third/src/avutil/mod.rs create mode 100644 ffmpeg-sys-the-third/src/avutil/pixfmt.rs create mode 100644 ffmpeg-sys-the-third/src/avutil/rational.rs create mode 100644 ffmpeg-sys-the-third/src/avutil/util.rs create mode 100644 ffmpeg-sys-the-third/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index a1c1157..7a3d8ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,120 +1,128 @@ [package] -name = "ffmpeg-next" +name = "ffmpeg-the-third" version = "5.1.1" -build = "build.rs" +build = "build.rs" authors = ["meh. ", "Zhiming Wang "] license = "WTFPL" -description = "Safe FFmpeg wrapper (FFmpeg 4 compatible fork of the ffmpeg crate)" -documentation = "https://docs.rs/ffmpeg-next" -homepage = "https://github.com/zmwangx/rust-ffmpeg#readme" -repository = "https://github.com/zmwangx/rust-ffmpeg" -readme = "README.md" -keywords = ["ffmpeg", "multimedia", "video", "audio"] -categories = ["multimedia"] +description = "Safe FFmpeg wrapper (FFmpeg 4 compatible fork of the ffmpeg crate)" +documentation = "https://docs.rs/ffmpeg-the-third" +homepage = "https://github.com/shssoichiro/ffmpeg-the-third" +repository = "https://github.com/shssoichiro/ffmpeg-the-third" +readme = "README.md" +keywords = ["ffmpeg", "multimedia", "video", "audio"] +categories = ["multimedia"] [features] -default = ["codec", "device", "filter", "format", "software-resampling", "software-scaling", "non-exhaustive-enums"] +default = [ + "codec", + "device", + "filter", + "format", + "software-resampling", + "software-scaling", + "non-exhaustive-enums", +] # ffmpeg are obsolete features kept for backward compatibility purposes and # don't do anything anymore (equivalents are automatically specified through -# compile-time detection in ffmpeg-sys-next). Deprecation plan: all these +# compile-time detection in ffmpeg-sys-the-third). Deprecation plan: all these # features will be removed come 5.0. ffmpeg43 = [] ffmpeg42 = [] ffmpeg41 = [] ffmpeg4 = [] -static = ["ffmpeg-sys-next/static"] -build = ["static", "ffmpeg-sys-next/build"] +static = ["ffmpeg-sys-the-third/static"] +build = ["static", "ffmpeg-sys-the-third/build"] # mark enums in generated bindings as #[non_exhaustive] -non-exhaustive-enums = ["ffmpeg-sys-next/non-exhaustive-enums"] +non-exhaustive-enums = ["ffmpeg-sys-the-third/non-exhaustive-enums"] # licensing -build-license-gpl = ["ffmpeg-sys-next/build-license-gpl"] -build-license-nonfree = ["ffmpeg-sys-next/build-license-nonfree"] -build-license-version3 = ["ffmpeg-sys-next/build-license-version3"] +build-license-gpl = ["ffmpeg-sys-the-third/build-license-gpl"] +build-license-nonfree = ["ffmpeg-sys-the-third/build-license-nonfree"] +build-license-version3 = ["ffmpeg-sys-the-third/build-license-version3"] # misc -build-pic = ["ffmpeg-sys-next/build-pic"] -build-zlib = ["ffmpeg-sys-next/build-zlib"] +build-pic = ["ffmpeg-sys-the-third/build-pic"] +build-zlib = ["ffmpeg-sys-the-third/build-zlib"] # ssl -build-lib-gnutls = ["ffmpeg-sys-next/build-lib-gnutls"] -build-lib-openssl = ["ffmpeg-sys-next/build-lib-openssl"] +build-lib-gnutls = ["ffmpeg-sys-the-third/build-lib-gnutls"] +build-lib-openssl = ["ffmpeg-sys-the-third/build-lib-openssl"] # filters -build-lib-fontconfig = ["ffmpeg-sys-next/build-lib-fontconfig"] -build-lib-frei0r = ["ffmpeg-sys-next/build-lib-frei0r"] -build-lib-ladspa = ["ffmpeg-sys-next/build-lib-ladspa"] -build-lib-ass = ["ffmpeg-sys-next/build-lib-ass"] -build-lib-freetype = ["ffmpeg-sys-next/build-lib-freetype"] -build-lib-freebidi = ["ffmpeg-sys-next/build-lib-freebidi"] -build-lib-opencv = ["ffmpeg-sys-next/build-lib-opencv"] -build-lib-vmaf = ["ffmpeg-sys-next/build-lib-vmaf"] +build-lib-fontconfig = ["ffmpeg-sys-the-third/build-lib-fontconfig"] +build-lib-frei0r = ["ffmpeg-sys-the-third/build-lib-frei0r"] +build-lib-ladspa = ["ffmpeg-sys-the-third/build-lib-ladspa"] +build-lib-ass = ["ffmpeg-sys-the-third/build-lib-ass"] +build-lib-freetype = ["ffmpeg-sys-the-third/build-lib-freetype"] +build-lib-freebidi = ["ffmpeg-sys-the-third/build-lib-freebidi"] +build-lib-opencv = ["ffmpeg-sys-the-third/build-lib-opencv"] +build-lib-vmaf = ["ffmpeg-sys-the-third/build-lib-vmaf"] # encoders/decoders -build-lib-aacplus = ["ffmpeg-sys-next/build-lib-aacplus"] -build-lib-celt = ["ffmpeg-sys-next/build-lib-celt"] -build-lib-dav1d = ["ffmpeg-sys-next/build-lib-dav1d"] -build-lib-dcadec = ["ffmpeg-sys-next/build-lib-dcadec"] -build-lib-faac = ["ffmpeg-sys-next/build-lib-faac"] -build-lib-fdk-aac = ["ffmpeg-sys-next/build-lib-fdk-aac"] -build-lib-gsm = ["ffmpeg-sys-next/build-lib-gsm"] -build-lib-ilbc = ["ffmpeg-sys-next/build-lib-ilbc"] -build-lib-kvazaar = ["ffmpeg-sys-next/build-lib-kvazaar"] -build-lib-mp3lame = ["ffmpeg-sys-next/build-lib-mp3lame"] -build-lib-opencore-amrnb = ["ffmpeg-sys-next/build-lib-opencore-amrnb"] -build-lib-opencore-amrwb = ["ffmpeg-sys-next/build-lib-opencore-amrwb"] -build-lib-openh264 = ["ffmpeg-sys-next/build-lib-openh264"] -build-lib-openjpeg = ["ffmpeg-sys-next/build-lib-openjpeg"] -build-lib-opus = ["ffmpeg-sys-next/build-lib-opus"] -build-lib-schroedinger = ["ffmpeg-sys-next/build-lib-schroedinger"] -build-lib-shine = ["ffmpeg-sys-next/build-lib-shine"] -build-lib-snappy = ["ffmpeg-sys-next/build-lib-snappy"] -build-lib-speex = ["ffmpeg-sys-next/build-lib-speex"] -build-lib-stagefright-h264 = ["ffmpeg-sys-next/build-lib-stagefright-h264"] -build-lib-theora = ["ffmpeg-sys-next/build-lib-theora"] -build-lib-twolame = ["ffmpeg-sys-next/build-lib-twolame"] -build-lib-utvideo = ["ffmpeg-sys-next/build-lib-utvideo"] -build-lib-vo-aacenc = ["ffmpeg-sys-next/build-lib-vo-aacenc"] -build-lib-vo-amrwbenc = ["ffmpeg-sys-next/build-lib-vo-amrwbenc"] -build-lib-vorbis = ["ffmpeg-sys-next/build-lib-vorbis"] -build-lib-vpx = ["ffmpeg-sys-next/build-lib-vpx"] -build-lib-wavpack = ["ffmpeg-sys-next/build-lib-wavpack"] -build-lib-webp = ["ffmpeg-sys-next/build-lib-webp"] -build-lib-x264 = ["ffmpeg-sys-next/build-lib-x264"] -build-lib-x265 = ["ffmpeg-sys-next/build-lib-x265"] -build-lib-avs = ["ffmpeg-sys-next/build-lib-avs"] -build-lib-xvid = ["ffmpeg-sys-next/build-lib-xvid"] +build-lib-aacplus = ["ffmpeg-sys-the-third/build-lib-aacplus"] +build-lib-celt = ["ffmpeg-sys-the-third/build-lib-celt"] +build-lib-dav1d = ["ffmpeg-sys-the-third/build-lib-dav1d"] +build-lib-dcadec = ["ffmpeg-sys-the-third/build-lib-dcadec"] +build-lib-faac = ["ffmpeg-sys-the-third/build-lib-faac"] +build-lib-fdk-aac = ["ffmpeg-sys-the-third/build-lib-fdk-aac"] +build-lib-gsm = ["ffmpeg-sys-the-third/build-lib-gsm"] +build-lib-ilbc = ["ffmpeg-sys-the-third/build-lib-ilbc"] +build-lib-kvazaar = ["ffmpeg-sys-the-third/build-lib-kvazaar"] +build-lib-mp3lame = ["ffmpeg-sys-the-third/build-lib-mp3lame"] +build-lib-opencore-amrnb = ["ffmpeg-sys-the-third/build-lib-opencore-amrnb"] +build-lib-opencore-amrwb = ["ffmpeg-sys-the-third/build-lib-opencore-amrwb"] +build-lib-openh264 = ["ffmpeg-sys-the-third/build-lib-openh264"] +build-lib-openjpeg = ["ffmpeg-sys-the-third/build-lib-openjpeg"] +build-lib-opus = ["ffmpeg-sys-the-third/build-lib-opus"] +build-lib-schroedinger = ["ffmpeg-sys-the-third/build-lib-schroedinger"] +build-lib-shine = ["ffmpeg-sys-the-third/build-lib-shine"] +build-lib-snappy = ["ffmpeg-sys-the-third/build-lib-snappy"] +build-lib-speex = ["ffmpeg-sys-the-third/build-lib-speex"] +build-lib-stagefright-h264 = ["ffmpeg-sys-the-third/build-lib-stagefright-h264"] +build-lib-theora = ["ffmpeg-sys-the-third/build-lib-theora"] +build-lib-twolame = ["ffmpeg-sys-the-third/build-lib-twolame"] +build-lib-utvideo = ["ffmpeg-sys-the-third/build-lib-utvideo"] +build-lib-vo-aacenc = ["ffmpeg-sys-the-third/build-lib-vo-aacenc"] +build-lib-vo-amrwbenc = ["ffmpeg-sys-the-third/build-lib-vo-amrwbenc"] +build-lib-vorbis = ["ffmpeg-sys-the-third/build-lib-vorbis"] +build-lib-vpx = ["ffmpeg-sys-the-third/build-lib-vpx"] +build-lib-wavpack = ["ffmpeg-sys-the-third/build-lib-wavpack"] +build-lib-webp = ["ffmpeg-sys-the-third/build-lib-webp"] +build-lib-x264 = ["ffmpeg-sys-the-third/build-lib-x264"] +build-lib-x265 = ["ffmpeg-sys-the-third/build-lib-x265"] +build-lib-avs = ["ffmpeg-sys-the-third/build-lib-avs"] +build-lib-xvid = ["ffmpeg-sys-the-third/build-lib-xvid"] # protocols -build-lib-smbclient = ["ffmpeg-sys-next/build-lib-smbclient"] -build-lib-ssh = ["ffmpeg-sys-next/build-lib-ssh"] +build-lib-smbclient = ["ffmpeg-sys-the-third/build-lib-smbclient"] +build-lib-ssh = ["ffmpeg-sys-the-third/build-lib-ssh"] # components -codec = ["ffmpeg-sys-next/avcodec"] -device = ["ffmpeg-sys-next/avdevice", "format"] -filter = ["ffmpeg-sys-next/avfilter"] -format = ["ffmpeg-sys-next/avformat", "codec"] -resampling = ["ffmpeg-sys-next/avresample"] -postprocessing = ["ffmpeg-sys-next/postproc"] -software-resampling = ["ffmpeg-sys-next/swresample"] -software-scaling = ["ffmpeg-sys-next/swscale", "codec"] +codec = ["ffmpeg-sys-the-third/avcodec"] +device = ["ffmpeg-sys-the-third/avdevice", "format"] +filter = ["ffmpeg-sys-the-third/avfilter"] +format = ["ffmpeg-sys-the-third/avformat", "codec"] +resampling = ["ffmpeg-sys-the-third/avresample"] +postprocessing = ["ffmpeg-sys-the-third/postproc"] +software-resampling = ["ffmpeg-sys-the-third/swresample"] +software-scaling = ["ffmpeg-sys-the-third/swscale", "codec"] # platforms rpi = [] [dependencies] -libc = "0.2" +libc = "0.2" bitflags = "1.2" [dependencies.image] -version = "0.23" +version = "0.23" optional = true -[dependencies.ffmpeg-sys-next] +[dependencies.ffmpeg-sys-the-third] version = "5.1.1" default-features = false diff --git a/README.md b/README.md index 6a8ce8b..f956577 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,23 @@ -[![crates.io](https://img.shields.io/crates/v/ffmpeg-next.svg)](https://crates.io/crates/ffmpeg-next) -[![docs.rs](https://docs.rs/ffmpeg-next/badge.svg)](https://docs.rs/ffmpeg-next/) -[![build](https://github.com/zmwangx/rust-ffmpeg/workflows/build/badge.svg)](https://github.com/zmwangx/rust-ffmpeg/actions) +[![crates.io](https://img.shields.io/crates/v/ffmpeg-the-third.svg)](https://crates.io/crates/ffmpeg-the-third) +[![docs.rs](https://docs.rs/ffmpeg-the-third/badge.svg)](https://docs.rs/ffmpeg-the-third/) +[![build](https://github.com/shssoichiro/ffmpeg-the-third/workflows/build/badge.svg)](https://github.com/shssoichiro/ffmpeg-the-third/actions) -This is a fork of the abandoned [ffmpeg](https://crates.io/crates/ffmpeg) crate by [meh.](https://github.com/meh/rust-ffmpeg). +This is a fork of the abandoned [ffmpeg-next](https://crates.io/crates/ffmpeg-next) crate which is a fork of the abandoned [ffmpeg](https://crates.io/crates/ffmpeg) crate. -Currently supported FFmpeg versions: 3.4.x through 4.4.x. +Currently supported FFmpeg versions: 4.x, 5.x. Build instructions can be found on the [wiki](https://github.com/zmwangx/rust-ffmpeg/wiki/Notes-on-building). Documentation: -- [docs.rs](https://docs.rs/ffmpeg-next/); +- [docs.rs](https://docs.rs/ffmpeg-the-third/); - [FFmpeg user manual](https://ffmpeg.org/ffmpeg-all.html); - [FFmpeg Doxygen](https://ffmpeg.org/doxygen/trunk/). -*Note on upgrading to v4.3.4 or later: v4.3.4 introduced automatic FFmpeg version detection, obsoleting feature flags `ffmpeg4`, `ffmpeg41`, `ffmpeg42` and `ffmpeg43`. If you manually specify any of these features, now is the time to remove them; if you use `ffmpeg43` through the `default` feature, it's still on for backward-compatibility but it has turned into a no-op, and you don't need to do anything. Deprecation plan: `ffmpeg43` will be dropped from default features come 4.4, and all these features will be removed come 5.0.* +_Note on upgrading to v4.3.4 or later: v4.3.4 introduced automatic FFmpeg version detection, obsoleting feature flags `ffmpeg4`, `ffmpeg41`, `ffmpeg42` and `ffmpeg43`. If you manually specify any of these features, now is the time to remove them; if you use `ffmpeg43` through the `default` feature, it's still on for backward-compatibility but it has turned into a no-op, and you don't need to do anything. Deprecation plan: `ffmpeg43` will be dropped from default features come 4.4, and all these features will be removed come 5.0._ -*See [CHANGELOG.md](CHANGELOG.md) for other information on version upgrades.* +_See [CHANGELOG.md](CHANGELOG.md) for other information on version upgrades._ A word on versioning: major and minor versions of this crate track major and minor versions of FFmpeg, e.g. 4.2.x of this crate has been updated to support the 4.2.x series of FFmpeg. Patch level is reserved for changes to this crate and does not track FFmpeg patch versions. Since we can only freely bump the patch level, versioning of this crate differs from semver: minor versions may behave like semver major versions and introduce backward-incompatible changes; patch versions may behave like semver minor versions and introduce new APIs. Please peg the version you use accordingly. -**Please realize that this crate is in maintenance-only mode for the most part.** Which means I'll try my best to ensure the crate compiles against all release branches of FFmpeg 3.4 and later (only the latest patch release of each release branch is officially supported) and fix reported bugs, but if a new FFmpeg version brings new APIs that require significant effort to port to Rust, you might have to send me a PR (and just to be clear, I can't really guarantee I'll have the time to review). Any PR to improve existing API is unlikely to be merged, unfortunately. - -🤝 **If you have significant, demonstrable experience in Rust and multimedia-related programming, please let me know, I'll be more than happy to invite you as a collaborator.** 🤝 +**If you have significant, demonstrable experience in Rust and multimedia-related programming, please let me know, I'll be more than happy to invite you as a collaborator.** diff --git a/ffmpeg-sys-the-third/.github/workflows/build.yml b/ffmpeg-sys-the-third/.github/workflows/build.yml new file mode 100644 index 0000000..7dc321f --- /dev/null +++ b/ffmpeg-sys-the-third/.github/workflows/build.yml @@ -0,0 +1,41 @@ +name: build +on: + push: + pull_request: + schedule: + - cron: "0 0 * * *" +jobs: + build-test-lint: + name: FFmpeg ${{ matrix.ffmpeg_version }} - build, test and lint + runs-on: ubuntu-latest + container: jrottenberg/ffmpeg:${{ matrix.ffmpeg_version }}-ubuntu + strategy: + matrix: + ffmpeg_version: ['3.3', '3.4', '4.0', '4.1', '4.2', '4.3', '4.4', '5.0', '5.1'] + fail-fast: false + env: + FEATURES: avcodec,avdevice,avfilter,avformat,postproc,swresample,swscale + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: | + apt update + apt install -y --no-install-recommends clang curl pkg-config + - name: Set up Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + components: rustfmt, clippy + - name: Build + run: | + cargo build --features $FEATURES + - name: Test + run: | + cargo test --features $FEATURES + - name: Lint + run: | + cargo clippy --features $FEATURES -- -D warnings + - name: Check format + run: | + cargo fmt -- --check diff --git a/ffmpeg-sys-the-third/.gitignore b/ffmpeg-sys-the-third/.gitignore new file mode 100644 index 0000000..9079119 --- /dev/null +++ b/ffmpeg-sys-the-third/.gitignore @@ -0,0 +1,3 @@ +target +Cargo.lock +/tmp diff --git a/ffmpeg-sys-the-third/Cargo.toml b/ffmpeg-sys-the-third/Cargo.toml new file mode 100644 index 0000000..ee5db9e --- /dev/null +++ b/ffmpeg-sys-the-third/Cargo.toml @@ -0,0 +1,119 @@ +[package] +name = "ffmpeg-sys-the-third" +version = "5.1.1" +build = "build.rs" +links = "ffmpeg" + +authors = ["meh. ", "Zhiming Wang "] +license = "WTFPL" + +description = "FFI bindings to FFmpeg" +repository = "https://github.com/zmwangx/rust-ffmpeg-sys" +keywords = ["audio", "video"] + +[lib] +# Disable doctests as a workaround for https://github.com/rust-lang/rust-bindgen/issues/1313 +doctest = false + +[dependencies] +libc = "0.2" + +[build-dependencies] +num_cpus = "1.11" +cc = "1.0" +pkg-config = "0.3" +bindgen = { version = "0.59", default-features = false, features = ["runtime"] } + +[target.'cfg(target_env = "msvc")'.build-dependencies] +vcpkg = "0.2" + +[features] +default = [ + "avcodec", + "avdevice", + "avfilter", + "avformat", + "swresample", + "swscale", + "non-exhaustive-enums", +] + +static = [] +build = ["static"] + +# mark enums in generated bindings as #[non_exhaustive] +non-exhaustive-enums = [] + +# licensing +build-license-gpl = ["build"] +build-license-nonfree = ["build"] +build-license-version3 = ["build"] + +# misc +build-drm = ["build"] +build-nvenc = ["build"] +build-pic = ["build"] +build-zlib = ["build"] + +# ssl +build-lib-gnutls = ["build"] +build-lib-openssl = ["build"] + +# filters +build-lib-fontconfig = ["build"] +build-lib-frei0r = ["build"] +build-lib-ladspa = ["build"] +build-lib-ass = ["build"] +build-lib-freetype = ["build"] +build-lib-freebidi = ["build"] +build-lib-opencv = ["build"] +build-lib-vmaf = ["build"] + +# encoders/decoders +build-lib-aacplus = ["build"] +build-lib-celt = ["build"] +build-lib-dav1d = ["build"] +build-lib-dcadec = ["build"] +build-lib-faac = ["build"] +build-lib-fdk-aac = ["build"] +build-lib-gsm = ["build"] +build-lib-ilbc = ["build"] +build-lib-kvazaar = ["build"] +build-lib-mp3lame = ["build"] +build-lib-opencore-amrnb = ["build"] +build-lib-opencore-amrwb = ["build"] +build-lib-openh264 = ["build"] +build-lib-openjpeg = ["build"] +build-lib-opus = ["build"] +build-lib-schroedinger = ["build"] +build-lib-shine = ["build"] +build-lib-snappy = ["build"] +build-lib-speex = ["build"] +build-lib-stagefright-h264 = ["build"] +build-lib-theora = ["build"] +build-lib-twolame = ["build"] +build-lib-utvideo = ["build"] +build-lib-vo-aacenc = ["build"] +build-lib-vo-amrwbenc = ["build"] +build-lib-vorbis = ["build"] +build-lib-vpx = ["build"] +build-lib-wavpack = ["build"] +build-lib-webp = ["build"] +build-lib-x264 = ["build"] +build-lib-x265 = ["build"] +build-lib-avs = ["build"] +build-lib-xvid = ["build"] + +# protocols +build-lib-smbclient = ["build"] +build-lib-ssh = ["build"] + +# components +avcodec = [] +avdevice = ["avformat"] +avfilter = [] +avformat = ["avcodec"] +avresample = [] +postproc = [] +swresample = [] +swscale = [] diff --git a/ffmpeg-sys-the-third/README.md b/ffmpeg-sys-the-third/README.md new file mode 100644 index 0000000..1061a1d --- /dev/null +++ b/ffmpeg-sys-the-third/README.md @@ -0,0 +1,31 @@ +[![ffmpeg-sys-the-third on crates.io](https://img.shields.io/crates/v/ffmpeg-sys-the-third?cacheSeconds=3600)](https://crates.io/crates/ffmpeg-sys-the-third) +[![build](https://github.com/zmwangx/rust-ffmpeg-sys/workflows/build/badge.svg)](https://github.com/zmwangx/rust-ffmpeg-sys/actions) + +This is a fork of the abandoned [ffmpeg-sys](https://github.com/meh/rust-ffmpeg-sys) crate. You can find this crate as [ffmpeg-sys-the-third](https://crates.io/crates/ffmpeg-sys-the-third) on crates.io. + +This crate contains low level bindings to FFmpeg. You're probably interested in the high level bindings instead: [ffmpeg-next](https://github.com/zmwangx/rust-ffmpeg). + +A word on versioning: major and minor versions track major and minor versions of FFmpeg, e.g. 4.2.x of this crate has been updated to support the 4.2.x series of FFmpeg. Patch level is reserved for bug fixes of this crate and does not track FFmpeg patch versions. + +## Feature flags + +In addition to feature flags declared in `Cargo.toml`, this crate performs various compile-time version and feature detections and exposes the results in additional flags. These flags are briefly documented below; run `cargo build -vv` to view more details. + +- `ffmpeg__` flags (new in v4.3.2), e.g. `ffmpeg_4_4`, indicating the FFmpeg installation being compiled against is at least version `.`. Currently available: + + - `ffmpeg_3_0` + - `ffmpeg_3_1` + - `ffmpeg_3_2` + - `ffmpeg_3_3` + - `ffmpeg_3_1` + - `ffmpeg_4_0` + - `ffmpeg_4_1` + - `ffmpeg_4_2` + - `ffmpeg_4_3` + - `ffmpeg_4_4` + +- `avcodec_version_greater_than__` (new in v4.3.2), e.g., `avcodec_version_greater_than_58_90`. The name should be self-explanatory. + +- `ff_api_`, e.g. `ff_api_vaapi`, corresponding to whether their respective uppercase deprecation guards evaluate to true. + +- `ff_api__is_defined`, e.g. `ff_api_vappi_is_defined`, similar to above except these are enabled as long as the corresponding deprecation guards are defined. diff --git a/ffmpeg-sys-the-third/build.rs b/ffmpeg-sys-the-third/build.rs new file mode 100644 index 0000000..ecf3d9c --- /dev/null +++ b/ffmpeg-sys-the-third/build.rs @@ -0,0 +1,1301 @@ +extern crate bindgen; +extern crate cc; +extern crate num_cpus; +extern crate pkg_config; + +use std::env; +use std::fmt::Write as FmtWrite; +use std::fs::{self, File}; +use std::io::{self, BufRead, BufReader, Write}; +use std::path::PathBuf; +use std::process::Command; +use std::str; + +use bindgen::callbacks::{ + EnumVariantCustomBehavior, EnumVariantValue, IntKind, MacroParsingBehavior, ParseCallbacks, +}; + +#[derive(Debug)] +struct Library { + name: &'static str, + is_feature: bool, +} + +impl Library { + fn feature_name(&self) -> Option { + if self.is_feature { + Some("CARGO_FEATURE_".to_string() + &self.name.to_uppercase()) + } else { + None + } + } +} + +static LIBRARIES: &[Library] = &[ + Library { + name: "avcodec", + is_feature: true, + }, + Library { + name: "avdevice", + is_feature: true, + }, + Library { + name: "avfilter", + is_feature: true, + }, + Library { + name: "avformat", + is_feature: true, + }, + Library { + name: "avresample", + is_feature: true, + }, + Library { + name: "avutil", + is_feature: false, + }, + Library { + name: "postproc", + is_feature: true, + }, + Library { + name: "swresample", + is_feature: true, + }, + Library { + name: "swscale", + is_feature: true, + }, +]; + +#[derive(Debug)] +struct Callbacks; + +impl ParseCallbacks for Callbacks { + fn int_macro(&self, _name: &str, value: i64) -> Option { + let ch_layout_prefix = "AV_CH_"; + let codec_cap_prefix = "AV_CODEC_CAP_"; + let codec_flag_prefix = "AV_CODEC_FLAG_"; + let error_max_size = "AV_ERROR_MAX_STRING_SIZE"; + + if value >= i64::min_value() as i64 + && value <= i64::max_value() as i64 + && _name.starts_with(ch_layout_prefix) + { + Some(IntKind::ULongLong) + } else if value >= i32::min_value() as i64 + && value <= i32::max_value() as i64 + && (_name.starts_with(codec_cap_prefix) || _name.starts_with(codec_flag_prefix)) + { + Some(IntKind::UInt) + } else if _name == error_max_size { + Some(IntKind::Custom { + name: "usize", + is_signed: false, + }) + } else if value >= i32::min_value() as i64 && value <= i32::max_value() as i64 { + Some(IntKind::Int) + } else { + None + } + } + + fn enum_variant_behavior( + &self, + _enum_name: Option<&str>, + original_variant_name: &str, + _variant_value: EnumVariantValue, + ) -> Option { + let dummy_codec_id_prefix = "AV_CODEC_ID_FIRST_"; + if original_variant_name.starts_with(dummy_codec_id_prefix) { + Some(EnumVariantCustomBehavior::Constify) + } else { + None + } + } + + // https://github.com/rust-lang/rust-bindgen/issues/687#issuecomment-388277405 + fn will_parse_macro(&self, name: &str) -> MacroParsingBehavior { + use MacroParsingBehavior::*; + + match name { + "FP_INFINITE" => Ignore, + "FP_NAN" => Ignore, + "FP_NORMAL" => Ignore, + "FP_SUBNORMAL" => Ignore, + "FP_ZERO" => Ignore, + _ => Default, + } + } +} + +fn version() -> String { + let major: u8 = env::var("CARGO_PKG_VERSION_MAJOR") + .unwrap() + .parse() + .unwrap(); + let minor: u8 = env::var("CARGO_PKG_VERSION_MINOR") + .unwrap() + .parse() + .unwrap(); + + format!("{}.{}", major, minor) +} + +fn output() -> PathBuf { + PathBuf::from(env::var("OUT_DIR").unwrap()) +} + +fn source() -> PathBuf { + output().join(format!("ffmpeg-{}", version())) +} + +fn search() -> PathBuf { + let mut absolute = env::current_dir().unwrap(); + absolute.push(&output()); + absolute.push("dist"); + + absolute +} + +fn fetch() -> io::Result<()> { + let output_base_path = output(); + let clone_dest_dir = format!("ffmpeg-{}", version()); + let _ = std::fs::remove_dir_all(output_base_path.join(&clone_dest_dir)); + let status = Command::new("git") + .current_dir(&output_base_path) + .arg("clone") + .arg("--depth=1") + .arg("-b") + .arg(format!("release/{}", version())) + .arg("https://github.com/FFmpeg/FFmpeg") + .arg(&clone_dest_dir) + .status()?; + + if status.success() { + Ok(()) + } else { + Err(io::Error::new(io::ErrorKind::Other, "fetch failed")) + } +} + +fn switch(configure: &mut Command, feature: &str, name: &str) { + let arg = if env::var("CARGO_FEATURE_".to_string() + feature).is_ok() { + "--enable-" + } else { + "--disable-" + }; + configure.arg(arg.to_string() + name); +} + +fn build() -> io::Result<()> { + let source_dir = source(); + + // Command's path is not relative to command's current_dir + let configure_path = source_dir.join("configure"); + assert!(configure_path.exists()); + let mut configure = Command::new(&configure_path); + configure.current_dir(&source_dir); + + configure.arg(format!("--prefix={}", search().to_string_lossy())); + + if env::var("TARGET").unwrap() != env::var("HOST").unwrap() { + // Rust targets are subtly different than naming scheme for compiler prefixes. + // The cc crate has the messy logic of guessing a working prefix, + // and this is a messy way of reusing that logic. + let cc = cc::Build::new(); + let compiler = cc.get_compiler(); + let compiler = compiler.path().file_stem().unwrap().to_str().unwrap(); + let suffix_pos = compiler.rfind('-').unwrap(); // cut off "-gcc" + let prefix = compiler[0..suffix_pos].trim_end_matches("-wr"); // "wr-c++" compiler + + configure.arg(format!("--cross-prefix={}-", prefix)); + configure.arg(format!( + "--arch={}", + env::var("CARGO_CFG_TARGET_ARCH").unwrap() + )); + configure.arg(format!( + "--target_os={}", + env::var("CARGO_CFG_TARGET_OS").unwrap() + )); + } + + // control debug build + if env::var("DEBUG").is_ok() { + configure.arg("--enable-debug"); + configure.arg("--disable-stripping"); + } else { + configure.arg("--disable-debug"); + configure.arg("--enable-stripping"); + } + + // make it static + configure.arg("--enable-static"); + configure.arg("--disable-shared"); + + configure.arg("--enable-pic"); + + // stop autodetected libraries enabling themselves, causing linking errors + configure.arg("--disable-autodetect"); + + // do not build programs since we don't need them + configure.arg("--disable-programs"); + + macro_rules! enable { + ($conf:expr, $feat:expr, $name:expr) => { + if env::var(concat!("CARGO_FEATURE_", $feat)).is_ok() { + $conf.arg(concat!("--enable-", $name)); + } + }; + } + + // macro_rules! disable { + // ($conf:expr, $feat:expr, $name:expr) => ( + // if env::var(concat!("CARGO_FEATURE_", $feat)).is_err() { + // $conf.arg(concat!("--disable-", $name)); + // } + // ) + // } + + // the binary using ffmpeg-sys must comply with GPL + switch(&mut configure, "BUILD_LICENSE_GPL", "gpl"); + + // the binary using ffmpeg-sys must comply with (L)GPLv3 + switch(&mut configure, "BUILD_LICENSE_VERSION3", "version3"); + + // the binary using ffmpeg-sys cannot be redistributed + switch(&mut configure, "BUILD_LICENSE_NONFREE", "nonfree"); + + let ffmpeg_major_version: u32 = env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap(); + + // configure building libraries based on features + for lib in LIBRARIES + .iter() + .filter(|lib| lib.is_feature) + .filter(|lib| !(lib.name == "avresample" && ffmpeg_major_version >= 5)) + { + switch(&mut configure, &lib.name.to_uppercase(), lib.name); + } + + // configure external SSL libraries + enable!(configure, "BUILD_LIB_GNUTLS", "gnutls"); + enable!(configure, "BUILD_LIB_OPENSSL", "openssl"); + + // configure external filters + enable!(configure, "BUILD_LIB_FONTCONFIG", "fontconfig"); + enable!(configure, "BUILD_LIB_FREI0R", "frei0r"); + enable!(configure, "BUILD_LIB_LADSPA", "ladspa"); + enable!(configure, "BUILD_LIB_ASS", "libass"); + enable!(configure, "BUILD_LIB_FREETYPE", "libfreetype"); + enable!(configure, "BUILD_LIB_FRIBIDI", "libfribidi"); + enable!(configure, "BUILD_LIB_OPENCV", "libopencv"); + enable!(configure, "BUILD_LIB_VMAF", "libvmaf"); + + // configure external encoders/decoders + enable!(configure, "BUILD_LIB_AACPLUS", "libaacplus"); + enable!(configure, "BUILD_LIB_CELT", "libcelt"); + enable!(configure, "BUILD_LIB_DCADEC", "libdcadec"); + enable!(configure, "BUILD_LIB_DAV1D", "libdav1d"); + enable!(configure, "BUILD_LIB_FAAC", "libfaac"); + enable!(configure, "BUILD_LIB_FDK_AAC", "libfdk-aac"); + enable!(configure, "BUILD_LIB_GSM", "libgsm"); + enable!(configure, "BUILD_LIB_ILBC", "libilbc"); + enable!(configure, "BUILD_LIB_VAZAAR", "libvazaar"); + enable!(configure, "BUILD_LIB_MP3LAME", "libmp3lame"); + enable!(configure, "BUILD_LIB_OPENCORE_AMRNB", "libopencore-amrnb"); + enable!(configure, "BUILD_LIB_OPENCORE_AMRWB", "libopencore-amrwb"); + enable!(configure, "BUILD_LIB_OPENH264", "libopenh264"); + enable!(configure, "BUILD_LIB_OPENH265", "libopenh265"); + enable!(configure, "BUILD_LIB_OPENJPEG", "libopenjpeg"); + enable!(configure, "BUILD_LIB_OPUS", "libopus"); + enable!(configure, "BUILD_LIB_SCHROEDINGER", "libschroedinger"); + enable!(configure, "BUILD_LIB_SHINE", "libshine"); + enable!(configure, "BUILD_LIB_SNAPPY", "libsnappy"); + enable!(configure, "BUILD_LIB_SPEEX", "libspeex"); + enable!( + configure, + "BUILD_LIB_STAGEFRIGHT_H264", + "libstagefright-h264" + ); + enable!(configure, "BUILD_LIB_THEORA", "libtheora"); + enable!(configure, "BUILD_LIB_TWOLAME", "libtwolame"); + enable!(configure, "BUILD_LIB_UTVIDEO", "libutvideo"); + enable!(configure, "BUILD_LIB_VO_AACENC", "libvo-aacenc"); + enable!(configure, "BUILD_LIB_VO_AMRWBENC", "libvo-amrwbenc"); + enable!(configure, "BUILD_LIB_VORBIS", "libvorbis"); + enable!(configure, "BUILD_LIB_VPX", "libvpx"); + enable!(configure, "BUILD_LIB_WAVPACK", "libwavpack"); + enable!(configure, "BUILD_LIB_WEBP", "libwebp"); + enable!(configure, "BUILD_LIB_X264", "libx264"); + enable!(configure, "BUILD_LIB_X265", "libx265"); + enable!(configure, "BUILD_LIB_AVS", "libavs"); + enable!(configure, "BUILD_LIB_XVID", "libxvid"); + + // other external libraries + enable!(configure, "BUILD_LIB_DRM", "libdrm"); + enable!(configure, "BUILD_NVENC", "nvenc"); + + // configure external protocols + enable!(configure, "BUILD_LIB_SMBCLIENT", "libsmbclient"); + enable!(configure, "BUILD_LIB_SSH", "libssh"); + + // configure misc build options + enable!(configure, "BUILD_PIC", "pic"); + + // run ./configure + let output = configure + .output() + .unwrap_or_else(|_| panic!("{:?} failed", configure)); + if !output.status.success() { + println!("configure: {}", String::from_utf8_lossy(&output.stdout)); + + return Err(io::Error::new( + io::ErrorKind::Other, + format!( + "configure failed {}", + String::from_utf8_lossy(&output.stderr) + ), + )); + } + + // run make + if !Command::new("make") + .arg("-j") + .arg(num_cpus::get().to_string()) + .current_dir(&source()) + .status()? + .success() + { + return Err(io::Error::new(io::ErrorKind::Other, "make failed")); + } + + // run make install + if !Command::new("make") + .current_dir(&source()) + .arg("install") + .status()? + .success() + { + return Err(io::Error::new(io::ErrorKind::Other, "make install failed")); + } + + Ok(()) +} + +#[cfg(not(target_env = "msvc"))] +fn try_vcpkg(_statik: bool) -> Option> { + None +} + +#[cfg(target_env = "msvc")] +fn try_vcpkg(statik: bool) -> Option> { + if !statik { + env::set_var("VCPKGRS_DYNAMIC", "1"); + } + + vcpkg::find_package("ffmpeg") + .map_err(|e| { + println!("Could not find ffmpeg with vcpkg: {}", e); + }) + .map(|library| library.include_paths) + .ok() +} + +fn check_features( + include_paths: Vec, + infos: &[(&'static str, Option<&'static str>, &'static str)], +) { + let mut includes_code = String::new(); + let mut main_code = String::new(); + + for &(header, feature, var) in infos { + if let Some(feature) = feature { + if env::var(format!("CARGO_FEATURE_{}", feature.to_uppercase())).is_err() { + continue; + } + } + + let include = format!("#include <{}>", header); + if !includes_code.contains(&include) { + includes_code.push_str(&include); + includes_code.push('\n'); + } + let _ = write!( + includes_code, + r#" + #ifndef {var}_is_defined + #ifndef {var} + #define {var} 0 + #define {var}_is_defined 0 + #else + #define {var}_is_defined 1 + #endif + #endif + "#, + var = var + ); + + let _ = write!( + main_code, + r#"printf("[{var}]%d%d\n", {var}, {var}_is_defined); + "#, + var = var + ); + } + + let version_check_info = [("avcodec", 56, 60, 0, 108)]; + for &(lib, begin_version_major, end_version_major, begin_version_minor, end_version_minor) in + version_check_info.iter() + { + for version_major in begin_version_major..end_version_major { + for version_minor in begin_version_minor..end_version_minor { + let _ = write!( + main_code, + r#"printf("[{lib}_version_greater_than_{version_major}_{version_minor}]%d\n", LIB{lib_uppercase}_VERSION_MAJOR > {version_major} || (LIB{lib_uppercase}_VERSION_MAJOR == {version_major} && LIB{lib_uppercase}_VERSION_MINOR > {version_minor})); + "#, + lib = lib, + lib_uppercase = lib.to_uppercase(), + version_major = version_major, + version_minor = version_minor + ); + } + } + } + + let out_dir = output(); + + write!( + File::create(out_dir.join("check.c")).expect("Failed to create file"), + r#" + #include + {includes_code} + + int main() + {{ + {main_code} + return 0; + }} + "#, + includes_code = includes_code, + main_code = main_code + ) + .expect("Write failed"); + + let executable = out_dir.join(if cfg!(windows) { "check.exe" } else { "check" }); + let mut compiler = cc::Build::new() + .target(&env::var("HOST").unwrap()) // don't cross-compile this + .get_compiler() + .to_command(); + + for dir in include_paths { + compiler.arg("-I"); + compiler.arg(dir.to_string_lossy().into_owned()); + } + if !compiler + .current_dir(&out_dir) + .arg("-o") + .arg(&executable) + .arg("check.c") + .status() + .expect("Command failed") + .success() + { + panic!("Compile failed"); + } + + let check_output = Command::new(out_dir.join(&executable)) + .current_dir(&out_dir) + .output() + .expect("Check failed"); + if !check_output.status.success() { + panic!( + "{} failed: {}\n{}", + executable.display(), + String::from_utf8_lossy(&check_output.stdout), + String::from_utf8_lossy(&check_output.stderr) + ); + } + + let stdout = str::from_utf8(&check_output.stdout).unwrap(); + + println!("stdout of {}={}", executable.display(), stdout); + + for &(_, feature, var) in infos { + if let Some(feature) = feature { + if env::var(format!("CARGO_FEATURE_{}", feature.to_uppercase())).is_err() { + continue; + } + } + + let var_str = format!("[{var}]", var = var); + let pos = var_str.len() + + stdout + .find(&var_str) + .unwrap_or_else(|| panic!("Variable '{}' not found in stdout output", var_str)); + if &stdout[pos..pos + 1] == "1" { + println!(r#"cargo:rustc-cfg=feature="{}""#, var.to_lowercase()); + println!(r#"cargo:{}=true"#, var.to_lowercase()); + } + + // Also find out if defined or not (useful for cases where only the definition of a macro + // can be used as distinction) + if &stdout[pos + 1..pos + 2] == "1" { + println!( + r#"cargo:rustc-cfg=feature="{}_is_defined""#, + var.to_lowercase() + ); + println!(r#"cargo:{}_is_defined=true"#, var.to_lowercase()); + } + } + + for &(lib, begin_version_major, end_version_major, begin_version_minor, end_version_minor) in + version_check_info.iter() + { + for version_major in begin_version_major..end_version_major { + for version_minor in begin_version_minor..end_version_minor { + let search_str = format!( + "[{lib}_version_greater_than_{version_major}_{version_minor}]", + version_major = version_major, + version_minor = version_minor, + lib = lib + ); + let pos = stdout + .find(&search_str) + .expect("Variable not found in output") + + search_str.len(); + + if &stdout[pos..pos + 1] == "1" { + println!( + r#"cargo:rustc-cfg=feature="{}""#, + &search_str[1..(search_str.len() - 1)] + ); + println!(r#"cargo:{}=true"#, &search_str[1..(search_str.len() - 1)]); + } + } + } + } + + let ffmpeg_lavc_versions = [ + ("ffmpeg_3_0", 57, 24), + ("ffmpeg_3_1", 57, 48), + ("ffmpeg_3_2", 57, 64), + ("ffmpeg_3_3", 57, 89), + ("ffmpeg_3_1", 57, 107), + ("ffmpeg_4_0", 58, 18), + ("ffmpeg_4_1", 58, 35), + ("ffmpeg_4_2", 58, 54), + ("ffmpeg_4_3", 58, 91), + ("ffmpeg_4_4", 58, 100), + ("ffmpeg_5_0", 59, 18), + ("ffmpeg_5_1", 59, 37), + ]; + for &(ffmpeg_version_flag, lavc_version_major, lavc_version_minor) in + ffmpeg_lavc_versions.iter() + { + let search_str = format!( + "[avcodec_version_greater_than_{lavc_version_major}_{lavc_version_minor}]", + lavc_version_major = lavc_version_major, + lavc_version_minor = lavc_version_minor - 1 + ); + let pos = stdout + .find(&search_str) + .expect("Variable not found in output") + + search_str.len(); + if &stdout[pos..pos + 1] == "1" { + println!(r#"cargo:rustc-cfg=feature="{}""#, ffmpeg_version_flag); + println!(r#"cargo:{}=true"#, ffmpeg_version_flag); + } + } +} + +fn search_include(include_paths: &[PathBuf], header: &str) -> String { + for dir in include_paths { + let include = dir.join(header); + if fs::metadata(&include).is_ok() { + return include.as_path().to_str().unwrap().to_string(); + } + } + format!("/usr/include/{}", header) +} + +fn maybe_search_include(include_paths: &[PathBuf], header: &str) -> Option { + let path = search_include(include_paths, header); + if fs::metadata(&path).is_ok() { + Some(path) + } else { + None + } +} + +fn link_to_libraries(statik: bool) { + let ffmpeg_ty = if statik { "static" } else { "dylib" }; + for lib in LIBRARIES { + let feat_is_enabled = lib.feature_name().and_then(|f| env::var(&f).ok()).is_some(); + if !lib.is_feature || feat_is_enabled { + println!("cargo:rustc-link-lib={}={}", ffmpeg_ty, lib.name); + } + } + if env::var("CARGO_FEATURE_BUILD_ZLIB").is_ok() && cfg!(target_os = "linux") { + println!("cargo:rustc-link-lib=z"); + } +} + +fn main() { + let statik = env::var("CARGO_FEATURE_STATIC").is_ok(); + let ffmpeg_major_version: u32 = env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap(); + + let include_paths: Vec = if env::var("CARGO_FEATURE_BUILD").is_ok() { + println!( + "cargo:rustc-link-search=native={}", + search().join("lib").to_string_lossy() + ); + link_to_libraries(statik); + if fs::metadata(&search().join("lib").join("libavutil.a")).is_err() { + fs::create_dir_all(&output()).expect("failed to create build directory"); + fetch().unwrap(); + build().unwrap(); + } + + // Check additional required libraries. + { + let config_mak = source().join("ffbuild/config.mak"); + let file = File::open(config_mak).unwrap(); + let reader = BufReader::new(file); + let extra_libs = reader + .lines() + .find(|line| line.as_ref().unwrap().starts_with("EXTRALIBS")) + .map(|line| line.unwrap()) + .unwrap(); + + let linker_args = extra_libs.split('=').last().unwrap().split(' '); + let include_libs = linker_args + .filter(|v| v.starts_with("-l")) + .map(|flag| &flag[2..]); + + for lib in include_libs { + println!("cargo:rustc-link-lib={}", lib); + } + } + + vec![search().join("include")] + } + // Use prebuilt library + else if let Ok(ffmpeg_dir) = env::var("FFMPEG_DIR") { + let ffmpeg_dir = PathBuf::from(ffmpeg_dir); + println!( + "cargo:rustc-link-search=native={}", + ffmpeg_dir.join("lib").to_string_lossy() + ); + link_to_libraries(statik); + vec![ffmpeg_dir.join("include")] + } else if let Some(paths) = try_vcpkg(statik) { + // vcpkg doesn't detect the "system" dependencies + if statik { + if cfg!(feature = "avcodec") || cfg!(feature = "avdevice") { + println!("cargo:rustc-link-lib=ole32"); + } + + if cfg!(feature = "avformat") { + println!("cargo:rustc-link-lib=secur32"); + println!("cargo:rustc-link-lib=ws2_32"); + } + + // avutil depdendencies + println!("cargo:rustc-link-lib=bcrypt"); + println!("cargo:rustc-link-lib=user32"); + } + + paths + } + // Fallback to pkg-config + else { + pkg_config::Config::new() + .statik(statik) + .probe("libavutil") + .unwrap(); + + let mut libs = vec![ + ("libavformat", "AVFORMAT"), + ("libavfilter", "AVFILTER"), + ("libavdevice", "AVDEVICE"), + ("libswscale", "SWSCALE"), + ("libswresample", "SWRESAMPLE"), + ]; + if ffmpeg_major_version < 5 { + libs.push(("libavresample", "AVRESAMPLE")); + } + + for (lib_name, env_variable_name) in libs.iter() { + if env::var(format!("CARGO_FEATURE_{}", env_variable_name)).is_ok() { + pkg_config::Config::new() + .statik(statik) + .probe(lib_name) + .unwrap(); + } + } + + pkg_config::Config::new() + .statik(statik) + .probe("libavcodec") + .unwrap() + .include_paths + }; + + if statik && cfg!(target_os = "macos") { + let frameworks = vec![ + "AppKit", + "AudioToolbox", + "AVFoundation", + "CoreFoundation", + "CoreGraphics", + "CoreMedia", + "CoreServices", + "CoreVideo", + "Foundation", + "OpenCL", + "OpenGL", + "QTKit", + "QuartzCore", + "Security", + "VideoDecodeAcceleration", + "VideoToolbox", + ]; + for f in frameworks { + println!("cargo:rustc-link-lib=framework={}", f); + } + } + + check_features( + include_paths.clone(), + &[ + ("libavutil/avutil.h", None, "FF_API_OLD_AVOPTIONS"), + ("libavutil/avutil.h", None, "FF_API_PIX_FMT"), + ("libavutil/avutil.h", None, "FF_API_CONTEXT_SIZE"), + ("libavutil/avutil.h", None, "FF_API_PIX_FMT_DESC"), + ("libavutil/avutil.h", None, "FF_API_AV_REVERSE"), + ("libavutil/avutil.h", None, "FF_API_AUDIOCONVERT"), + ("libavutil/avutil.h", None, "FF_API_CPU_FLAG_MMX2"), + ("libavutil/avutil.h", None, "FF_API_LLS_PRIVATE"), + ("libavutil/avutil.h", None, "FF_API_AVFRAME_LAVC"), + ("libavutil/avutil.h", None, "FF_API_VDPAU"), + ( + "libavutil/avutil.h", + None, + "FF_API_GET_CHANNEL_LAYOUT_COMPAT", + ), + ("libavutil/avutil.h", None, "FF_API_XVMC"), + ("libavutil/avutil.h", None, "FF_API_OPT_TYPE_METADATA"), + ("libavutil/avutil.h", None, "FF_API_DLOG"), + ("libavutil/avutil.h", None, "FF_API_HMAC"), + ("libavutil/avutil.h", None, "FF_API_VAAPI"), + ("libavutil/avutil.h", None, "FF_API_PKT_PTS"), + ("libavutil/avutil.h", None, "FF_API_ERROR_FRAME"), + ("libavutil/avutil.h", None, "FF_API_FRAME_QP"), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_VIMA_DECODER", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_REQUEST_CHANNELS", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_OLD_DECODE_AUDIO", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_OLD_ENCODE_AUDIO", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_OLD_ENCODE_VIDEO", + ), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_CODEC_ID"), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_AUDIO_CONVERT", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_AVCODEC_RESAMPLE", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_DEINTERLACE", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_DESTRUCT_PACKET", + ), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_GET_BUFFER"), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_MISSING_SAMPLE", + ), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_LOWRES"), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_CAP_VDPAU"), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_BUFS_VDPAU"), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_VOXWARE"), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_SET_DIMENSIONS", + ), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_DEBUG_MV"), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_AC_VLC"), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_OLD_MSMPEG4", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_ASPECT_EXTENDED", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_THREAD_OPAQUE", + ), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_CODEC_PKT"), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_ARCH_ALPHA"), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_ERROR_RATE"), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_QSCALE_TYPE", + ), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_MB_TYPE"), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_MAX_BFRAMES", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_NEG_LINESIZES", + ), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_EMU_EDGE"), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_ARCH_SH4"), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_ARCH_SPARC"), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_UNUSED_MEMBERS", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_IDCT_XVIDMMX", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_INPUT_PRESERVED", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_NORMALIZE_AQP", + ), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_GMC"), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_MV0"), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_CODEC_NAME"), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_AFD"), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_VISMV"), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_DV_FRAME_PROFILE", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_AUDIOENC_DELAY", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_VAAPI_CONTEXT", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_AVCTX_TIMEBASE", + ), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_MPV_OPT"), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_STREAM_CODEC_TAG", + ), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_QUANT_BIAS"), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_RC_STRATEGY", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_CODED_FRAME", + ), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_MOTION_EST"), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_WITHOUT_PREFIX", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_CONVERGENCE_DURATION", + ), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_PRIVATE_OPT", + ), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_CODER_TYPE"), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_RTP_CALLBACK", + ), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_STAT_BITS"), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_VBV_DELAY"), + ( + "libavcodec/avcodec.h", + Some("avcodec"), + "FF_API_SIDEDATA_ONLY_PKT", + ), + ("libavcodec/avcodec.h", Some("avcodec"), "FF_API_AVPICTURE"), + ( + "libavformat/avformat.h", + Some("avformat"), + "FF_API_LAVF_BITEXACT", + ), + ( + "libavformat/avformat.h", + Some("avformat"), + "FF_API_LAVF_FRAC", + ), + ( + "libavformat/avformat.h", + Some("avformat"), + "FF_API_URL_FEOF", + ), + ( + "libavformat/avformat.h", + Some("avformat"), + "FF_API_PROBESIZE_32", + ), + ( + "libavformat/avformat.h", + Some("avformat"), + "FF_API_LAVF_AVCTX", + ), + ( + "libavformat/avformat.h", + Some("avformat"), + "FF_API_OLD_OPEN_CALLBACKS", + ), + ( + "libavfilter/avfilter.h", + Some("avfilter"), + "FF_API_AVFILTERPAD_PUBLIC", + ), + ( + "libavfilter/avfilter.h", + Some("avfilter"), + "FF_API_FOO_COUNT", + ), + ( + "libavfilter/avfilter.h", + Some("avfilter"), + "FF_API_OLD_FILTER_OPTS", + ), + ( + "libavfilter/avfilter.h", + Some("avfilter"), + "FF_API_OLD_FILTER_OPTS_ERROR", + ), + ( + "libavfilter/avfilter.h", + Some("avfilter"), + "FF_API_AVFILTER_OPEN", + ), + ( + "libavfilter/avfilter.h", + Some("avfilter"), + "FF_API_OLD_FILTER_REGISTER", + ), + ( + "libavfilter/avfilter.h", + Some("avfilter"), + "FF_API_OLD_GRAPH_PARSE", + ), + ( + "libavfilter/avfilter.h", + Some("avfilter"), + "FF_API_NOCONST_GET_NAME", + ), + ( + "libavresample/avresample.h", + Some("avresample"), + "FF_API_RESAMPLE_CLOSE_OPEN", + ), + ( + "libswscale/swscale.h", + Some("swscale"), + "FF_API_SWS_CPU_CAPS", + ), + ("libswscale/swscale.h", Some("swscale"), "FF_API_ARCH_BFIN"), + ], + ); + + let clang_includes = include_paths + .iter() + .map(|include| format!("-I{}", include.to_string_lossy())); + + // The bindgen::Builder is the main entry point + // to bindgen, and lets you build up options for + // the resulting bindings. + let mut builder = bindgen::Builder::default() + .clang_args(clang_includes) + .ctypes_prefix("libc") + // https://github.com/rust-lang/rust-bindgen/issues/550 + .blocklist_type("max_align_t") + .blocklist_function("_.*") + // Blocklist functions with u128 in signature. + // https://github.com/zmwangx/rust-ffmpeg-sys/issues/1 + // https://github.com/rust-lang/rust-bindgen/issues/1549 + .blocklist_function("acoshl") + .blocklist_function("acosl") + .blocklist_function("asinhl") + .blocklist_function("asinl") + .blocklist_function("atan2l") + .blocklist_function("atanhl") + .blocklist_function("atanl") + .blocklist_function("cbrtl") + .blocklist_function("ceill") + .blocklist_function("copysignl") + .blocklist_function("coshl") + .blocklist_function("cosl") + .blocklist_function("dreml") + .blocklist_function("ecvt_r") + .blocklist_function("erfcl") + .blocklist_function("erfl") + .blocklist_function("exp2l") + .blocklist_function("expl") + .blocklist_function("expm1l") + .blocklist_function("fabsl") + .blocklist_function("fcvt_r") + .blocklist_function("fdiml") + .blocklist_function("finitel") + .blocklist_function("floorl") + .blocklist_function("fmal") + .blocklist_function("fmaxl") + .blocklist_function("fminl") + .blocklist_function("fmodl") + .blocklist_function("frexpl") + .blocklist_function("gammal") + .blocklist_function("hypotl") + .blocklist_function("ilogbl") + .blocklist_function("isinfl") + .blocklist_function("isnanl") + .blocklist_function("j0l") + .blocklist_function("j1l") + .blocklist_function("jnl") + .blocklist_function("ldexpl") + .blocklist_function("lgammal") + .blocklist_function("lgammal_r") + .blocklist_function("llrintl") + .blocklist_function("llroundl") + .blocklist_function("log10l") + .blocklist_function("log1pl") + .blocklist_function("log2l") + .blocklist_function("logbl") + .blocklist_function("logl") + .blocklist_function("lrintl") + .blocklist_function("lroundl") + .blocklist_function("modfl") + .blocklist_function("nanl") + .blocklist_function("nearbyintl") + .blocklist_function("nextafterl") + .blocklist_function("nexttoward") + .blocklist_function("nexttowardf") + .blocklist_function("nexttowardl") + .blocklist_function("powl") + .blocklist_function("qecvt") + .blocklist_function("qecvt_r") + .blocklist_function("qfcvt") + .blocklist_function("qfcvt_r") + .blocklist_function("qgcvt") + .blocklist_function("remainderl") + .blocklist_function("remquol") + .blocklist_function("rintl") + .blocklist_function("roundl") + .blocklist_function("scalbl") + .blocklist_function("scalblnl") + .blocklist_function("scalbnl") + .blocklist_function("significandl") + .blocklist_function("sinhl") + .blocklist_function("sinl") + .blocklist_function("sqrtl") + .blocklist_function("strtold") + .blocklist_function("tanhl") + .blocklist_function("tanl") + .blocklist_function("tgammal") + .blocklist_function("truncl") + .blocklist_function("y0l") + .blocklist_function("y1l") + .blocklist_function("ynl") + .opaque_type("__mingw_ldbl_type_t") + .prepend_enum_name(false) + .derive_eq(true) + .size_t_is_usize(true) + .parse_callbacks(Box::new(Callbacks)); + + if env::var("CARGO_FEATURE_NON_EXHAUSTIVE_ENUMS").is_ok() { + builder = builder.rustified_non_exhaustive_enum("*"); + } else { + builder = builder.rustified_enum("*"); + } + + // The input headers we would like to generate + // bindings for. + if env::var("CARGO_FEATURE_AVCODEC").is_ok() { + builder = builder + .header(search_include(&include_paths, "libavcodec/avcodec.h")) + .header(search_include(&include_paths, "libavcodec/dv_profile.h")) + .header(search_include(&include_paths, "libavcodec/avfft.h")) + .header(search_include(&include_paths, "libavcodec/vorbis_parser.h")); + + if ffmpeg_major_version < 5 { + builder = builder.header(search_include(&include_paths, "libavcodec/vaapi.h")) + } + } + + if env::var("CARGO_FEATURE_AVDEVICE").is_ok() { + builder = builder.header(search_include(&include_paths, "libavdevice/avdevice.h")); + } + + if env::var("CARGO_FEATURE_AVFILTER").is_ok() { + builder = builder + .header(search_include(&include_paths, "libavfilter/buffersink.h")) + .header(search_include(&include_paths, "libavfilter/buffersrc.h")) + .header(search_include(&include_paths, "libavfilter/avfilter.h")); + } + + if env::var("CARGO_FEATURE_AVFORMAT").is_ok() { + builder = builder + .header(search_include(&include_paths, "libavformat/avformat.h")) + .header(search_include(&include_paths, "libavformat/avio.h")); + } + + if env::var("CARGO_FEATURE_AVRESAMPLE").is_ok() { + builder = builder.header(search_include(&include_paths, "libavresample/avresample.h")); + } + + builder = builder + .header(search_include(&include_paths, "libavutil/adler32.h")) + .header(search_include(&include_paths, "libavutil/aes.h")) + .header(search_include(&include_paths, "libavutil/audio_fifo.h")) + .header(search_include(&include_paths, "libavutil/base64.h")) + .header(search_include(&include_paths, "libavutil/blowfish.h")) + .header(search_include(&include_paths, "libavutil/bprint.h")) + .header(search_include(&include_paths, "libavutil/buffer.h")) + .header(search_include(&include_paths, "libavutil/camellia.h")) + .header(search_include(&include_paths, "libavutil/cast5.h")) + .header(search_include(&include_paths, "libavutil/channel_layout.h")) + // Here until https://github.com/rust-lang/rust-bindgen/issues/2192 / + // https://github.com/rust-lang/rust-bindgen/issues/258 is fixed. + .header("channel_layout_fixed.h") + .header(search_include(&include_paths, "libavutil/cpu.h")) + .header(search_include(&include_paths, "libavutil/crc.h")) + .header(search_include(&include_paths, "libavutil/dict.h")) + .header(search_include(&include_paths, "libavutil/display.h")) + .header(search_include(&include_paths, "libavutil/downmix_info.h")) + .header(search_include(&include_paths, "libavutil/error.h")) + .header(search_include(&include_paths, "libavutil/eval.h")) + .header(search_include(&include_paths, "libavutil/fifo.h")) + .header(search_include(&include_paths, "libavutil/file.h")) + .header(search_include(&include_paths, "libavutil/frame.h")) + .header(search_include(&include_paths, "libavutil/hash.h")) + .header(search_include(&include_paths, "libavutil/hmac.h")) + .header(search_include(&include_paths, "libavutil/hwcontext.h")) + .header(search_include(&include_paths, "libavutil/imgutils.h")) + .header(search_include(&include_paths, "libavutil/lfg.h")) + .header(search_include(&include_paths, "libavutil/log.h")) + .header(search_include(&include_paths, "libavutil/lzo.h")) + .header(search_include(&include_paths, "libavutil/macros.h")) + .header(search_include(&include_paths, "libavutil/mathematics.h")) + .header(search_include(&include_paths, "libavutil/md5.h")) + .header(search_include(&include_paths, "libavutil/mem.h")) + .header(search_include(&include_paths, "libavutil/motion_vector.h")) + .header(search_include(&include_paths, "libavutil/murmur3.h")) + .header(search_include(&include_paths, "libavutil/opt.h")) + .header(search_include(&include_paths, "libavutil/parseutils.h")) + .header(search_include(&include_paths, "libavutil/pixdesc.h")) + .header(search_include(&include_paths, "libavutil/pixfmt.h")) + .header(search_include(&include_paths, "libavutil/random_seed.h")) + .header(search_include(&include_paths, "libavutil/rational.h")) + .header(search_include(&include_paths, "libavutil/replaygain.h")) + .header(search_include(&include_paths, "libavutil/ripemd.h")) + .header(search_include(&include_paths, "libavutil/samplefmt.h")) + .header(search_include(&include_paths, "libavutil/sha.h")) + .header(search_include(&include_paths, "libavutil/sha512.h")) + .header(search_include(&include_paths, "libavutil/stereo3d.h")) + .header(search_include(&include_paths, "libavutil/avstring.h")) + .header(search_include(&include_paths, "libavutil/threadmessage.h")) + .header(search_include(&include_paths, "libavutil/time.h")) + .header(search_include(&include_paths, "libavutil/timecode.h")) + .header(search_include(&include_paths, "libavutil/twofish.h")) + .header(search_include(&include_paths, "libavutil/avutil.h")) + .header(search_include(&include_paths, "libavutil/xtea.h")); + + if env::var("CARGO_FEATURE_POSTPROC").is_ok() { + builder = builder.header(search_include(&include_paths, "libpostproc/postprocess.h")); + } + + if env::var("CARGO_FEATURE_SWRESAMPLE").is_ok() { + builder = builder.header(search_include(&include_paths, "libswresample/swresample.h")); + } + + if env::var("CARGO_FEATURE_SWSCALE").is_ok() { + builder = builder.header(search_include(&include_paths, "libswscale/swscale.h")); + } + + if let Some(hwcontext_drm_header) = + maybe_search_include(&include_paths, "libavutil/hwcontext_drm.h") + { + builder = builder.header(hwcontext_drm_header); + } + + // Finish the builder and generate the bindings. + let bindings = builder + .generate() + // Unwrap the Result and panic on failure. + .expect("Unable to generate bindings"); + + // Write the bindings to the $OUT_DIR/bindings.rs file. + bindings + .write_to_file(output().join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/ffmpeg-sys-the-third/channel_layout_fixed.h b/ffmpeg-sys-the-third/channel_layout_fixed.h new file mode 100644 index 0000000..ca80edf --- /dev/null +++ b/ffmpeg-sys-the-third/channel_layout_fixed.h @@ -0,0 +1,188 @@ +// Here until https://github.com/rust-lang/rust-bindgen/issues/2192 / +// https://github.com/rust-lang/rust-bindgen/issues/258 is fixed. +#include + +#if LIBAVUTIL_VERSION_MAJOR >= 57 && LIBAVUTIL_VERSION_MINOR >= 28 + +#undef AV_CH_FRONT_LEFT +#undef AV_CH_FRONT_RIGHT +#undef AV_CH_FRONT_CENTER +#undef AV_CH_LOW_FREQUENCY +#undef AV_CH_BACK_LEFT +#undef AV_CH_BACK_RIGHT +#undef AV_CH_FRONT_LEFT_OF_CENTER +#undef AV_CH_FRONT_RIGHT_OF_CENTER +#undef AV_CH_BACK_CENTER +#undef AV_CH_SIDE_LEFT +#undef AV_CH_SIDE_RIGHT +#undef AV_CH_TOP_CENTER +#undef AV_CH_TOP_FRONT_LEFT +#undef AV_CH_TOP_FRONT_CENTER +#undef AV_CH_TOP_FRONT_RIGHT +#undef AV_CH_TOP_BACK_LEFT +#undef AV_CH_TOP_BACK_CENTER +#undef AV_CH_TOP_BACK_RIGHT +#undef AV_CH_STEREO_LEFT +#undef AV_CH_STEREO_RIGHT +#undef AV_CH_WIDE_LEFT +#undef AV_CH_WIDE_RIGHT +#undef AV_CH_SURROUND_DIRECT_LEFT +#undef AV_CH_SURROUND_DIRECT_RIGHT +#undef AV_CH_LOW_FREQUENCY_2 +#undef AV_CH_TOP_SIDE_LEFT +#undef AV_CH_TOP_SIDE_RIGHT +#undef AV_CH_BOTTOM_FRONT_CENTER +#undef AV_CH_BOTTOM_FRONT_LEFT +#undef AV_CH_BOTTOM_FRONT_RIGHT + +const unsigned long long AV_CH_FRONT_LEFT = (1ULL << AV_CHAN_FRONT_LEFT); +const unsigned long long AV_CH_FRONT_RIGHT = (1ULL << AV_CHAN_FRONT_RIGHT); +const unsigned long long AV_CH_FRONT_CENTER = + (1ULL << AV_CHAN_FRONT_CENTER); +const unsigned long long AV_CH_LOW_FREQUENCY = + (1ULL << AV_CHAN_LOW_FREQUENCY); +const unsigned long long AV_CH_BACK_LEFT = (1ULL << AV_CHAN_BACK_LEFT); +const unsigned long long AV_CH_BACK_RIGHT = (1ULL << AV_CHAN_BACK_RIGHT); +const unsigned long long AV_CH_FRONT_LEFT_OF_CENTER = + (1ULL << AV_CHAN_FRONT_LEFT_OF_CENTER); +const unsigned long long AV_CH_FRONT_RIGHT_OF_CENTER = + (1ULL << AV_CHAN_FRONT_RIGHT_OF_CENTER); +const unsigned long long AV_CH_BACK_CENTER = (1ULL << AV_CHAN_BACK_CENTER); +const unsigned long long AV_CH_SIDE_LEFT = (1ULL << AV_CHAN_SIDE_LEFT); +const unsigned long long AV_CH_SIDE_RIGHT = (1ULL << AV_CHAN_SIDE_RIGHT); +const unsigned long long AV_CH_TOP_CENTER = (1ULL << AV_CHAN_TOP_CENTER); +const unsigned long long AV_CH_TOP_FRONT_LEFT = + (1ULL << AV_CHAN_TOP_FRONT_LEFT); +const unsigned long long AV_CH_TOP_FRONT_CENTER = + (1ULL << AV_CHAN_TOP_FRONT_CENTER); +const unsigned long long AV_CH_TOP_FRONT_RIGHT = + (1ULL << AV_CHAN_TOP_FRONT_RIGHT); +const unsigned long long AV_CH_TOP_BACK_LEFT = + (1ULL << AV_CHAN_TOP_BACK_LEFT); +const unsigned long long AV_CH_TOP_BACK_CENTER = + (1ULL << AV_CHAN_TOP_BACK_CENTER); +const unsigned long long AV_CH_TOP_BACK_RIGHT = + (1ULL << AV_CHAN_TOP_BACK_RIGHT); +const unsigned long long AV_CH_STEREO_LEFT = (1ULL << AV_CHAN_STEREO_LEFT); +const unsigned long long AV_CH_STEREO_RIGHT = + (1ULL << AV_CHAN_STEREO_RIGHT); +const unsigned long long AV_CH_WIDE_LEFT = (1ULL << AV_CHAN_WIDE_LEFT); +const unsigned long long AV_CH_WIDE_RIGHT = (1ULL << AV_CHAN_WIDE_RIGHT); +const unsigned long long AV_CH_SURROUND_DIRECT_LEFT = + (1ULL << AV_CHAN_SURROUND_DIRECT_LEFT); +const unsigned long long AV_CH_SURROUND_DIRECT_RIGHT = + (1ULL << AV_CHAN_SURROUND_DIRECT_RIGHT); +const unsigned long long AV_CH_LOW_FREQUENCY_2 = + (1ULL << AV_CHAN_LOW_FREQUENCY_2); +const unsigned long long AV_CH_TOP_SIDE_LEFT = + (1ULL << AV_CHAN_TOP_SIDE_LEFT); +const unsigned long long AV_CH_TOP_SIDE_RIGHT = + (1ULL << AV_CHAN_TOP_SIDE_RIGHT); +const unsigned long long AV_CH_BOTTOM_FRONT_CENTER = + (1ULL << AV_CHAN_BOTTOM_FRONT_CENTER); +const unsigned long long AV_CH_BOTTOM_FRONT_LEFT = + (1ULL << AV_CHAN_BOTTOM_FRONT_LEFT); +const unsigned long long AV_CH_BOTTOM_FRONT_RIGHT = + (1ULL << AV_CHAN_BOTTOM_FRONT_RIGHT); + +#undef AV_CH_LAYOUT_MONO +#undef AV_CH_LAYOUT_STEREO +#undef AV_CH_LAYOUT_2POINT1 +#undef AV_CH_LAYOUT_2_1 +#undef AV_CH_LAYOUT_SURROUND +#undef AV_CH_LAYOUT_3POINT1 +#undef AV_CH_LAYOUT_4POINT0 +#undef AV_CH_LAYOUT_4POINT1 +#undef AV_CH_LAYOUT_2_2 +#undef AV_CH_LAYOUT_QUAD +#undef AV_CH_LAYOUT_5POINT0 +#undef AV_CH_LAYOUT_5POINT1 +#undef AV_CH_LAYOUT_5POINT0_BACK +#undef AV_CH_LAYOUT_5POINT1_BACK +#undef AV_CH_LAYOUT_6POINT0 +#undef AV_CH_LAYOUT_6POINT0_FRONT +#undef AV_CH_LAYOUT_HEXAGONAL +#undef AV_CH_LAYOUT_6POINT1 +#undef AV_CH_LAYOUT_6POINT1_BACK +#undef AV_CH_LAYOUT_6POINT1_FRONT +#undef AV_CH_LAYOUT_7POINT0 +#undef AV_CH_LAYOUT_7POINT0_FRONT +#undef AV_CH_LAYOUT_7POINT1 +#undef AV_CH_LAYOUT_7POINT1_WIDE +#undef AV_CH_LAYOUT_7POINT1_WIDE_BACK +#undef AV_CH_LAYOUT_OCTAGONAL +#undef AV_CH_LAYOUT_HEXADECAGONAL +#undef AV_CH_LAYOUT_STEREO_DOWNMIX +#undef AV_CH_LAYOUT_22POINT2 + +const unsigned long long AV_CH_LAYOUT_MONO = (AV_CH_FRONT_CENTER); +const unsigned long long AV_CH_LAYOUT_STEREO = + (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT); +const unsigned long long AV_CH_LAYOUT_2POINT1 = + (AV_CH_LAYOUT_STEREO | AV_CH_LOW_FREQUENCY); +const unsigned long long AV_CH_LAYOUT_2_1 = + (AV_CH_LAYOUT_STEREO | AV_CH_BACK_CENTER); +const unsigned long long AV_CH_LAYOUT_SURROUND = + (AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER); +const unsigned long long AV_CH_LAYOUT_3POINT1 = + (AV_CH_LAYOUT_SURROUND | AV_CH_LOW_FREQUENCY); +const unsigned long long AV_CH_LAYOUT_4POINT0 = + (AV_CH_LAYOUT_SURROUND | AV_CH_BACK_CENTER); +const unsigned long long AV_CH_LAYOUT_4POINT1 = + (AV_CH_LAYOUT_4POINT0 | AV_CH_LOW_FREQUENCY); +const unsigned long long AV_CH_LAYOUT_2_2 = + (AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT); +const unsigned long long AV_CH_LAYOUT_QUAD = + (AV_CH_LAYOUT_STEREO | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT); +const unsigned long long AV_CH_LAYOUT_5POINT0 = + (AV_CH_LAYOUT_SURROUND | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT); +const unsigned long long AV_CH_LAYOUT_5POINT1 = + (AV_CH_LAYOUT_5POINT0 | AV_CH_LOW_FREQUENCY); +const unsigned long long AV_CH_LAYOUT_5POINT0_BACK = + (AV_CH_LAYOUT_SURROUND | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT); +const unsigned long long AV_CH_LAYOUT_5POINT1_BACK = + (AV_CH_LAYOUT_5POINT0_BACK | AV_CH_LOW_FREQUENCY); +const unsigned long long AV_CH_LAYOUT_6POINT0 = + (AV_CH_LAYOUT_5POINT0 | AV_CH_BACK_CENTER); +const unsigned long long AV_CH_LAYOUT_6POINT0_FRONT = + (AV_CH_LAYOUT_2_2 | AV_CH_FRONT_LEFT_OF_CENTER | + AV_CH_FRONT_RIGHT_OF_CENTER); +const unsigned long long AV_CH_LAYOUT_HEXAGONAL = + (AV_CH_LAYOUT_5POINT0_BACK | AV_CH_BACK_CENTER); +const unsigned long long AV_CH_LAYOUT_6POINT1 = + (AV_CH_LAYOUT_5POINT1 | AV_CH_BACK_CENTER); +const unsigned long long AV_CH_LAYOUT_6POINT1_BACK = + (AV_CH_LAYOUT_5POINT1_BACK | AV_CH_BACK_CENTER); +const unsigned long long AV_CH_LAYOUT_6POINT1_FRONT = + (AV_CH_LAYOUT_6POINT0_FRONT | AV_CH_LOW_FREQUENCY); +const unsigned long long AV_CH_LAYOUT_7POINT0 = + (AV_CH_LAYOUT_5POINT0 | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT); +const unsigned long long AV_CH_LAYOUT_7POINT0_FRONT = + (AV_CH_LAYOUT_5POINT0 | AV_CH_FRONT_LEFT_OF_CENTER | + AV_CH_FRONT_RIGHT_OF_CENTER); +const unsigned long long AV_CH_LAYOUT_7POINT1 = + (AV_CH_LAYOUT_5POINT1 | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT); +const unsigned long long AV_CH_LAYOUT_7POINT1_WIDE = + (AV_CH_LAYOUT_5POINT1 | AV_CH_FRONT_LEFT_OF_CENTER | + AV_CH_FRONT_RIGHT_OF_CENTER); +const unsigned long long AV_CH_LAYOUT_7POINT1_WIDE_BACK = + (AV_CH_LAYOUT_5POINT1_BACK | AV_CH_FRONT_LEFT_OF_CENTER | + AV_CH_FRONT_RIGHT_OF_CENTER); +const unsigned long long AV_CH_LAYOUT_OCTAGONAL = + (AV_CH_LAYOUT_5POINT0 | AV_CH_BACK_LEFT | AV_CH_BACK_CENTER | + AV_CH_BACK_RIGHT); +const unsigned long long AV_CH_LAYOUT_HEXADECAGONAL = + (AV_CH_LAYOUT_OCTAGONAL | AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT | + AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT | AV_CH_TOP_BACK_CENTER | + AV_CH_TOP_FRONT_CENTER | AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT); +const unsigned long long AV_CH_LAYOUT_STEREO_DOWNMIX = + (AV_CH_STEREO_LEFT | AV_CH_STEREO_RIGHT); +const unsigned long long AV_CH_LAYOUT_22POINT2 = + (AV_CH_LAYOUT_5POINT1_BACK | AV_CH_FRONT_LEFT_OF_CENTER | + AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_BACK_CENTER | AV_CH_LOW_FREQUENCY_2 | + AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT | AV_CH_TOP_FRONT_LEFT | + AV_CH_TOP_FRONT_RIGHT | AV_CH_TOP_FRONT_CENTER | AV_CH_TOP_CENTER | + AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT | AV_CH_TOP_SIDE_LEFT | + AV_CH_TOP_SIDE_RIGHT | AV_CH_TOP_BACK_CENTER | AV_CH_BOTTOM_FRONT_CENTER | + AV_CH_BOTTOM_FRONT_LEFT | AV_CH_BOTTOM_FRONT_RIGHT); +#endif diff --git a/ffmpeg-sys-the-third/src/avutil/error.rs b/ffmpeg-sys-the-third/src/avutil/error.rs new file mode 100644 index 0000000..cce458c --- /dev/null +++ b/ffmpeg-sys-the-third/src/avutil/error.rs @@ -0,0 +1,68 @@ +use libc::{c_char, c_int, size_t}; + +// Note: FFmpeg's AVERROR and AVUNERROR are conditionally defined based on +// whether EDOM is positive, claiming that "Some platforms have E* and errno +// already negated". This can be traced to a commit in 2007 where "some +// platforms" were specifically identified as BeOS (so maybe also Haiku?): +// https://github.com/FFmpeg/FFmpeg/commit/8fa36ae09dddb1b639b4df5d505c0dbcf4e916e4 +// constness is more valuable than BeOS support, so if someone really needs it, +// send a patch with cfg_attr. + +#[inline(always)] +pub const fn AVERROR(e: c_int) -> c_int { + -e +} + +#[inline(always)] +pub const fn AVUNERROR(e: c_int) -> c_int { + -e +} + +macro_rules! FFERRTAG { + ($a:expr, $b:expr, $c:expr, $d:expr) => { + -MKTAG!($a, $b, $c, $d) as c_int + }; +} + +pub const AVERROR_BSF_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'B', b'S', b'F'); +pub const AVERROR_BUG: c_int = FFERRTAG!(b'B', b'U', b'G', b'!'); +pub const AVERROR_BUFFER_TOO_SMALL: c_int = FFERRTAG!(b'B', b'U', b'F', b'S'); +pub const AVERROR_DECODER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'D', b'E', b'C'); +pub const AVERROR_DEMUXER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'D', b'E', b'M'); +pub const AVERROR_ENCODER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'E', b'N', b'C'); +pub const AVERROR_EOF: c_int = FFERRTAG!(b'E', b'O', b'F', b' '); +pub const AVERROR_EXIT: c_int = FFERRTAG!(b'E', b'X', b'I', b'T'); +pub const AVERROR_EXTERNAL: c_int = FFERRTAG!(b'E', b'X', b'T', b' '); +pub const AVERROR_FILTER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'F', b'I', b'L'); +pub const AVERROR_INVALIDDATA: c_int = FFERRTAG!(b'I', b'N', b'D', b'A'); +pub const AVERROR_MUXER_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'M', b'U', b'X'); +pub const AVERROR_OPTION_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'O', b'P', b'T'); +pub const AVERROR_PATCHWELCOME: c_int = FFERRTAG!(b'P', b'A', b'W', b'E'); +pub const AVERROR_PROTOCOL_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'P', b'R', b'O'); + +pub const AVERROR_STREAM_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'S', b'T', b'R'); + +pub const AVERROR_BUG2: c_int = FFERRTAG!(b'B', b'U', b'G', b' '); +pub const AVERROR_UNKNOWN: c_int = FFERRTAG!(b'U', b'N', b'K', b'N'); + +pub const AVERROR_HTTP_BAD_REQUEST: c_int = FFERRTAG!(0xF8, b'4', b'0', b'0'); +pub const AVERROR_HTTP_UNAUTHORIZED: c_int = FFERRTAG!(0xF8, b'4', b'0', b'1'); +pub const AVERROR_HTTP_FORBIDDEN: c_int = FFERRTAG!(0xF8, b'4', b'0', b'3'); +pub const AVERROR_HTTP_NOT_FOUND: c_int = FFERRTAG!(0xF8, b'4', b'0', b'4'); +pub const AVERROR_HTTP_OTHER_4XX: c_int = FFERRTAG!(0xF8, b'4', b'X', b'X'); +pub const AVERROR_HTTP_SERVER_ERROR: c_int = FFERRTAG!(0xF8, b'5', b'X', b'X'); + +#[inline(always)] +pub unsafe fn av_make_error_string( + errbuf: *mut c_char, + errbuf_size: size_t, + errnum: c_int, +) -> *mut c_char { + av_strerror(errnum, errbuf, errbuf_size); + + errbuf +} + +extern "C" { + pub fn av_strerror(errnum: c_int, errbuf: *mut c_char, errbuf_size: size_t) -> c_int; +} diff --git a/ffmpeg-sys-the-third/src/avutil/macros.rs b/ffmpeg-sys-the-third/src/avutil/macros.rs new file mode 100644 index 0000000..a50636e --- /dev/null +++ b/ffmpeg-sys-the-third/src/avutil/macros.rs @@ -0,0 +1,13 @@ +#[macro_export] +macro_rules! MKBETAG { + ($a:expr, $b:expr, $c:expr, $d:expr) => { + ($d as isize) | (($c as isize) << 8) | (($b as isize) << 16) | (($a as isize) << 24) + }; +} + +#[macro_export] +macro_rules! MKTAG { + ($a:expr, $b:expr, $c:expr, $d:expr) => { + ($a as isize) | (($b as isize) << 8) | (($c as isize) << 16) | (($d as isize) << 24) + }; +} diff --git a/ffmpeg-sys-the-third/src/avutil/mod.rs b/ffmpeg-sys-the-third/src/avutil/mod.rs new file mode 100644 index 0000000..af8aaf2 --- /dev/null +++ b/ffmpeg-sys-the-third/src/avutil/mod.rs @@ -0,0 +1,14 @@ +#[macro_use] +mod macros; + +mod error; +pub use self::error::*; + +mod util; +pub use self::util::*; + +mod rational; +pub use self::rational::*; + +mod pixfmt; +pub use self::pixfmt::*; diff --git a/ffmpeg-sys-the-third/src/avutil/pixfmt.rs b/ffmpeg-sys-the-third/src/avutil/pixfmt.rs new file mode 100644 index 0000000..0bd0a6b --- /dev/null +++ b/ffmpeg-sys-the-third/src/avutil/pixfmt.rs @@ -0,0 +1,236 @@ +use AVPixelFormat; +use AVPixelFormat::*; + +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_RGB32: AVPixelFormat = AV_PIX_FMT_BGRA; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_RGB32_1: AVPixelFormat = AV_PIX_FMT_ABGR; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_BGR32: AVPixelFormat = AV_PIX_FMT_RGBA; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_BGR32_1: AVPixelFormat = AV_PIX_FMT_ARGB; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_0RGB32: AVPixelFormat = AV_PIX_FMT_BGR0; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_0BGR32: AVPixelFormat = AV_PIX_FMT_RGB0; + +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_GRAY16: AVPixelFormat = AV_PIX_FMT_GRAY16LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YA16: AVPixelFormat = AV_PIX_FMT_YA16LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_RGB48: AVPixelFormat = AV_PIX_FMT_RGB48LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_RGB565: AVPixelFormat = AV_PIX_FMT_RGB565LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_RGB555: AVPixelFormat = AV_PIX_FMT_RGB555LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_RGB444: AVPixelFormat = AV_PIX_FMT_RGB444LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_BGR48: AVPixelFormat = AV_PIX_FMT_BGR48LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_BGR565: AVPixelFormat = AV_PIX_FMT_BGR565LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_BGR555: AVPixelFormat = AV_PIX_FMT_BGR555LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_BGR444: AVPixelFormat = AV_PIX_FMT_BGR444LE; + +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV420P9: AVPixelFormat = AV_PIX_FMT_YUV420P9LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV422P9: AVPixelFormat = AV_PIX_FMT_YUV422P9LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV444P9: AVPixelFormat = AV_PIX_FMT_YUV444P9LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV420P10: AVPixelFormat = AV_PIX_FMT_YUV420P10LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV422P10: AVPixelFormat = AV_PIX_FMT_YUV422P10LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV440P10: AVPixelFormat = AV_PIX_FMT_YUV440P10LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV444P10: AVPixelFormat = AV_PIX_FMT_YUV444P10LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV420P12: AVPixelFormat = AV_PIX_FMT_YUV420P12LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV422P12: AVPixelFormat = AV_PIX_FMT_YUV422P12LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV440P12: AVPixelFormat = AV_PIX_FMT_YUV440P12LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV444P12: AVPixelFormat = AV_PIX_FMT_YUV444P12LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV420P14: AVPixelFormat = AV_PIX_FMT_YUV420P14LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV422P14: AVPixelFormat = AV_PIX_FMT_YUV422P14LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV444P14: AVPixelFormat = AV_PIX_FMT_YUV444P14LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV420P16: AVPixelFormat = AV_PIX_FMT_YUV420P16LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV422P16: AVPixelFormat = AV_PIX_FMT_YUV422P16LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUV444P16: AVPixelFormat = AV_PIX_FMT_YUV444P16LE; + +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_GBRP9: AVPixelFormat = AV_PIX_FMT_GBRP9LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_GBRP10: AVPixelFormat = AV_PIX_FMT_GBRP10LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_GBRP12: AVPixelFormat = AV_PIX_FMT_GBRP12LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_GBRP14: AVPixelFormat = AV_PIX_FMT_GBRP14LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_GBRP16: AVPixelFormat = AV_PIX_FMT_GBRP16LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_GBRAP16: AVPixelFormat = AV_PIX_FMT_GBRAP16LE; + +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_BAYER_BGGR16: AVPixelFormat = AV_PIX_FMT_BAYER_BGGR16LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_BAYER_RGGB16: AVPixelFormat = AV_PIX_FMT_BAYER_RGGB16LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_BAYER_GBRG16: AVPixelFormat = AV_PIX_FMT_BAYER_GBRG16LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_BAYER_GRBG16: AVPixelFormat = AV_PIX_FMT_BAYER_GRBG16LE; + +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUVA420P9: AVPixelFormat = AV_PIX_FMT_YUVA420P9LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUVA422P9: AVPixelFormat = AV_PIX_FMT_YUVA422P9LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUVA444P9: AVPixelFormat = AV_PIX_FMT_YUVA444P9LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUVA420P10: AVPixelFormat = AV_PIX_FMT_YUVA420P10LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUVA422P10: AVPixelFormat = AV_PIX_FMT_YUVA422P10LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUVA444P10: AVPixelFormat = AV_PIX_FMT_YUVA444P10LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUVA420P16: AVPixelFormat = AV_PIX_FMT_YUVA420P16LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUVA422P16: AVPixelFormat = AV_PIX_FMT_YUVA422P16LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_YUVA444P16: AVPixelFormat = AV_PIX_FMT_YUVA444P16LE; + +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_XYZ12: AVPixelFormat = AV_PIX_FMT_XYZ12LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_NV20: AVPixelFormat = AV_PIX_FMT_NV20LE; +#[cfg(target_endian = "little")] +pub const AV_PIX_FMT_AYUV64: AVPixelFormat = AV_PIX_FMT_AYUV64LE; + +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_RGB32: AVPixelFormat = AV_PIX_FMT_ARGB; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_RGB32_1: AVPixelFormat = AV_PIX_FMT_RGBA; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_BGR32: AVPixelFormat = AV_PIX_FMT_ABGR; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_BGR32_1: AVPixelFormat = AV_PIX_FMT_BGRA; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_0RGB32: AVPixelFormat = AV_PIX_FMT_0RGB; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_0BGR32: AVPixelFormat = AV_PIX_FMT_0BGR; + +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_GRAY16: AVPixelFormat = AV_PIX_FMT_GRAY16BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YA16: AVPixelFormat = AV_PIX_FMT_YA16BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_RGB48: AVPixelFormat = AV_PIX_FMT_RGB48BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_RGB565: AVPixelFormat = AV_PIX_FMT_RGB565BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_RGB555: AVPixelFormat = AV_PIX_FMT_RGB555BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_RGB444: AVPixelFormat = AV_PIX_FMT_RGB444BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_BGR48: AVPixelFormat = AV_PIX_FMT_BGR48BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_BGR565: AVPixelFormat = AV_PIX_FMT_BGR565BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_BGR555: AVPixelFormat = AV_PIX_FMT_BGR555BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_BGR444: AVPixelFormat = AV_PIX_FMT_BGR444BE; + +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV420P9: AVPixelFormat = AV_PIX_FMT_YUV420P9BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV422P9: AVPixelFormat = AV_PIX_FMT_YUV422P9BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV444P9: AVPixelFormat = AV_PIX_FMT_YUV444P9BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV420P10: AVPixelFormat = AV_PIX_FMT_YUV420P10BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV422P10: AVPixelFormat = AV_PIX_FMT_YUV422P10BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV440P10: AVPixelFormat = AV_PIX_FMT_YUV440P10BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV444P10: AVPixelFormat = AV_PIX_FMT_YUV444P10BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV420P12: AVPixelFormat = AV_PIX_FMT_YUV420P12BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV422P12: AVPixelFormat = AV_PIX_FMT_YUV422P12BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV440P12: AVPixelFormat = AV_PIX_FMT_YUV440P12BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV444P12: AVPixelFormat = AV_PIX_FMT_YUV444P12BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV420P14: AVPixelFormat = AV_PIX_FMT_YUV420P14BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV422P14: AVPixelFormat = AV_PIX_FMT_YUV422P14BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV444P14: AVPixelFormat = AV_PIX_FMT_YUV444P14BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV420P16: AVPixelFormat = AV_PIX_FMT_YUV420P16BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV422P16: AVPixelFormat = AV_PIX_FMT_YUV422P16BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUV444P16: AVPixelFormat = AV_PIX_FMT_YUV444P16BE; + +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_GBRP9: AVPixelFormat = AV_PIX_FMT_GBRP9BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_GBRP10: AVPixelFormat = AV_PIX_FMT_GBRP10BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_GBRP12: AVPixelFormat = AV_PIX_FMT_GBRP12BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_GBRP14: AVPixelFormat = AV_PIX_FMT_GBRP14BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_GBRP16: AVPixelFormat = AV_PIX_FMT_GBRP16BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_GBRAP16: AVPixelFormat = AV_PIX_FMT_GBRAP16BE; + +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_BAYER_BGGR16: AVPixelFormat = AV_PIX_FMT_BAYER_BGGR16BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_BAYER_RGGB16: AVPixelFormat = AV_PIX_FMT_BAYER_RGGB16BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_BAYER_GBRG16: AVPixelFormat = AV_PIX_FMT_BAYER_GBRG16BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_BAYER_GRBG16: AVPixelFormat = AV_PIX_FMT_BAYER_GRBG16BE; + +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUVA420P9: AVPixelFormat = AV_PIX_FMT_YUVA420P9BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUVA422P9: AVPixelFormat = AV_PIX_FMT_YUVA422P9BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUVA444P9: AVPixelFormat = AV_PIX_FMT_YUVA444P9BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUVA420P10: AVPixelFormat = AV_PIX_FMT_YUVA420P10BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUVA422P10: AVPixelFormat = AV_PIX_FMT_YUVA422P10BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUVA444P10: AVPixelFormat = AV_PIX_FMT_YUVA444P10BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUVA420P16: AVPixelFormat = AV_PIX_FMT_YUVA420P16BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUVA422P16: AVPixelFormat = AV_PIX_FMT_YUVA422P16BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_YUVA444P16: AVPixelFormat = AV_PIX_FMT_YUVA444P16BE; + +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_XYZ12: AVPixelFormat = AV_PIX_FMT_XYZ12BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_NV20: AVPixelFormat = AV_PIX_FMT_NV20BE; +#[cfg(target_endian = "big")] +pub const AV_PIX_FMT_AYUV64: AVPixelFormat = AV_PIX_FMT_AYUV64BE; diff --git a/ffmpeg-sys-the-third/src/avutil/rational.rs b/ffmpeg-sys-the-third/src/avutil/rational.rs new file mode 100644 index 0000000..641e09f --- /dev/null +++ b/ffmpeg-sys-the-third/src/avutil/rational.rs @@ -0,0 +1,35 @@ +use libc::{c_double, c_int}; +use AVRational; + +#[inline(always)] +pub unsafe fn av_make_q(num: c_int, den: c_int) -> AVRational { + AVRational { num, den } +} + +#[inline(always)] +pub unsafe fn av_cmp_q(a: AVRational, b: AVRational) -> c_int { + let tmp = i64::from(a.num) * i64::from(b.den) - i64::from(b.num) * i64::from(a.den); + + if tmp != 0 { + (((tmp ^ i64::from(a.den) ^ i64::from(b.den)) >> 63) | 1) as c_int + } else if b.den != 0 && a.den != 0 { + 0 + } else if a.num != 0 && b.num != 0 { + ((i64::from(a.num) >> 31) - (i64::from(b.num) >> 31)) as c_int + } else { + c_int::min_value() + } +} + +#[inline(always)] +pub unsafe fn av_q2d(a: AVRational) -> c_double { + f64::from(a.num) / f64::from(a.den) +} + +#[inline(always)] +pub unsafe fn av_inv_q(q: AVRational) -> AVRational { + AVRational { + num: q.den, + den: q.num, + } +} diff --git a/ffmpeg-sys-the-third/src/avutil/util.rs b/ffmpeg-sys-the-third/src/avutil/util.rs new file mode 100644 index 0000000..49f631d --- /dev/null +++ b/ffmpeg-sys-the-third/src/avutil/util.rs @@ -0,0 +1,8 @@ +use libc::c_int; +use {AVRational, AV_TIME_BASE}; + +pub const AV_NOPTS_VALUE: i64 = 0x8000000000000000u64 as i64; +pub const AV_TIME_BASE_Q: AVRational = AVRational { + num: 1, + den: AV_TIME_BASE as c_int, +}; diff --git a/ffmpeg-sys-the-third/src/lib.rs b/ffmpeg-sys-the-third/src/lib.rs new file mode 100644 index 0000000..532f134 --- /dev/null +++ b/ffmpeg-sys-the-third/src/lib.rs @@ -0,0 +1,16 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(clippy::approx_constant)] +#![allow(clippy::missing_safety_doc)] +#![allow(clippy::redundant_static_lifetimes)] +#![allow(clippy::too_many_arguments)] +#![allow(clippy::type_complexity)] + +extern crate libc; + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + +#[macro_use] +mod avutil; +pub use avutil::*;