Skip to content

Commit ad20466

Browse files
committed
Advance OHOS platform foundation
1 parent 8ce6684 commit ad20466

29 files changed

Lines changed: 1027 additions & 212 deletions

‎AGENTS.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,9 @@ download commands and the complete consumption contract.
7676
Regardless of the resolution order above, any task that modifies `ffmpeg/**`
7777
must run the directly affected native build script locally and pass
7878
`cmake/verify-install.cmake`. Use `ffmpeg/scripts/build-android.sh` or
79-
`ffmpeg/scripts/build-ohos.sh` on macOS and
80-
`ffmpeg/scripts/build-windows.ps1` on Windows.
79+
`ffmpeg/scripts/build-ohos.sh` on macOS,
80+
`ffmpeg/scripts/build-ohos.ps1` for an OHOS cross-build on Windows, and
81+
`ffmpeg/scripts/build-windows.ps1` for the Windows x64 target.
8182

8283
## Non-negotiable architecture rules
8384

‎README.md‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,20 @@ gh run download $runId `
8181
--repo qietv/qtav `
8282
--name qtav-ffmpeg-x64-windows-static-md `
8383
--dir ffmpeg/build/x64-windows-static-md/vcpkg_installed
84+
85+
# When Windows is the OHOS cross-compilation host instead:
86+
gh run download $runId `
87+
--repo qietv/qtav `
88+
--name qtav-ffmpeg-arm64-ohos-23-static `
89+
--dir ffmpeg/build/arm64-ohos-23-static/vcpkg_installed
8490
```
8591

8692
The platform build scripts remain the source of those artifacts. If both local
8793
lookup and artifact download fail, run `ffmpeg/scripts/build-android.sh` or
88-
`ffmpeg/scripts/build-ohos.sh` on macOS, or
89-
`ffmpeg/scripts/build-windows.ps1` on Windows. Run the corresponding script
90-
unconditionally when the current change modifies `ffmpeg/**`.
94+
`ffmpeg/scripts/build-ohos.sh` on macOS, `ffmpeg/scripts/build-ohos.ps1` for an
95+
OHOS cross-build on Windows, or `ffmpeg/scripts/build-windows.ps1` for the
96+
Windows x64 target. Run the corresponding script unconditionally when the
97+
current change modifies `ffmpeg/**`.
9198

9299
The same artifacts can be downloaded manually from the
93100
[FFmpeg dependencies workflow](https://github.com/qietv/qtav/actions/workflows/ffmpeg-dependencies.yml).

‎ffmpeg/AGENTS.md‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ It builds FFmpeg 8.1.2 and the player dependency closure for these targets:
99
| --- | --- | --- |
1010
| macOS | Android arm64-v8a, API 28 | `arm64-android-28-static` |
1111
| macOS | OHOS arm64-v8a, API 23 | `arm64-ohos-23-static` |
12+
| 64-bit Windows | OHOS arm64-v8a, API 23 | `arm64-ohos-23-static` |
1213
| 64-bit Windows | Windows x64, Visual Studio ABI | `x64-windows-static-md` |
1314

1415
macOS is a cross-compilation host only. Do not add macOS or iOS outputs. Do
@@ -43,8 +44,9 @@ toolchains, overlay ports, verification rules, or output layout.
4344
- Keep `vcpkg.json`, `vcpkg-configuration.json`, overlay ports, and the
4445
verifier synchronized when dependencies or features change.
4546
- Keep source and text files UTF-8 without BOM and use LF line endings.
46-
- Preserve `scripts/build-android.sh` and `scripts/build-ohos.sh` as stable,
47-
directly callable local entry points. CI must call the same scripts.
47+
- Preserve `scripts/build-android.sh`, `scripts/build-ohos.sh`, and
48+
`scripts/build-ohos.ps1` as stable, directly callable local entry points.
49+
CI must use one of the supported target entry points.
4850
- Preserve the default package layout under
4951
`build/<triplet>/vcpkg_installed/<triplet>/`.
5052

@@ -77,11 +79,13 @@ On Windows, run from PowerShell on a machine with Visual Studio C++ and C++
7779
Clang tools installed:
7880

7981
```powershell
82+
./ffmpeg/scripts/build-ohos.ps1
8083
./ffmpeg/scripts/build-windows.ps1
8184
```
8285

83-
Use `QTAV_FFMPEG_INSTALL_ROOT` on macOS or `-InstallRoot` on Windows only when
84-
an alternate package location is required.
86+
The first command cross-compiles OHOS with the DevEco native SDK; the second
87+
builds the Windows x64 package. Use `QTAV_FFMPEG_INSTALL_ROOT` on macOS or
88+
`-InstallRoot` on Windows only when an alternate package location is required.
8589

8690
## Toolchain invariants
8791

‎ffmpeg/ARCHITECTURE.md‎

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ Windows outputs are independent and are never interchangeable.
1616
```text
1717
build-android.sh ─┐
1818
build-ohos.sh ────┼─> install-unix.sh ─┐
19-
build-windows.ps1 ┘ │
20-
v
19+
build-ohos.ps1 ───┤ │
20+
build-windows.ps1 ┘ │
21+
v
2122
vcpkg manifest + pinned registry baseline
2223
+ overlay ports
2324
+ target triplet
@@ -96,20 +97,24 @@ not FFmpeg executables or one combined shared object.
9697

9798
### OHOS
9899

99-
- Build host: macOS.
100+
- Build host: macOS or 64-bit Windows.
100101
- Target: arm64-v8a, API 23.
101102
- Toolchain: OpenHarmony native SDK `ohos.toolchain.cmake`.
102103
- vcpkg triplet: `arm64-ohos-23-static`.
103104
- Dependencies: release-only static archives; SDK system runtime linkage
104105
remains governed by the OHOS toolchain.
105-
- Default SDK discovery: `$HOME/Library/OpenHarmony/Sdk/23`.
106+
- Default SDK discovery: `$HOME/Library/OpenHarmony/Sdk/23` on macOS or the
107+
DevEco Studio SDK under `Program Files` on Windows.
106108

107109
vcpkg has no first-class OHOS platform model at the pinned baseline. The
108110
triplet uses its Linux compatibility path for port selection, then the
109111
chainloaded toolchain redirects every compiler and target flag to OHOS. The
110112
`VCPKG_TARGET_IS_OHOS` marker lets overlays distinguish OHOS from a real Linux
111-
target. Host pkg-config libraries must never enter this build. A native
112-
macOS `patchelf` is used only for vcpkg packaging operations.
113+
target. Host pkg-config libraries must never enter this build. A native macOS
114+
`patchelf` is used only for macOS packaging operations; vcpkg acquires its
115+
Windows `patchelf.exe` tool when the PowerShell entry point requires it. The
116+
Windows script uses a stable no-space SDK junction because MSYS-driven OpenSSL
117+
and FFmpeg steps cannot reliably consume the normal `Program Files` path.
113118

114119
### Windows
115120

@@ -154,6 +159,9 @@ project-specific behavior:
154159
- the Android FFmpeg overlay enables FFmpeg's built-in RPU decoder for the
155160
HEVC MediaCodec wrapper and PTS-correlates parsed Dolby Vision metadata with
156161
hardware output frames before QtAVCore receives them.
162+
- the OHOS FFmpeg overlay requires the native H.264 and HEVC OHCodec wrappers;
163+
configure failure is fatal and the verifier checks both decoder symbols in
164+
the installed `libavcodec.a` archive.
157165
- libsmb2 supplies the missing private Winsock link metadata required by a
158166
static Windows consumer.
159167

@@ -188,6 +196,7 @@ Every entry script runs `cmake/verify-install.cmake` after vcpkg installation.
188196
The verifier checks:
189197

190198
- required FFmpeg 8/libavcodec 62 headers and metadata;
199+
- H.264 and HEVC OHCodec decoder symbols in the OHOS archive;
191200
- OpenSSL, libsmb2, libass, libplacebo/glslang/OpenGL/OpenGL ES/Dolby Vision
192201
reshaping, dav1d, and Vulkan, plus libplacebo D3D11/SPIRV-Cross on Windows;
193202
- the required FFmpeg feature records;
@@ -198,7 +207,8 @@ The root GitHub Actions workflow runs automatically for changes to
198207
`ffmpeg/**`: Android and OHOS use self-hosted macOS arm64 runners, while
199208
Windows uses a self-hosted Visual Studio runner. Successful target prefixes
200209
and the vcpkg status database are uploaded as artifacts for parent-project
201-
builds and inspection.
210+
builds and inspection. That is the current CI topology, not a local-host
211+
restriction; the OHOS package also has a supported Windows PowerShell entry.
202212

203213
These fixed self-hosted runners retain vcpkg's default local binary archive
204214
directory between jobs. CI intentionally does not use `actions/cache` for that

‎ffmpeg/README.md‎

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ Supported build hosts and targets:
1515
| --- | --- | --- |
1616
| macOS | Android arm64-v8a, API 28 | `arm64-android-28-static` |
1717
| macOS | OHOS arm64-v8a, API 23 | `arm64-ohos-23-static` |
18+
| 64-bit Windows with DevEco Studio | OHOS arm64-v8a, API 23 | `arm64-ohos-23-static` |
1819
| 64-bit Windows with Visual Studio and Clang tools | Windows x64 | `x64-windows-static-md` |
1920

2021
macOS itself is not a QtAVCore target. Windows dependencies must be built and
21-
validated on Windows; the PowerShell entry point is not a cross-compiler.
22+
validated on Windows; `build-windows.ps1` is not a cross-compiler. The separate
23+
`build-ohos.ps1` entry point uses the DevEco native SDK to cross-compile OHOS.
2224

2325
## Pinned dependency policy
2426

@@ -34,6 +36,8 @@ The FFmpeg overlay applies this policy:
3436
- `--enable-libsmb2`, using the FFmpeg integration patch and protocol sources
3537
imported from the reference `avbuild2` tree;
3638
- `--enable-vulkan --enable-libplacebo --enable-libass --enable-libdav1d`;
39+
- `--enable-ohcodec` for the OHOS triplet, with H.264 and HEVC wrapper
40+
decoders required by installed-package verification;
3741
- FFmpeg's native VVC/H.266 decoder remains enabled because the build never
3842
disables the native decoder set; no external VVC encoder is included;
3943
- `--enable-lto --enable-small --disable-avdevice --disable-iamf`;
@@ -112,7 +116,28 @@ directly or set `OHOS_SDK_ROOT`:
112116

113117
The OpenHarmony compiler target and CMake platform are fixed to OHOS API 23.
114118

115-
## Windows with Visual Studio
119+
## OHOS on Windows
120+
121+
Run from 64-bit PowerShell with DevEco Studio/OpenHarmony native SDK and Visual
122+
Studio C++ Build Tools installed:
123+
124+
```powershell
125+
git submodule update --init ffmpeg/vcpkg
126+
./ffmpeg/scripts/build-ohos.ps1
127+
```
128+
129+
The script locates the normal DevEco SDK automatically. Use `-SdkRoot` for a
130+
non-standard SDK, `-InstallRoot` for a different vcpkg database, or `-WorkRoot`
131+
for a different space-free work directory. Because DevEco is normally under
132+
`Program Files`, the script creates a stable no-space SDK junction below the
133+
work root for OpenSSL/FFmpeg MSYS build steps. Windows `patchelf.exe` is
134+
acquired by vcpkg when required; a separate WSL or macOS installation is not
135+
needed.
136+
137+
See [`../modern/OHOS_WINDOWS.md`](../modern/OHOS_WINDOWS.md) for the complete
138+
dependency plus QtAVCore build and install workflow.
139+
140+
## Windows x64 target with Visual Studio
116141

117142
Run from 64-bit PowerShell on a Windows machine with Visual Studio C++ tools
118143
and the **C++ Clang tools for Windows** component installed:
@@ -161,7 +186,9 @@ cmake -S modern -B build/modern-android \
161186

162187
Use the corresponding OHOS or Windows triplet for those targets. The build
163188
scripts accept `QTAV_FFMPEG_INSTALL_ROOT` on macOS and `-InstallRoot` on
164-
Windows when a different artifact directory is needed.
189+
Windows when a different artifact directory is needed. For a Windows-hosted
190+
OHOS parent build, prefer `modern/scripts/build-ohos.ps1`, which supplies the
191+
required vcpkg and OHOS chainload toolchains together.
165192

166193
See [`ARCHITECTURE.md`](ARCHITECTURE.md) for the subproject's layering,
167194
dependency graph, target model, and parent-project integration contract, and
@@ -174,3 +201,5 @@ Maintenance rules for agents and contributors are in [`AGENTS.md`](AGENTS.md).
174201
self-hosted macOS arm64 runner and Windows on a self-hosted Visual Studio
175202
runner. The OHOS job uses `OHOS_SDK_ROOT` when set and otherwise checks
176203
`$HOME/Library/OpenHarmony/Sdk/23`; macOS-native `patchelf` must be installed.
204+
This describes the current CI assignment only; local OHOS builds are supported
205+
on both macOS and Windows.

‎modern/MIGRATION.md‎

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -482,14 +482,17 @@ implementation.
482482
- `renderVideoDetailed()` runs synchronously on its caller and should be called
483483
from the thread that owns the native graphics context. Atomically published
484484
immutable frame/binding snapshots keep this hot path off the Player control
485-
mutex. Its `VideoRenderResult` distinguishes rendered, no-frame, Player-busy,
486-
and renderer-busy outcomes and includes a frame sequence and presentation
487-
generation for bounded retry coalescing. A generation change during the
488-
backend call rejects that stale completion;
485+
mutex. `VideoRenderAPI::renderDetailed()` classifies a backend attempt as
486+
presented, deferred until a backend redraw, timer-backoff retry, terminally
487+
discarded, surface-lost, or fatal. `VideoRenderResult` maps those outcomes
488+
to Player-facing statuses and includes frame sequence, presentation
489+
generation, optional retry delay, and detail. A generation change during the
490+
backend call returns a terminal `FrameDiscarded` completion;
489491
- compatibility `renderVideo()` returns a negative value for every non-rendered
490492
result and therefore cannot distinguish a missing frame from retryable
491-
contention. New native render loops should retry only the detailed busy
492-
results rather than blocking their UI/render thread;
493+
contention. New native render loops retain the exact frame for
494+
`RendererDeferred`, retry `RendererBusy` after bounded backoff, recreate the
495+
platform surface for `SurfaceLost`, and do not retry `FrameDiscarded`;
493496
- `OpenGLPresentCallback` runs on that same graphics-owner thread after
494497
framebuffer submission and before hardware-source release; it is intended
495498
for the adapter's bounded window-present call, not general application work;
@@ -500,9 +503,10 @@ implementation.
500503
contention. A private output worker may pair `reserveContext()` with
501504
`tryContextGuardFor()` for a bounded, reservation-aware handoff without
502505
blocking an application UI thread;
503-
- `VideoRenderAPI::render()` runs synchronously inside
506+
- `VideoRenderAPI::renderDetailed()` runs synchronously inside Player's
504507
`renderVideoDetailed()` (and therefore the compatibility `renderVideo()`
505-
wrapper), and backend event callbacks may request another player state;
508+
wrapper). Its default implementation calls the legacy boolean `render()`;
509+
backend event callbacks may request another player state;
506510
- audio-sink and video-render backend event callbacks run on the thread chosen
507511
by the backend and may request another player state;
508512
- compressed audio packets cross a bounded queue to their decode worker, then

‎modern/MOBILE.md‎

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,17 @@ failed recovery enters the explicit no-renderer state. Selection notifications
170170
record selected, recovered, fallback, and unavailable transitions with their
171171
reasons.
172172

173+
The portable `VideoRenderAttemptResult` is the synchronous decision boundary
174+
used by both mobile APIs and future OHOS adapters. `Presented` completes the
175+
frame, `DeferredUntilRedraw` retains that exact frame until an asynchronous
176+
producer/GPU callback raises `RedrawRequested`, `RetryAfterBackoff` asks the
177+
application for a bounded timer retry, and `Discarded` terminally consumes a
178+
stale or retired-generation frame. `SurfaceLost` starts bounded same-API
179+
recreation; `FatalError` starts the one-way Vulkan-to-OpenGL ES policy. These
180+
outcomes no longer depend on guessing from a boolean return plus a synchronous
181+
event side channel. Legacy boolean renderers remain supported through the
182+
default retry-after-backoff mapping.
183+
173184
The platform calls `suspendSurface()` before releasing a native-window
174185
generation, updates the application state captured by the factories, and calls
175186
`recreateSurface()` after publishing the replacement. The selector object
@@ -201,10 +212,9 @@ without mapping. OpenGL ES interop requires the prepared candidate to
201212
advertise the source hardware device; no callback or a `None` decision makes
202213
presentation explicitly unavailable.
203214

204-
An asynchronous interop attempt may return `false` before its producer image
205-
is ready without emitting `SurfaceLost` or `Error`. The selector treats this
206-
as retryable and preserves the active API. Only an emitted lifecycle or fatal
207-
event starts recovery or fallback.
215+
An asynchronous interop attempt returns `DeferredUntilRedraw` before its
216+
producer image is ready. The selector preserves the active API and exact frame;
217+
only `SurfaceLost` or `FatalError` starts recovery or fallback.
208218

209219
## Platform surface adapters
210220

‎modern/OHOS_WINDOWS.md‎

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Building QtAVCore for OHOS on Windows
2+
3+
QtAVCore and its repository-pinned FFmpeg dependency closure can be
4+
cross-compiled for OHOS arm64/API 23 directly on 64-bit Windows. WSL is not
5+
required. The supported Windows route uses PowerShell plus the native tools
6+
bundled with the OpenHarmony SDK installed by DevEco Studio.
7+
8+
## Prerequisites
9+
10+
- 64-bit Windows and 64-bit PowerShell;
11+
- DevEco Studio with an OpenHarmony SDK containing `native/`;
12+
- Git and the repository's pinned `ffmpeg/vcpkg` submodule;
13+
- Visual Studio C++ Build Tools for vcpkg host utilities;
14+
- network access for source downloads when the vcpkg download/cache is empty.
15+
16+
The scripts look for the SDK in this order: `-SdkRoot`, `OHOS_SDK_ROOT`,
17+
`OHOS_NDK`, `DEVECO_SDK_HOME`, then the normal DevEco Studio installation
18+
under `Program Files`. The target remains arm64-v8a/API 23 even when a newer
19+
compatible SDK is installed.
20+
21+
Initialize vcpkg once from the repository root:
22+
23+
```powershell
24+
git submodule update --init ffmpeg/vcpkg
25+
```
26+
27+
## Build FFmpeg dependencies
28+
29+
Run the Windows OHOS dependency entry point:
30+
31+
```powershell
32+
./ffmpeg/scripts/build-ohos.ps1
33+
```
34+
35+
For a non-standard SDK or output location:
36+
37+
```powershell
38+
./ffmpeg/scripts/build-ohos.ps1 `
39+
-SdkRoot D:/OpenHarmony/Sdk/openharmony `
40+
-InstallRoot D:/qtav-ohos/vcpkg_installed `
41+
-WorkRoot D:/qtav-ohos/vcpkg-work
42+
```
43+
44+
`WorkRoot` must not contain spaces. DevEco normally resides below
45+
`C:\Program Files`; OpenSSL and FFmpeg invoke MSYS tools which cannot reliably
46+
consume that compiler path. The script therefore creates a stable, space-free
47+
SDK junction under the work root. It does not modify the installed SDK. Choose
48+
a different work root when intentionally switching between SDK installations.
49+
50+
The default package database and target prefix are:
51+
52+
```text
53+
ffmpeg/build/arm64-ohos-23-static/vcpkg_installed/
54+
├── vcpkg/
55+
└── arm64-ohos-23-static/
56+
```
57+
58+
The FFmpeg overlay requires `--enable-ohcodec` on this triplet. The final
59+
verifier uses the SDK's `llvm-nm` to require both `ff_h264_oh_decoder` and
60+
`ff_hevc_oh_decoder` in `libavcodec.a`; a configure-time fallback to an
61+
OHCodec-disabled package is therefore an error.
62+
63+
## Build and install QtAVCore
64+
65+
The normal command builds missing dependencies, then configures, builds, and
66+
installs a shared Release SDK:
67+
68+
```powershell
69+
./modern/scripts/build-ohos.ps1
70+
```
71+
72+
The default output is `build/modern-ohos-shared/`, with its install tree under
73+
`build/modern-ohos-shared/install/`. To reuse an already verified dependency
74+
database without invoking vcpkg again:
75+
76+
```powershell
77+
./modern/scripts/build-ohos.ps1 -SkipDependencies
78+
```
79+
80+
This skips compilation, not validation: `verify-install.cmake` still rejects
81+
an older dependency package that does not contain the required OHCodec decoder
82+
symbols.
83+
84+
Build a static SDK with:
85+
86+
```powershell
87+
./modern/scripts/build-ohos.ps1 `
88+
-LibraryType Static `
89+
-BuildDirectory build/modern-ohos-static
90+
```
91+
92+
Useful options include `-BuildType`, `-BuildTests`, `-BuildExamples`,
93+
`-InstallPrefix`, `-NoInstall`, and `-Parallel`. Cross-compiled tests and
94+
examples can be built on Windows but cannot be executed as Windows programs;
95+
runtime tests must be packaged in an OHOS application and run on a device.
96+
97+
For an external CMake consumer, set `QtAVCore_DIR` to the installed
98+
`lib/cmake/QtAVCore` directory. The OHOS SDK intentionally restricts package
99+
searches to its sysroot, so `CMAKE_PREFIX_PATH` alone may not discover an SDK
100+
installed elsewhere on the Windows filesystem.
101+
102+
The script explicitly chainloads the repository OHOS toolchain through vcpkg.
103+
Shared QtAVCore libraries receive `-Wl,-Bsymbolic` from the project CMake rules
104+
so the PIC static FFmpeg closure, including its AArch64 assembly, can be linked
105+
without interposable relocation failures. FFmpeg's pkg-config metadata supplies
106+
libsmb2, OpenSSL, dav1d, and the OHCodec system libraries to the final link.
107+
108+
## Packaging and signing
109+
110+
These scripts produce native libraries and CMake package metadata; they do not
111+
create or sign a HAP. Add the installed libraries to the application's
112+
`libs/arm64-v8a/` directory and configure the application certificate/signing
113+
in DevEco Studio. Device installation and authorization remain application
114+
integration steps.
115+
116+
When diagnosing a manual CMake invocation, prefer the supported script. A
117+
compiler test that links Windows system libraries means the OHOS chainload
118+
toolchain was omitted. A shared-link `R_AARCH64_ADR_PREL_PG_HI21` failure means
119+
the QtAVCore OHOS `-Bsymbolic` rule was bypassed or removed.

0 commit comments

Comments
 (0)