Skip to content

Commit 6b79645

Browse files
authored
mcpplibs.mwrap.libvpx 1.17.0: libvpx-m (VP9 and WebM as C++23 modules) (#627)
Descriptor pkgs/mwrap/libvpx.lua (form A, the immutable mwrap-1.17.0 release asset, tagged on libvpx-m's merged main; no CN mirror yet), over compat.libvpx 1.17.0 and compat.libwebm 1.0.0.32. Consumer tests/mwrap/libvpx-webm: VP9 frames encoded through the typed controls, muxed into a WebM with mkvmuxer (the same bytes twice), parsed back with mkvparser and decoded within a PSNR; and the side header beside the import. The installed-template check in validate.yml with its deployment contract (the wrapper's LICENSE/NOTICE, libvpx's and libwebm's README, LICENSE, PATENTS and AUTHORS, byte for byte in a relocated bundle), and the plan.
1 parent 1809c8b commit 6b79645

9 files changed

Lines changed: 324 additions & 0 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Add mcpplibs.mwrap.libvpx (libvpx-m 1.17.0)
2+
3+
## Form
4+
5+
- Third-party upstreams, both BSD-3-Clause with the WebM project's royalty-free patent grant: [libvpx](https://chromium.googlesource.com/webm/libvpx)
6+
1.17.0 (VP9) and [libwebm](https://github.com/webmproject/libwebm) 1.0.0.32 (the WebM container), the tag archives
7+
compat.libvpx and compat.libwebm pin (#624).
8+
- Form A external mwrap module repository [mcpplibs/libvpx-m](https://github.com/mcpplibs/libvpx-m), package
9+
`mcpplibs.mwrap.libvpx`, version 1.17.0 (libvpx's version; the first release of the identity, no revision suffix; libwebm
10+
1.0.0.32 in `[package.metadata.mwrap]`), tag series `mwrap-${version}`, tagged on the merged main commit (`676fceb`);
11+
release asset `libvpx-m-1.17.0.tar.gz` (`e6a5a062…9211`). No CN mirror yet (docs/cn-mirror.md: CN users fall back to the
12+
GitHub release).
13+
- The container is bundled with the codec as libogg is with libopus in opus-m: WebM is how VP9 travels, and libvpx's own
14+
tree carries libwebm for vpxenc/vpxdec.
15+
- Implementation ownership: the libraries are compat.libvpx and compat.libwebm (static libraries from the tag archives).
16+
The wrapper vendors no library code. It retains each upstream's README, LICENSE, PATENTS and AUTHORS under
17+
`upstream/{libvpx,libwebm}/`, with checksums in `upstream/documents.json`, and deploys them with its own LICENSE/NOTICE
18+
(`runtime.deploy`).
19+
20+
## Modules
21+
22+
- `mcpplibs.mwrap.libvpx`: libvpx — 133 types, 192 enumerators, the 35 functions upstream exports (vpx/exports_* and vp9's
23+
lists) and the two VP9 interfaces, by `export using`. VP8 is not built (compat.libvpx: `--disable-vp8`): its interfaces,
24+
which vp8cx.h/vp8dx.h declare, are not exported. The headers' 86 typed controls (static functions made by
25+
`VPX_CTRL_USE_TYPE`) adapted under the same names in `mcpplibs::mwrap::libvpx`, each calling `vpx_codec_control_` as
26+
upstream's body does. Re-exports the two below.
27+
- `mcpplibs.mwrap.libvpx.webm`: libwebm — the classes, types, enumerators and free functions of mkvmuxer (29/0/26),
28+
mkvparser (24/0/11) and libwebm (4/154/9) in their own namespaces; the namespace-scope constants (internal linkage) under
29+
the same names in `mcpplibs::mwrap::libvpx::mkvmuxer` / `::mkvparser`.
30+
- `mcpplibs.mwrap.libvpx.macros`: 74 macros as `inline constexpr` of their expression's type, `vpx_codec_enc_init`,
31+
`vpx_codec_enc_init_multi`, `vpx_codec_dec_init`, `vpx_codec_version_major/_minor/_patch` as functions,
32+
`VPX_VERSION_MAJOR/_MINOR/_PATCH` as constexpr functions.
33+
- Stay macros, in `<mwrap/libvpx/macros.hpp>`: `vpx_codec_control` (token concatenation), `VPX_CTRL_USE_TYPE*`,
34+
`VPX_CTRL_VOID`, the 86 empty `VPX_CTRL_<id>` feature tests, the declaration annotations, libwebm's
35+
`LIBWEBM_DISALLOW_COPY_AND_ASSIGN`, the include guards.
36+
37+
`tools/check_exports.py` fails when the generated sources are stale, a declaration is not exported, a control not adapted,
38+
or a macro neither mapped nor accounted for; every mapping is checked against the raw headers in a header-mixing test,
39+
and every exported function and control's address is taken in a link test.
40+
41+
## Verification
42+
43+
Wrapper CI (Linux x86_64 GCC 16.1 and LLVM 23.1.3, Linux arm64 GCC 16.1, macOS LLVM, Windows LLVM, wasm32-emscripten under
44+
node; all required): build, the three test programs in the dev and release profiles — VP9 at good quality, real time, four
45+
threads and lossless, muxed into WebM, parsed and decoded back, each file's FNV-1a pinned and the same on every row —, the
46+
export audit, and the conformance run on Linux and macOS: `examples/vpxwebm`, written against the module, writes the same
47+
IVF bytes as upstream's `vpxenc` (built from the same tag by its own configure) for six settings, and `vpxdec` reads its
48+
WebM files to the same frames as the module reads `vpxenc`'s (18 comparisons). The templates job scaffolds the default
49+
`webm` template as an installed package and runs it.
50+
51+
Here, with the CI-pinned mcpp 2026.10.27.1:
52+
53+
- `bash tests/run_members.sh libvpx-webm`: the real release archive; VP9 frames through the typed controls, muxed with
54+
mkvmuxer (track UID given: the same bytes twice), parsed with mkvparser and decoded (50.7 dB), and the side header
55+
beside the import: `test result ok`.
56+
- `python3 tests/mwrap/check_installed_template.py --package mcpplibs.mwrap.libvpx@1.17.0 --deploy`: the unmodified
57+
template from the real archive (60 frames, 51.8 dB), then a relocated self-contained bundle whose `licenses/libvpx/`
58+
holds the wrapper's LICENSE/NOTICE and both libraries' README, LICENSE, PATENTS and AUTHORS byte for byte.
59+
60+
## Motivation
61+
62+
openmui's video component (openmui.video, D-86) encodes its frames and sound track into WebM: VP9 through this wrapper and
63+
Opus through mcpplibs.mwrap.opus, both royalty-free and BSD-3-Clause, linked statically under the project's licence policy.

‎.github/workflows/validate.yml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,6 +1663,11 @@ jobs:
16631663
shell: bash
16641664
run: python3 tests/mwrap/check_installed_template.py --mcpp "$MCPP" --package mcpplibs.mwrap.libwebp@1.5.0 --deploy
16651665

1666+
- name: Installed libvpx wrapper archive, actual default webm template and its relocated notices
1667+
if: contains(format(' {0} ', env.MEMBERS), ' libvpx-webm ') && matrix.toolchain == 'default'
1668+
shell: bash
1669+
run: python3 tests/mwrap/check_installed_template.py --mcpp "$MCPP" --package mcpplibs.mwrap.libvpx@1.17.0 --deploy
1670+
16661671
- name: Installed PocketPy wrapper archive, actual default script template and its relocated notices
16671672
if: contains(format(' {0} ', env.MEMBERS), ' pocketpy-embed ') && matrix.toolchain == 'default'
16681673
shell: bash

‎CHANGELOG.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@
99

1010
### Added
1111

12+
- **mcpplibs.mwrap.libvpx 1.17.0(新包)。** libvpx-m:以 C++23 模块(`import mcpplibs.mwrap.libvpx;`)使用 VP9 编解码库
13+
libvpx 1.17.0 与 WebM 容器库 libwebm 1.0.0.32(建立在 compat.libvpx 与 compat.libwebm 之上)。根模块导出 libvpx 头文件的
14+
133 个类型、192 个枚举值、上游导出的 35 个函数与两个 VP9 接口(VP8 未构建,其接口不导出),头文件中 86 个类型化控制函数
15+
(`VPX_CTRL_USE_TYPE` 生成的 static 函数)在 `mcpplibs::mwrap::libvpx` 中同名适配;`mcpplibs.mwrap.libvpx.webm` 在各自
16+
命名空间导出 libwebm 的 mkvmuxer、mkvparser 与 libwebm(命名空间作用域常量为内部链接,其值在
17+
`mcpplibs::mwrap::libvpx::mkvmuxer` / `::mkvparser` 下同名提供);`mcpplibs.mwrap.libvpx.macros` 把 74 个宏映射为常量、
18+
函数与 constexpr 函数,其余(`vpx_codec_control` 等)留在 `<mwrap/libvpx/macros.hpp>`。描述符为 libvpx-m 的不可变
19+
`mwrap-1.17.0` 发布包(暂无 CN 镜像)。新增使用者 `tests/mwrap/libvpx-webm`:经类型化控制编码 VP9、mkvmuxer 封装、
20+
mkvparser 解析并解码(PSNR 下限)、两次封装字节相同,以及侧边头文件与 import 同时使用;validate.yml 新增已安装模板检查
21+
(wrapper 的 LICENSE/NOTICE 与两个库的 README、LICENSE、PATENTS、AUTHORS 在搬迁后的发布包中逐字节一致)。
1222
- **compat.libvpx 1.17.0(新包)。** libvpx:WebM 项目的 VP9 视频编解码器(编码器与解码器;BSD-3-Clause,附 WebM 项目的
1323
免版税专利授权 PATENTS)。从 `v1.17.0` 标签归档构建上游 `configure --target=generic-gnu --disable-vp8 --enable-vp9
1424
--enable-multithread`(不含示例、工具、文档、单元测试、webm-io、libyuv)所编译的 101 个 C 源文件:通用 C 实现,无 SIMD、

‎mcpp.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ members = [
2727
"tests/mwrap/sheenbidi-bidi",
2828
"tests/mwrap/dr_libs-audio",
2929
"tests/mwrap/opus-ogg",
30+
"tests/mwrap/libvpx-webm",
3031
"tests/mwrap/box2d-physics",
3132
"tests/mwrap/miniaudio-engine",
3233
"tests/mwrap/freetype-render",

‎pkgs/mwrap/libvpx.lua‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
-- Immutable upstream-aligned mwrap source release (libvpx-m mwrap-1.17.0).
2+
-- The CN mirror is added by a maintainer with mcpp-res access; until then CN
3+
-- users fall back to the GitHub release (docs/cn-mirror.md).
4+
--
5+
-- The wrapper is Apache-2.0. The libraries it links are BSD-3-Clause with the
6+
-- WebM project's patent grant, linked statically: compat.libvpx (libvpx
7+
-- 1.17.0, VP9) and compat.libwebm (libwebm 1.0.0.32, the WebM container). The
8+
-- package deploys each one's README, LICENSE, PATENTS and AUTHORS beside
9+
-- programs (runtime.deploy).
10+
package = {
11+
spec = "1",
12+
namespace = "mcpplibs.mwrap",
13+
name = "libvpx",
14+
description = "libvpx-m: VP9 video (libvpx 1.17.0) and the WebM container (libwebm 1.0.0.32) as C++23 modules",
15+
licenses = { "Apache-2.0" },
16+
repo = "https://github.com/mcpplibs/libvpx-m",
17+
type = "package",
18+
extensions = {
19+
autoupdate = {
20+
tag = "mwrap-${version}",
21+
url = "https://github.com/mcpplibs/libvpx-m/releases/download/${tag}/libvpx-m-${version}.tar.gz",
22+
},
23+
},
24+
xpm = {
25+
linux = {
26+
["1.17.0"] = {
27+
url = "https://github.com/mcpplibs/libvpx-m/releases/download/mwrap-1.17.0/libvpx-m-1.17.0.tar.gz",
28+
sha256 = "e6a5a062923b17961d44c7d1d74cd4190f774d4eb38d639607530ff987669211",
29+
},
30+
},
31+
macosx = {
32+
["1.17.0"] = {
33+
url = "https://github.com/mcpplibs/libvpx-m/releases/download/mwrap-1.17.0/libvpx-m-1.17.0.tar.gz",
34+
sha256 = "e6a5a062923b17961d44c7d1d74cd4190f774d4eb38d639607530ff987669211",
35+
},
36+
},
37+
windows = {
38+
["1.17.0"] = {
39+
url = "https://github.com/mcpplibs/libvpx-m/releases/download/mwrap-1.17.0/libvpx-m-1.17.0.tar.gz",
40+
sha256 = "e6a5a062923b17961d44c7d1d74cd4190f774d4eb38d639607530ff987669211",
41+
},
42+
},
43+
},
44+
}

‎tests/mwrap/check_installed_template.py‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,30 @@ def main():
272272
notice = (roots[0] / "NOTICE").read_bytes()
273273
assert b"mcpp-community" in notice and b"Google" in notice
274274
print(f"Verified {len(declared)} byte-identical wrapper/libwebp license files", flush=True)
275+
elif identity == "mcpplibs.mwrap.libvpx":
276+
# libvpx and libwebm (BSD-3-Clause with the WebM project's
277+
# patent grant) are linked statically: the wrapper's
278+
# LICENSE/NOTICE and each library's README, LICENSE, PATENTS
279+
# and AUTHORS travel with the program.
280+
sources = [path for store in (home / "xpkgs", home / "registry/data/xpkgs")
281+
for path in store.glob(f"mcpplibs.mwrap-x-libvpx/{version}/*/src/libvpx.cppm")]
282+
assert len(sources) == 1, sources
283+
source = sources[0].parent.parent
284+
declared = tomllib.loads((source / "mcpp.toml").read_text(encoding="utf-8"))["runtime"]["deploy"]
285+
roots = list(relocated.rglob("licenses/libvpx"))
286+
assert len(roots) == 1, f"Missing libvpx runtime license tree: {roots}"
287+
for entry in declared:
288+
notice = source / entry["from"]
289+
copied = roots[0].parent.parent / entry["to"] / notice.name
290+
assert copied.is_file() and copied.read_bytes() == notice.read_bytes(), copied
291+
assert b"The WebM Project authors" in (roots[0] / "upstream/libvpx/LICENSE").read_bytes()
292+
assert b"Google Inc." in (roots[0] / "upstream/libwebm/LICENSE.TXT").read_bytes()
293+
for patents in ("upstream/libvpx/PATENTS", "upstream/libwebm/PATENTS.TXT"):
294+
assert b"patent" in (roots[0] / patents).read_bytes(), patents
295+
assert b"Apache License" in (roots[0] / "LICENSE").read_bytes()
296+
notice = (roots[0] / "NOTICE").read_bytes()
297+
assert b"mcpp-community" in notice and b"WebM Project" in notice
298+
print(f"Verified {len(declared)} byte-identical wrapper/libvpx/libwebm license files", flush=True)
275299
elif identity == "mcpplibs.mwrap.pocketpy":
276300
# PocketPy is MIT and linked statically: its LICENSE and README
277301
# travel with the program beside the wrapper's LICENSE/NOTICE.

‎tests/mwrap/libvpx-webm/mcpp.toml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "libvpx-webm"
3+
version = "1.17.0"
4+
description = "Consume the immutable libvpx wrapper: VP9 frames encoded through the typed controls, muxed into a WebM with mkvmuxer, parsed back with mkvparser and decoded within a PSNR, the bytes the same twice; the side header beside the import"
5+
6+
[indices]
7+
# Use the complete candidate built-in index prepared by tests/run_members.sh.
8+
# An explicit empty table overrides the legacy workspace redirect.
9+
10+
[dependencies]
11+
"mcpplibs.mwrap.libvpx" = "1.17.0"
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// The wrapper through its modules alone: VP9 frames encoded through the typed
2+
// controls, muxed into a WebM in memory with mkvmuxer (track UID given),
3+
// parsed back with mkvparser and decoded within a PSNR; the same bytes twice.
4+
import std;
5+
import mcpplibs.mwrap.libvpx;
6+
7+
namespace m = mcpplibs::mwrap::libvpx::macros;
8+
namespace vpx = mcpplibs::mwrap::libvpx;
9+
10+
namespace {
11+
12+
constexpr int W = 160, H = 96, FRAMES = 20;
13+
14+
void draw(vpx_image_t& img, int t) {
15+
for (int y = 0; y < H; ++y)
16+
for (int x = 0; x < W; ++x)
17+
img.planes[0][y * img.stride[0] + x] = static_cast<unsigned char>(x >= 20 + 4 * t && x < 50 + 4 * t && y >= 30 && y < 60 ? 230 : 16 + (x + y + 3 * t) % 200);
18+
for (int p = 1; p < 3; ++p)
19+
for (int y = 0; y < H / 2; ++y)
20+
for (int x = 0; x < W / 2; ++x) img.planes[p][y * img.stride[p] + x] = static_cast<unsigned char>(p == 1 ? 100 + x : 150 - y);
21+
}
22+
23+
class Memory final : public mkvmuxer::IMkvWriter {
24+
public:
25+
std::vector<unsigned char> bytes;
26+
std::int64_t at = 0;
27+
mkvmuxer::int32 Write(const void* buf, mkvmuxer::uint32 len) override {
28+
if (bytes.size() < static_cast<std::size_t>(at) + len) bytes.resize(static_cast<std::size_t>(at) + len);
29+
std::memcpy(bytes.data() + at, buf, len);
30+
at += len;
31+
return 0;
32+
}
33+
mkvmuxer::int64 Position() const override { return at; }
34+
mkvmuxer::int32 Position(mkvmuxer::int64 p) override { return at = p, 0; }
35+
bool Seekable() const override { return true; }
36+
void ElementStartNotify(mkvmuxer::uint64, mkvmuxer::int64) override {}
37+
};
38+
39+
class Reader final : public mkvparser::IMkvReader {
40+
public:
41+
explicit Reader(const std::vector<unsigned char>& b) : bytes(b) {}
42+
int Read(long long pos, long len, unsigned char* buf) override {
43+
if (pos < 0 || len < 0 || static_cast<std::size_t>(pos + len) > bytes.size()) return -1;
44+
std::memcpy(buf, bytes.data() + pos, static_cast<std::size_t>(len));
45+
return 0;
46+
}
47+
int Length(long long* total, long long* available) override {
48+
*total = *available = static_cast<long long>(bytes.size());
49+
return 0;
50+
}
51+
const std::vector<unsigned char>& bytes;
52+
};
53+
54+
std::vector<unsigned char> webm() {
55+
vpx_codec_enc_cfg_t cfg;
56+
vpx_codec_enc_config_default(vpx_codec_vp9_cx(), &cfg, 0);
57+
cfg.g_w = W;
58+
cfg.g_h = H;
59+
cfg.g_timebase = {1, 30};
60+
cfg.g_lag_in_frames = 0;
61+
cfg.rc_end_usage = VPX_Q;
62+
vpx_codec_ctx_t enc;
63+
if (m::vpx_codec_enc_init(&enc, vpx_codec_vp9_cx(), &cfg, 0) != VPX_CODEC_OK) return {};
64+
vpx::vpx_codec_control_VP8E_SET_CPUUSED(&enc, VP8E_SET_CPUUSED, 6);
65+
vpx::vpx_codec_control_VP8E_SET_CQ_LEVEL(&enc, VP8E_SET_CQ_LEVEL, 20u);
66+
Memory out;
67+
mkvmuxer::Segment segment;
68+
segment.Init(&out);
69+
segment.set_mode(mkvmuxer::Segment::kFile);
70+
const auto track = segment.AddVideoTrack(W, H, 1);
71+
auto* v = static_cast<mkvmuxer::VideoTrack*>(segment.GetTrackByNumber(track));
72+
v->set_codec_id(mkvmuxer::Tracks::kVp9CodecId);
73+
v->set_uid(7);
74+
vpx_image_t img;
75+
vpx_img_alloc(&img, VPX_IMG_FMT_I420, W, H, 16);
76+
for (int t = 0; t <= FRAMES; ++t) {
77+
if (t < FRAMES) draw(img, t);
78+
vpx_codec_encode(&enc, t < FRAMES ? &img : nullptr, t, 1, 0, m::VPX_DL_GOOD_QUALITY);
79+
vpx_codec_iter_t it = nullptr;
80+
while (const vpx_codec_cx_pkt_t* p = vpx_codec_get_cx_data(&enc, &it))
81+
if (p->kind == VPX_CODEC_CX_FRAME_PKT)
82+
segment.AddFrame(static_cast<const std::uint8_t*>(p->data.frame.buf), p->data.frame.sz, track,
83+
static_cast<std::uint64_t>(p->data.frame.pts) * 1'000'000'000 / 30, (p->data.frame.flags & m::VPX_FRAME_IS_KEY) != 0);
84+
}
85+
vpx_img_free(&img);
86+
vpx_codec_destroy(&enc);
87+
segment.Finalize();
88+
return out.bytes;
89+
}
90+
91+
} // namespace
92+
93+
int main() {
94+
const auto file = webm();
95+
if (file.empty() || file != webm()) return 1;
96+
Reader reader(file);
97+
long long pos = 0;
98+
mkvparser::EBMLHeader header;
99+
mkvparser::Segment* raw = nullptr;
100+
if (header.Parse(&reader, pos) != 0 || std::string_view(header.m_docType) != "webm") return 2;
101+
if (mkvparser::Segment::CreateInstance(&reader, pos, raw) != 0 || !raw || raw->Load() < 0) return 3;
102+
std::unique_ptr<mkvparser::Segment> segment(raw);
103+
vpx_codec_dec_cfg_t dcfg{};
104+
vpx_codec_ctx_t dec;
105+
if (m::vpx_codec_dec_init(&dec, vpx_codec_vp9_dx(), &dcfg, 0) != VPX_CODEC_OK) return 4;
106+
vpx_image_t ref;
107+
vpx_img_alloc(&ref, VPX_IMG_FMT_I420, W, H, 16);
108+
int frames = 0;
109+
double worst = 99;
110+
for (const mkvparser::Cluster* c = segment->GetFirst(); c && !c->EOS(); c = segment->GetNext(c)) {
111+
const mkvparser::BlockEntry* e = nullptr;
112+
for (c->GetFirst(e); e && !e->EOS(); c->GetNext(e, e)) {
113+
const mkvparser::Block::Frame& f = e->GetBlock()->GetFrame(0);
114+
std::vector<unsigned char> data(static_cast<std::size_t>(f.len));
115+
f.Read(&reader, data.data());
116+
vpx_codec_decode(&dec, data.data(), static_cast<unsigned>(data.size()), nullptr, 0);
117+
vpx_codec_iter_t it = nullptr;
118+
while (vpx_image_t* out = vpx_codec_get_frame(&dec, &it)) {
119+
draw(ref, frames++);
120+
double se = 0;
121+
for (int y = 0; y < H; ++y)
122+
for (int x = 0; x < W; ++x) {
123+
const int d = out->planes[0][y * out->stride[0] + x] - ref.planes[0][y * ref.stride[0] + x];
124+
se += d * d;
125+
}
126+
if (se > 0) worst = std::min(worst, 10 * std::log10(255.0 * 255.0 * W * H / se));
127+
}
128+
}
129+
}
130+
vpx_img_free(&ref);
131+
vpx_codec_destroy(&dec);
132+
std::println("{} frames in {} bytes of WebM, worst PSNR {:.1f} dB ({})", frames, file.size(), worst, vpx_codec_version_str());
133+
return frames == FRAMES && worst > 35 ? 0 : 5;
134+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// The side header from the installed package, beside the import: the
2+
// header's vpx_codec_control macro (its typed static control) and the
3+
// adapted control set the same thing; a VPX_CTRL_<id> feature test; the
4+
// mapped constants beside the macros (a function-like macro is not expanded
5+
// when its name is followed by `)`).
6+
#include <mwrap/libvpx/macros.hpp>
7+
8+
import std;
9+
import mcpplibs.mwrap.libvpx;
10+
11+
namespace m = mcpplibs::mwrap::libvpx::macros;
12+
13+
#ifndef VPX_CTRL_VP9E_SET_ROW_MT
14+
#error "the VPX_CTRL_<id> feature tests come with the header"
15+
#endif
16+
17+
int main() {
18+
vpx_codec_enc_cfg_t cfg;
19+
if (vpx_codec_enc_config_default(vpx_codec_vp9_cx(), &cfg, 0) != VPX_CODEC_OK) return 1;
20+
cfg.g_w = 64;
21+
cfg.g_h = 64;
22+
vpx_codec_ctx_t a, b;
23+
if ((m::vpx_codec_enc_init)(&a, vpx_codec_vp9_cx(), &cfg, 0) != VPX_CODEC_OK) return 2;
24+
if (vpx_codec_enc_init(&b, vpx_codec_vp9_cx(), &cfg, 0) != VPX_CODEC_OK) return 3;
25+
if (vpx_codec_control(&a, VP8E_SET_CPUUSED, 7) != VPX_CODEC_OK) return 4;
26+
if (mcpplibs::mwrap::libvpx::vpx_codec_control_VP8E_SET_CPUUSED(&b, VP8E_SET_CPUUSED, 7) != VPX_CODEC_OK) return 5;
27+
if (&::vpx_codec_encode != &vpx_codec_encode) return 6;
28+
static_assert((m::VPX_VERSION_MAJOR)(0x011100) == VPX_VERSION_MAJOR(0x011100));
29+
vpx_codec_destroy(&a);
30+
vpx_codec_destroy(&b);
31+
return 0;
32+
}

0 commit comments

Comments
 (0)