Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .agents/docs/2026-10-25-unified-mwrap-checkpoint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Unified mwrap first release

Package/module: `mcpplibs.mwrap.ffmpeg`; upstream version: `8.1.2`.

This checkpoint migrates wrapper identity while retaining upstream API names and SDK sources.
Default README is English with a mandatory Chinese counterpart; original section order is preserved.
Validation and release evidence are recorded in the PR and the index ecosystem ledger.
No old release tag or source resource is rewritten.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ jobs:
# No host nasm needed: mcpp >= 0.0.97 provisions nasm through the same
# synchronous gate as the toolchain (index refresh + install + payload
# check BEFORE the build plans, mcpp#232).
- name: Mwrap identity and bilingual README contract
run: python3 tools/check_mwrap_release.py

- name: Install Xlings
env:
XLINGS_NON_INTERACTIVE: 1
Expand Down
83 changes: 37 additions & 46 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,58 +1,49 @@
name: Release

on:
push:
tags: ["v*"]

tags: ["mwrap-*"]
permissions:
contents: write

contents: read
jobs:
verify-and-release:
name: verify (linux) + GitHub Release
publish:
runs-on: ubuntu-latest
timeout-minutes: 60
timeout-minutes: 30
permissions:
contents: write
actions: read
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install nasm
run: sudo apt-get update && sudo apt-get install -y nasm

- name: Install Xlings
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Check tag, upstream version and bilingual entry pages
run: python3 tools/check_mwrap_release.py --tag "$GITHUB_REF_NAME"
- name: Require successful source CI at this exact commit
env:
XLINGS_NON_INTERACTIVE: 1
run: |
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/refs/heads/main/tools/other/quick_install.sh | bash
echo "$HOME/.xlings/subos/current/bin" >> "$GITHUB_PATH"

- name: Install project tools
run: |
xlings update
xlings install

- name: Set default toolchain
run: |
mcpp toolchain install gcc 16.1.0
mcpp toolchain default gcc@16.1.0
mcpp --version

- name: Build + test at the tagged revision
run: |
mcpp build
mcpp test

- name: Verify tag matches package version
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
pkg_ver="$(sed -n 's/^version *= *"\(.*\)"/\1/p' mcpp.toml | head -1)"
tag="${GITHUB_REF_NAME#v}"
test "$pkg_ver" = "$tag" || { echo "tag $GITHUB_REF_NAME != package version $pkg_ver"; exit 1; }

- name: Create GitHub Release
set -euo pipefail
result=$(gh run list --repo "$GITHUB_REPOSITORY" --workflow ci.yml --commit "$GITHUB_SHA" --limit 1 --json status,conclusion --jq '.[0] | .status == "completed" and .conclusion == "success"')
test "$result" = true || { echo 'No successful source CI at the tag commit'; exit 1; }
- name: Build immutable source asset and publish
env:
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
gh release create "$GITHUB_REF_NAME" \
--title "ffmpeg-m $GITHUB_REF_NAME" \
--generate-notes \
--verify-tag
set -euo pipefail
version="${GITHUB_REF_NAME#mwrap-}"
repo="${GITHUB_REPOSITORY#*/}"
asset="${repo}-${version}.tar.gz"
git archive --format=tar.gz --prefix="${repo}-${version}/" "$GITHUB_SHA" > "$RUNNER_TEMP/$asset"
(cd "$RUNNER_TEMP" && sha256sum "$asset" > "$asset.sha256")
if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
echo 'Release already exists; refusing to change immutable assets'; exit 1
fi
extra=()
if [[ "$version" == *-rc* ]]; then extra+=(--prerelease); fi
gh release create "$GITHUB_REF_NAME" "$RUNNER_TEMP/$asset" "$RUNNER_TEMP/$asset.sha256" \
--repo "$GITHUB_REPOSITORY" --verify-tag --title "$repo $version" \
--notes "Module wrapper for upstream $version. New mwrap package identities become installable after mcpp-index publication; see the bilingual README for the tested support scope." "${extra[@]}"
42 changes: 42 additions & 0 deletions .github/workflows/templates.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Actual project templates
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: templates-${{ github.ref }}
cancel-in-progress: true
env:
MCPP_VERSION: "2026.10.24.1"
jobs:
templates:
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: ~/.mcpp/registry
key: template-registry-${{ github.repository }}-${{ env.MCPP_VERSION }}-${{ hashFiles('mcpp.toml') }}
restore-keys: |
template-registry-${{ github.repository }}-${{ env.MCPP_VERSION }}-
- name: Install current mcpp
shell: bash
run: |
archive="mcpp-${MCPP_VERSION}-linux-x86_64.tar.gz"
curl -L -fsS -o "$archive" "https://github.com/mcpp-community/mcpp/releases/download/v${MCPP_VERSION}/$archive"
tar -xzf "$archive"
root="$PWD/mcpp-${MCPP_VERSION}-linux-x86_64"
mkdir -p "$HOME/.mcpp/registry"
cp -a "$root/registry/." "$HOME/.mcpp/registry/"
echo "$root/bin" >> "$GITHUB_PATH"
- name: Install toolchains
run: |
mcpp toolchain install gcc 16.1.0
mcpp toolchain install llvm 23.1.3
- name: Actual scaffold, strict build and runtime behavior
run: |
python3 tools/test_template.py --template decode --toolchain llvm@23.1.3
6 changes: 3 additions & 3 deletions .xlings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"workspace": {
"xim:mcpp": "2026.8.5.4"
}
"workspace": {
"xim:mcpp": "2026.10.24.1"
}
}
91 changes: 29 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,86 +1,53 @@
# ffmpeg

> FFmpeg 的 C++ 模块化封装 — `import ffmpeg.av;` 即用 · 三平台 · 全从源码构建,API 不变
> FFmpeg 8.1.2 as C++23 modules, preserving the C API.

**English** · [简体中文](README.zh.md) · [Upstream](https://github.com/FFmpeg/FFmpeg) · [Releases](https://github.com/mcpplibs/ffmpeg-m/releases) · [mcpp](https://github.com/mcpp-community/mcpp) · [Index](https://github.com/mcpplibs/mcpp-index)

[![Release](https://img.shields.io/github/v/release/mcpplibs/ffmpeg-m)](https://github.com/mcpplibs/ffmpeg-m/releases)
[![C++23](https://img.shields.io/badge/C%2B%2B-23-blue.svg)](https://en.cppreference.com/w/cpp/23)
[![Module](https://img.shields.io/badge/module-ok-green.svg)](https://en.cppreference.com/w/cpp/language/modules)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![CI](https://github.com/mcpplibs/ffmpeg-m/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/mcpplibs/ffmpeg-m/actions/workflows/ci.yml)

| [mcpp 构建工具](https://github.com/mcpp-community/mcpp) · [包索引 mcpp-index](https://github.com/mcpp-community/mcpp-index) · [FFmpeg 上游](https://github.com/FFmpeg/FFmpeg) · [Issues](https://github.com/mcpplibs/ffmpeg-m/issues) · [Releases](https://github.com/mcpplibs/ffmpeg-m/releases) |
|:---:|
| [![CI](https://github.com/mcpplibs/ffmpeg-m/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/mcpplibs/ffmpeg-m/actions/workflows/ci.yml) |

## 核心特性
Thin module interfaces over `compat.ffmpeg`; sources, frozen configuration and NASM support belong to that provider.

- **纯模块导入** — `import ffmpeg.av;`,消费者代码零 `#include`,用的仍是你熟悉的 C API 与全局名(`avcodec_open2`、`AVFrame`、`AV_CODEC_ID_H264` …)
- **从源码构建,消费端不跑 configure** — [`compat.ffmpeg`](https://github.com/mcpp-community/mcpp-index) 携带冻结 configure 快照 + 精确源码清单,mcpp 直接编译整套 FFmpeg 8.1.2(2124 `.c` + 157 NASM `.asm`,x86 SIMD 含)—— 32 核冷构建 ≈ 21 s;本仓库只是薄薄的模块层
- **全功能 profile** — 600+ decoders / 350+ demuxers / encoders / muxers / filters / swscale / swresample 全开,hermetic(不探测宿主库),LGPL-2.1+ 干净(无 `--enable-gpl`/`nonfree`)
- **三平台** — Linux / macOS / Windows 三平台 CI
## Modules

## 快速开始
- `import mcpplibs.mwrap.ffmpeg;`: Complete FFmpeg module aggregate
- `import mcpplibs.mwrap.ffmpeg.avcodec;`: Audio/video codecs
- `import mcpplibs.mwrap.ffmpeg.avformat;`: Containers and stream I/O
- `import mcpplibs.mwrap.ffmpeg.avutil;`: Common media types and utilities
- `import mcpplibs.mwrap.ffmpeg.macros;`: Common macro constant mappings

```bash
mcpp new myplayer --template ffmpeg && cd myplayer && mcpp run -- video.mp4 # 解码骨架
```
> More Modules API -> [Usage and API](docs/usage.md)

或在已有项目中手动接入:
## Getting started

```toml
[dependencies.ffmpeg]
ffmpeg = "8.1.2"
```sh
mcpp new media --template mcpplibs.mwrap.ffmpeg@8.1.2
cd media
mcpp run
```

```cpp
import std;
import ffmpeg.av; // 整套 FFmpeg 表面,Python `import av` 风格

int main() {
AVFormatContext* fmt { nullptr };
avformat_open_input(&fmt, "video.mp4", nullptr, nullptr);
// … 还是你熟悉的 C API,只是不用 #include
avformat_close_input(&fmt);
return 0;
}
```toml
[dependencies]
mcpplibs.mwrap.ffmpeg = "8.1.2"
```

## 模块一览

| import | 内容 |
|---|---|
| `ffmpeg.av` | 下面全部(推荐默认) |
| `ffmpeg.avutil` / `ffmpeg.avcodec` / `ffmpeg.avformat` / `ffmpeg.avfilter` / `ffmpeg.avdevice` / `ffmpeg.swscale` / `ffmpeg.swresample` | 每库一个;依赖自动 re-export(`import ffmpeg.avformat;` 带上 avcodec + avutil) |
| `ffmpeg` | `ffmpeg.av` 的 lib-root 别名 |

命名模块不能导出宏或 `static inline` 帮助函数。有链接的都从 import 来;宏拼写(`AVERROR`、`AV_NOPTS_VALUE`、`AVIO_FLAG_WRITE`、`MKTAG` …)与 inline 工具(`av_q2d`、`av_clip` …)在 import 前加可选侧头:

```cpp
#include <ffmpeg-m/macros.h>
import ffmpeg.av;
```

C 的复合字面量宏有 C++ 替换从模块导出:`av_err2str` → `av_err2string(err).c_str()`、`av_ts2str` → `av_ts2string`、`av_ts2timestr` → `av_ts2timestring`、`av_fourcc2str` → `av_fourcc2string`。

## 示例

| 示例 | 内容 |
|---|---|
| [`examples/probe`](examples/probe) | 版本 / 组件信息(无需输入) |
| [`examples/decode_frames`](examples/decode_frames) | 解码一个视频文件的帧 |

```bash
cd examples/decode_frames && mcpp run -- video.mp4
import mcpplibs.mwrap.ffmpeg.av;
int main() { return avcodec_version() == 0; }
```

`mcpp build && mcpp test` 验证包(自包含 encode→decode 往返 + API 表面测试)。
## Examples

## 工具链与运行时
The default template encodes and decodes a generated frame without external files.
[Probe](examples/probe) · [Decode frames](examples/decode_frames) · [Details](docs/usage.md)

包不固定工具链(mcpp 解析环境默认)。上游 FFmpeg 源码**不 vendored**,经 `compat.ffmpeg` 索引包(官方 ffmpeg.org tarball,GLOBAL + CN 镜像,sha256 锁定)到达消费端;描述符(configure 快照 inline 为 `generated_files` + `make -n` 源码清单)在 mcpp-index(`tools/compat-ffmpeg/`)维护。需要外部 SDK 的硬件加速头(`libavutil/hwcontext_cuda.h`、VAAPI …)不在模块导出面内,SDK 存在时在 import 旁 textual include。外部编解码器 / GPL 组件 / slim profile 等变体计划以 mcpp features(按 profile 的配置快照)提供。
## Build and runtime

> [!NOTE]
> 早期版本,接口可能调整。问题与想法欢迎提 [issue](https://github.com/mcpplibs/ffmpeg-m/issues)。
Linux, macOS and Windows; use `mcpp build` and `mcpp test`. External hardware SDK APIs require separate headers/SDKs.
The source profile does not enable GPL/nonfree components.

## License

封装代码 MIT;上游 FFmpeg 经 `compat.ffmpeg` 提供,**LGPL-2.1-or-later**(无 `--enable-gpl`/`nonfree` 组件),源码分发天然满足 LGPL 重链接要求。
Wrapper: [MIT](LICENSE). FFmpeg provider: LGPL-2.1-or-later; preserve selected source and license notices.
53 changes: 53 additions & 0 deletions README.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# ffmpeg

> FFmpeg 8.1.2 的 C++23 模块封装,保留 C API。

[English](README.md) · **简体中文** · [Upstream](https://github.com/FFmpeg/FFmpeg) · [Releases](https://github.com/mcpplibs/ffmpeg-m/releases) · [mcpp](https://github.com/mcpp-community/mcpp) · [Index](https://github.com/mcpplibs/mcpp-index)

[![C++23](https://img.shields.io/badge/C%2B%2B-23-blue.svg)](https://en.cppreference.com/w/cpp/23)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![CI](https://github.com/mcpplibs/ffmpeg-m/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/mcpplibs/ffmpeg-m/actions/workflows/ci.yml)

基于 `compat.ffmpeg` 的薄模块层;源码、冻结配置与 NASM 支持由供应者提供。

## 模块

- `import mcpplibs.mwrap.ffmpeg;`: FFmpeg 模块聚合
- `import mcpplibs.mwrap.ffmpeg.avcodec;`: 音视频编解码
- `import mcpplibs.mwrap.ffmpeg.avformat;`: 容器与流输入输出
- `import mcpplibs.mwrap.ffmpeg.avutil;`: 媒体公共类型与工具
- `import mcpplibs.mwrap.ffmpeg.macros;`: 常用宏常量映射

> More Modules API -> [模块与 API](docs/usage.md)

## 快速开始

```sh
mcpp new media --template mcpplibs.mwrap.ffmpeg@8.1.2
cd media
mcpp run
```

```toml
[dependencies]
mcpplibs.mwrap.ffmpeg = "8.1.2"
```

```cpp
import mcpplibs.mwrap.ffmpeg.av;
int main() { return avcodec_version() == 0; }
```

## 示例

默认模板编码并解码生成的图像帧,无需外部文件。
[组件信息](examples/probe) · [视频解码](examples/decode_frames) · [详细说明](docs/usage.md)

## 工具链与运行时

支持 Linux、macOS、Windows;使用 `mcpp build`、`mcpp test`。外部硬件 API 仍需要对应头文件与 SDK。
当前源码 profile 未启用 GPL/nonfree 组件。

## 许可证

封装:[MIT](LICENSE)。FFmpeg 供应者:LGPL-2.1-or-later;保留选中源码与许可证通知。
Loading
Loading