Compare commits
226
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca8dc9147b | ||
|
|
df8b99490c | ||
|
|
c78142a973 | ||
|
|
a8e6caf56b | ||
|
|
e6cca1e43b | ||
|
|
d7538d3597 | ||
|
|
f3eb5b143c | ||
|
|
9993fd8888 | ||
|
|
d9c3a51d87 | ||
|
|
619fa761af | ||
|
|
717d729dcb | ||
|
|
4eb5b62e5a | ||
|
|
b9e32d0d3d | ||
|
|
28e2b95f58 | ||
|
|
491f633a20 | ||
|
|
eb5e45855a | ||
|
|
59e55bb0e1 | ||
|
|
9f46be7373 | ||
|
|
3623fb38ee | ||
|
|
1ad9e322e3 | ||
|
|
cad63810c5 | ||
|
|
da17c64c76 | ||
|
|
57f32f7ca8 | ||
|
|
3d85137495 | ||
|
|
4aff0076a0 | ||
|
|
70f8ea228d | ||
|
|
3196f4cdd7 | ||
|
|
4fa0853c34 | ||
|
|
6598b55c35 | ||
|
|
848d7979e5 | ||
|
|
13301daf6a | ||
|
|
763a38f889 | ||
|
|
ed1e4de452 | ||
|
|
0e2fe55fde | ||
|
|
22cfb48b52 | ||
|
|
4a07120f83 | ||
|
|
d06ff691ed | ||
|
|
34cee2a77d | ||
|
|
8f5eb7b780 | ||
|
|
b991c072f6 | ||
|
|
3c2777994b | ||
|
|
80741f27f3 | ||
|
|
3d18ab77b3 | ||
|
|
8d2baaa318 | ||
|
|
2758bc462d | ||
|
|
2687b43dd0 | ||
|
|
bb40daf367 | ||
|
|
cc1f926441 | ||
|
|
67f653324a | ||
|
|
6e2c29b786 | ||
|
|
e565217f22 | ||
|
|
144c67efaf | ||
|
|
96d7e80ddf | ||
|
|
dde72c5c54 | ||
|
|
577d03da0c | ||
|
|
fc510f0da8 | ||
|
|
8d5775a8d2 | ||
|
|
cf8ff2fd87 | ||
|
|
852c924a60 | ||
|
|
1685d198b9 | ||
|
|
1e2d28f567 | ||
|
|
89973ebca1 | ||
|
|
3f4e528f73 | ||
|
|
6f7c9f516e | ||
|
|
33e0074603 | ||
|
|
b6ed94fa7c | ||
|
|
a419703549 | ||
|
|
5171da86e3 | ||
|
|
7bd670949c | ||
|
|
421b2be348 | ||
|
|
b659476ed9 | ||
|
|
689c3f47a8 | ||
|
|
677d4615ba | ||
|
|
5f788a7812 | ||
|
|
dba25e13c0 | ||
|
|
623b97e45a | ||
|
|
7a645ba62f | ||
|
|
63afe3eb98 | ||
|
|
72c70eb05b | ||
|
|
df0ec55499 | ||
|
|
542bcdfc9d | ||
|
|
218667b5a2 | ||
|
|
13a0e34aec | ||
|
|
76b7a1a713 | ||
|
|
6d6eee2e70 | ||
|
|
89f20cd2f3 | ||
|
|
cce2b675ac | ||
|
|
c1ed4dc242 | ||
|
|
712657a894 | ||
|
|
496956de3d | ||
|
|
483e703793 | ||
|
|
717cdeb95d | ||
|
|
315f3a9218 | ||
|
|
d857722618 | ||
|
|
6d9d597b10 | ||
|
|
c4d905b567 | ||
|
|
e4c69376fc | ||
|
|
842689bbf6 | ||
|
|
5ab2aa84e0 | ||
|
|
229d398ba9 | ||
|
|
5f1b155307 | ||
|
|
241cbe5065 | ||
|
|
76d771a6fa | ||
|
|
19caba0794 | ||
|
|
391546c52f | ||
|
|
a8af6a7852 | ||
|
|
960aca3386 | ||
|
|
e72a327d74 | ||
|
|
87f955f3e9 | ||
|
|
5536ebe82f | ||
|
|
ef8b37ca2a | ||
|
|
d4a5513847 | ||
|
|
d42212cd67 | ||
|
|
674cc1d3a9 | ||
|
|
c47bb9ca42 | ||
|
|
938dad0b88 | ||
|
|
82b5361946 | ||
|
|
f99f48684b | ||
|
|
25864a5539 | ||
|
|
524d9585fd | ||
|
|
95a72baf92 | ||
|
|
48112a74ed | ||
|
|
8427cdc717 | ||
|
|
b695ca1e27 | ||
|
|
801feb6420 | ||
|
|
de6a452039 | ||
|
|
4b764b6cc6 | ||
|
|
7b7c31b190 | ||
|
|
70a66b461d | ||
|
|
844e8f2b51 | ||
|
|
3f4ed8920f | ||
|
|
7ad2999b5f | ||
|
|
14fdbe07ac | ||
|
|
61ed9a8747 | ||
|
|
0801345d68 | ||
|
|
5bd0fe5daf | ||
|
|
cab3c5fbb8 | ||
|
|
99ceae8cc3 | ||
|
|
ebe04ab692 | ||
|
|
808aa08cc0 | ||
|
|
2065e0ba36 | ||
|
|
3c43a022af | ||
|
|
02513cd5df | ||
|
|
4d986d2a98 | ||
|
|
ada6f96811 | ||
|
|
321b3952b0 | ||
|
|
d49b49ff96 | ||
|
|
f088abb2bf | ||
|
|
4a3975bf7e | ||
|
|
a064143899 | ||
|
|
f264d52099 | ||
|
|
74a3c169b5 | ||
|
|
34d9787fcf | ||
|
|
1c0b80d518 | ||
|
|
a9bafeb589 | ||
|
|
3a33db3d92 | ||
|
|
d276f753f7 | ||
|
|
c06000eef8 | ||
|
|
1bc1cd2305 | ||
|
|
a735a2abd7 | ||
|
|
112c1abe31 | ||
|
|
362b35b631 | ||
|
|
49cf0af294 | ||
|
|
1b26874710 | ||
|
|
8fe636da7a | ||
|
|
812f149585 | ||
|
|
635424c8f0 | ||
|
|
2319918721 | ||
|
|
9fabf85a44 | ||
|
|
54fd5d0979 | ||
|
|
d141d281ca | ||
|
|
ebc3d74b04 | ||
|
|
a63fab8921 | ||
|
|
4ee8d8d3f9 | ||
|
|
574a2484c1 | ||
|
|
f5b92bee5e | ||
|
|
ca3d7144db | ||
|
|
86e7c3defb | ||
|
|
0fe1385d80 | ||
|
|
f4e9371d0f | ||
|
|
909185d49e | ||
|
|
c18c324c6f | ||
|
|
6b20c24413 | ||
|
|
5c42d1eb92 | ||
|
|
e34132f8d5 | ||
|
|
bd7ff23f96 | ||
|
|
e6c184e2b1 | ||
|
|
33c4920967 | ||
|
|
0c36f655e1 | ||
|
|
cd31697dd8 | ||
|
|
c497b82583 | ||
|
|
6f5dfb5102 | ||
|
|
59f970d492 | ||
|
|
29c74b42b4 | ||
|
|
4b2a3e50e2 | ||
|
|
35b01c9604 | ||
|
|
09b95257fe | ||
|
|
0cf2df38d1 | ||
|
|
4326fdfe2a | ||
|
|
9755850b3d | ||
|
|
96b50e770b | ||
|
|
9f6551160a | ||
|
|
89b854165e | ||
|
|
0beece4397 | ||
|
|
8abdf1f56e | ||
|
|
5a81f7678e | ||
|
|
e26286dfdb | ||
|
|
389232e5a2 | ||
|
|
c5de0b0a6c | ||
|
|
f9bdfc0782 | ||
|
|
5c9a7e24f6 | ||
|
|
b56f61d2ab | ||
|
|
82ab3a8160 | ||
|
|
e371f2ebd3 | ||
|
|
29b68d69c0 | ||
|
|
6c770eb6df | ||
|
|
965f336917 | ||
|
|
47fae324c7 | ||
|
|
6ab0dbf2ed | ||
|
|
c002196ffe | ||
|
|
3c8fc4588d | ||
|
|
416015f059 | ||
|
|
773db053aa | ||
|
|
a8c09d003f | ||
|
|
1284a6b6b0 | ||
|
|
78c35e42ea |
No files matched your search
@@ -1,26 +0,0 @@
|
||||
# To use this config on you editor, follow the instructions at:
|
||||
# http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
max_line_length = 80
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[.git/COMMIT*]
|
||||
max_line_length = 72
|
||||
|
||||
[{osdep/dirent-win.h,TOOLS/osxbundle/mpv.app/Contents/PkgInfo,TOOLS/osxbundle/mpv.app/Contents/Resources/Assets.car}]
|
||||
charset = unset
|
||||
insert_final_newline = unset
|
||||
indent_style = unset
|
||||
indent_size = unset
|
||||
max_line_length = unset
|
||||
trim_trailing_whitespace = unset
|
||||
|
||||
[menu.conf]
|
||||
indent_style = tab
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"Format": "github-actions",
|
||||
"Disable": {
|
||||
"IndentSize": true,
|
||||
"MaxLineLength": true
|
||||
}
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
name: "Report a Linux Issue"
|
||||
description: "Create a report for a runtime related Linux Issue"
|
||||
labels: ["os:linux"]
|
||||
type: Bug
|
||||
body:
|
||||
- type: textarea
|
||||
id: mpv_information
|
||||
attributes:
|
||||
label: "mpv Information"
|
||||
placeholder: |
|
||||
mpv v0.38.0-96-gf776be6af5 Copyright © 2000-2024 mpv/MPlayer/mplayer2 projects
|
||||
built on May 5 2024 18:37:43
|
||||
libplacebo version: v7.349.0 (v6.338.0-120-g7b294350)
|
||||
FFmpeg version: 6.1.1
|
||||
FFmpeg library versions:
|
||||
libavutil 58.29.100
|
||||
libavcodec 60.31.102
|
||||
libavformat 60.16.100
|
||||
libswscale 7.5.100
|
||||
libavfilter 9.12.100
|
||||
libswresample 4.12.100
|
||||
description: |
|
||||
Provide the output of `mpv --version`.
|
||||
render: bash
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: other_information
|
||||
attributes:
|
||||
label: "Other Information"
|
||||
description: >
|
||||
Provide following information if applicable.
|
||||
- Linux Version: `cat /etc/os-release | grep "NAME"`
|
||||
- Kernel Version: `uname -a`
|
||||
- GPU Model: `lspci -nn | grep VGA` or `lshw -C display -numeric`
|
||||
- Mesa/GPU Driver Version: `glxinfo -B | grep "OpenGL version string"` or `vulkaninfo | grep driverInfo`
|
||||
- Window Manager and Version
|
||||
- Source of the mpv binary
|
||||
- Latest version of mpv you know without the problem
|
||||
- The time when the problem started to happen (after updating mpv, system, driver, etc.)
|
||||
- Possible screenshot or video of visual glitches
|
||||
|
||||
If you're not using the git master branch or the [latest release](https://github.com/mpv-player/mpv/releases/latest), please update.
|
||||
Older versions are not supported. If your distribution does not provide the latest version, please report the issue to them.
|
||||
|
||||
Packages and builds can be found [here](https://mpv.io/installation/).
|
||||
value: |-
|
||||
- Linux version:
|
||||
- Kernel Version:
|
||||
- GPU Model:
|
||||
- Mesa/GPU Driver Version:
|
||||
- Window Manager and Version:
|
||||
- Source of mpv:
|
||||
- Latest known working version:
|
||||
- Issue started after the following happened:
|
||||
render: text
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction_steps
|
||||
attributes:
|
||||
label: "Reproduction Steps"
|
||||
description: >
|
||||
Try to reproduce your issue with `--no-config` first. If it isn't reproducible
|
||||
with `--no-config` try to find out which option or script causes your issue.
|
||||
|
||||
|
||||
If the issue is render performance-related, try to reproduce it with `--no-config
|
||||
--profile=fast`, which is designed to work on lower-end mobile devices.
|
||||
|
||||
|
||||
For decoding performance-related issues, additionally try to enable hardware
|
||||
decoding with `--hwdec=yes` or the `Ctrl+h` shortcut.
|
||||
|
||||
|
||||
Describe the reproduction steps as precise as possible. It's very likely that
|
||||
the bug you experience wasn't reproduced by the developer because the workflow
|
||||
differs from your own.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected_behavior
|
||||
attributes:
|
||||
label: "Expected Behavior"
|
||||
placeholder: "What were you expecting?"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: actual_behavior
|
||||
attributes:
|
||||
label: "Actual Behavior"
|
||||
placeholder: "What happened instead?"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: log_file
|
||||
attributes:
|
||||
label: "Log File"
|
||||
placeholder: "Drag and drop log file here (Don't paste content directly)"
|
||||
description: >
|
||||
Make a log file with `--gpu-debug --log-file=output.txt`, which is our preferred way, and
|
||||
attach it to the issue.
|
||||
|
||||
|
||||
If you have trouble producing a log file, you can alternatively use `--gpu-debug --msg-time -v -v`,
|
||||
save the terminal output to a file, and attach it to the issue.
|
||||
|
||||
|
||||
In the case of a crash, please provide a [backtrace](https://wiki.archlinux.org/title/Debugging/Getting_traces).
|
||||
|
||||
|
||||
Without the log file, this issue will be closed for ignoring the issue template.
|
||||
|
||||
|
||||
Disclaimer: The log file may contain identifiable information, such as your username.
|
||||
Review the log file before sharing and redact any sensitive data if necessary.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: sample_files
|
||||
attributes:
|
||||
label: "Sample Files"
|
||||
placeholder: "Drag and drop sample files here"
|
||||
description: >
|
||||
Please provide sample files for a minimal reproduction case, if the issue can't be
|
||||
reproduced without it or it is helpful to demonstrate the issue.
|
||||
|
||||
|
||||
Preferably files should be attached directly within the text field below. Due to GitHub's
|
||||
upload restriction, you may need to archive the sample file first and upload it as `.zip`
|
||||
file. If the sample file is too big to attach directly, use a solution that is easy to
|
||||
access with possible long-term retention. Possible services include, but are not limited
|
||||
to, the following:
|
||||
|
||||
- [0x0.st](https://0x0.st/) (no long-term retention)
|
||||
- [Dropbox](https://www.dropbox.com)
|
||||
- [Google Drive](https://www.google.com/drive/)
|
||||
- [iCLoud Drive](https://www.icloud.com/iclouddrive/)
|
||||
- [MediaFire](https://www.mediafire.com/)
|
||||
- [OneDrive](https://onedrive.live.com/)
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: "I carefully read all instruction and confirm that I did the following:"
|
||||
options:
|
||||
- label: "I tested and confirmed that the issue exists with the [latest release version](https://github.com/mpv-player/mpv/releases/latest) or newer."
|
||||
required: true
|
||||
- label: "I provided all required information including system and mpv version."
|
||||
required: true
|
||||
- label: >-
|
||||
I produced the log file with the exact same set of files, parameters, and conditions
|
||||
used in "Reproduction Steps", with the addition of `--log-file=output.txt`.
|
||||
required: true
|
||||
- label: >-
|
||||
I produced the log file while the behaviors described in "Actual Behavior" were
|
||||
actively observed.
|
||||
required: true
|
||||
- label: "I attached the full, untruncated log file."
|
||||
required: true
|
||||
- label: "I attached the backtrace in the case of a crash."
|
||||
required: true
|
||||
@@ -1,153 +0,0 @@
|
||||
name: "Report a macOS Issue"
|
||||
description: "Create a report for a runtime related macOS Issue"
|
||||
labels: ["os:mac"]
|
||||
type: Bug
|
||||
body:
|
||||
- type: textarea
|
||||
id: mpv_information
|
||||
attributes:
|
||||
label: "mpv Information"
|
||||
placeholder: |
|
||||
mpv v0.38.0-96-gf776be6af5 Copyright © 2000-2024 mpv/MPlayer/mplayer2 projects
|
||||
built on May 5 2024 18:37:43
|
||||
libplacebo version: v7.349.0 (v6.338.0-120-g7b294350)
|
||||
FFmpeg version: 6.1.1
|
||||
FFmpeg library versions:
|
||||
libavutil 58.29.100
|
||||
libavcodec 60.31.102
|
||||
libavformat 60.16.100
|
||||
libswscale 7.5.100
|
||||
libavfilter 9.12.100
|
||||
libswresample 4.12.100
|
||||
description: |
|
||||
Provide the output of `mpv --version`.
|
||||
render: bash
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: other_info
|
||||
attributes:
|
||||
label: "Other Information"
|
||||
description: >
|
||||
- macOS Version: `system_profiler SPSoftwareDataType | sed -rn 's/^ *System Version: (.*$)/\1/p'`
|
||||
- Source of the mpv binary or bundle
|
||||
- Latest version of mpv you know without the problem
|
||||
- The time when the problem started to happen (after updating mpv, system, driver, etc.)
|
||||
- Possible screenshot or video of visual glitches
|
||||
|
||||
If you're not using git master or the latest release, update.
|
||||
Nightly builds from master can be found [here](https://github.com/mpv-player/mpv/actions/workflows/build.yml?query=branch%3Amaster+event%3Apush),
|
||||
click on the latest workflow run, scroll down to the Artifacts section and download the
|
||||
appropriate build. Packages and builds can be found [here](https://mpv.io/installation/).
|
||||
value: |-
|
||||
- macOS version:
|
||||
- Source of mpv:
|
||||
- Latest known working version:
|
||||
- Issue started after the following happened:
|
||||
render: text
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction_steps
|
||||
attributes:
|
||||
label: "Reproduction Steps"
|
||||
description: >
|
||||
Try to reproduce your issue with `--no-config` first. If it isn't reproducible
|
||||
with `--no-config` try to find out which option or script causes your issue.
|
||||
|
||||
|
||||
If the issue is render performance-related, try to reproduce it with `--no-config
|
||||
--profile=fast`, which is designed to work on lower-end mobile devices.
|
||||
|
||||
|
||||
For decoding performance-related issues, additionally try to enable hardware
|
||||
decoding with `--hwdec=yes` or the `Ctrl+h` shortcut.
|
||||
|
||||
|
||||
Describe the reproduction steps as precise as possible. It's very likely that
|
||||
the bug you experience wasn't reproduced by the developer because the workflow
|
||||
differs from your own.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected_behavior
|
||||
attributes:
|
||||
label: "Expected Behavior"
|
||||
placeholder: "What were you expecting?"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: actual_behavior
|
||||
attributes:
|
||||
label: "Actual Behavior"
|
||||
placeholder: "What happened instead?"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: log_file
|
||||
attributes:
|
||||
label: "Log File"
|
||||
placeholder: "Drag and drop log file here (Don't paste content directly)"
|
||||
description: >
|
||||
Make a log file with `--gpu-debug --log-file=output.txt`, which is our preferred way, and
|
||||
attach it to the issue. If you use the Bundle, a default log is created for your last run
|
||||
at `~/Library/Logs/mpv.log`. You can jump to that file via the `Help > Show log File…` menu.
|
||||
|
||||
|
||||
If you have trouble producing a log file, you can alternatively use `--gpu-debug --msg-time -v -v`,
|
||||
save the terminal output to a file, and attach it to the issue.
|
||||
|
||||
|
||||
In the case of a crash, please provide the macOS Crash Report or create a [backtrace](https://developer.apple.com/library/archive/documentation/General/Conceptual/lldb-guide/chapters/C5-Examining-The-Call-Stack.html)
|
||||
yourself.
|
||||
|
||||
|
||||
Without the log file, this issue will be closed for ignoring the issue template.
|
||||
|
||||
|
||||
Disclaimer: The log file may contain identifiable information, such as your username.
|
||||
Review the log file before sharing and redact any sensitive data if necessary.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: sample_files
|
||||
attributes:
|
||||
label: "Sample Files"
|
||||
placeholder: "Drag and drop sample files here"
|
||||
description: >
|
||||
Please provide sample files for a minimal reproduction case, if the issue can't be
|
||||
reproduced without it or it is helpful to demonstrate the issue.
|
||||
|
||||
|
||||
Preferably files should be attached directly within the text field below. Due to GitHub's
|
||||
upload restriction, you may need to archive the sample file first and upload it as `.zip`
|
||||
file. If the sample file is too big to attach directly, use a solution that is easy to
|
||||
access with possible long-term retention. Possible services include, but are not limited
|
||||
to, the following:
|
||||
|
||||
- [0x0.st](https://0x0.st/) (no long-term retention)
|
||||
- [Dropbox](https://www.dropbox.com)
|
||||
- [Google Drive](https://www.google.com/drive/)
|
||||
- [iCLoud Drive](https://www.icloud.com/iclouddrive/)
|
||||
- [MediaFire](https://www.mediafire.com/)
|
||||
- [OneDrive](https://onedrive.live.com/)
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: "I carefully read all instruction and confirm that I did the following:"
|
||||
options:
|
||||
- label: "I tested and confirmed that the issue exists with the [latest release version](https://github.com/mpv-player/mpv/releases/latest) or newer."
|
||||
required: true
|
||||
- label: "I provided all required information including system and mpv version."
|
||||
required: true
|
||||
- label: >-
|
||||
I produced the log file with the exact same set of files, parameters, and conditions
|
||||
used in "Reproduction Steps", with the addition of `--log-file=output.txt`.
|
||||
required: true
|
||||
- label: >-
|
||||
I produced the log file while the behaviors described in "Actual Behavior" were
|
||||
actively observed.
|
||||
required: true
|
||||
- label: "I attached the full, untruncated log file."
|
||||
required: true
|
||||
- label: "I attached the backtrace in the case of a crash."
|
||||
required: true
|
||||
@@ -1,154 +0,0 @@
|
||||
name: "Report a Windows Issue"
|
||||
description: "Create a report for a runtime related Windows Issue"
|
||||
labels: ["os:win"]
|
||||
type: Bug
|
||||
body:
|
||||
- type: textarea
|
||||
id: mpv_information
|
||||
attributes:
|
||||
label: "mpv Information"
|
||||
placeholder: |
|
||||
mpv v0.38.0-96-gf776be6af5 Copyright © 2000-2024 mpv/MPlayer/mplayer2 projects
|
||||
built on May 5 2024 18:37:43
|
||||
libplacebo version: v7.349.0 (v6.338.0-120-g7b294350)
|
||||
FFmpeg version: 6.1.1
|
||||
FFmpeg library versions:
|
||||
libavutil 58.29.100
|
||||
libavcodec 60.31.102
|
||||
libavformat 60.16.100
|
||||
libswscale 7.5.100
|
||||
libavfilter 9.12.100
|
||||
libswresample 4.12.100
|
||||
description: |
|
||||
Provide the output of `mpv --version`.
|
||||
render: bash
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: other_information
|
||||
attributes:
|
||||
label: "Other Information"
|
||||
description: >
|
||||
- Windows Version: `cmd /c ver`
|
||||
- GPU model, driver and version
|
||||
- Source of the mpv binary
|
||||
- Latest version of mpv you know without the problem
|
||||
- The time when the problem started to happen (after updating mpv, system, driver, etc.)
|
||||
- Possible screenshot or video of visual glitches
|
||||
|
||||
If you're not using git master or the latest release, update.
|
||||
Nightly builds from master can be found [here](https://github.com/mpv-player/mpv/actions/workflows/build.yml?query=branch%3Amaster+event%3Apush),
|
||||
click on the latest workflow run, scroll down to the Artifacts section and download the
|
||||
appropriate build. Packages and builds can be found [here](https://mpv.io/installation/).
|
||||
value: |-
|
||||
- Windows version:
|
||||
- GPU model, driver and version:
|
||||
- Source of mpv:
|
||||
- Latest known working version:
|
||||
- Issue started after the following happened:
|
||||
render: text
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction_steps
|
||||
attributes:
|
||||
label: "Reproduction Steps"
|
||||
description: >
|
||||
Try to reproduce your issue with `--no-config` first. If it isn't reproducible
|
||||
with `--no-config` try to find out which option or script causes your issue.
|
||||
|
||||
|
||||
If the issue is render performance-related, try to reproduce it with `--no-config
|
||||
--profile=fast`, which is designed to work on lower-end mobile devices.
|
||||
|
||||
|
||||
For decoding performance-related issues, additionally try to enable hardware
|
||||
decoding with `--hwdec=yes` or the `Ctrl+h` shortcut.
|
||||
|
||||
|
||||
Describe the reproduction steps as precise as possible. It's very likely that
|
||||
the bug you experience wasn't reproduced by the developer because the workflow
|
||||
differs from your own.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected_behavior
|
||||
attributes:
|
||||
label: "Expected Behavior"
|
||||
placeholder: "What were you expecting?"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: actual_behavior
|
||||
attributes:
|
||||
label: "Actual Behavior"
|
||||
placeholder: "What happened instead?"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: log_file
|
||||
attributes:
|
||||
label: "Log File"
|
||||
placeholder: "Drag and drop log file here (Don't paste content directly)"
|
||||
description: >
|
||||
Make a log file with `--gpu-debug --log-file=output.txt`, which is our preferred way, and
|
||||
attach it to the issue.
|
||||
|
||||
|
||||
If you have trouble producing a log file, you can alternatively use `--gpu-debug --msg-time -v -v`,
|
||||
save the terminal output to a file, and attach it to the issue.
|
||||
|
||||
|
||||
In the case of a crash, please provide a backtrace, attach the appropriate `.dmp` file
|
||||
from `%LOCALAPPDATA%\CrashDumps`.
|
||||
|
||||
|
||||
Without the log file, this issue will be closed for ignoring the issue template.
|
||||
|
||||
|
||||
Disclaimer: The log file may contain identifiable information, such as your username.
|
||||
Review the log file before sharing and redact any sensitive data if necessary.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: sample_files
|
||||
attributes:
|
||||
label: "Sample Files"
|
||||
placeholder: "Drag and drop sample files here"
|
||||
description: >
|
||||
Please provide sample files for a minimal reproduction case, if the issue can't be
|
||||
reproduced without it or it is helpful to demonstrate the issue.
|
||||
|
||||
|
||||
Preferably files should be attached directly within the text field below. Due to GitHub's
|
||||
upload restriction, you may need to archive the sample file first and upload it as `.zip`
|
||||
file. If the sample file is too big to attach directly, use a solution that is easy to
|
||||
access with possible long-term retention. Possible services include, but are not limited
|
||||
to, the following:
|
||||
|
||||
- [0x0.st](https://0x0.st/) (no long-term retention)
|
||||
- [Dropbox](https://www.dropbox.com)
|
||||
- [Google Drive](https://www.google.com/drive/)
|
||||
- [iCLoud Drive](https://www.icloud.com/iclouddrive/)
|
||||
- [MediaFire](https://www.mediafire.com/)
|
||||
- [OneDrive](https://onedrive.live.com/)
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: "I carefully read all instruction and confirm that I did the following:"
|
||||
options:
|
||||
- label: "I tested and confirmed that the issue exists with the [latest release version](https://github.com/mpv-player/mpv/releases/latest) or newer."
|
||||
required: true
|
||||
- label: "I provided all required information including system and mpv version."
|
||||
required: true
|
||||
- label: >-
|
||||
I produced the log file with the exact same set of files, parameters, and conditions
|
||||
used in "Reproduction Steps", with the addition of `--log-file=output.txt`.
|
||||
required: true
|
||||
- label: >-
|
||||
I produced the log file while the behaviors described in "Actual Behavior" were
|
||||
actively observed.
|
||||
required: true
|
||||
- label: "I attached the full, untruncated log file."
|
||||
required: true
|
||||
- label: "I attached the backtrace in the case of a crash."
|
||||
required: true
|
||||
@@ -1,151 +0,0 @@
|
||||
name: "Report an Issue on other platforms"
|
||||
description: "Create a report for a runtime related Issue on other platforms"
|
||||
labels: []
|
||||
type: Bug
|
||||
body:
|
||||
- type: textarea
|
||||
id: mpv_information
|
||||
attributes:
|
||||
label: "mpv Information"
|
||||
placeholder: |
|
||||
mpv v0.38.0-96-gf776be6af5 Copyright © 2000-2024 mpv/MPlayer/mplayer2 projects
|
||||
built on May 5 2024 18:37:43
|
||||
libplacebo version: v7.349.0 (v6.338.0-120-g7b294350)
|
||||
FFmpeg version: 6.1.1
|
||||
FFmpeg library versions:
|
||||
libavutil 58.29.100
|
||||
libavcodec 60.31.102
|
||||
libavformat 60.16.100
|
||||
libswscale 7.5.100
|
||||
libavfilter 9.12.100
|
||||
libswresample 4.12.100
|
||||
description: |
|
||||
Provide the output of `mpv --version`.
|
||||
render: bash
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: important_information
|
||||
attributes:
|
||||
label: "Important Information"
|
||||
description: >
|
||||
- Platform and Version
|
||||
- GPU model, driver and version
|
||||
- Source of the mpv binary
|
||||
- Latest version of mpv you know without the problem
|
||||
- The time when the problem started to happen (after updating mpv, system, driver, etc.)
|
||||
- Possible screenshot or video of visual glitches
|
||||
|
||||
If you're not using git master or the latest release, update.
|
||||
Packages and builds can be found [here](https://mpv.io/installation/).
|
||||
value: |-
|
||||
- Platform version:
|
||||
- GPU model, driver and version:
|
||||
- Source of mpv:
|
||||
- Latest known working version:
|
||||
- Issue started after the following happened:
|
||||
render: text
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction_steps
|
||||
attributes:
|
||||
label: "Reproduction Steps"
|
||||
description: >
|
||||
Try to reproduce your issue with `--no-config` first. If it isn't reproducible
|
||||
with `--no-config` try to find out which option or script causes your issue.
|
||||
|
||||
|
||||
If the issue is render performance-related, try to reproduce it with `--no-config
|
||||
--profile=fast`, which is designed to work on lower-end mobile devices.
|
||||
|
||||
|
||||
For decoding performance-related issues, additionally try to enable hardware
|
||||
decoding with `--hwdec=yes` or the `Ctrl+h` shortcut.
|
||||
|
||||
|
||||
Describe the reproduction steps as precise as possible. It's very likely that
|
||||
the bug you experience wasn't reproduced by the developer because the workflow
|
||||
differs from your own.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected_behavior
|
||||
attributes:
|
||||
label: "Expected Behavior"
|
||||
placeholder: "What were you expecting?"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: actual_behavior
|
||||
attributes:
|
||||
label: "Actual Behavior"
|
||||
placeholder: "What happened instead?"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: log_file
|
||||
attributes:
|
||||
label: "Log File"
|
||||
placeholder: "Drag and drop log file here (Don't paste content directly)"
|
||||
description: >
|
||||
Make a log file with `--gpu-debug --log-file=output.txt`, which is our preferred way, and
|
||||
attach it to the issue.
|
||||
|
||||
|
||||
If you have trouble producing a log file, you can alternatively use `--gpu-debug --msg-time -v -v`,
|
||||
save the terminal output to a file, and attach it to the issue.
|
||||
|
||||
|
||||
In the case of a crash, please provide a backtrace.
|
||||
|
||||
|
||||
Without the log file, this issue will be closed for ignoring the issue template.
|
||||
|
||||
|
||||
Disclaimer: The log file may contain identifiable information, such as your username.
|
||||
Review the log file before sharing and redact any sensitive data if necessary.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: sample_files
|
||||
attributes:
|
||||
label: "Sample Files"
|
||||
placeholder: "Drag and drop sample files here"
|
||||
description: >
|
||||
Please provide sample files for a minimal reproduction case, if the issue can't be
|
||||
reproduced without it or it is helpful to demonstrate the issue.
|
||||
|
||||
|
||||
Preferably files should be attached directly within the text field below. Due to GitHub's
|
||||
upload restriction, you may need to archive the sample file first and upload it as `.zip`
|
||||
file. If the sample file is too big to attach directly, use a solution that is easy to
|
||||
access with possible long-term retention. Possible services include, but are not limited
|
||||
to, the following:
|
||||
|
||||
- [0x0.st](https://0x0.st/) (no long-term retention)
|
||||
- [Dropbox](https://www.dropbox.com)
|
||||
- [Google Drive](https://www.google.com/drive/)
|
||||
- [iCLoud Drive](https://www.icloud.com/iclouddrive/)
|
||||
- [MediaFire](https://www.mediafire.com/)
|
||||
- [OneDrive](https://onedrive.live.com/)
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: "I carefully read all instruction and confirm that I did the following:"
|
||||
options:
|
||||
- label: "I tested and confirmed that the issue exists with the [latest release version](https://github.com/mpv-player/mpv/releases/latest) or newer."
|
||||
required: true
|
||||
- label: "I provided all required information including system and mpv version."
|
||||
required: true
|
||||
- label: >-
|
||||
I produced the log file with the exact same set of files, parameters, and conditions
|
||||
used in "Reproduction Steps", with the addition of `--log-file=output.txt`.
|
||||
required: true
|
||||
- label: >-
|
||||
I produced the log file while the behaviors described in "Actual Behavior" were
|
||||
actively observed.
|
||||
required: true
|
||||
- label: "I attached the full, untruncated log file."
|
||||
required: true
|
||||
- label: "I attached the backtrace in the case of a crash."
|
||||
required: true
|
||||
@@ -1,76 +0,0 @@
|
||||
name: "Report a build Problem"
|
||||
description: "Create a report for a build related Issue"
|
||||
labels: ["core:meson"]
|
||||
type: Bug
|
||||
body:
|
||||
- type: textarea
|
||||
id: important_information
|
||||
attributes:
|
||||
label: "Important Information"
|
||||
description: >
|
||||
- mpv version
|
||||
- Platform and Version
|
||||
- Meson version
|
||||
|
||||
If you're not using git master or the latest release, update.
|
||||
Releases are listed [here](https://github.com/mpv-player/mpv/releases).
|
||||
value: |-
|
||||
- mpv version:
|
||||
- Platform version:
|
||||
- Meson version:
|
||||
render: text
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction_steps
|
||||
attributes:
|
||||
label: "Reproduction Steps"
|
||||
description: >
|
||||
Describe the reproduction steps as precise as possible. It's very likely that
|
||||
the bug you experience wasn't reproduced by the developer because the workflow
|
||||
differs from your own.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected_behavior
|
||||
attributes:
|
||||
label: "Expected Behavior"
|
||||
placeholder: "What were you expecting?"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: actual_behavior
|
||||
attributes:
|
||||
label: "Actual Behavior"
|
||||
placeholder: "What happened instead?"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: log_file
|
||||
attributes:
|
||||
label: "Log File"
|
||||
placeholder: "Drag and drop log file here (Don't paste content directly)"
|
||||
description: >
|
||||
Attach meson-logs/meson-log.txt or meson setup build output to the issue.
|
||||
|
||||
Without the log file, this issue will be closed for ignoring the issue template.
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: "I carefully read all instruction and confirm that I did the following:"
|
||||
options:
|
||||
- label: "I tested and confirmed that the issue exists with the [latest release version](https://github.com/mpv-player/mpv/releases/latest) or newer."
|
||||
required: true
|
||||
- label: "I provided all required information including system and mpv version."
|
||||
required: true
|
||||
- label: >-
|
||||
I produced the log file with the exact same set of parameters, and conditions used in
|
||||
"Reproduction Steps".
|
||||
required: true
|
||||
- label: >-
|
||||
I produced the log file while the behaviors described in "Actual Behavior" were
|
||||
actively observed.
|
||||
required: true
|
||||
- label: "I attached the full, untruncated log file."
|
||||
required: true
|
||||
@@ -1,60 +0,0 @@
|
||||
name: "Request a new Feature"
|
||||
description: "Create a request for a new feature"
|
||||
labels: ["meta:feature-request"]
|
||||
type: Feature
|
||||
body:
|
||||
- type: textarea
|
||||
id: expected_behavior
|
||||
attributes:
|
||||
label: "Expected behavior of the wanted feature"
|
||||
description: >
|
||||
Before requesting a new feature, make sure it hasn't been
|
||||
[requested yet](https://github.com/mpv-player/mpv/labels/meta%3Afeature-request),
|
||||
and isn't already supported by [mpv](https://mpv.io/manual/master/),
|
||||
[ffmpeg](https://ffmpeg.org/documentation.html), or existing
|
||||
[mpv scripts](https://github.com/mpv-player/mpv/wiki/User-Scripts).
|
||||
|
||||
|
||||
If you are not sure about this, ask on
|
||||
[mpv Discussions](https://github.com/mpv-player/mpv/discussions) and
|
||||
[mpv IRC channel](https://mpv.io/community/) first before opening a feature request.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: alternative_behavior
|
||||
attributes:
|
||||
label: "Alternative behavior of the wanted feature"
|
||||
- type: textarea
|
||||
id: log_file
|
||||
attributes:
|
||||
label: "Log File"
|
||||
description: >
|
||||
Even if you think it's not necessary at first, it might help us later to find
|
||||
possible issues. Make a log file with `--log-file=output.txt`, which is our preferred way,
|
||||
and attach it to the issue.
|
||||
|
||||
|
||||
If you have trouble producing a log file, you can alternatively use `-v -v`, save the
|
||||
terminal output to a file, and attach it to the issue.
|
||||
- type: textarea
|
||||
id: sample_files
|
||||
attributes:
|
||||
label: "Sample Files"
|
||||
placeholder: "Drag and drop sample files here"
|
||||
description: >
|
||||
Please provide sample files in the case you request a format/codec/container dependent
|
||||
feature, and it could help us test and implement it.
|
||||
|
||||
|
||||
Preferably files should be attached directly within the text field below. Due to GitHub's
|
||||
upload restriction, you may need to archive the sample file first and upload it as `.zip`
|
||||
file. If the sample file is too big to attach directly, use a solution that is easy to
|
||||
access with possible long-term retention. Possible services include, but are not limited
|
||||
to, the following:
|
||||
|
||||
- [0x0.st](https://0x0.st/) (no long-term retention)
|
||||
- [Dropbox](https://www.dropbox.com)
|
||||
- [Google Drive](https://www.google.com/drive/)
|
||||
- [iCLoud Drive](https://www.icloud.com/iclouddrive/)
|
||||
- [MediaFire](https://www.mediafire.com/)
|
||||
- [OneDrive](https://onedrive.live.com/)
|
||||
@@ -1,12 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: mpv Discussions
|
||||
url: https://github.com/mpv-player/mpv/discussions
|
||||
about: If you have questions or want to discuss things use our GitHub Discussions
|
||||
- name: mpv IRC channel
|
||||
url: https://mpv.io/community/
|
||||
about: Feel free to ask questions here irc://irc.libera.chat/mpv
|
||||
- name: mpv IRC developer channel
|
||||
url: https://mpv.io/community/
|
||||
about: Ask questions related to the development of mpv here
|
||||
irc://irc.libera.chat/mpv-devel
|
||||
@@ -1,5 +0,0 @@
|
||||
Read this before you submit this pull request:
|
||||
https://github.com/mpv-player/mpv/blob/master/DOCS/contribute.md
|
||||
|
||||
Reading this link and following the rules will get your pull request reviewed
|
||||
and merged faster. Nobody wants lazy pull requests.
|
||||
@@ -1,8 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
commit-message:
|
||||
prefix: "ci"
|
||||
@@ -1,830 +0,0 @@
|
||||
name: build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- ci
|
||||
- 'release/**'
|
||||
paths-ignore:
|
||||
- 'DOCS/**'
|
||||
- 'TOOLS/lua/**'
|
||||
- '.editorconfig'
|
||||
- '.github/ISSUE_TEMPLATE/**'
|
||||
- '.github/PULL_REQUEST_TEMPLATE'
|
||||
- '.gitignore'
|
||||
- 'Copyright'
|
||||
- 'README.md'
|
||||
- 'RELEASE_NOTES'
|
||||
pull_request:
|
||||
branches: [master]
|
||||
paths-ignore:
|
||||
- 'DOCS/**'
|
||||
- 'TOOLS/lua/**'
|
||||
- '.editorconfig'
|
||||
- '.github/ISSUE_TEMPLATE/**'
|
||||
- '.github/PULL_REQUEST_TEMPLATE'
|
||||
- '.gitignore'
|
||||
- 'Copyright'
|
||||
- 'README.md'
|
||||
- 'RELEASE_NOTES'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
mingw:
|
||||
runs-on: ubuntu-24.04
|
||||
env:
|
||||
CCACHE_BASEDIR: ${{ github.workspace }}
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_MAXSIZE: 500M
|
||||
DOWNLOAD_CACHE: ${{ github.workspace }}/.ccache/downloads
|
||||
TARGET: ${{ matrix.arch }}-w64-mingw32
|
||||
RUST_TARGET: ${{ matrix.arch }}-pc-windows-gnu
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: i686
|
||||
wine: wine32
|
||||
- arch: x86_64
|
||||
wine: wine64
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Get time
|
||||
id: get_time
|
||||
run: echo "timestamp=`date +%s%N`" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore cache
|
||||
uses: actions/cache/restore@v6
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ env.TARGET }}-${{ steps.get_time.outputs.timestamp }}
|
||||
restore-keys: ${{ env.TARGET }}-
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
rustup target add ${{ env.RUST_TARGET }}
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt-get update
|
||||
sudo apt-get install --no-install-recommends -y ccache g++-mingw-w64 gcc-multilib python3-pip nasm ninja-build pkgconf ${{ matrix.wine }} wine
|
||||
python -m pip install meson
|
||||
|
||||
- name: Install Meson Wraps
|
||||
run: |
|
||||
mkdir subprojects -p
|
||||
meson wrap install mujs
|
||||
meson subprojects download
|
||||
|
||||
- name: Build libraries
|
||||
run: |
|
||||
./ci/build-mingw64.sh
|
||||
|
||||
- name: Build with meson
|
||||
id: build
|
||||
run: |
|
||||
./ci/build-mingw64.sh meson pack
|
||||
|
||||
- name: Print meson log
|
||||
if: ${{ failure() && steps.build.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./mingw_build/meson-logs/meson-log.txt
|
||||
|
||||
- name: Functional test
|
||||
run: |
|
||||
cd artifact && wine ./mpv.com -v --no-config
|
||||
env:
|
||||
WINEDEBUG: '+loaddll'
|
||||
|
||||
- name: Run meson tests
|
||||
id: tests
|
||||
run: |
|
||||
meson test -C mingw_build
|
||||
|
||||
- name: Print meson test log
|
||||
if: ${{ failure() && steps.tests.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./mingw_build/meson-logs/testlog.txt
|
||||
|
||||
- name: Artifact name
|
||||
id: artifact
|
||||
run: |
|
||||
VERSION_FILE=$(find . -path "*/common/version.h" -type f | head -n 1)
|
||||
VER=$(grep VERSION "$VERSION_FILE" | cut -d'"' -f2)
|
||||
PR=${{ github.event.pull_request.number && format('-pr{0}', github.event.pull_request.number) || '' }}
|
||||
echo "name=mpv-$VER$PR-${{ github.run_id }}-$TARGET" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ steps.artifact.outputs.name }}
|
||||
path: artifact/*
|
||||
|
||||
- name: Save Cache
|
||||
uses: actions/cache/save@v6
|
||||
if: always()
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ env.TARGET }}-${{ steps.get_time.outputs.timestamp }}
|
||||
|
||||
win32:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- target: x86_64-pc-windows-msvc
|
||||
arch: "x64"
|
||||
os: "windows-2025-vs2026"
|
||||
- target: aarch64-pc-windows-msvc
|
||||
arch: "arm64"
|
||||
os: "windows-11-arm"
|
||||
env:
|
||||
CC: "ccache clang"
|
||||
CXX: "ccache clang++"
|
||||
CC_LD: "lld-link"
|
||||
CXX_LD: "lld-link"
|
||||
RUST_LD: "lld-link"
|
||||
WINDRES: "llvm-rc"
|
||||
CCACHE_BASEDIR: ${{ github.workspace }}
|
||||
CCACHE_DIR: "${{ github.workspace }}\\.ccache"
|
||||
CCACHE_MAXSIZE: 500M
|
||||
steps:
|
||||
- name: Disable autocrlf
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
git config --global core.eol lf
|
||||
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Get time
|
||||
id: get_time
|
||||
run: |
|
||||
"timestamp=$((Get-Date).Ticks)" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- name: Restore cache
|
||||
uses: actions/cache/restore@v6
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ matrix.target }}-${{ steps.get_time.outputs.timestamp }}
|
||||
restore-keys: ${{ matrix.target }}-
|
||||
|
||||
- name: Install Winget on windows-11-arm
|
||||
if: matrix.os == 'windows-11-arm'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Install-Module -Name Microsoft.WinGet.Client -Repository PSGallery -Force
|
||||
Repair-WinGetPackageManager -Latest -Force
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install meson
|
||||
winget install --accept-source-agreements --accept-package-agreements Ccache.Ccache NASM.NASM
|
||||
echo "$env:LOCALAPPDATA\Microsoft\WinGet\Links" >> $env:GITHUB_PATH
|
||||
# For cargo -C
|
||||
rustup default nightly
|
||||
|
||||
- name: Update Meson WrapDB
|
||||
run: |
|
||||
meson wrap update-db
|
||||
# Explicitly download wraps, as nested projects may have older versions of them.
|
||||
meson wrap install expat
|
||||
meson wrap install harfbuzz
|
||||
meson wrap install libpng
|
||||
meson wrap install zlib
|
||||
|
||||
- name: Find Visual Studio
|
||||
run: |
|
||||
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
|
||||
$vsPath = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
|
||||
if (-not $vsPath) { throw "Could not find a Visual Studio installation" }
|
||||
"VS=$vsPath"
|
||||
"VS=$vsPath" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Build
|
||||
id: build
|
||||
run: |
|
||||
$env:PATH = ($env:PATH -split ';' | Where-Object { $_ -ne 'C:\Program Files\LLVM\bin' -and `
|
||||
$_ -ne 'C:\Program Files\CMake\bin' -and `
|
||||
$_ -ne 'C:\Strawberry\c\bin' }) -join ';'
|
||||
$env:PATH += ';C:\Program Files\NASM'
|
||||
Import-Module "$env:VS\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
|
||||
Enter-VsDevShell -VsInstallPath $env:VS -SkipAutomaticLocation -DevCmdArguments "-arch=${{ matrix.arch }} -host_arch=${{ matrix.arch }}"
|
||||
./ci/build-win32.ps1
|
||||
|
||||
- name: Print build log
|
||||
if: ${{ failure() && steps.build.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/meson-log.txt
|
||||
|
||||
- name: Run meson tests
|
||||
id: tests
|
||||
run: |
|
||||
$env:PATH = ($env:PATH -split ';' | Where-Object { $_ -ne 'C:\Program Files\LLVM\bin' -and `
|
||||
$_ -ne 'C:\Program Files\CMake\bin' -and `
|
||||
$_ -ne 'C:\Strawberry\c\bin' }) -join ';'
|
||||
$env:PATH += ';C:\Program Files\NASM'
|
||||
Import-Module "$env:VS\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
|
||||
Enter-VsDevShell -VsInstallPath $env:VS -SkipAutomaticLocation -DevCmdArguments "-arch=${{ matrix.arch }} -host_arch=${{ matrix.arch }}"
|
||||
meson test -C build -t 2
|
||||
|
||||
- name: Print meson test log
|
||||
if: ${{ failure() && steps.tests.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/testlog.txt
|
||||
|
||||
- name: Artifact name
|
||||
id: artifact
|
||||
run: |
|
||||
$VERSION_FILE = gci . -r -Filter "version.h" | ? { $_.FullName -match "[/\\]common[/\\]version\.h$" } | select -First 1 -exp FullName
|
||||
$VER = (sls $VERSION_FILE -Pattern 'VERSION').Line -replace '.*"([^"]+)".*', '$1'
|
||||
$PR = if ("${{ github.event.pull_request.number }}") { "-pr${{ github.event.pull_request.number }}" } else { "" }
|
||||
$name = "mpv-$VER$PR-${{ github.run_id }}-${{ matrix.target }}"
|
||||
"name=$name" >> $env:GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ steps.artifact.outputs.name }}
|
||||
path: |
|
||||
build/mpv.???
|
||||
build/mpv-*.bat
|
||||
build/vulkan-*.dll
|
||||
!build/mpv.lib
|
||||
!build/mpv.pdb
|
||||
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ steps.artifact.outputs.name }}-pdb
|
||||
path: |
|
||||
build/mpv.pdb
|
||||
|
||||
- name: Save Cache
|
||||
uses: actions/cache/save@v6
|
||||
if: always()
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ matrix.target }}-${{ steps.get_time.outputs.timestamp }}
|
||||
|
||||
macos:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: "macos-14"
|
||||
arch: "arm"
|
||||
xcode: "Xcode_15.0"
|
||||
- os: "macos-15"
|
||||
arch: "arm"
|
||||
- os: "macos-15-intel"
|
||||
- os: "macos-26"
|
||||
arch: "arm"
|
||||
- os: "macos-26"
|
||||
arch: "test"
|
||||
swift: "-target arm64-apple-macosx10.15"
|
||||
target: "10.15"
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Remove stray upstream python binary symlinks under /usr/local
|
||||
run: |
|
||||
find /usr/local/bin -lname '*/Library/Frameworks/Python.framework/*' -delete -print
|
||||
brew unlink python && brew link --overwrite python
|
||||
|
||||
- name: Unlink pkg-config if the CI runner happens to have it already installed
|
||||
run: |
|
||||
find "$(brew config | grep HOMEBREW_PREFIX | cut -f 2- -d ' ')/bin" -lname '*/pkg-config@0*/*' -print -exec brew unlink pkg-config@0.29.2 \; -quit
|
||||
|
||||
- name: Change Xcode version
|
||||
if: ${{ matrix.xcode != '' }}
|
||||
run: |
|
||||
sudo xcode-select -s /Applications/${{ matrix.xcode }}.app
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
if [[ -n "${{ matrix.homebrew }}" ]]; then
|
||||
export HOMEBREW_NO_AUTO_UPDATE=1
|
||||
cd "$(brew --repo homebrew/core)"
|
||||
git checkout --force ${{ matrix.homebrew }}
|
||||
else
|
||||
brew update
|
||||
fi
|
||||
if brew list ffmpeg &> /dev/null; then brew unlink ffmpeg; fi
|
||||
brew install -q autoconf automake curl pkgconf libtool python freetype fribidi little-cms2 \
|
||||
luajit libass ffmpeg-full meson rust uchardet mujs libplacebo molten-vk vulkan-loader vulkan-headers \
|
||||
libarchive libbluray libcaca libcdio-paranoia libdvdnav rubberband zimg
|
||||
brew link ffmpeg-full
|
||||
|
||||
- name: Build with meson
|
||||
id: build
|
||||
run: |
|
||||
./ci/build-macos.sh
|
||||
env:
|
||||
TRAVIS_OS_NAME: "${{ matrix.os }}"
|
||||
SWIFT_FLAGS: "${{ matrix.swift }}"
|
||||
MACOSX_DEPLOYMENT_TARGET: "${{ matrix.target }}"
|
||||
|
||||
- name: Create App Bundle
|
||||
if: ${{ matrix.arch != 'test' }}
|
||||
run: |
|
||||
meson compile -C build macos-bundle
|
||||
tar -czvf mpv.tar.gz -C build mpv.app
|
||||
|
||||
- name: Print meson log
|
||||
if: ${{ failure() && steps.build.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/meson-log.txt
|
||||
|
||||
- name: Run meson tests
|
||||
id: tests
|
||||
run: |
|
||||
meson test -C build
|
||||
|
||||
- name: Print meson test log
|
||||
if: ${{ failure() && steps.tests.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/testlog.txt
|
||||
|
||||
- name: Artifact name
|
||||
id: artifact
|
||||
run: |
|
||||
VERSION_FILE=$(find . -path "*/common/version.h" -type f | head -n 1)
|
||||
VER=$(grep VERSION "$VERSION_FILE" | cut -d'"' -f2)
|
||||
TARGET=${{ matrix.os }}${{ matrix.arch != '' && format('-{0}', matrix.arch) || '' }}
|
||||
PR=${{ github.event.pull_request.number && format('-pr{0}', github.event.pull_request.number) || '' }}
|
||||
echo "name=mpv-$VER$PR-${{ github.run_id }}-$TARGET" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- uses: actions/upload-artifact@v7
|
||||
if: ${{ matrix.arch != 'test' }}
|
||||
with:
|
||||
name: ${{ steps.artifact.outputs.name }}
|
||||
path: mpv.tar.gz
|
||||
|
||||
linux:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: "registry.opensuse.org/home/mia/images/images/mpv-ci:stable-deps"
|
||||
env:
|
||||
CC: "${{ matrix.config.cc }}"
|
||||
CXX: "${{ matrix.config.cxx }}"
|
||||
CC_LD: "${{ matrix.config.ld }}"
|
||||
CXX_LD: "${{ matrix.config.ld }}"
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- cc: "gcc"
|
||||
cxx: "g++"
|
||||
args: "-Db_ndebug=true"
|
||||
- cc: "clang"
|
||||
cxx: "clang++"
|
||||
ld: "lld"
|
||||
args: "-Db_lto=true -Db_lto_mode=thin"
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Build with meson
|
||||
id: build
|
||||
run: |
|
||||
./ci/build-tumbleweed.sh ${{ matrix.config.args }}
|
||||
|
||||
- name: Print meson log
|
||||
if: ${{ failure() && steps.build.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/meson-log.txt
|
||||
|
||||
- name: Run meson tests
|
||||
id: tests
|
||||
run: |
|
||||
meson test -C build
|
||||
|
||||
- name: Print meson test log
|
||||
if: ${{ failure() && steps.tests.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/testlog.txt
|
||||
|
||||
linux-fuzz:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: "registry.opensuse.org/home/mia/images/images/mpv-ci:stable-deps"
|
||||
env:
|
||||
CC: "clang"
|
||||
CXX: "clang++"
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Build with meson
|
||||
id: build
|
||||
run: |
|
||||
meson setup build \
|
||||
--werror \
|
||||
-Dfuzzers=true -Dlibmpv=true -Dcplayer=false
|
||||
meson compile -C build fuzzers
|
||||
|
||||
- name: Print meson log
|
||||
if: ${{ failure() && steps.build.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/meson-log.txt
|
||||
|
||||
linux-ffmpeg-6-1:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
# We want to test ffmpeg 6.1.2, which Alpine 3.21 includes.
|
||||
# Also test compatibility with Wayland Protocols 1.38 and Wayland libs 1.23.
|
||||
# Musl support is an added bonus.
|
||||
image: alpine:3.21
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
apk update
|
||||
apk add \
|
||||
binutils \
|
||||
curl-dev \
|
||||
ffmpeg-dev \
|
||||
gcc \
|
||||
git \
|
||||
g++ \
|
||||
libass-dev \
|
||||
lua5.2-dev \
|
||||
pulseaudio-dev \
|
||||
libplacebo-dev \
|
||||
libx11-dev \
|
||||
libxfixes-dev \
|
||||
libxkbcommon-dev \
|
||||
libxrandr-dev \
|
||||
libxpresent-dev \
|
||||
libxscrnsaver-dev \
|
||||
meson \
|
||||
musl-dev \
|
||||
rust \
|
||||
samurai \
|
||||
wayland-dev \
|
||||
wayland-protocols
|
||||
|
||||
- name: Build with meson
|
||||
id: build
|
||||
run: |
|
||||
./ci/build-linux-old.sh
|
||||
|
||||
- name: Print meson log
|
||||
if: ${{ failure() && steps.build.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/meson-log.txt
|
||||
|
||||
- name: Run meson tests
|
||||
id: tests
|
||||
run: |
|
||||
meson test -C build
|
||||
|
||||
- name: Print meson test log
|
||||
if: ${{ failure() && steps.tests.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/testlog.txt
|
||||
|
||||
openbsd:
|
||||
runs-on: ubuntu-latest # until https://github.com/actions/runner/issues/385
|
||||
timeout-minutes: 15 # avoid any weirdness with the VM
|
||||
defaults:
|
||||
run:
|
||||
shell: cpa.sh {0} --sync-files none
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Start OpenBSD VM
|
||||
uses: cross-platform-actions/action@v1.4.0
|
||||
with:
|
||||
operating_system: openbsd
|
||||
version: '7.8'
|
||||
sync_files: runner-to-vm
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo pkg_add -U \
|
||||
cmake \
|
||||
curl \
|
||||
ffmpeg \
|
||||
git \
|
||||
libarchive \
|
||||
libbluray \
|
||||
libcaca \
|
||||
libcdio-paranoia \
|
||||
libdvdnav \
|
||||
libiconv \
|
||||
libplacebo \
|
||||
libv4l \
|
||||
libxkbcommon \
|
||||
luajit \
|
||||
meson \
|
||||
openal \
|
||||
pkgconf \
|
||||
pulseaudio \
|
||||
python3 \
|
||||
rubberband \
|
||||
rust \
|
||||
sdl2 \
|
||||
shaderc \
|
||||
spirv-cross \
|
||||
spirv-headers \
|
||||
uchardet \
|
||||
vulkan-loader \
|
||||
vulkan-headers \
|
||||
zimg
|
||||
|
||||
- name: Build with meson
|
||||
id: build
|
||||
run: |
|
||||
./ci/build-openbsd.sh
|
||||
|
||||
- name: Print meson log
|
||||
if: ${{ failure() && steps.build.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/meson-log.txt
|
||||
|
||||
- name: Run meson tests
|
||||
id: tests
|
||||
run: |
|
||||
meson test -C build
|
||||
|
||||
- name: Print meson test log
|
||||
if: ${{ failure() && steps.tests.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/testlog.txt
|
||||
|
||||
freebsd:
|
||||
runs-on: ubuntu-latest # until https://github.com/actions/runner/issues/385
|
||||
timeout-minutes: 15 # avoid any weirdness with the VM
|
||||
defaults:
|
||||
run:
|
||||
shell: cpa.sh {0} --sync-files none
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Start FreeBSD VM
|
||||
uses: cross-platform-actions/action@v1.4.0
|
||||
with:
|
||||
operating_system: freebsd
|
||||
version: '15.1'
|
||||
sync_files: runner-to-vm
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo pkg update
|
||||
sudo pkg install -y \
|
||||
alsa-lib \
|
||||
cmake \
|
||||
curl \
|
||||
evdev-proto \
|
||||
ffmpeg \
|
||||
git \
|
||||
iconv \
|
||||
jackit \
|
||||
libarchive \
|
||||
libbluray \
|
||||
libcaca \
|
||||
libcdio-paranoia \
|
||||
libdvdnav \
|
||||
libdisplay-info \
|
||||
libplacebo \
|
||||
libXinerama \
|
||||
libxkbcommon \
|
||||
libXpresent \
|
||||
libXv \
|
||||
luajit \
|
||||
meson \
|
||||
mujs \
|
||||
openal-soft \
|
||||
pipewire \
|
||||
pkgconf \
|
||||
pulseaudio \
|
||||
python3 \
|
||||
rubberband \
|
||||
rust \
|
||||
sekrit-twc-zimg \
|
||||
sdl2 \
|
||||
sndio \
|
||||
uchardet \
|
||||
v4l_compat \
|
||||
vulkan-headers \
|
||||
wayland-protocols
|
||||
|
||||
- name: Build with meson
|
||||
id: build
|
||||
run: |
|
||||
./ci/build-freebsd.sh
|
||||
|
||||
- name: Print meson log
|
||||
if: ${{ failure() && steps.build.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/meson-log.txt
|
||||
|
||||
- name: Run meson tests
|
||||
id: tests
|
||||
run: |
|
||||
meson test -C build
|
||||
|
||||
- name: Print meson test log
|
||||
if: ${{ failure() && steps.tests.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/testlog.txt
|
||||
|
||||
msys2:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- sys: "clang64"
|
||||
os: "windows-2025-vs2026"
|
||||
auto-var-init: "uninitialized"
|
||||
- sys: "clang64"
|
||||
os: "windows-2025-vs2026"
|
||||
asan: true
|
||||
- sys: "clang64"
|
||||
os: "windows-2025-vs2026"
|
||||
auto-var-init: "zero"
|
||||
- sys: "clang64"
|
||||
os: "windows-2025-vs2026"
|
||||
auto-var-init: "pattern"
|
||||
- sys: "mingw64"
|
||||
os: "windows-2025-vs2026"
|
||||
- sys: "ucrt64"
|
||||
os: "windows-2025-vs2026"
|
||||
- sys: "clangarm64"
|
||||
os: "windows-11-arm"
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- name: Disable autocrlf
|
||||
shell: pwsh
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
git config --global core.eol lf
|
||||
- uses: actions/checkout@v7
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.sys }}
|
||||
update: true
|
||||
install: git
|
||||
pacboy: >-
|
||||
amf-headers:p
|
||||
angleproject:p
|
||||
ca-certificates:p
|
||||
cc:p
|
||||
cppwinrt:p
|
||||
curl:p
|
||||
ffmpeg:p
|
||||
lcms2:p
|
||||
libarchive:p
|
||||
libass:p
|
||||
libcdio-paranoia:p
|
||||
libdvdnav:p
|
||||
libjpeg-turbo:p
|
||||
libplacebo:p
|
||||
lua51:p
|
||||
meson:p
|
||||
ninja:p
|
||||
pkgconf:p
|
||||
python:p
|
||||
rst2pdf:p
|
||||
rubberband:p
|
||||
rust:p
|
||||
shaderc:p
|
||||
spirv-cross:p
|
||||
uchardet:p
|
||||
vapoursynth:p
|
||||
vulkan-devel:p
|
||||
|
||||
- name: Build with meson
|
||||
id: build
|
||||
run: |
|
||||
./ci/build-msys2.sh meson
|
||||
env:
|
||||
SYS: ${{ matrix.sys }}
|
||||
ASAN: ${{ matrix.asan }}
|
||||
AUTO_VAR_INIT: ${{ matrix.auto-var-init }}
|
||||
|
||||
- name: Print meson log
|
||||
if: ${{ failure() && steps.build.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/meson-log.txt
|
||||
|
||||
- name: Run meson tests
|
||||
id: tests
|
||||
run: |
|
||||
meson test -C build
|
||||
env:
|
||||
GGML_NO_BACKTRACE: 1
|
||||
|
||||
- name: Print meson test log
|
||||
if: ${{ failure() && steps.tests.outcome == 'failure' }}
|
||||
run: |
|
||||
cat ./build/meson-logs/testlog.txt
|
||||
|
||||
publish:
|
||||
name: Publish git release
|
||||
needs: [mingw, win32, macos]
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master' &&
|
||||
github.repository == 'mpv-player/mpv'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
actions: read
|
||||
concurrency:
|
||||
group: publish-git
|
||||
cancel-in-progress: false
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Publish to git release
|
||||
env:
|
||||
GH_REPO: ${{ github.repository }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -eu
|
||||
tag=git-release
|
||||
base_url="https://github.com/$GH_REPO/releases/download/$tag"
|
||||
|
||||
artifacts=$(gh api "repos/{owner}/{repo}/actions/runs/${{ github.run_id }}/artifacts")
|
||||
|
||||
# Attach every build artifact unchanged; the notes link to them with
|
||||
# labels derived from the verbose names.
|
||||
mkdir -p release
|
||||
jq -r '.artifacts[] | "\(.id)\t\(.name)"' <<< "$artifacts" |
|
||||
while IFS=$'\t' read -r id name; do
|
||||
gh api "repos/{owner}/{repo}/actions/artifacts/$id/zip" > "release/$name.zip"
|
||||
done
|
||||
|
||||
section() {
|
||||
jq -r --arg url "$base_url" --arg re "$1" '
|
||||
def pretty:
|
||||
(if test("i686") then "i686"
|
||||
elif test("aarch64") then "arm64"
|
||||
elif test("-arm$") then "arm64"
|
||||
elif test("intel") then "x86_64"
|
||||
else "x86_64" end) as $arch
|
||||
| [ (if test("mingw") then "GCC" elif test("msvc") then "Clang" else empty end),
|
||||
(if test("macos") then "macOS " + capture("macos-(?<v>[0-9]+)").v else empty end),
|
||||
(if test("-pdb") then "debug symbols" else empty end) ] as $q
|
||||
| $arch + (if ($q | length) > 0 then " (" + ($q | join(", ")) + ")" else "" end);
|
||||
# primary builds first (x86_64, arm64, i686; Clang before GCC), debug symbols last
|
||||
def rank:
|
||||
[ (if test("-pdb") then 1 else 0 end),
|
||||
(if test("x86_64|intel") then 0 elif test("i686") then 2 else 1 end),
|
||||
(if test("mingw") then 1 else 0 end),
|
||||
(if test("macos") then (capture("macos-(?<v>[0-9]+)").v | tonumber) else 0 end) ];
|
||||
[ .artifacts[] | select(.name | test($re)) ] | sort_by(.name | rank)
|
||||
| map("* [\(.name | pretty)](\($url)/\(.name).zip)") | join("\n")
|
||||
' <<< "$artifacts"
|
||||
}
|
||||
|
||||
# Match the version string baked into the build (see common/meson.build).
|
||||
version=$(git describe --abbrev=9 --tags --dirty --match "v0.*")
|
||||
notes=$(cat <<EOF
|
||||
Automated development build of the latest \`master\` branch.
|
||||
|
||||
- Version: \`$version\`
|
||||
- Commit: ${{ github.sha }}
|
||||
- Built: $(date -u '+%Y-%m-%d %H:%M:%S UTC')
|
||||
|
||||
### Windows
|
||||
|
||||
$(section 'w64|msvc')
|
||||
|
||||
### macOS
|
||||
|
||||
$(section 'macos')
|
||||
|
||||
> [!WARNING]
|
||||
> These are untested development builds of the very latest \`master\`.
|
||||
> They are **not** official releases. For stable builds see the
|
||||
> [latest release](https://github.com/$GH_REPO/releases/latest).
|
||||
EOF
|
||||
)
|
||||
|
||||
# Create the release once (which also creates the tag), then only edit
|
||||
# it in place so watchers aren't notified on every master push. Stale
|
||||
# assets are dropped first since their names embed the run id.
|
||||
if gh release view "$tag" >/dev/null 2>&1; then
|
||||
gh release view "$tag" --json assets --jq '.assets[].name' |
|
||||
while read -r asset; do
|
||||
gh release delete-asset "$tag" "$asset" --yes
|
||||
done
|
||||
gh release edit "$tag" \
|
||||
--prerelease \
|
||||
--latest=false \
|
||||
--title "mpv development build" \
|
||||
--notes "$notes"
|
||||
gh release upload "$tag" release/*
|
||||
else
|
||||
gh release create "$tag" \
|
||||
--target "$GITHUB_SHA" \
|
||||
--prerelease \
|
||||
--latest=false \
|
||||
--title "mpv development build" \
|
||||
--notes "$notes" \
|
||||
release/*
|
||||
fi
|
||||
@@ -1,66 +0,0 @@
|
||||
name: Cleanup caches
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [build]
|
||||
types: [completed]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
actions: write
|
||||
|
||||
jobs:
|
||||
cache:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: |
|
||||
set -o pipefail
|
||||
gh cache list -L 1000 --json id,key,ref -S last_accessed_at -O desc > caches.json
|
||||
|
||||
# Resolve the state of every pull request that owns a cache.
|
||||
for pr in $(jq -r '.[].ref | select(test("^refs/pull/[0-9]+/merge$")) |
|
||||
split("/")[2]' caches.json | sort -u); do
|
||||
jq -n --arg pr "$pr" --arg state "$(gh pr view $pr --json state --jq .state)" \
|
||||
'{($pr): $state}'
|
||||
done | jq -s 'add // {}' > prs.json
|
||||
|
||||
jq -r --slurpfile prs prs.json --arg default "$DEFAULT_REF" '
|
||||
$prs[0] as $state |
|
||||
|
||||
# Group caches by kind, dropping the timestamp or content hash
|
||||
# that every save appends to the key.
|
||||
def family: if startswith("msys2-") then "msys2"
|
||||
elif test("-[0-9]+$") then "ccache"
|
||||
else "other" end;
|
||||
def group: if family == "msys2" then sub("-(files|state):.*$"; "")
|
||||
else sub("-[0-9]+$"; "") end;
|
||||
|
||||
[ .[] | . + { family: (.key | family),
|
||||
group: (.key | group),
|
||||
pr: (.ref | if test("^refs/pull/[0-9]+/merge$")
|
||||
then split("/")[2] else null end) } ]
|
||||
| map(select(.family != "other")) as $all
|
||||
|
||||
# Caches of merged or closed pull requests, and msys2 caches
|
||||
# outside the default branch, which every ref restores from.
|
||||
| ( $all | map(select(
|
||||
(.pr != null and $state[.pr] != "OPEN") or
|
||||
(.family == "msys2" and .ref != $default)
|
||||
)) ) as $dead
|
||||
|
||||
# Of the rest only the newest cache of each kind per ref is used.
|
||||
| ( ($all - $dead) | group_by([.ref, .group]) | map(.[1:]) | add // [] ) as $superseded
|
||||
|
||||
| ($dead + $superseded)[] | "\(.id)\t\(.ref)\t\(.key)"
|
||||
' caches.json |
|
||||
while IFS=$'\t' read -r id ref key; do
|
||||
echo "deleting $ref $key"
|
||||
gh cache delete "$id"
|
||||
done
|
||||
env:
|
||||
GH_REPO: ${{ github.repository }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DEFAULT_REF: refs/heads/${{ github.event.repository.default_branch }}
|
||||
@@ -1,55 +0,0 @@
|
||||
name: comment
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [build]
|
||||
types: [completed]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
pr_comment:
|
||||
if: github.event.workflow_run.event == 'pull_request' &&
|
||||
github.event.workflow_run.conclusion == 'success'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- env:
|
||||
GH_REPO: ${{ github.repository }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
pr=$(gh pr list --state open --json headRefOid,number \
|
||||
--jq '.[] | select(.headRefOid == "${{ github.event.workflow_run.head_sha }}") | .number')
|
||||
if [ -z "$pr" ]; then
|
||||
echo "No matching open pull request found"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
artifacts=$(gh api repos/{owner}/{repo}/actions/runs/${{ github.event.workflow_run.id }}/artifacts --jq '.artifacts')
|
||||
if [ "$(echo "$artifacts" | jq 'length')" -eq 0 ]; then
|
||||
echo "No artifacts found"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
body=$(echo "$artifacts" | jq -r '
|
||||
def link: "https://nightly.link/${{ github.repository }}/actions/artifacts/\(.id).zip";
|
||||
def entry: "* [\(.name)](\(link))";
|
||||
"Download the artifacts for this pull request:\n<details><summary>Windows</summary>\n\n" +
|
||||
(sort_by(.name) | map(select(.name | test("w64|msvc")) | entry) | join("\n")) +
|
||||
"\n</details>\n<details><summary>macOS</summary>\n\n" +
|
||||
(sort_by(.name) | map(select(.name | test("macos")) | entry) | join("\n")) +
|
||||
"\n</details>"
|
||||
')
|
||||
|
||||
comment_id=$(gh issue view $pr --json comments \
|
||||
--jq '.comments[] | select(.author.login == "github-actions") | .id')
|
||||
if [ -n "$comment_id" ]; then
|
||||
edit=--edit-last
|
||||
fi
|
||||
gh pr comment $pr --body "$body" $edit
|
||||
@@ -1,31 +0,0 @@
|
||||
name: docs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- ci
|
||||
- 'release/**'
|
||||
paths:
|
||||
- 'DOCS/**'
|
||||
pull_request:
|
||||
branches: [master]
|
||||
paths:
|
||||
- 'DOCS/**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
check-docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- name: Docs
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install --no-install-recommends -y python3-docutils rst2pdf
|
||||
./TOOLS/docutils-wrapper.py rst2man --strip-elements-with-class=contents --halt=2 ./DOCS/man/mpv.rst mpv.1
|
||||
./TOOLS/docutils-wrapper.py rst2html --halt=2 ./DOCS/man/mpv.rst mpv.html
|
||||
./TOOLS/docutils-wrapper.py rst2pdf -c -b 1 --repeat-table-rows ./DOCS/man/mpv.rst -o mpv.pdf
|
||||
@@ -1,61 +0,0 @@
|
||||
name: Pull Request Fuzzing
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [master]
|
||||
paths-ignore:
|
||||
- 'DOCS/**'
|
||||
- 'TOOLS/lua/**'
|
||||
- '.editorconfig'
|
||||
- '.github/ISSUE_TEMPLATE/**'
|
||||
- '.github/PULL_REQUEST_TEMPLATE'
|
||||
- '.gitignore'
|
||||
- 'Copyright'
|
||||
- 'README.md'
|
||||
- 'RELEASE_NOTES'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
Fuzzing:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
sanitizer: [address, undefined, memory]
|
||||
steps:
|
||||
- name: Build Fuzzers (${{ matrix.sanitizer }})
|
||||
id: build
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
||||
with:
|
||||
oss-fuzz-project-name: 'mpv'
|
||||
language: c
|
||||
sanitizer: ${{ matrix.sanitizer }}
|
||||
- name: Run Fuzzers (${{ matrix.sanitizer }})
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
|
||||
with:
|
||||
oss-fuzz-project-name: 'mpv'
|
||||
language: c
|
||||
fuzz-seconds: 1200
|
||||
sanitizer: ${{ matrix.sanitizer }}
|
||||
report-ooms: true
|
||||
report-timeouts: true
|
||||
output-sarif: true
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@v7
|
||||
if: failure() && steps.build.outcome == 'success'
|
||||
with:
|
||||
name: ${{ matrix.sanitizer }}-artifacts
|
||||
path: ./out/artifacts
|
||||
- name: Upload Sarif
|
||||
if: always() && steps.build.outcome == 'success'
|
||||
uses: github/codeql-action/upload-sarif@v4
|
||||
with:
|
||||
sarif_file: cifuzz-sarif/results.sarif
|
||||
checkout_path: cifuzz-sarif
|
||||
@@ -1,75 +0,0 @@
|
||||
name: lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- ci
|
||||
- 'release/**'
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
commit-msg:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 50
|
||||
|
||||
- name: Lint
|
||||
run: |
|
||||
./ci/lint-commit-msg.py
|
||||
|
||||
swift:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- uses: norio-nomura/action-swiftlint@3.2.1
|
||||
|
||||
lua:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: lunarmodules/luacheck@v1
|
||||
|
||||
ruff:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- name: Check
|
||||
id: check
|
||||
uses: astral-sh/ruff-action@v3
|
||||
with:
|
||||
src: ". TOOLS/umpv"
|
||||
- name: Suggested changes
|
||||
if: ${{ failure() && steps.check.outcome == 'failure' }}
|
||||
run: ruff check . TOOLS/umpv --diff
|
||||
|
||||
mypy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: python/mypy@master
|
||||
with:
|
||||
install_project_dependencies: no
|
||||
options: '--check-untyped-defs'
|
||||
paths: ". TOOLS/umpv"
|
||||
|
||||
editorconfig:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: editorconfig-checker/action-editorconfig-checker@main
|
||||
- run: editorconfig-checker -config .editorconfig-checker.json
|
||||
|
||||
pre-commit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: pre-commit/action@v3.0.1
|
||||
+36
-7
@@ -1,7 +1,36 @@
|
||||
/subprojects/*
|
||||
!/subprojects/packagefiles
|
||||
!/subprojects/*.wrap
|
||||
/build/
|
||||
/dist/
|
||||
.hvigor/
|
||||
.DS_Store
|
||||
*.o
|
||||
*.a
|
||||
*.d
|
||||
*.exe
|
||||
*.pyc
|
||||
.depend
|
||||
|
||||
/config.h
|
||||
/config.mak
|
||||
/config.log
|
||||
/mpv
|
||||
/mpv.app
|
||||
/version.h
|
||||
/input/input_conf.h
|
||||
/tags
|
||||
/TAGS
|
||||
/video/out/gl_video_shaders.h
|
||||
/video/out/x11_icon.inc
|
||||
/demux/ebml_defs.c
|
||||
/demux/ebml_types.h
|
||||
/sub/osd_font.h
|
||||
/player/lua/*.inc
|
||||
/DOCS/man/*/mpv.1
|
||||
/DOCS/man/*/mpv.aux
|
||||
/DOCS/man/*/mpv.log
|
||||
/DOCS/man/*/mpv.out
|
||||
/DOCS/man/*/mpv.pdf
|
||||
/DOCS/man/*/mpv.toc
|
||||
|
||||
/waf
|
||||
/build
|
||||
/.waf*
|
||||
/.lock-waf_*
|
||||
|
||||
/old_build
|
||||
/Makefile
|
||||
-110
@@ -1,110 +0,0 @@
|
||||
local mp_globals = {
|
||||
mp = {
|
||||
fields = {
|
||||
command = {},
|
||||
commandv = {},
|
||||
command_native = {},
|
||||
command_native_async = {},
|
||||
add_hook = {},
|
||||
abort_async_command = {},
|
||||
del_property = {},
|
||||
get_property = {},
|
||||
get_property_osd = {},
|
||||
get_property_bool = {},
|
||||
get_property_number = {},
|
||||
get_property_native = {},
|
||||
set_property = {},
|
||||
set_property_bool = {},
|
||||
set_property_number = {},
|
||||
set_property_native = {},
|
||||
get_time = {},
|
||||
add_key_binding = {},
|
||||
add_forced_key_binding = {},
|
||||
remove_key_binding = {},
|
||||
register_event = {},
|
||||
unregister_event = {},
|
||||
observe_property = {},
|
||||
unobserve_property = {},
|
||||
add_timeout = {},
|
||||
add_periodic_timer = {},
|
||||
get_opt = {},
|
||||
get_script_name = {},
|
||||
get_script_directory = {},
|
||||
osd_message = {},
|
||||
get_wakeup_pipe = {},
|
||||
get_next_timeout = {},
|
||||
dispatch_events = {},
|
||||
register_idle = {},
|
||||
unregister_idle = {},
|
||||
enable_messages = {},
|
||||
register_script_message = {},
|
||||
unregister_script_message = {},
|
||||
create_osd_overlay = {},
|
||||
get_osd_size = {},
|
||||
msg = {
|
||||
fields = {
|
||||
fatal = {},
|
||||
error = {},
|
||||
warn = {},
|
||||
info = {},
|
||||
verbose = {},
|
||||
debug = {},
|
||||
trace = {},
|
||||
}
|
||||
},
|
||||
-- Not documented
|
||||
-- TODO: Document or remove them
|
||||
disable_key_bindings = {},
|
||||
enable_key_bindings = {},
|
||||
find_config_file = {},
|
||||
flush_keybindings = {},
|
||||
format_time = {},
|
||||
get_mouse_pos = {},
|
||||
set_key_bindings = {},
|
||||
set_mouse_area = {},
|
||||
set_osd_ass = {},
|
||||
}
|
||||
},
|
||||
exit = {},
|
||||
unpack = {},
|
||||
}
|
||||
|
||||
local mp_internal = {
|
||||
mp = {
|
||||
fields = {
|
||||
-- Internal
|
||||
-- TODO: Move to mp_internal module
|
||||
ARRAY = { fields = { info = {}, type = {} }},
|
||||
MAP = { fields = { info = {}, type = {} }},
|
||||
UNKNOWN_TYPE = { fields = { info = {}, type = {} }},
|
||||
_legacy_overlay = { fields = { res_x = {}, res_y = {}, data = {}, update = {} }},
|
||||
cancel_timer = {},
|
||||
get_osd_margins = {},
|
||||
input_define_section = {},
|
||||
input_disable_section = {},
|
||||
input_enable_section = {},
|
||||
input_set_section_mouse_area = {},
|
||||
keep_running = {},
|
||||
log = {},
|
||||
raw_abort_async_command = {},
|
||||
raw_command_native_async = {},
|
||||
raw_hook_add = {},
|
||||
raw_hook_continue = {},
|
||||
raw_observe_property = {},
|
||||
raw_unobserve_property = {},
|
||||
raw_wait_event = {},
|
||||
request_event = {},
|
||||
script_name = {},
|
||||
use_suspend = {},
|
||||
wait_event = {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std = "min+mp"
|
||||
stds = { mp = { read_globals = mp_globals } }
|
||||
-- mp_internal seems to be merged with mp for other files too...
|
||||
files["player/lua/defaults.lua"] = { globals = mp_internal }
|
||||
files["player/lua/auto_profiles.lua"] = { globals = { "p", "get" } }
|
||||
files["player/lua/select.lua"] = { globals = { "p", "get" } }
|
||||
max_line_length = 100
|
||||
@@ -1,23 +0,0 @@
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: check-case-conflict
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-illegal-windows-names
|
||||
- id: check-json
|
||||
- id: check-shebang-scripts-are-executable
|
||||
- id: check-xml
|
||||
exclude: ^TOOLS/mpv-osd-symbols.sfdir/font.props$
|
||||
- id: check-yaml
|
||||
- id: end-of-file-fixer
|
||||
exclude: ^TOOLS/osxbundle/mpv.app/Contents/PkgInfo$
|
||||
- id: fix-byte-order-marker
|
||||
- id: mixed-line-ending
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.3.0
|
||||
hooks:
|
||||
- id: codespell
|
||||
args: ["--ignore-words-list", "ALS,als,datas,DNE,enew,HDA,numer,ontop,optionA,Paeth,pathc,inout,requestor"]
|
||||
exclude: ^(etc/menu.conf|misc/language.c)$
|
||||
@@ -1,10 +0,0 @@
|
||||
disabled_rules:
|
||||
- identifier_name
|
||||
- line_length
|
||||
- large_tuple
|
||||
- void_function_in_ternary
|
||||
- function_body_length
|
||||
- cyclomatic_complexity
|
||||
- file_length
|
||||
- type_body_length
|
||||
strict: true
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
language: c
|
||||
|
||||
env:
|
||||
- LIBAV=libav-stable
|
||||
- LIBAV=libav-git
|
||||
- LIBAV=ffmpeg-stable
|
||||
- LIBAV=ffmpeg-git
|
||||
compiler:
|
||||
- clang
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- ci
|
||||
|
||||
before_install: ./travis-deps libass-stable $LIBAV
|
||||
script:
|
||||
- ./bootstrap.py
|
||||
- ./waf configure
|
||||
- ./waf build
|
||||
|
||||
notifications-policy: ¬ifications-policy
|
||||
on_success: change
|
||||
on_failure: always
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
irc:
|
||||
channels:
|
||||
- "irc.freenode.org#mpv-player-dev"
|
||||
<<: *notifications-policy
|
||||
@@ -1,78 +1,19 @@
|
||||
mpv is a fork of mplayer2, which is a fork of MPlayer.
|
||||
|
||||
mpv as a whole is licensed under the GNU General Public License GPL version 2
|
||||
or later (called GPLv2+ in this document, see LICENSE.GPL for full license
|
||||
text) by default. The mpv program is licensed the GNU Lesser General Public
|
||||
License LGPL version 2 or later (LGPLv2.1+ in this document, see LICENSE.LGPL
|
||||
for full license text) if built without using any GPL only files.
|
||||
The -Dgpl=false configure switch is provided as a convenience for excluding
|
||||
the GPL only files listed below from the build process.
|
||||
|
||||
However, do note that the build system is provided "as is" and using the
|
||||
-Dgpl=false configure switch does not in itself create a LGPLv2.1+ license
|
||||
grant.
|
||||
|
||||
Additionally, some non-program parts, such as the documentation and some config
|
||||
files listed below, are still built and licensed under their respective licenses
|
||||
even when -Dgpl=false is used. Please consult GPLv2+ and LGPLv2.1+ license texts
|
||||
for further details on how to distribute these files.
|
||||
|
||||
Most source files are LGPLv2.1+ or GPLv2+, but some files are available under
|
||||
more liberal licenses, such as BSD, MIT, ISC, and possibly others. Look at the
|
||||
copyright header of each source file, and grep the sources for "Copyright" if
|
||||
you need to know details. C source files without Copyright notice are usually
|
||||
licensed as LGPLv2.1+. Also see the list of files with specific licenses below
|
||||
(not all files can have a standard license header).
|
||||
|
||||
All new contributions must be LGPLv2.1+ licensed. Using a more liberal license
|
||||
compatible to LGPLv2.1+ is also ok.
|
||||
|
||||
Changes done to GPL code must come with the implicit/explicit agreement that the
|
||||
project can relicense the changes to LGPLv2.1+ at a later point without asking
|
||||
the contributor. This is a safeguard for making potential relicensing of
|
||||
remaining GPL code to LGPLv2.1+ easier.
|
||||
|
||||
See DOCS/contribute.md for binding rules wrt. licensing for contributions.
|
||||
mpv as a whole is licensed as GPL version 2 or later (see LICENSE). Most source
|
||||
files are GPLv2+, but some files are available under a more liberal license,
|
||||
such as LGPLv2+, BSD, MIT, ISC, and possibly others. Look at the copyright
|
||||
header of each source file, and grep the sources for "Copyright" if you need
|
||||
to know details. Files without Copyright notice are licensed as LGPLv2+.
|
||||
|
||||
For information about authors and contributors, consult the git log, which
|
||||
contains the complete SVN and CVS history as well.
|
||||
|
||||
mpv can be built as LGPLv2.1+ without using any GPL only files. To add a
|
||||
LGPL mode to mpv, MPlayer code had to be relicensed from GPLv2+ to LGPLv2.1+ by
|
||||
asking the MPlayer authors for permission. Since permission could not be
|
||||
obtained from everyone, LGPL mode disables the following features, some of them
|
||||
quite central:
|
||||
- Linux X11 video output
|
||||
- BSD audio output via OSS
|
||||
- NVIDIA/Linux hardware decoding (vdpau, although nvdec usually works)
|
||||
- minor features: jack, DVD, CDDA, DVB, CACA, legacy direct3d VO
|
||||
Some of these will be fixed in the future. The intended use for LGPL mode is
|
||||
with libmpv, and currently it's not recommended to build mpv CLI in LGPL mode
|
||||
at all.
|
||||
Note that mplayer2 as a whole is licensed under GPLv3+. This is because it uses
|
||||
a copy of talloc (part of Samba), which is LGPLv3+, and the next compatible
|
||||
license for this mix is GPLv3+.
|
||||
|
||||
The following files are still GPL only (-Dgpl=false disables them):
|
||||
|
||||
audio/out/ao_jack.c will stay GPL
|
||||
audio/out/ao_oss.c will stay GPL
|
||||
stream/dvb* must stay GPL
|
||||
stream/stream_cdda.c unknown
|
||||
stream/stream_dvb.* must stay GPL
|
||||
stream/stream_dvdnav.c unknown
|
||||
video/out/vo_caca.c unknown
|
||||
video/out/vo_direct3d.c unknown
|
||||
video/out/vo_vaapi.c probably impossible (some company's code)
|
||||
video/out/vo_vdpau.c probably impossible (nVidia's code)
|
||||
video/out/vo_x11.c probably impossible
|
||||
video/out/vo_xv.c probably impossible
|
||||
video/out/x11_common.* probably impossible
|
||||
video/vdpau.c hard (GPL-only parts must be ifdefed)
|
||||
video/vdpau.h unknown
|
||||
video/vdpau_mixer.* actual code must be rewritten
|
||||
DOCS/man/ GPLv2+
|
||||
etc/mplayer-input.conf unknown license, probably GPLv2+
|
||||
etc/mpv.desktop unknown license, probably GPLv2+
|
||||
etc/restore-old-bindings.conf unknown license, probably GPLv2+
|
||||
|
||||
None of the cases listed above affect the final binary if it's built as
|
||||
LGPL. Linked libraries still can affect the final license (for example if
|
||||
FFmpeg was built as GPL).
|
||||
MPlayer as a whole is licensed under GPLv2 (incompatible to GPLv3!), because
|
||||
some files are licensed to GPLv2 (and _not_ any later version of the license).
|
||||
In particular, this affects the file libmpdemux/demux_ty_osd.c. It is disabled
|
||||
under mplayer2, and has been removed from mpv.
|
||||
@@ -1,22 +0,0 @@
|
||||
# Phase 6 Benchmark 方法
|
||||
|
||||
## 执行
|
||||
|
||||
```sh
|
||||
python3 benchmark/runner/run_emulator.py startup_local --repeat 20
|
||||
python3 benchmark/runner/run_emulator.py seek_local --repeat 50
|
||||
python3 benchmark/runner/run_emulator.py stress_lifecycle --repeat 100
|
||||
python3 benchmark/runner/run_emulator.py play_pause --repeat 200
|
||||
```
|
||||
|
||||
runner 通过 hdc/uitest 驱动 `Playback Lab`,每次 load 使用内置 `sample.mp4`,记录 timeline、错误、状态和进程采样。startup 的首轮标为 cold-ish,后续为 warm;OS page cache 未被强制清空。seek 使用加载后立即触发的原生 `+10s`,避免短样片在输入框多次 keyEvent 期间自然结束。
|
||||
|
||||
每个场景输出逐次 JSON 和 min/max/avg/median/P90/P95。百分位采用排序后的 nearest-rank;负时间线值是 unavailable,不参与统计。错误单独保留,不从成功样本中删除。
|
||||
|
||||
## 采样边界
|
||||
|
||||
- VmRSS、VmSize、Threads、fd count 和原始 CPU jiffies 来自 `/proc`;PSS、精确 native heap、可靠 CPU permille 未被模拟器公开,输出 null/原始值。
|
||||
- host wall time 包含 hdc 往返,只用于发现自动化超时,不作为启动性能结论。
|
||||
- `firstAudioCallbackMs` 是 Playback Lab 诊断轮询观察到 callback_count>0 的时间;要取得 callback 内精确时间需独立 tracing,因此不把它当作硬件时钟证据。
|
||||
- `stress_lifecycle` 覆盖 load/stop;release/recreate 需要新 XComponent surface,另行作为实体设备/手工场景。
|
||||
- HTTPS、HLS、鉴权、网络字幕必须使用受控 fixture;本轮没有把公网失败当作性能数据。
|
||||
@@ -1,7 +0,0 @@
|
||||
# Buffering Model
|
||||
|
||||
buffering 是 MPV `cache-buffering` 属性与网络状态的边沿诊断,不是 UI 的瞬时文案。进入时记录 `bufferingEnterCount` 和起始 monotonic 时间;退出时累加 `bufferingTotalMs`,并更新 `bufferingMaxSingleMs`。重复的同值属性通知不会重复计数。
|
||||
|
||||
网络快照同时保留 protocol、host、HTTP status、redirect count、cache duration/bytes、current bitrate、range support 和最近 seek result。`networkWaitMs` 只计算已观察到的 network-open 到 first-byte/file-loaded 间隔;file:// 输入为 -1。
|
||||
|
||||
本地短片通常在首帧后很快 EOF,因此 buffering 计数为 0 不代表网络流在真实设备上不会重缓冲。受控 HTTP Range fixture 已在 Phase 5 验证;HTTPS/HLS、鉴权和弱网重缓冲应在实体设备用固定服务端脚本复测。
|
||||
@@ -1,97 +0,0 @@
|
||||
# Phase 1 Build Issues
|
||||
|
||||
## BUILD-001
|
||||
|
||||
Component: FFmpeg configure
|
||||
|
||||
Command: `scripts/build-ffmpeg-ohos.sh`
|
||||
|
||||
Original Error: `Unknown option "--disable-postproc".`
|
||||
|
||||
File: `scripts/build-ffmpeg-ohos.sh`
|
||||
|
||||
Root Cause: 当前 FFmpeg 已移除独立 postproc 配置项,Phase 0 示例参数过期。
|
||||
|
||||
Platform Difference: 无;属于当前 upstream 配置接口变化。
|
||||
|
||||
Fix: 删除不存在的 `--disable-postproc`,以当前 `configure --help` 为准。
|
||||
|
||||
Files Changed: `scripts/build-ffmpeg-ohos.sh`
|
||||
|
||||
Patch Required: Build script only
|
||||
|
||||
Result: configure 继续执行。
|
||||
|
||||
Regression Risk: Low
|
||||
|
||||
## BUILD-002
|
||||
|
||||
Component: FFmpeg compiler/linker probe
|
||||
|
||||
Command: `scripts/build-ffmpeg-ohos.sh`
|
||||
|
||||
Original Error: `ld: library 'System' not found`,随后 `C compiler test failed`。
|
||||
|
||||
File: `scripts/build-ffmpeg-ohos.sh`、`ffbuild/config.log`
|
||||
|
||||
Root Cause: `--sysroot` 不会自动改变 Clang target;链接探针仍按 macOS 目标寻找 `libSystem`。
|
||||
|
||||
Platform Difference: macOS arm64 与 OHOS arm64 架构相同,但 ABI、对象格式和系统库不同。
|
||||
|
||||
Fix: 同时向 CFLAGS 和 LDFLAGS 显式传入 `--target=aarch64-linux-ohos`。
|
||||
|
||||
Files Changed: `scripts/build-ffmpeg-ohos.sh`
|
||||
|
||||
Patch Required: Build script only
|
||||
|
||||
Result: FFmpeg configure、build、install 成功,产物为 AArch64 ELF。
|
||||
|
||||
Regression Risk: Low
|
||||
|
||||
## BUILD-003
|
||||
|
||||
Component: FreeType zlib resolution
|
||||
|
||||
Command: `scripts/build-font-stack-ohos.sh`
|
||||
|
||||
Original Error: `ERROR: Subproject zlib is buildable: NO`,Meson 尝试下载 WrapDB zlib。
|
||||
|
||||
File: `scripts/build-font-stack-ohos.sh`
|
||||
|
||||
Root Cause: FreeType 的 `zlib=external` 表示构建 fallback subproject,不表示使用外部系统库。
|
||||
|
||||
Platform Difference: SDK 已提供 target `libz.so`,不应另行下载 target zlib。
|
||||
|
||||
Fix: 使用当前 FreeType 定义的 `zlib=system`,通过隔离 `.pc` 指向 SDK AArch64 zlib。
|
||||
|
||||
Files Changed: `scripts/build-font-stack-ohos.sh`
|
||||
|
||||
Patch Required: Build script only
|
||||
|
||||
Result: FreeType 2.14.3 静态库构建成功。
|
||||
|
||||
Regression Risk: Low
|
||||
|
||||
## BUILD-004
|
||||
|
||||
Component: Meson cross-file pkg-config resolution
|
||||
|
||||
Command: `scripts/build-font-stack-ohos.sh`
|
||||
|
||||
Original Error: HarfBuzz 报 `Dependency 'freetype2' is required but not found`,包装器被解析到 HarfBuzz 源码目录。
|
||||
|
||||
File: `toolchains/ohos-api24-arm64.ini`
|
||||
|
||||
Root Cause: `@GLOBAL_SOURCE_ROOT@` 指向当前被配置项目的 source root,不固定指向 Velix-MPV-Core。
|
||||
|
||||
Platform Difference: 多个独立 Meson 源码树共享一个 target prefix。
|
||||
|
||||
Fix: 使用以 Cross File 自身为基准的 `@DIRNAME@/../` 定位包装器与 prefix。
|
||||
|
||||
Files Changed: `toolchains/ohos-api24-arm64.ini`
|
||||
|
||||
Patch Required: Cross File only
|
||||
|
||||
Result: FreeType、HarfBuzz、libass 和 MPV 均只从 OHOS prefix 解析依赖。
|
||||
|
||||
Regression Risk: Low
|
||||
@@ -1,64 +0,0 @@
|
||||
# HarmonyOS Native Build Strategy
|
||||
|
||||
## Scope
|
||||
|
||||
Phase 1 只构建 HarmonyOS API 24 arm64 `libmpv`。不包含播放器 UI、XComponent 集成、`ao_harmony`、MPV OHCodec backend、性能优化、HDR 或真机运行声明。
|
||||
|
||||
## Toolchain
|
||||
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| SDK | `/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony` |
|
||||
| Version | 6.1.1.125 / API 24 |
|
||||
| Target | `aarch64-linux-ohos` |
|
||||
| Sysroot | `<SDK>/native/sysroot` |
|
||||
| Compiler | OHOS Clang 15.0.4 |
|
||||
| Meson | 1.9.0,仓库隔离 venv |
|
||||
| Ninja | SDK 1.12.0 |
|
||||
| pkgconf | 3.0.6,仓库隔离 host tool |
|
||||
| Cross File | `toolchains/ohos-api24-arm64.ini` |
|
||||
| Prefix | `build/ohos-arm64/prefix` |
|
||||
|
||||
`scripts/setup-ohos-env.sh` 清空 `CPATH`、`C_INCLUDE_PATH`、`CPLUS_INCLUDE_PATH`、`LIBRARY_PATH`、`CMAKE_PREFIX_PATH`,并将 pkg-config 限制到 OHOS prefix。target 编译和链接必须同时带 `--target` 与 `--sysroot`。
|
||||
|
||||
## Reproducible Build
|
||||
|
||||
```sh
|
||||
scripts/build-all-ohos.sh
|
||||
```
|
||||
|
||||
顺序固定为:host tools → pinned sources → C/C++ probes → SDK zlib metadata → OpenSSL → FFmpeg → FreeType/FriBidi/HarfBuzz/libass → libplacebo → MPV → 全量 ABI/污染/符号校验。
|
||||
|
||||
各步骤也可单独执行:
|
||||
|
||||
```sh
|
||||
scripts/verify-toolchain.sh
|
||||
scripts/build-openssl-ohos.sh
|
||||
scripts/build-ffmpeg-ohos.sh
|
||||
scripts/build-font-stack-ohos.sh
|
||||
scripts/build-libplacebo-ohos.sh
|
||||
scripts/build-mpv-ohos.sh
|
||||
scripts/verify-ohos-prefix.sh
|
||||
```
|
||||
|
||||
所有下载源码按 `scripts/fetch-phase1-sources.sh` 的 tag/commit 固定。构建目录可删除后重建,禁止从 Homebrew 或 macOS prefix 提供 target library。
|
||||
|
||||
## MPV Configuration
|
||||
|
||||
MPV 使用 `-Dauto_features=disabled`,再显式启用 `libmpv`、GPL、`plain-gl`、OpenGL、vector、zlib。CLI、测试、脚本语言、桌面后端、平台硬件加速 backend 和 Vulkan 均关闭。实际 feature 列表以 `DOCS/MPV_BUILD_REPORT.md` 和 `build/ohos-arm64/logs/mpv.log` 为准。
|
||||
|
||||
MPV 源码仅增加明确的 `host_machine.system() == 'ohos'` 检测与 `ohos` feature。POSIX 路径继续复用现有 threads、timer、path、poll、IPC、subprocess 实现;这些能力当前只能标记 compile verified。
|
||||
|
||||
## Output and Gates
|
||||
|
||||
主产物:`build/ohos-arm64/prefix/lib/libmpv.so.2.5.0`。
|
||||
|
||||
`scripts/verify-ohos-prefix.sh` 必须同时证明:
|
||||
|
||||
- 所有 prefix 静态库成员为 AArch64 ELF;
|
||||
- `libmpv` 为 AArch64 ELF shared object;
|
||||
- 动态依赖仅来自 HarmonyOS SDK allowlist(启用 `harmony-audio` 时包含 `libohaudio.so`);
|
||||
- `.pc`/CMake/Ninja target metadata 无 Homebrew、`/usr/local`、`.dylib` 或 Apple framework;
|
||||
- Client API 与 OpenGL Render API 必需符号存在。
|
||||
|
||||
真机行为、CA store、XComponent/EGL 生命周期及 OHCodec buffer 语义留到后续阶段验证。
|
||||
@@ -1,11 +0,0 @@
|
||||
# Core API versioning
|
||||
|
||||
当前冻结版本:`VELIX_CORE_API_VERSION = 0x000100`(v0)。
|
||||
|
||||
- `MAJOR` 变化表示 ABI/API 不兼容,必须升级主 App 适配层。
|
||||
- `MINOR` 变化只增加尾部字段或能力,旧调用方保持可用。
|
||||
- `PATCH` 变化只修复实现,不改变公开结构布局。
|
||||
|
||||
版本宏、`velix_core_get_api_version()`、`velix_core_get_version()` 和 `velix_core_get_build_info()` 位于 `include/velix/core.h`,C ABI 使用 opaque handle 与固定宽度整数。变更 API 时同步更新 `metadata/build-info.json`、此文档与集成文档,并在发布前检查动态符号。
|
||||
|
||||
v0 不把 `mpv_handle`、`mpv_node`、FFmpeg、OHCodec、EGL、OHAudio 或 OHNativeWindow 类型带出 SDK。
|
||||
@@ -1,27 +0,0 @@
|
||||
# Velix Core SDK
|
||||
|
||||
Phase 7 SDK v0 以 `include/velix/core.h` 与 `libvelix_core_binding.so` 为产品边界,主 App 不编译 MPV/FFmpeg 源码。
|
||||
|
||||
## 目录
|
||||
|
||||
```text
|
||||
velix-core/
|
||||
├── include/velix/core.h
|
||||
├── include/mpv/harmony_playback.h
|
||||
├── lib/arm64-v8a/libvelix_core_binding.so
|
||||
├── lib/arm64-v8a/libmpv.so.2
|
||||
├── lib/arm64-v8a/libc++_shared.so
|
||||
├── metadata/build-info.json
|
||||
└── licenses/
|
||||
```
|
||||
|
||||
`libvelix_core_binding.so` 仅提供产品生命周期、控制、状态、媒体、音轨、字幕、指标与 build-info NAPI;XComponent 的 OHNativeWindow/EGL/mpv render context 仍由 Core 内部实现。主 App 只能看到 `PlaybackEngine`/`PlaybackController` 的业务类型。
|
||||
|
||||
默认 profile 为 software decode,OHCodec GL mapper 保持关闭。SDK 产物位于 `dist/velix-core`,已在 `.gitignore` 中忽略,禁止把 34MB `libmpv` 二进制提交到 Git。
|
||||
|
||||
构建与 staging:
|
||||
|
||||
```sh
|
||||
./scripts/package-velix-core-sdk.sh --profile default
|
||||
../Velix/scripts/build-velix-app.sh --release-core --build-mode debug
|
||||
```
|
||||
@@ -1,81 +0,0 @@
|
||||
# FFmpeg Strategy
|
||||
|
||||
## 决策
|
||||
|
||||
Phase 1 使用独立构建的 **官方 FFmpeg upstream**,不把源码揉进 MPV,也暂不建立 `Velix-FFmpeg-Harmony`。
|
||||
|
||||
研究基线:FFmpeg master `3acec0a1af2dda0a0838689b8b8649e7deb080a0`(2026-08-28)。该 commit 已提供 OpenHarmony `ohcodec` hwcontext/pixel format 以及 H.264/HEVC decoder/encoder,显著降低自行 fork 的必要性。
|
||||
|
||||
## MPV 依赖约束
|
||||
|
||||
MPV 当前 Meson 最低要求:
|
||||
|
||||
| Library | 最低版本 |
|
||||
|---|---:|
|
||||
| libavcodec | 60.31.102 |
|
||||
| libavfilter | 9.12.100 |
|
||||
| libavformat | 60.16.100 |
|
||||
| libavutil | 58.29.100 |
|
||||
| libswresample | 4.12.100 |
|
||||
| libswscale | 7.5.100 |
|
||||
|
||||
必须同时生成 pkg-config 文件供 MPV cross build 使用。
|
||||
|
||||
## 两种方案评估
|
||||
|
||||
### A. 官方 FFmpeg 独立构建(采用)
|
||||
|
||||
- 独立源码目录与安装前缀。
|
||||
- arm64 OHOS toolchain 交叉编译。
|
||||
- Phase 1 首先保留 software decode、demux、HTTP/HLS、字幕相关基础;OHCodec 可编译但不要求首次 MPV 构建即启用硬解。
|
||||
- TLS 使用 FFmpeg 已支持并经过许可审核的第三方 backend(优先 OpenSSL);Harmony `libnet_ssl.so` 不能直接替代。
|
||||
- 优点:上游同步清晰、已有 OHCodec、MPV 仓库 patch 最小。
|
||||
|
||||
### B. Velix-FFmpeg-Harmony fork(暂不采用)
|
||||
|
||||
只有满足以下任一条件才触发:
|
||||
|
||||
1. 官方 OHCodec 在 API 24 上存在阻断编译/运行问题,且修复无法及时 upstream。
|
||||
2. 需要 OHNativeBuffer/GPU import 或 HDR metadata 等实质性 FFmpeg API 扩展。
|
||||
3. 网络/TLS 或 Harmony 生命周期需要不可在外部构建脚本解决的源码 patch。
|
||||
|
||||
建立后必须同样保留完整历史、配置 `upstream`、小 patch 分支,并单独维护许可证审计。
|
||||
|
||||
## Phase 1 建议配置轮廓
|
||||
|
||||
实际参数必须先由交叉编译探针和 FFmpeg `configure --help` 固化;以下是预计命令,不是已成功结果:
|
||||
|
||||
```sh
|
||||
./configure \
|
||||
--prefix="$FFMPEG_PREFIX" \
|
||||
--target-os=linux \
|
||||
--arch=aarch64 \
|
||||
--cc="$OHOS_CLANG --target=aarch64-linux-ohos --sysroot=$OHOS_SYSROOT" \
|
||||
--cxx="$OHOS_CLANGXX --target=aarch64-linux-ohos --sysroot=$OHOS_SYSROOT" \
|
||||
--ar="$OHOS_LLVM_AR" \
|
||||
--strip="$OHOS_LLVM_STRIP" \
|
||||
--enable-cross-compile \
|
||||
--enable-pic \
|
||||
--enable-shared \
|
||||
--disable-programs \
|
||||
--disable-doc \
|
||||
--enable-network \
|
||||
--enable-openssl
|
||||
```
|
||||
|
||||
注意:FFmpeg 当前 configure 未发现独立 `target-os=ohos` 结论,是否应使用 `linux` 必须由真实配置日志决定;编译器会同时定义 `__OHOS__` 与 `__linux__`。`--enable-ohcodec` 在首次软件解码 build 可暂缓,第二个受控构建再开启并验证其五个 Native media 库。
|
||||
|
||||
## 网络与 TLS
|
||||
|
||||
- HTTP/HLS 主要由 libavformat protocol/demuxer 提供,不新增 MPV 自定义网络栈。
|
||||
- socket/DNS 可直接使用 OHOS libc。
|
||||
- HTTPS 需要 FFmpeg 支持的 TLS backend。首选独立交叉构建 OpenSSL,并固定 CA bundle/系统证书策略;证书路径、SNI、代理、IPv6、重定向、Range 请求必须真机验证。
|
||||
- 禁止将“SDK 有 `libnet_ssl.so`”写成“FFmpeg HTTPS 已支持”。
|
||||
|
||||
## 验收与 fork 决策点
|
||||
|
||||
1. `configure` 识别 arm64 OHOS、pthreads、network、dlopen。
|
||||
2. 所需 FFmpeg libraries 完整生成,pkg-config 不泄漏宿主机路径。
|
||||
3. software decode + HTTP/HLS 单测通过。
|
||||
4. `--enable-ohcodec` 能链接 API 24 SDK,并枚举 `h264_oh` / `hevc_oh`。
|
||||
5. 任何源码 patch 先形成最小 diff、根因、upstream 可接受性评估,再决定是否 fork。
|
||||
@@ -1,102 +0,0 @@
|
||||
# HarmonyOS OHAudio Backend
|
||||
|
||||
状态:Phase 3 CODE COMPLETE / DEVICE VALIDATION PENDING。
|
||||
|
||||
代码、OHOS arm64 交叉编译和模拟器 H.264/AAC smoke test 已完成。实体设备上的真实输出路由、延迟、A/V sync 精度、蓝牙/耳机、多声道和长时间稳定性仍未宣称完成。
|
||||
|
||||
## Architecture
|
||||
|
||||
```text
|
||||
MPV decoder/filter
|
||||
↓
|
||||
MPV AO buffer (audio/out/buffer.c)
|
||||
↓ pull callback
|
||||
audio/out/ao_harmony.c
|
||||
↓
|
||||
OH_AudioRenderer write callback
|
||||
↓
|
||||
HarmonyOS audio device
|
||||
```
|
||||
|
||||
`ao_harmony` 是 MPV pull AO。PCM 始终在 native 层流动;ArkTS 只负责播放控制和诊断展示,不参与持续 PCM 搬运。
|
||||
|
||||
实现文件:
|
||||
|
||||
- `audio/out/ao_harmony.c`:AO、OHAudio renderer、callback、时钟和统计。
|
||||
- `audio/out/ao_harmony.h`:Playback Lab 使用的只读诊断 ABI。
|
||||
- `audio/out/ao.c`、`meson.build`、`meson.options`:driver 注册和 `harmony-audio` feature。
|
||||
|
||||
## OHAudio API
|
||||
|
||||
实现以当前 API 24 SDK headers 为准:
|
||||
|
||||
- `ohaudio/native_audiostreambuilder.h`
|
||||
- `ohaudio/native_audiorenderer.h`
|
||||
- `ohaudio/native_audiostream_base.h`
|
||||
- `multimedia/native_audio_channel_layout.h`
|
||||
- 链接库:`libohaudio.so`
|
||||
|
||||
Builder 设置 `SamplingRate`、`ChannelCount`、`ChannelLayout`、`SampleFormat`、`EncodingType(RAW)`、`LatencyMode(NORMAL)`、`RendererInfo(USAGE_MOVIE)` 和 write/device/error callbacks,然后 `GenerateRenderer` 并销毁 Builder。Renderer 使用 `Start`、`Pause`、`Stop`、`Flush`、`Release`、`SetVolume`、`GetFrameSizeInCallback`、`GetLatency` 和 `GetAudioTimestampInfo`。
|
||||
|
||||
## MPV AO / callback model
|
||||
|
||||
`write` 保持 NULL,`start` 触发 OHAudio。OHAudio 回调只计算 frame 数、调用 `ao_read_data(..., pad_silence=true, blocking=false)`,不足部分填静音并更新轻量原子计数;不访问网络、不调用 N-API/ArkTS、不分配大对象、不逐回调打印日志。回调首包仅在 debug 日志中记录一次。
|
||||
|
||||
MPV AO buffer 是 producer,OHAudio callback 是 consumer。`ao_read_data` 返回的 PCM 只在当前 callback 内有效,系统提供的 `audioData` 由 OHAudio 所有;没有 AVFrame 或 PCM 指针跨生命周期保存。
|
||||
|
||||
## Format / sample rate / channel layout
|
||||
|
||||
- 仅接受 PCM;MPV float 优先映射 `AUDIOSTREAM_SAMPLE_F32LE`,创建失败时回退 `AF_FORMAT_S16` / `AUDIOSTREAM_SAMPLE_S16LE`。
|
||||
- 采样率使用 MPV 请求值,不强制改成 48 kHz;设备拒绝时返回真实 renderer 创建错误,由 MPV 上层重新协商/重采样。
|
||||
- 单声道映射 `CH_LAYOUT_MONO`,其余首版限制为双声道 `CH_LAYOUT_STEREO`;超过 2 声道先通过 MPV channel map downmix 到 stereo。没有声称 5.1/7.1/Atmos/Dolby 已支持,实体设备能力仍待验证。
|
||||
|
||||
模拟器实际日志:请求 48 kHz、5.1、floatp,经 MPV downmix 后创建 48 kHz、2 声道、float32 renderer。
|
||||
|
||||
## Pause / resume / stop / seek / flush
|
||||
|
||||
- pause:`OH_AudioRenderer_Pause`。
|
||||
- resume/start:`OH_AudioRenderer_Start`。
|
||||
- stop:MPV 的 stop/EOF 通过 AO reset/uninit 路径停止 renderer;不把 pause、stop、release 混为 destroy。
|
||||
- seek/reset:先禁止新 callback,`Stop`,等待 inflight callback 清零,再 `Flush`;清空本地提交/播放 epoch,增加 `audioFlushCount` 与 `seekAudioResetCount`,下一次 `start` 重新开始。
|
||||
- release:禁止 callback → Stop → 等待 callback → 停止并 join timestamp 线程 → Release renderer;回调不会持有释放后的 player/AO 指针。
|
||||
|
||||
所有 OHAudio 返回值都检查;失败通过 MPV AO error/reload 路径处理,使用 `AUDIO_BUILDER_FAILED`、`AUDIO_RENDERER_CREATE_FAILED`、`AUDIO_RENDERER_START_FAILED`、`AUDIO_FLUSH_FAILED`、`AUDIO_RELEASE_ERROR`、`AUDIO_UNSUPPORTED_FORMAT` 等明确日志。
|
||||
|
||||
## A/V clock and delay
|
||||
|
||||
timestamp 线程每 20 ms 调用 `OH_AudioRenderer_GetAudioTimestampInfo`。`submittedFrames` 在 callback 完成填充后递增;`playedFrames` 使用 renderer frame position 减去本次 Flush 的 timestamp origin,避免设备在 Flush 后继续返回旧 epoch。延迟计算为:
|
||||
|
||||
```text
|
||||
pending = max(submittedFrames - playedFrames, 0)
|
||||
estimatedDelayMs = rendererLatencyMs + pending * 1000 / sampleRate
|
||||
```
|
||||
|
||||
`audioTimestamp` 保留 OHAudio 的 monotonic timestamp。MPV 播放倍速仍由 MPV 音频滤镜/时钟负责,不叠加 renderer speed。算法已编译并在模拟器观察到稳定计数;绝对 A/V 偏差与设备路由连续性必须实体机测量。
|
||||
|
||||
## Volume and underrun
|
||||
|
||||
Renderer volume 固定为 unity,最终音量由 MPV 软件 gain 处理,避免双重增益。API 24 当前没有可用的系统 underrun counter,因此不伪造 `systemUnderrun`;callback 返回帧不足时只增加 Velix-side `bufferStarvation`。
|
||||
|
||||
## Playback Lab diagnostics
|
||||
|
||||
Playback Lab 保持原有 video-only 启动路径,新增 `Audio On/Off`(切换 MPV `aid=auto/no`)和以下 native 状态:`audioBackend`、`sampleRate`、`sampleFormat`、`channels`、`channelLayout`、`submittedFrames`、`playedFrames`、`estimatedAudioDelayMs`、`audioBufferStarvation`、`audioFlushCount`、`seekAudioResetCount`、`audioState`。返回值使用 ArkTS Number,避免 BigInt 让 Inspector 无法序列化。
|
||||
|
||||
## Validation
|
||||
|
||||
- Audio-enabled:OHOS arm64 `libmpv.so.2.5.0` clean build,DT_NEEDED 新增 `libohaudio.so`,Playback Lab HAP 构建成功。
|
||||
- Video-only:使用 `-Dharmony-audio=disabled` 的独立 Meson build 编译成功。
|
||||
- Emulator smoke:H.264/AAC MP4 上确认 renderer create、start、callback PCM consumed、pause、resume、seek/flush、stop、release;示例观察到 `starvation=0`,模拟器日志无新增崩溃。
|
||||
- 未验证:实体设备、真实 latency/A-V 偏差、蓝牙/有线/扬声器切换、系统 audio focus/interruption、5.1/7.1、30 分钟压力。
|
||||
|
||||
## Known limitations and physical TODO
|
||||
|
||||
1. 当前仅实现 OHAudio renderer;没有 OHCodec/hwdec、Vulkan、音频焦点业务和设备专属路由策略。
|
||||
2. `systemUnderrun` 需要 SDK 提供真实接口后再接入;当前仅有 `bufferStarvation`。
|
||||
3. 多声道真实 capability、采样率拒绝后的设备行为、timestamp 在路由切换后的连续性需要实体设备矩阵。
|
||||
4. 上层应用负责电话/音频焦点策略;Core 只接受 pause/resume 或 AO reload。
|
||||
|
||||
Phase 4 不在本次变更中启动。未来 OHCodec 评估至少需要单独验证 surface/buffer 同步、stride/format、fence 与生命周期、零拷贝/DRM 约束、不同设备实现差异五类风险。
|
||||
|
||||
## License
|
||||
|
||||
本次仅修改 Velix-MPV-Core 内的 MPV 集成代码和 Playback Lab;MPV 原有 GPL/LGPL 许可保持不变。HarmonyOS SDK 头文件/系统库按 SDK 自身许可使用,没有复制第三方实现源码。
|
||||
@@ -1,59 +0,0 @@
|
||||
# HarmonyOS Audio Research
|
||||
|
||||
> 状态:IMPLEMENTED(代码、OHOS arm64 编译、Playback Lab 模拟器音频 smoke test 已完成);实体设备输出路由、真实延迟、A/V sync 精度、多声道与长稳仍为 NEED PHYSICAL DEVICE VERIFY。
|
||||
|
||||
## 1. 推荐方案
|
||||
|
||||
新增 MPV 音频输出 `ao_harmony`,直接接 HarmonyOS OHAudio:
|
||||
|
||||
```text
|
||||
MPV audio pipeline -> native PCM ring/buffer -> OHAudio write callback -> AudioRenderer
|
||||
```
|
||||
|
||||
禁止 PCM 逐块跨 N-API/ArkTS。ArkTS 只发送播放器级控制和生命周期事件。
|
||||
|
||||
## 2. SDK 依据
|
||||
|
||||
- headers:`ohaudio/native_audiostreambuilder.h`、`native_audiorenderer.h`、`native_audiostream_base.h`、`multimedia/native_audio_channel_layout.h`
|
||||
- library:`libohaudio.so`
|
||||
- SDK 依据:当前 API 24 headers;builder 基础接口从 API 10 起,独立 write callback 从 API 12 起,`GetAudioTimestampInfo` 从 API 15 起,`GetLatency` 从 API 23 起。
|
||||
- builder:采样率、声道数、sample format、encoding、latency mode、channel layout、usage、write callback、callback frame size
|
||||
- renderer:Start、Pause、Stop、Flush、Release、`GetAudioTimestampInfo`、`SetVolume`、`GetLatency`;API 24 没有可用的系统 underrun counter,Velix 只记录 callback starvation。
|
||||
|
||||
API 24 还提供 advanced callback 等新接口,但首版使用最低且稳定的 callback API,避免无必要抬高最低版本。
|
||||
|
||||
## 3. 与 MPV AO 的映射
|
||||
|
||||
| MPV / 播放需求 | OHAudio 映射 | 设计 |
|
||||
|---|---|---|
|
||||
| PCM 格式协商 | `SetSamplingRate`、`SetChannelCount/Layout`、`SetSampleFormat` | `init()` 将 MPV `ao->format` 映射为 OHAudio;不支持时返回 unsupported,让 MPV 重采样 |
|
||||
| 数据输出 | renderer write callback | 回调只读取 MPV AO buffer,禁止阻塞、分配大对象或调用 ArkTS |
|
||||
| Pause/Resume | `OH_AudioRenderer_Pause/Start` | 与 MPV `control()` 状态串行化 |
|
||||
| Stop/Seek | `Stop/Flush/Start` | Seek 时停止 callback、清空 OHAudio、重建 timestamp epoch,避免旧 PCM 泄漏 |
|
||||
| Volume | `OH_AudioRenderer_SetVolume` | 系统 renderer 固定 unity;最终增益由 MPV 软件音量处理,避免重复增益 |
|
||||
| Speed | MPV 音频滤镜为主 | 不直接用 Renderer speed 改变 MPV 时钟;系统 speed 仅后续专项验证 |
|
||||
| A/V Sync | `GetAudioTimestampInfo` | 驱动 delay 由 callback 已提交帧与 timestamp epoch 内的硬件播放位置计算;路由切换仍需实体设备测试 |
|
||||
| 低延迟 | `SetLatencyMode` | 视频播放默认 normal;fast 仅在设备支持和稳定性测试后启用 |
|
||||
| 多声道 | channel layout + capability | 先 stereo;5.1/7.1 按设备能力协商,失败回退重混音,不 fake success |
|
||||
|
||||
## 4. MPV 接入位置
|
||||
|
||||
- 新文件建议:`audio/out/ao_harmony.c`。
|
||||
- 注册位置:`meson.build` 的 audio outputs 区域和 `audio/out/ao.c` driver list。
|
||||
- 参考结构:`ao_aaudio.c` 的 callback/pull 模式及状态控制;不能复制其 Android API。
|
||||
- OHAudio callback 与 MPV AO buffer 的线程安全遵循 `audio/out/buffer.c` 现有模型;回调只消费系统请求的 frame 数。
|
||||
|
||||
## 5. 格式策略
|
||||
|
||||
首版候选优先级:float32(若稳定支持)→ signed 16-bit。采样率优先内容原始值,设备拒绝则让 MPV/libswresample 转为 48 kHz。声道首版 2.0,随后验证 5.1/7.1。所有实际支持值通过 builder 创建结果与设备行为确认,不从枚举存在推断硬件支持。
|
||||
|
||||
## 6. 风险与验证
|
||||
|
||||
1. write callback 的实时线程约束和最大执行时间。
|
||||
2. `GetTimestamp` 在暂停、Flush、蓝牙/有线切换后的连续性。
|
||||
3. underrun、首包预填充与首音频时间。
|
||||
4. Surface 暂停但音频继续、应用后台、音频焦点中断。
|
||||
5. 播放速度与 MPV 时钟双重调整风险。
|
||||
6. 多声道 layout 枚举和实际设备 route 不一致。
|
||||
|
||||
代码验收:PCM 正常播放;pause/resume/seek/flush/release 生命周期已在模拟器通过;starvation 与 timestamp metrics 已接入。1 小时稳定性、真实 underrun、A/V sync 偏差、路由与多声道仍需实体设备,不宣称低延迟或多声道完成。
|
||||
@@ -1,65 +0,0 @@
|
||||
# HarmonyOS Native Capability Research
|
||||
|
||||
## 1. 取证基线
|
||||
|
||||
- SDK:`/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony`
|
||||
- Native / Toolchains:`6.1.1.125`,API 24
|
||||
- 目标:`aarch64-linux-ohos`
|
||||
- 编译器:OHOS Clang 15.0.4
|
||||
- 最小头文件探针已通过:pthread、dlopen、mmap、epoll、poll、socket、DNS、EGL、GLES3、Vulkan、XComponent、OHAudio、Native AVCodec 可被同一 C translation unit 包含。
|
||||
- 编译器预定义:`__OHOS__`、`__linux__`、`__unix__`、`__aarch64__`、`__LP64__`。EGL 平台头使用 `OHOS_PLATFORM` 选择 `OHNativeWindow *`,构建时必须显式定义该宏。
|
||||
|
||||
以下“最低 API”来自本机 API 24 SDK 头文件的 `@since` / availability;运行行为仍需 Phase 1/2 真机验证。
|
||||
|
||||
## 2. 能力矩阵
|
||||
|
||||
| 能力 | C/C++ API / header | library | 最低 API | 生命周期与限制 | 结论 |
|
||||
|---|---|---|---:|---|---|
|
||||
| ArkUI Surface | `OH_NativeXComponent_RegisterCallback`;`OnSurfaceCreated/Changed/Destroyed`;`ace/xcomponent/native_interface_xcomponent.h` | `libace_ndk.z.so` | 8 | `window` 只在组件 Surface 生命周期内有效;销毁前停止渲染并释放 EGL/Vulkan surface | 可用 |
|
||||
| Native Window | `OHNativeWindow`;`native_window/external_window.h` | `libnative_window.so` | 8 起,部分新 buffer API 23 | XComponent 回调交付 window;不得替换成 Android `ANativeWindow` | 可用 |
|
||||
| Native Buffer | `OH_NativeBuffer_*`;`native_buffer/native_buffer.h` | `libnative_buffer.so` | 11 起,具体函数不同 | 用于后续互操作;格式、usage、fence 必须真机查询 | 可用,Phase 0 不承诺零拷贝 |
|
||||
| OpenGL ES | `<GLES2/gl2.h>`、`<GLES3/gl3.h>` | `libGLESv2.so` / `libGLESv3.so` | SDK 基础能力 | 实际 GLES 版本、扩展、10-bit/HDR 格式按设备查询 | 可用 |
|
||||
| EGL | `eglGetDisplay`、`eglCreateWindowSurface`、`eglSwapBuffers`;`<EGL/egl.h>` | `libEGL.so` | SDK 基础能力 | `EGLNativeWindowType` 在 `OHOS_PLATFORM` 下是 `OHNativeWindow *`;上下文线程归属必须固定 | 可用,首选渲染入口 |
|
||||
| Vulkan | `VK_OHOS_surface`、`vkCreateSurfaceOHOS`;`<vulkan/vulkan.h>` / `vulkan_ohos.h` | `libvulkan.so` | 10 | Surface 绑定 `OHNativeWindow`;扩展和 format 支持需设备枚举 | 可用,但不是 libmpv 公共 Render API |
|
||||
| VSync | `OH_NativeVSync_*`;`native_vsync/native_vsync.h` | `libnative_vsync.so` | 9 | 回调与 Surface 生命周期协调 | 可用,首版可先由 EGL swap/MPV 调度 |
|
||||
| Native Audio | `OH_AudioStreamBuilder_*`、`OH_AudioRenderer_*`;`ohaudio/*.h` | `libohaudio.so` | 10 | builder 生成 renderer 后销毁;renderer 使用写回调拉取 PCM;Start/Pause/Stop/Flush/Release 有明确状态机 | 可用,需新增 AO |
|
||||
| Native Video Decoder | `OH_VideoDecoder_*`;`multimedia/player_framework/native_avcodec_videodecoder.h` | `libnative_media_vdec.so`、`libnative_media_codecbase.so`、`libnative_media_core.so`、`libnative_window.so` | 9;buffer 新接口 11 | Create→Configure→SetSurface→Prepare→Start;Seek 需要 Flush 后重启;输出可直接 RenderOutputBuffer 到 Surface | 可用 |
|
||||
| Codec Capability | `OH_AVCodec_GetCapability*`、`OH_AVCapability_*`;`native_avcapability.h` | Native media libs | 10 | 必须在目标设备查询硬件/软件、尺寸、帧率、profile/level;SDK 头不能证明某机型支持 4K/10-bit/HDR | 可用,能力值待真机 |
|
||||
| POSIX file | `open/read/write/stat`;`fcntl.h`、`unistd.h`、`sys/stat.h` | libc | 基础 | 受应用沙箱与授权 URI 限制;ArkUI picker URI/FD 需桥接到 native | 可用但路径权限需集成层处理 |
|
||||
| Packaged rawfile | `OH_ResourceManager_*` / `rawfile/*.h` | `librawfile.z.so` | 8 起 | 只适合包内资源,不是通用媒体文件系统 | 可用,不替代 POSIX file |
|
||||
| pthread | `pthread_create`、mutex/cond;`pthread.h` | libc | 基础 | MPV `threads-posix.c` 可优先复用;线程名函数需 Meson 实测 | 可复用 |
|
||||
| socket | BSD sockets;`sys/socket.h`、`netinet/in.h` | libc | 基础 | 需要网络权限;移动网络切换、IPv6、代理需真机测试 | 可复用 |
|
||||
| DNS | `getaddrinfo/freeaddrinfo`;`netdb.h` | libc | 基础 | DNS/网络切换错误传播由 FFmpeg 网络层处理 | 可复用 |
|
||||
| Native HTTP | `OH_Http_*`;`network/netstack/net_http.h` | `libnet_http.so` | 20 | 与 FFmpeg AVIO 不直接兼容;不作为首版 MPV 网络栈 | API 24 可用但不采用 |
|
||||
| TLS certificate verification | `OH_NetStack_CertVerification` 等;`network/netstack/net_ssl/net_ssl_c.h` | `libnet_ssl.so` | 11 | 这是证书链验证接口,不是 FFmpeg TLS transport backend;首版需交叉构建 FFmpeg 支持的 TLS 库 | 系统验证能力可用,MPV 路径需第三方 TLS |
|
||||
| Shared library | `dlopen/dlsym/dlclose`;`dlfcn.h` | `libdl.a` / libc | 基础 | 插件路径和符号可见性受沙箱约束 | 编译可用,运行待测 |
|
||||
| Timer | `clock_gettime`、`nanosleep`;`time.h` | libc | 基础 | MPV `timer-linux.c` 实际只依赖这两个 POSIX API;源码应改名/条件化以免平台语义错误 | 可复用实现,需整理检测 |
|
||||
| Memory mapping | `mmap/munmap`;`sys/mman.h` | libc | 基础 | 文件映射权限及大文件压力需真机测试 | 编译可用 |
|
||||
| poll / epoll | `poll`、`epoll_*`;`poll.h`、`sys/epoll.h` | libc | 基础 | 头文件存在且探针通过;运行语义、FD 类型兼容性仍需测 | 可用,优先 POSIX poll |
|
||||
| System information | `uname`、`sysconf`、`getauxval`;`sys/utsname.h`、`unistd.h`、`sys/auxv.h`;`OH_GetDeviceType` (`deviceinfo.h`) | libc / `libdeviceinfo_ndk.z.so` | API 10 起(DeviceInfo) | 只用于诊断与保守能力探测,不按设备名硬编码功能 | 可用 |
|
||||
| CPU detection | AArch64 编译宏、`getauxval`;FFmpeg CPU detection | libc | 基础 | arm64 基线已有 NEON;不得未经实测强开额外 ISA | 可复用 |
|
||||
| Lifecycle | XComponent Surface callbacks + N-API/ArkTS 页面生命周期桥接 | `libace_ndk.z.so` / `libace_napi.z.so` | 8 | MPV Core 仅接受 surface attach/detach、pause/resume 等播放器级事件;业务生命周期留在宿主 | 需薄桥接 |
|
||||
| Power | 系统 running lock / 后台任务 API主要由应用层管理 | 系统服务 | 版本依 API | Core 不自行申请长期后台权限;向宿主暴露播放状态,由宿主管理屏幕常亮/后台播放 | 不建 MPV backend |
|
||||
|
||||
## 3. 直接可复用的 MPV/POSIX 区域
|
||||
|
||||
- `osdep/threads-posix.c`:pthread 基础满足。
|
||||
- `osdep/path-unix.c`、`osdep/language-posix.c`:大部分 POSIX 路径/locale 逻辑可编译,沙箱路径语义需测试。
|
||||
- `osdep/timer-linux.c` 的实现仅用 `clock_gettime`/`nanosleep`,能力可复用,但构建选择需改为 `ohos` 明确分支或重命名为 POSIX timer。
|
||||
- socket、DNS、poll、mmap、dlopen 头文件均存在,先通过 feature detection,不因 `__linux__` 自动宣称全部 Linux 特性可用。
|
||||
- demux、字幕、滤镜、同步、命令和 libmpv client API 与平台无关,可直接复用。
|
||||
|
||||
## 4. 必须新增或调整的边界
|
||||
|
||||
1. Meson 增加 `host_machine.system() == 'ohos'` / `features['harmony']`,生成 `HAVE_HARMONY`,防止把 OHOS 的 `__linux__` 等同桌面 Linux。
|
||||
2. 新增 OHAudio AO,不能复用 Android AAudio/OpenSL ES。
|
||||
3. 若构建 MPV 自管 VO,新增 Harmony EGL/Vulkan context;首版 Playback Lab 可由宿主持有 EGL context,使用 libmpv OpenGL Render API,减少 upstream patch。
|
||||
4. 硬解需要 MPV 识别 FFmpeg 的 `AV_PIX_FMT_OHCODEC` 与 `AV_HWDEVICE_TYPE_OHCODEC`;该工作晚于软件解码首帧。
|
||||
5. 日志可先复用 stderr;实验室集成阶段增加 HiLog sink,不能让日志 backend 阻塞首次构建。
|
||||
|
||||
## 5. 未验证项
|
||||
|
||||
- 各目标设备具体 Vulkan/GLES 扩展、HDR/10-bit swapchain、codec profile/level、最大分辨率/码率。
|
||||
- `epoll`、`dlopen`、mmap 大文件在应用沙箱内的运行行为。
|
||||
- 后台播放、音频焦点、路由切换、蓝牙延迟和 Surface 重建行为。
|
||||
- Native HTTP/TLS 与系统代理/证书策略;首版按 FFmpeg + 独立 TLS 依赖验证。
|
||||
@@ -1,7 +0,0 @@
|
||||
# Harmony 字体策略
|
||||
|
||||
第一优先级使用系统字体;应用字体只允许由产品明确提供的开源字体;libass 使用 mpv 已配置的字体 provider,不新增商业字体包。当前 OHOS 字体栈按 `scripts/build-font-stack-ohos.sh` 构建:FreeType + HarfBuzz + FriBidi + libass,libass 明确关闭 fontconfig、DirectWrite、CoreText 和 iconv provider,因此不依赖 Linux `fonts.conf`。
|
||||
|
||||
Playback Lab 初始化时将 mpv `sub-fonts-dir` 指向 `/system/fonts`;模拟器已确认该目录存在,`/system/etc/fontconfig` 与 `/system/etc/fonts` 不存在。libass 的 `ass_set_fonts_dir` 会从该目录加载字体,`sub-font-provider=auto` 在当前无系统 provider 时仍可使用目录字体和字幕内嵌字体。中文、英文、日文、韩文的缺字由目录字体顺序、libass fallback 与内嵌字体共同决定;应用若需补充字体,应通过 Resource Manager/应用沙箱提供明确的开源字体目录并在产品层映射到 `sub-fonts-dir`,不修改核心、不提交商业字体。
|
||||
|
||||
Playback Lab 只验证字幕渲染和缺字表现,不把字体文件或用户凭证提交到仓库。设备侧若系统字体目录、provider 行为或 fallback 顺序不同,应记录实际字体、脚本和缺字结果。
|
||||
@@ -1,64 +0,0 @@
|
||||
# HarmonyOS Hardware Decode Research
|
||||
|
||||
## 1. 关键发现
|
||||
|
||||
截至 FFmpeg 官方 master `3acec0a1af2dda0a0838689b8b8649e7deb080a0`(2026-08-28),upstream 已包含 OpenHarmony Codec:
|
||||
|
||||
- configure:`--enable-ohcodec`
|
||||
- hw device:`AV_HWDEVICE_TYPE_OHCODEC`
|
||||
- pixel format:`AV_PIX_FMT_OHCODEC`
|
||||
- public device context:`AVOHCodecDeviceContext.native_window`
|
||||
- decoder/encoder:`h264_oh`、`hevc_oh`
|
||||
- SDK linkage:`native_media_vdec`、`native_media_venc`、`native_media_codecbase`、`native_media_core`、`native_window`
|
||||
|
||||
其 surface 路径把 `OHNativeWindow *` 放入 hw device,FFmpeg 配置 `AV_PIXEL_FORMAT_SURFACE_FORMAT`,并在 AVFrame release 时调用 `OH_VideoDecoder_RenderOutputBuffer()`。因此“不存在 FFmpeg Harmony hwcontext”已不是事实;当前缺口主要转移到 MPV 对 OHCODEC 的识别、Surface 所有权和呈现同步。
|
||||
|
||||
## 2. Codec 矩阵
|
||||
|
||||
| Codec | Harmony Native Support | FFmpeg Support | MPV Support | Surface Decode | Pixel Format | Copy | Zero Copy Feasibility | 10-bit / HDR | Known Limitation | Complexity |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|
|
||||
| H.264 | Native decoder API 存在;具体 profile/4K 由设备 capability 查询 | `h264_oh` 已在 upstream master | 无 OHCODEC 映射/backend | 已实现 | `AV_PIX_FMT_OHCODEC` / surface format | 解码器到 Surface 可避免 CPU frame;是否经过系统内部 copy 不可见 | 高,但直出播放 Surface 与 MPV shader/字幕合成冲突 | 设备查询;H.264 10-bit 通常不作为首要目标,不能猜 | FFmpeg 实现新、MPV 未接入、字幕/OSD 合成路径未解决 | 高 |
|
||||
| HEVC | Native decoder API 存在;profile/level/10-bit 待设备查询 | `hevc_oh` 已在 upstream master | 无 OHCODEC 映射/backend | 已实现 | 同上 | 同上 | 高 | Main10/HDR 必须按真机 capability + 实际流验证 | HDR metadata 传递和 Surface colorspace 未证明 | 高 |
|
||||
| AV1 | SDK API 可按 MIME 查询,不代表设备必有硬件 | 当前 OHCodec backend 未声明 `av1_oh` | 无 | FFmpeg OH 路径无 | 无 | 未定 | 未定 | 未定 | upstream FFmpeg 尚未接 OH AV1 | 很高 |
|
||||
| VP9 | SDK API可查询,不代表设备必有硬件 | 当前 OHCodec backend 未声明 `vp9_oh` | 无 | FFmpeg OH 路径无 | 无 | 未定 | 未定 | 未定 | upstream FFmpeg 尚未接 OH VP9 | 很高 |
|
||||
|
||||
## 3. MPV 缺口
|
||||
|
||||
1. `video/fmt-conversion.c` 没有 `IMGFMT_OHCODEC <-> AV_PIX_FMT_OHCODEC`。
|
||||
2. `video/decode/vd_lavc.c` 尚无 OHCODEC device/backend 选择。
|
||||
3. GPU interop driver 列表没有 Harmony/OHNativeBuffer 路径。
|
||||
4. libmpv OpenGL Render API的目标 Surface与 OHCodec 直接输出 Surface存在所有权冲突:同一个播放画面若让 decoder 直接呈现,MPV 的 shader、OSD、ASS 字幕、色彩管理无法自然叠加。
|
||||
5. FFmpeg 当前 OHCodec surface frame 在 AVFrame release 时触发呈现,呈现时钟、drop/late frame 与 MPV VO 调度需要逐帧语义验证。
|
||||
|
||||
## 4. 推荐路线
|
||||
|
||||
### Stage 1:软件解码基线
|
||||
|
||||
先以 FFmpeg software decode + libmpv GLES Render API 跑通首帧、Seek、字幕、网络和稳定性。该基线用于证明其后优化收益。
|
||||
|
||||
### Stage 2:FFmpeg OHCodec 可用性验证
|
||||
|
||||
独立验证官方 `h264_oh` / `hevc_oh`:创建 decoder、Flush/Seek、Surface destroy/recreate、4K、高码率、Main10;记录设备 capability。此阶段不修改 MPV 大量代码。
|
||||
|
||||
### Stage 3:选择合成架构
|
||||
|
||||
- 路线 3A,直接 Surface decode:最快接通、copy 少,但 MPV GPU shader/ASS/OSD 不能直接叠加。只适合验证硬解吞吐,不直接定为正式架构。
|
||||
- 路线 3B,OHNativeBuffer/GPU import:decoder 输出可导入 GLES/Vulkan,再由 MPV/libplacebo 合成。最符合最终产品,但 FFmpeg 当前 OHCodec API是否暴露可导入 buffer 尚需源码和真机证明。
|
||||
- 路线 3C,双 Surface/system overlay:视频与字幕分层,由系统合成。同步、HDR、截图和滤镜语义复杂,仅作备选。
|
||||
|
||||
正式路线优先研究 3B;在其不可行证据充分前,不宣称零拷贝。
|
||||
|
||||
## 5. Patch 边界
|
||||
|
||||
如进入实现,优先局限在:
|
||||
|
||||
- `video/fmt-conversion.c` / image format 定义
|
||||
- `video/decode/vd_lavc.c` 的 hw device 选择
|
||||
- `video/out/hwdec/hwdec_ohcodec.c` 或明确命名的 Harmony interop driver
|
||||
- `meson.build` Harmony feature gate
|
||||
|
||||
任何不支持格式明确返回 unsupported;不得以 CPU 黑帧、fake success 或注释掉检查伪装完成。
|
||||
|
||||
## 6. 当前判定
|
||||
|
||||
**不创建 Velix-FFmpeg-Harmony。** 官方 FFmpeg 已有关键 OHCodec 基础,Phase 1 应固定官方 commit 并先编译;只有真实 blocker 证明需要 patch 且无法快速 upstream 后,才建立独立 FFmpeg fork。AV1、VP9、buffer import、HDR metadata 仍为 `NEED VERIFY`。
|
||||
@@ -1,74 +0,0 @@
|
||||
# HarmonyOS Rendering Research
|
||||
|
||||
## 1. 结论
|
||||
|
||||
第一阶段推荐 **OpenGL ES + EGL + libmpv OpenGL Render API**:ArkUI XComponent 仅交付 `OHNativeWindow *`,Native 层创建 EGL window surface/context,并在 GL 线程调用 `mpv_render_context_render()` 渲染到默认 FBO,随后 `eglSwapBuffers()`。视频帧不经过 ArkTS/N-API。
|
||||
|
||||
```text
|
||||
XComponent Surface
|
||||
-> OHNativeWindow
|
||||
-> EGLSurface + GLES context(Native 渲染线程)
|
||||
-> libmpv OpenGL Render API
|
||||
-> GPU render -> eglSwapBuffers -> Display
|
||||
```
|
||||
|
||||
依据:本机 API 24 SDK 明确把 `EGLNativeWindowType` 定义为 `struct NativeWindow *`;MPV 公共 Render API 当前只公开 `MPV_RENDER_API_TYPE_OPENGL` 与软件渲染,未公开 Vulkan Render API。
|
||||
|
||||
## 2. 方案 A:OpenGL ES / EGL
|
||||
|
||||
### 调用边界
|
||||
|
||||
1. `OH_NativeXComponent_RegisterCallback()` 接收 Surface 创建/变化/销毁。
|
||||
2. `OnSurfaceCreated` 的 `void *window` 按 SDK 契约转换为 `OHNativeWindow *`。
|
||||
3. Native GL 线程执行 `eglGetDisplay`、`eglInitialize`、`eglChooseConfig`、`eglCreateWindowSurface`、`eglCreateContext`。
|
||||
4. 用 `MPV_RENDER_PARAM_API_TYPE=MPV_RENDER_API_TYPE_OPENGL` 和 `mpv_opengl_init_params` 创建 render context。
|
||||
5. update callback 只唤醒渲染线程;该线程 make-current,调用 `mpv_render_context_render()`,目标为默认 FBO 0 和当前 Surface 尺寸,再 swap。
|
||||
6. Surface changed 更新 viewport/FBO 尺寸;Surface destroyed 先停止提交帧,再释放 render context 的 surface 相关状态和 EGLSurface。
|
||||
|
||||
### 评估
|
||||
|
||||
| 维度 | 结论 |
|
||||
|---|---|
|
||||
| 实现复杂度 | 中;MPV 已有完整 OpenGL Render API,Harmony 只负责 EGL/XComponent 生命周期 |
|
||||
| MPV 支持度 | 高;公共 API 稳定,`include/mpv/render.h`、`render_gl.h` 为直接依据 |
|
||||
| HarmonyOS 支持度 | 高;API 24 提供 EGL、GLES2/3、OHNativeWindow |
|
||||
| Surface 生命周期 | 必须单线程串行化 create/change/destroy,销毁后禁止 swap |
|
||||
| Copy 次数 | 软件解码时 FFmpeg frame 上传 GPU,至少一次 CPU→GPU;无逐帧 N-API copy |
|
||||
| 4K | 渲染路径可行,性能取决于上传、shader、带宽;需 Benchmark |
|
||||
| 10-bit | 软件帧可由 MPV shader 处理;Surface 色深/输出格式待设备 EGLConfig 验证 |
|
||||
| HDR | MPV 色彩处理可复用,但 Harmony Surface 色域、transfer、HDR metadata 通路尚未证明 |
|
||||
| 风险 | EGL context 线程归属、Surface 快速重建、默认 FBO 方向、vsync/帧节奏 |
|
||||
|
||||
### MPV 修改范围
|
||||
|
||||
- Phase 1 构建 `libmpv` 时启用 `plain-gl`,无需先新增完整 `vo_harmony`。
|
||||
- Playback Lab 的 Harmony glue 独立放在后续 `playback_lab/native/`,不把 ArkTS 业务代码放进 MPV core。
|
||||
- 只有确认必须让 MPV 自管 window/context 时,才新增 `video/out/opengl/context_harmony.c` 并在 Meson 中以 `features['harmony']` 注册。
|
||||
|
||||
## 3. 方案 B:Vulkan
|
||||
|
||||
### 可行基础
|
||||
|
||||
API 24 提供 `VK_OHOS_surface`、`VkSurfaceCreateInfoOHOS`、`vkCreateSurfaceOHOS()` 与 `libvulkan.so`,可从 `OHNativeWindow *` 创建 `VkSurfaceKHR`。MPV 内部 `vo_gpu_next` / libplacebo 支持 Vulkan,但 libmpv 公共 Render API 没有 Vulkan 类型。
|
||||
|
||||
| 维度 | 结论 |
|
||||
|---|---|
|
||||
| 实现复杂度 | 高;需要新增/扩展 MPV Vulkan context 或设计受支持的嵌入路径 |
|
||||
| MPV 支持度 | 内部高、公共嵌入 API 低 |
|
||||
| HarmonyOS 支持度 | API 10+ 有 surface 扩展,设备扩展需枚举 |
|
||||
| Surface 生命周期 | 需重建 swapchain,处理 out-of-date/suboptimal、旋转与尺寸变化 |
|
||||
| Copy 次数 | 软件解码仍需上传;未来 native buffer/Vulkan interop 有降 copy 潜力 |
|
||||
| 4K | 理论适合,未实测不能优于 GLES |
|
||||
| 10-bit/HDR | Vulkan format/colorspace 路径潜力更强,但 Harmony 设备与系统合成支持待证 |
|
||||
| 风险 | libplacebo/Vulkan 版本、OHOS surface 接入、swapchain、同步/fence、驱动差异 |
|
||||
|
||||
## 4. 禁止路径
|
||||
|
||||
`MPV -> CPU frame -> Native Buffer -> ArkTS -> ArkUI Image` 不进入正式架构。它会增加逐帧跨 N-API、CPU copy、GC/调度与背压风险,也无法作为 4K 主路径。
|
||||
|
||||
## 5. Phase 门禁
|
||||
|
||||
- Phase 1:只证明 `libmpv` arm64 编译,OpenGL Render API 符号存在。
|
||||
- Phase 2:Playback Lab 证明 XComponent→EGL→首帧;记录 Surface 重建和旋转。
|
||||
- Phase 3:软件解码基线后再接 OHCodec;分别测 CPU upload 与 surface decode。
|
||||
- Vulkan 只有在 GLES 基线与瓶颈证据齐备后启动,不以“理论更快”替代 Benchmark。
|
||||
@@ -1,7 +0,0 @@
|
||||
# OHCodec HDR pipeline notes
|
||||
|
||||
本阶段只保留 metadata 研究,不声明 HDR 完成。
|
||||
|
||||
FFmpeg upstream OHCodec stream-change 路径会把存在的 matrix、primaries、transfer、range 和 SAR 元数据复制到 `AVCodecContext`;MPV 现有 color-management pipeline 继续消费这些 metadata。设备是否输出 10-bit、支持 Main10 或 HDR surface,必须由 API24 capability 和真实设备 frame metadata 证明。
|
||||
|
||||
当前实现不添加 HDR transfer、tone mapping、Dolby Vision 或 10-bit surface 特判。Playback Lab 的 capability/diagnostics 只显示真实查询结果;没有设备数据时显示 `DEVICE TEST REQUIRED`,不得显示 `HDR YES`。
|
||||
@@ -1,79 +0,0 @@
|
||||
# HarmonyOS First Native Build Report
|
||||
|
||||
## Result
|
||||
|
||||
Phase 1 已在 DevEco Studio OpenHarmony SDK 6.1.1.125 / API 24 下生成真实 arm64 `libmpv`。本报告只证明编译、链接和静态检查,不声明真机运行语义已验证。
|
||||
|
||||
| 项目 | 结果 |
|
||||
|---|---|
|
||||
| Origin | `https://git.leee.xin/leeexin/Velix-MPV-Core.git` |
|
||||
| origin/harmony-port | 以本次 Phase 1 提交推送后的 commit 为准 |
|
||||
| MPV | `182fa6ca49f455cadb884858f386e2f00540aeb7` / 0.41.0-UNKNOWN |
|
||||
| FFmpeg | `3acec0a1af2dda0a0838689b8b8649e7deb080a0` |
|
||||
| libmpv | `build/ohos-arm64/prefix/lib/libmpv.so.2.5.0` |
|
||||
| Size | 34,314,184 bytes |
|
||||
| SHA-256 | `80e4c6fda86d9822543615a97045fff3641e9125b23a4f736fb8511fe5a47790` |
|
||||
| Architecture / ABI | ELF64, little-endian, AArch64, System V ABI, shared object, SONAME `libmpv.so.2` |
|
||||
| Toolchain | OHOS Clang/LLD 15.0.4, target `aarch64-linux-ohos`, musl sysroot |
|
||||
| MPV / build files | 7:`ao_harmony.c/.h`、AO 注册、Meson feature、OHOS build script、依赖 allowlist;第三方依赖源码修改 0 |
|
||||
| Build issues | 4,全部关闭 |
|
||||
|
||||
## Features
|
||||
|
||||
MPV enabled:`clone`、`ffmpeg`、`gl`、`glibc-thread-name`、`glob`、`glob-posix`、`gpl`、`harmony-audio`、`libass`、`libdl`、`libplacebo`、`linux-fstatfs`、`memrchr`、`ohos`、`posix`、`posix-shm`、`ppoll`、`pthread-condattr-setclock`、`vector`、`vt.h`、`zlib`、`libmpv shared`、`plain-gl`。
|
||||
|
||||
FFmpeg enabled:软件解码、demux、network、HTTP/HTTPS/TCP/TLS、OpenSSL 3.6.4、SDK zlib、OHCodec H.264/HEVC decoder/encoder。FFmpeg GPL/version3/nonfree 均为 0。
|
||||
|
||||
Disabled:mpv CLI、tests、fuzzers、Lua/JavaScript、libcurl、桌面音视频后端、X11、Wayland、DRM/GBM、Cocoa、Windows backend、Android-specific backend、Vulkan、VAAPI、VDPAU、CUDA。libplacebo 的 Vulkan/OpenGL 自有 backend 关闭;MPV 自身 OpenGL Render API 保留。
|
||||
|
||||
## Verification
|
||||
|
||||
- 最小 C/C++ 探针均为 OHOS AArch64 ELF;C++ 探针依赖 SDK `libc++_shared.so`。
|
||||
- prefix 内 13 个静态库的全部可见 archive object 均通过 AArch64 ELF 检查。
|
||||
- `libmpv.so.2.5.0` 动态依赖为 `libc.so`、`libz.so`、`libnative_media_vdec.so`、`libnative_media_venc.so`、`libnative_media_codecbase.so`、`libnative_media_core.so`、`libnative_window.so`、`libohaudio.so`;均来自 HarmonyOS SDK allowlist。
|
||||
- target metadata 未发现 Homebrew、`/usr/local`、`.dylib`、Apple framework 或 Mach-O 污染。
|
||||
- 已验证 `mpv_create`、`mpv_initialize`、`mpv_command`、`mpv_set_property`、`mpv_get_property`、`mpv_render_context_create`、`mpv_render_context_render`、`mpv_render_context_set_update_callback`、`mpv_render_context_free`。
|
||||
- `scripts/build-all-ohos.sh` 已完成本次 Phase 3 全链路构建与最终校验(`verified_archives=13`)。
|
||||
|
||||
## Warnings
|
||||
|
||||
剩余 18 条构建 warning:FFmpeg 5 条 upstream fallthrough/unused-function;FriBidi 5 条 enum-conversion;HarfBuzz 1 条仅开发者需要 Ragel;libass/MPV 4 条非阻塞 CMake compiler-state 探测;libplacebo 3 条无 graphics backend/name-prefix 提示。均不影响当前 target 产物,未通过关闭警告掩盖问题。
|
||||
|
||||
## Dependency Graph
|
||||
|
||||
实际依赖图见 `DOCS/PHASE1_DEPENDENCY_MATRIX.md`。所有第三方库均静态进入 `libmpv`,SDK zlib、OHCodec 与 libc 保持系统动态依赖。
|
||||
|
||||
## License
|
||||
|
||||
仓库与 `libmpv` 当前按 MPV GPL-2.0-or-later 路线管理。FFmpeg 为 LGPL 配置且未启用 GPL/nonfree;OpenSSL 为 Apache-2.0;静态 LGPL 组件仍需在正式发布时履行可重新链接、源码与 notices 义务。本文件不是最终发行 notice。
|
||||
|
||||
## Phase 2 Risks
|
||||
|
||||
1. POSIX、DNS、HTTP/HTTPS 与动态库加载目前仅 compile/link verified,尚未真机 runtime verified。
|
||||
2. XComponent / OHNativeWindow 生命周期、线程归属、窗口销毁与 EGL context loss 尚未验证。
|
||||
3. MPV plain-gl 与 HarmonyOS EGL/GLES 的实际格式、扩展、同步和首帧路径尚未联调。
|
||||
4. FFmpeg OHCodec 已编译,但 MPV hwdec 选择、surface/output buffer 生命周期及零拷贝均未验证。
|
||||
5. OpenSSL CA 路径与 HAP 内依赖打包、SDK系统库版本兼容仍需真机验证。
|
||||
|
||||
## Phase 2 Entry Condition
|
||||
|
||||
已具备 XComponent + OHNativeWindow + EGL + libmpv OpenGL Render API 真机首帧测试的编译侧条件:SDK API 可用、libmpv 可链接、OpenGL Render API symbols 齐全。尚不代表首帧已经成功;Phase 2 必须在真机建立窗口和 EGL context 后验证。
|
||||
|
||||
## FFmpeg-Harmony export prefix
|
||||
|
||||
Phase 4.5 的 FFmpeg fork 独立维护于
|
||||
`https://git.leee.xin/leeexin/Velix-FFmpeg-Harmony.git`,分支
|
||||
`harmony-ohcodec-export`,当前分支 tip `f3a036c695`(跨 origin 重定向丢弃敏感凭证;代码修正 commit
|
||||
`aacbe7d578`)。MPV 不包含 FFmpeg
|
||||
源码,也不读取其私有头文件;需要切换时执行:
|
||||
|
||||
```sh
|
||||
./scripts/build-mpv-ohos-ffmpeg-harmony.sh
|
||||
```
|
||||
|
||||
脚本默认消费 `../Velix-FFmpeg-Harmony/build/ohos-arm64/prefix`,也可用
|
||||
`FFMPEG_PREFIX=/path/to/prefix MPV_BUILD_ROOT=/path/to/mpv-build MPV_PREFIX=/path/to/mpv-prefix` 覆盖。切换脚本默认把 MPV 安装到
|
||||
`build/ohos-arm64/prefix-mpv-ffmpeg-harmony`,避免覆盖默认 prefix。默认
|
||||
`build-mpv-ohos.sh` 与 `build-mpv-ohos-software.sh` 的原有前缀和
|
||||
`harmony-ohcodec-gl=disabled` 行为不变。本次切换构建已通过 AArch64 ELF、符号
|
||||
和动态依赖校验,但没有进入 GPU mapper 或设备硬解验证。
|
||||
@@ -1,20 +0,0 @@
|
||||
# MPV 与 OHCodec 缺口分析
|
||||
|
||||
扫描基线:MPV 当前 `harmony-port` 工作树,FFmpeg OHCodec 头文件来自锁定 commit `3acec0a1af2dda0a0838689b8b8649e7deb080a0`。
|
||||
|
||||
| MPV location | 当前行为 | OHCodec requirement | 本阶段改动/结论 | 风险与 upstreamability |
|
||||
|---|---|---|---|---|
|
||||
| `video/img_format.h` / `video/fmt-conversion.c` | 只有通用 hardware format,没有 OHCodec 专用 ID。 | `AV_PIX_FMT_OHCODEC` 必须成为 MPV hardware image format。 | 新增 `IMGFMT_OHCODEC ↔ AV_PIX_FMT_OHCODEC` 单一映射。 | 纯 MPV 架构改动,可 upstream;依赖 FFmpeg enum。 |
|
||||
| `video/decode/vd_lavc.c:add_all_hwdec_methods()` | 动态枚举 FFmpeg HW config,并使用 `av_hwdevice_get_type_name()` 生成 method。 | 能识别 `AV_HWDEVICE_TYPE_OHCODEC`、`h264_oh`、`hevc_oh`。 | 不改 decoder core;FFmpeg config 会自然生成 `hwdec=ohcodec`,且仅 H.264/HEVC 由 adapter 放行。 | upstreamable;真实 capability 仍需设备验证。 |
|
||||
| `video/hwdec.c:hwcontext_fns[]` | 未注册 OHCodec copy-device callback;未知类型会尝试空 device。 | copy path 必须不能伪造 null-surface 成功。 | 注册 `hwcontext_fns_ohcodec`,明确拒绝无独占窗口的 copy path,并触发 software fallback。 | 纯 MPV 保护逻辑。 |
|
||||
| `video/out/gpu/hwdec.c` | 只注册已有 GPU interop/overlay drivers。 | Direct Surface 需要独立 backend,不能复用 MediaCodec/DRM。 | 注册 `ohcodec-direct-surface-experimental`,仅在 host 提供 `ohos_direct_surface` native resource 时创建设备。 | 当前 Playback Lab 不提供该 resource,故默认不会抢占 EGL Surface。 |
|
||||
| `video/out/gpu/video.c` / `gpu_next` | mapper 或 overlay 二选一;overlay 会绕过视频 GL 合成但保留 OSD。 | Direct Surface 不能与同一 EGL window 双重呈现。 | OHCodec 只使用 overlay probe;没有独占窗口时 init 失败。 | Direct Surface 不是最终 ASS/shader/color-management 产品路径。 |
|
||||
| `video/mp_image.c:mp_image_from_av_frame()` | 复制 AVFrame buffers/data;无 OHCodec 特判。 | frame 需要保留 `buf[0]` 生命周期和硬件格式。 | 现有 generic path 已满足:`data[3]` 作为 opaque plane,`buf[0]` 持有 release。 | 不能把 opaque plane 当 CPU pixels 或 fd。 |
|
||||
| `video/out/gpu/ra.h` native resources | 可由 host 注入平台资源。 | Surface ownership 需要明确边界。 | 约定 `ohos_direct_surface` 为独占、已由 host 管理的 `OHNativeWindow*`。 | 当前没有 host 注入,设备验证前不能宣称 direct active。 |
|
||||
| Diagnostics / Playback Lab | 原来只显示 software audio/video 状态。 | 必须显示 requested/actual decoder、hw state、fallback/capability。 | 新增导出统计 API、日志识别和 Playback Lab 面板字段。 | actual decoder 在设备上需以 FFmpeg 日志和真实 frame 验证。 |
|
||||
|
||||
## 选择路径
|
||||
|
||||
`hwdec=ohcodec` → FFmpeg OHCodec method → MPV 请求 `IMGFMT_OHCODEC` → GPU backend 请求 OHCodec device → adapter 查询 capability → 检查独占 Surface → 创建 `AVHWDeviceContext` → Direct Surface overlay。
|
||||
|
||||
任何一步失败均返回负值并保留 software decoder。GPU interop 不走猜测性的 opaque-pointer reinterpretation。
|
||||
@@ -1,13 +0,0 @@
|
||||
# 网络播放
|
||||
|
||||
网络播放复用 mpv/FFmpeg 的单一网络栈,不在产品中创建第二 HTTP client。支持范围是 mpv 已提供的 HTTP、HTTPS、HLS、重定向、Range seek、chunked 和大范围 seek 能力。
|
||||
|
||||
每次 load 先清空 http-header-fields,再设置本次请求的 headers;Cookie 作为本次请求的 Cookie header 发送,未启用 mpv 持久化 cookie 文件。请求可设置 user-agent、referrer、network-timeout、语言偏好和轨道选择。
|
||||
|
||||
网络诊断只报告实际可取得的 mpv 属性:协议、host、networkState、cache duration/bytes、demuxer、container、当前 bitrate,以及从实际日志识别到的 HTTP status/redirect count;`rangeSupported` 仅在观察到 206 响应时为 1,`seekResult` 记录最近一次 seek 的 `ok` 或脱敏错误。没有对应属性或日志时返回 -1/0/空值,不做推断。
|
||||
|
||||
HTTP MP4 已在 Playback Lab 模拟器通过宿主受控 Range server 验证:请求日志出现 `bytes=0-`、后续大范围 byte range,播放结束且无核心错误。跨 origin 重定向的敏感头过滤由 FFmpeg-Harmony 固定分支提供,实际 HTTPS/HLS/鉴权资源仍需受控网络源继续验收。
|
||||
|
||||
HLS Master/Variant 的当前媒体分辨率来自 video-params/width/height,码率来自 demux-bitrate;当前 MPV 没有独立稳定的“variant 名称”属性,因此不新增伪造字段。
|
||||
|
||||
DNS、TCP connect、connection reset、timeout 和 FFmpeg open failure 统一归入 NETWORK,并保留脱敏原始消息;TLS handshake/certificate 归入 TLS,HTTP status 归入 HTTP,demux/decoder 错误不伪装成网络错误。
|
||||
@@ -1,15 +0,0 @@
|
||||
# 网络安全
|
||||
|
||||
## Header 与会话隔离
|
||||
|
||||
每次 load 都覆盖 http-header-fields,不共享上一个 session 的 header、Cookie 或 URL。禁止把认证信息写入仓库、默认日志或诊断快照。Playback Lab 输入框可以编辑 header,但诊断默认只显示字段名和掩码值。
|
||||
|
||||
## 脱敏规则
|
||||
|
||||
Authorization、Proxy-Authorization、Cookie、X-Api-Key、X-Emby-Token、X-Auth-Token、X-Access-Token 及 token/api-key/signature 等认证头,以及 URL 中的 token、access_token、auth、key、api_key、apikey、auth_token、signature、x-amz-signature、sig、expires 参数在错误文本和日志中替换为 [REDACTED]。原始 mpv 日志不得直接写入 OH 日志。
|
||||
|
||||
## TLS、重定向与凭证
|
||||
|
||||
默认保持 tls-verify=yes。mpv 网络后端负责 TLS、重定向、Range 和 HLS;本层不复制 HTTP 行为。固定的 FFmpeg-Harmony 分支 `f3a036c695` 已在 `libavformat/http.c` 实现跨 origin(协议/host/port 任一变化)重定向时丢弃自定义 Authorization/Cookie/Token/API-key/Referer 等敏感头及 cookie 状态,同源重定向仍保留请求头;因此不会把凭证无条件转发到不同 host。Referer、User-Agent、header 仅属于当前加载请求。
|
||||
|
||||
实现依据:mpv 官方手册的 user-agent、referrer、cookies、http-header-fields、network-timeout、HLS 与 sub-add 选项说明。
|
||||
@@ -1,34 +0,0 @@
|
||||
# OHCodec GPU interop 设计与当前 blocker
|
||||
|
||||
## 目标
|
||||
|
||||
将 OHCodec hardware frame 交给 MPV OpenGL composition,同时保留 ASS、OSD、shader 和 color management。该路径必须是显式实验开关 `harmony-ohcodec-gl`,不能成为默认 hwdec。
|
||||
|
||||
## API24 合法链路(仅设计验证)
|
||||
|
||||
SDK 头文件提供:
|
||||
|
||||
1. `OH_AVBuffer_GetNativeBuffer(OH_AVBuffer*)`,返回一个需要 `OH_NativeBuffer_Unreference()` 的 `OH_NativeBuffer*`。
|
||||
2. `OH_NativeWindow_CreateNativeWindowBufferFromNativeBuffer()`,把 NativeBuffer 转成 `OHNativeWindowBuffer*`,并要求随后销毁 wrapper。
|
||||
3. `EGL_OHOS_image_native_buffer` / `EGL_NATIVE_BUFFER_OHOS`、`eglCreateImageKHR()` 和 `glEGLImageTargetTexture2DOES()`。
|
||||
|
||||
这证明 API 类型是 HarmonyOS 原生接口,不应使用 Android `AHardwareBuffer`、fd 猜测或指针重解释。未来 mapper 的资源生命周期应为:
|
||||
|
||||
`OH_AVBuffer` frame ref → `OH_NativeBuffer_Get/Reference` → `OHNativeWindowBuffer` wrapper → EGLImage → external texture → unmap 时反向销毁。
|
||||
|
||||
## OHCODEC-BLOCKER-001
|
||||
|
||||
当前 upstream `libavcodec/ohdec.c` 只有两种输出:
|
||||
|
||||
- 有 OHCodec device:强制 `output_to_window=true`、配置 `AV_PIXEL_FORMAT_SURFACE_FORMAT`、`SetSurface(window)`;
|
||||
- 无 device:CPU NV12 buffer,复制到 software frame。
|
||||
|
||||
hardware frame 的 `OH_AVBuffer*` 只存在于带 Surface 的分支,且自定义 `AVBuffer` release 会调用 `OH_VideoDecoder_RenderOutputBuffer()`。因此 MPV 不能在不修改 FFmpeg 的前提下请求“NativeBuffer hardware output but no decoder Surface present”模式。若 mapper 同时导入该 buffer 到 EGL,decoder release 仍可能向另一 Surface present,导致两个 owner、未定义 fence/queue ownership 和 seek/recreate race。
|
||||
|
||||
结论:本阶段不提交伪 interop mapper,不调用 `eglFinish/glFinish` 充当同步,不宣称零拷贝/GPU interop/HDR 完成。`harmony-ohcodec-gl` 作为 disabled-by-default feature 保留 API 探针入口;启用它前必须先解决该 upstream contract blocker,并补齐 output buffer、fence、crop/stride 和 surface ownership 的真实设备验证。
|
||||
|
||||
## Direct Surface ownership
|
||||
|
||||
`ohos_direct_surface` 是 adapter 专用 native resource。只有 host 明确注入一个不等于 Playback Lab EGL window 的独占窗口时,`ohcodec-direct-surface-experimental` 才会取得引用并创建设备;当前 Playback Lab 不注入此 resource,所以 decoder 不会和 EGL/libmpv 抢同一 Surface。
|
||||
|
||||
Surface destroy/recreate 必须停止 render/decoder、等待所有 AVFrame release、递增 generation,再以新窗口重新创建 OHCodec device。当前只完成 MPV adapter 侧的 ownership guard,实体设备上的 fence、present count、surface recreate 仍为 `DEVICE TEST REQUIRED`。
|
||||
@@ -1,42 +0,0 @@
|
||||
# MPV OHCodec 集成说明
|
||||
|
||||
## 已实现路径
|
||||
|
||||
`hwdec=ohcodec` 由 MPV/FFmpeg 的动态 hardware-decoder 枚举进入独立
|
||||
`AV_HWDEVICE_TYPE_OHCODEC` backend。`IMGFMT_OHCODEC` 与
|
||||
`AV_PIX_FMT_OHCODEC` 使用单一映射。当前 adapter 只允许 H.264 和 HEVC,先
|
||||
查询 API 24 OHCodec hardware capability,再检查 host 注入的独占
|
||||
`ohos_direct_surface`,最后创建带 `OHNativeWindow*` 的 FFmpeg hwdevice。
|
||||
|
||||
Direct Surface backend 的名称是
|
||||
`ohcodec-direct-surface-experimental`。它只负责证明 device/decoder/surface
|
||||
plumbing,不与 Playback Lab 的 EGL window 共享呈现权;没有独占窗口时明确失败,
|
||||
MPV 保留 software decoder fallback。
|
||||
|
||||
## 状态与回退
|
||||
|
||||
适配器记录 `HWDEC_DISABLED`、`HWDEC_REQUESTED`、`HWDEC_CAPABILITY_CHECK`、
|
||||
`HWDEC_DEVICE_CREATED`、`HWDEC_DECODER_CREATED`、`HWDEC_DIRECT_SURFACE`、
|
||||
`HWDEC_GPU_INTEROP`、`HWDEC_ACTIVE`、`HWDEC_FALLBACK`、`HWDEC_ERROR`。
|
||||
Playback Lab 通过 libmpv 诊断 API 与属性显示 requested/actual decoder、active
|
||||
状态、backend、capability、fallback reason 及 hardware/software frame 计数。
|
||||
|
||||
capability 查询失败、codec/profile/level 不支持、surface 不可用、device/decoder
|
||||
创建失败或后续 interop 失败都必须返回失败并回到 software path;不把空 device、
|
||||
opaque pointer 或 CPU readback 当成成功的硬件帧。
|
||||
|
||||
## Surface 生命周期约束
|
||||
|
||||
`ohos_direct_surface` 的引用由 adapter 持有,host 负责提供一个不等于
|
||||
Playback Lab EGL window 的独占窗口。Surface 销毁或重建时,host 必须先停止
|
||||
decoder/render、等待 AVFrame release,再销毁旧 device 并用新窗口重建;当前代
|
||||
码只完成 ownership guard,generation/fence/present 的实体设备验证仍待做。
|
||||
|
||||
## GPU interop 边界
|
||||
|
||||
`harmony-ohcodec-gl` 默认关闭,仅编译 API probe:API24 可探测
|
||||
`OH_AVBuffer_GetNativeBuffer`、NativeWindow wrapper、EGL native-buffer image
|
||||
和 GLES external texture 扩展。但 FFmpeg upstream 的硬件分支是 surface-first,
|
||||
没有“不 present 到 decoder Surface、直接导出可导入 NativeBuffer”的契约;见
|
||||
`DOCS/OHCODEC_GPU_INTEROP_DESIGN.md` 中的 `OHCODEC-BLOCKER-001`。因此当前不
|
||||
提交 mapper、不宣称 zero-copy,也不宣称 HDR。
|
||||
@@ -1,28 +0,0 @@
|
||||
# FFmpeg OHCodec upstream analysis
|
||||
|
||||
基线:FFmpeg `3acec0a1af2dda0a0838689b8b8649e7deb080a0`。本阶段没有修改 FFmpeg。
|
||||
|
||||
## 已核对的源码事实
|
||||
|
||||
| 位置 | 事实 | 对 MPV 的结论 |
|
||||
|---|---|---|
|
||||
| `libavutil/hwcontext.h` | 注册 `AV_HWDEVICE_TYPE_OHCODEC`。 | 设备类型可作为独立 MPV hwdec method,不能伪装成 MediaCodec/VAAPI。 |
|
||||
| `libavutil/pixfmt.h` | 注册 `AV_PIX_FMT_OHCODEC`,并标记为 OpenHarmony hardware decoding。 | MPV 需要自己的 `IMGFMT_OHCODEC` 映射。 |
|
||||
| `libavutil/hwcontext_oh.h` | `AVOHCodecDeviceContext` 只有 `void *native_window`,注释为 `OHNativeWindow`。 | FFmpeg 公共设备上下文只承载 Surface 指针,没有 device handle、fence 或 NativeBuffer export 字段。 |
|
||||
| `libavutil/hwcontext_oh.c:27-45` | `oh_device_create()` 只拒绝非空 device string;初始化不创建窗口、不取得引用,也不做 capability 检查。 | MPV 不能把 `av_hwdevice_ctx_create(..., NULL, ...)` 当成可呈现设备;Surface ownership 必须在 MPV/host adapter 中完成。 |
|
||||
| `libavcodec/ohdec.c:150-197` | OHCodec device 被发现后读取 `native_window`,设置 `output_to_window=true`,使用 `AV_PIXEL_FORMAT_SURFACE_FORMAT`,并调用 `OH_VideoDecoder_SetSurface(window)`。 | upstream 的硬件输出是 Direct Surface 语义。空窗口不是合法的 GPU interop 设备。 |
|
||||
| `libavcodec/ohdec.c:219-289` | stream change 读取 width/height/stride/slice height/pixel format;Surface 输出时设置 `avctx->pix_fmt=AV_PIX_FMT_OHCODEC`,并复制颜色元数据与 SAR。 | 尺寸/stride/pixel format 可进入 MPV diagnostics;不能由 enum 推导设备能力或 HDR 支持。 |
|
||||
| `libavcodec/ohdec.c:432-451` | AVFrame buffer release 时读取 buffer attr;非 discard 调 `OH_VideoDecoder_RenderOutputBuffer()`,否则 `FreeOutputBuffer()`;随后释放 decoder ref。 | AVFrame 生命周期会触发 Surface present/release。Surface 的 decoder ownership 必须持续到最后一个 frame 引用释放。 |
|
||||
| `libavcodec/ohdec.c:453-486` | hardware frame 的 `format=AV_PIX_FMT_OHCODEC`;`buf[0]` 持有 `OH_AVBuffer*` 的自定义 release;`data[3]=buf[0]->data`。 | 当前 FFmpeg 没有 `AVHWFramesContext`、transfer/map/export 回调。`data[3]` 是 upstream 当前内部布局,不应被重解释成 fd/Android hardware buffer。 |
|
||||
| `libavcodec/ohdec.c:489-532` | 非 Surface 分支才取得 CPU 地址并复制到 software frame。 | 当前 upstream 没有“NativeBuffer output、但不直接 present Surface”的公共 decoder 配置路径。 |
|
||||
| `libavcodec/ohdec.c` decoder close/flush | decoder 可能因硬件 frame 引用延迟释放;flush 会清空队列并重启 decoder。 | seek/flush 必须让 MPV 丢弃旧 generation 的 frame;Surface recreate 需要完整 decoder recreate。 |
|
||||
|
||||
## 关键问题结论
|
||||
|
||||
1. `AV_PIX_FMT_OHCODEC` frame 确实携带 `OH_AVBuffer*` 指针(`data[3]`),但 upstream 没有把它作为稳定的 MPV interop contract 暴露,也没有 non-surface output 模式。
|
||||
2. API24 SDK 的 `OH_AVBuffer_GetNativeBuffer()` 可以合法取得 `OH_NativeBuffer*`,但要导入 EGL 还需要转换为 `OHNativeWindowBuffer*`;FFmpeg 当前仍会在 frame release 时调用 `RenderOutputBuffer`,因此不能安全地同时让 decoder Surface 和 libmpv EGL surface 认为自己拥有呈现权。
|
||||
3. 因此本阶段在 MPV adapter 层实现了独立的 `ohcodec-direct-surface-experimental` 探针;GPU interop 保留 feature gate 与设计文档,明确记录 upstream blocker,不修改 FFmpeg。
|
||||
|
||||
## 变更边界
|
||||
|
||||
本仓库只新增 MPV image-format mapping、OHCodec hwdevice/Surface adapter、capability/fallback diagnostics 和 Playback Lab diagnostics。没有复制或修改 FFmpeg 源码。
|
||||
@@ -0,0 +1,160 @@
|
||||
1. Input layer, supported devices, methods:
|
||||
- plain file, with seeking
|
||||
- STDIN, without seeking backward
|
||||
- network streaming (currently plain wget-like HTTP and MMS (.asx))
|
||||
- VCD (Video CD) track, by direct CDROM device access (not requires mounting disc)
|
||||
- DVD titles using .IFO structure, by direct DVD device access (not requires mounting disc)
|
||||
- DVD titles using menu navigation (experimental/alpha, not yet finished!!!)
|
||||
- CDDA - raw audio from audio CD-ROM discs (using cdparanoia libs)
|
||||
- RTP streaming (mpeg-ps over multicast only)
|
||||
- LIVE555 streaming - support SDP/RTSP (using the LIVE555 libs)
|
||||
- SMB - file access over samba (experimental)
|
||||
|
||||
2. Demuxer/parser layer, supported file/media formats:
|
||||
|
||||
- MPEG streams (ES,PES,PS. no TS support yet)
|
||||
note: mpeg demuxer silently ignore non-mpeg content, and find mpeg packets
|
||||
in arbitrary streams. it means you can play directly VCD images (for example
|
||||
CDRwin's .BIN files) without extracting mpeg files first (with tools like vcdgear)
|
||||
It accepts all PES variants, including files created by VDR.
|
||||
Note: VOB (video object) is simple mpeg stream, but it usually has 01BD
|
||||
packets which may contain subtitles and non-mpeg audio. Usually found on DVD discs.
|
||||
|
||||
Headers: mpeg streams has no global header. each frame sequence (also called GOP,
|
||||
group of pictures) contains an sequence header, it describes that block.
|
||||
In normal mpeg 1/2 content there are groups of 12-15 frames (24/30 fps).
|
||||
It means you can freely seek in mpeg streams, and even can cut it to
|
||||
small parts with standard file tools (dd, cut) without destroying it.
|
||||
|
||||
Codecs: video is always mpeg video (mpeg1, mpeg2 or mpeg4).
|
||||
audio is usually mpeg audio (any layer allowed, but it's layer 2 in most files)
|
||||
but 01BD packets may contain AC3, DTS or LPCM too.
|
||||
|
||||
FPS: mpeg2 content allows variable framerate, in form of delayed frames.
|
||||
It's mostly used for playback 24fps content at 29.97/30 fps (NTSC) rate.
|
||||
(so called Telecine or 3:2 pulldown effect)
|
||||
It means you see 30 frames per second, but there are only 24 different
|
||||
pictures and some of them are shown longer to fill 30 frame time.
|
||||
If you encode such files with mencoder, using -ofps 24 or -ofps 23.976
|
||||
is recommended.
|
||||
|
||||
- AVI streams.
|
||||
Two kind of RIFF AVI files exists:
|
||||
1. interleaved: audio and video content is interleaved. it's faster and
|
||||
requires only 1 reading thread, so it's recommended (and mostly used).
|
||||
2. non-interleaved: audio and video aren't interleaved, i mean first come
|
||||
whole video followed by whole audio. it requires 2 reading process or
|
||||
1 reading with lots of seeking. very bad for network or cdrom.
|
||||
3. badly interleaved streams: mplayer detects interleaving at startup and
|
||||
enables -ni option if it finds non-interleaved content. but sometimes
|
||||
the stream seems to be interleaved, but with bad sync so it should be
|
||||
played as non-interleaved otherwise you get a-v desync or buffer overflow.
|
||||
|
||||
MPlayer supports 2 kind of timing for AVI files:
|
||||
- bps-based: it is based on bitrate/samplerate of video/audio stream.
|
||||
this method is used by most players, including avifile and wmp.
|
||||
files with broken headers, and files created with VBR audio but not
|
||||
vbr-compliant encoder will result a-v desync with this method.
|
||||
(mostly at seeking).
|
||||
- interleaving-based: note: it can't be used togethwer with -ni
|
||||
it doesn't use bitrate stuff of header, it uses the relative position
|
||||
of interleaved audio and video chunks. makes some badly encoded file
|
||||
with vbr audio playable.
|
||||
|
||||
Headers: AVI files has a mandatory header at the begin of the file,
|
||||
describing video parameters (resolution, fps) and codecs. Optionally
|
||||
they have an INDEX block at the end of the file. It's optional, but
|
||||
most files has such block, because it's REQUIRED for seeking.
|
||||
Btw usually it can be rebuilt from file content, mplayer does it with
|
||||
the -idx switch. MPlayer can recreate broken index blocks using -forceidx.
|
||||
As AVI files needs index for random access, broken files with no index
|
||||
are usually unplayable.
|
||||
Of course, cutting/joining AVI files needs special programs.
|
||||
|
||||
Codecs: any audio and video codecs allowed, but I note that VBR audio is
|
||||
not well supported by most players. The file format makes it possible to
|
||||
use VBR audio, but most players expect CBR audio and fails with VBR,
|
||||
as VBR is unusual, and Microsoft's AVI specs only describe CBR audio.
|
||||
I also note, that most AVI encoders/multiplexers create bad files if
|
||||
using VBR audio. only 2 exception (known by me): NaNDub and MEncoder.
|
||||
|
||||
FPS: only constant framerate allowed, but it's possible to skip frames.
|
||||
|
||||
- ASF streams:
|
||||
ASF (active streaming format) comes from Microsoft. they developed two
|
||||
variant of ASF, v1.0 and v2.0. v1.0 is used by their media tools (wmp and
|
||||
wme) and v2.0 is published and patented :). of course, they differ,
|
||||
no compatibility at all. (it's just a legality game)
|
||||
MPlayer supports only v1.0, as nobody ever seen v2.0 files :)
|
||||
Note, that .ASF files are nowdays come with extension .WMA or .WMV.
|
||||
UPDATE: MS recently released the ASF v1.0 specs too, but it has some
|
||||
restrictions making it illegal to read by us :)
|
||||
|
||||
Headers: Stream headers (codecs parameters) can be everywhere (in theory),
|
||||
but all files i've seen had it at the beginning of the file.
|
||||
Asf uses fixed packet size, so it is seekable without any INDEX block,
|
||||
and broken files are playable well.
|
||||
|
||||
Codecs: video is mostly microsoft's mpeg4 variants: MP42, MP43 (aka DivX),
|
||||
WMV1 and WMV2. but any codecs allowed.
|
||||
audio is usually wma or voxware, sometimes mp3, but any codecs allowed.
|
||||
|
||||
FPS: no fixed fps, every video frame has an exact timestamp instead.
|
||||
I've got stream with up to 3 sec frame display times.
|
||||
|
||||
- QuickTime / MOV files:
|
||||
They come from Mac users, usually with .mov or .qt extension, but as
|
||||
MPEG Group chose quicktime as recommended file format for MPEG4,
|
||||
sometimes you meet quicktime files with .mpg or .mp4 extension.
|
||||
|
||||
At first look, it's a mixture of ASF and AVI.
|
||||
It requires INDEX block for random access and seeking, and even for
|
||||
playback, like AVI, but uses timestamps instead of constant framerate
|
||||
and has more flexible stream options (including network stuff) like ASF.
|
||||
|
||||
Headers: header can be placed at the beginning or at the end of file.
|
||||
About half of my files have it at the beginning, others have it at the end.
|
||||
Broken files are only playable if they have header at the beginning!
|
||||
|
||||
Codecs: any codecs allowed, both CBR and VBR.
|
||||
Note: most new mov files use Sorenson video and QDesign Music audio,
|
||||
they are patented, closed, secret, (TM)-ed etc formats, only Apple's
|
||||
quicktime player is able to playback these files (on win/mac only).
|
||||
|
||||
- VIVO files:
|
||||
They are funny streams. They have a human-readable ascii header at
|
||||
the beginning, followed by interleaved audio and video chunks.
|
||||
It has no index block, has no fixed packetsize or sync bytes, and most
|
||||
files even has no keyframes, so forget seeking!
|
||||
Video is standard h.263 (in vivo/2.0 files it's modified, non-standard
|
||||
h.263), audio is either standard g.723 or Vivo Siren codec.
|
||||
|
||||
Note, that microsoft licensed vivo stuff, and included in their netshow
|
||||
v2.0 program, so there are VfW/ACM codecs for vivo video and audio.
|
||||
|
||||
- RealMedia files:
|
||||
A mixture of AVI and ASF features. It has mandatory headers at the
|
||||
beginning and an optional INDEX (missing in most files).
|
||||
The file is constructed of variable size chunks, with small header
|
||||
telling the stream ID, timestamp, flags (keyframe...) and size.
|
||||
But it has some features found in ASF files:
|
||||
The video is actually double-muxed, the video chunks are really
|
||||
appended fragments of the video frame. RV30+ supports B frames, so
|
||||
you have to parse some bits of the first fragment to get the real PTS.
|
||||
The audio frames are fixed size (CBR) but using the same scrambling
|
||||
(out-of-order interleaving) as in the ASF files.
|
||||
|
||||
Codecs: Audio is either COOK(er), SIPR(o), ATRAC3 or DNET.
|
||||
The DNET is actually a byte-swapped low-bitrate Dolby AC3 variant :)
|
||||
Video is RV10 (h263 variant), RV20 (rp G2), RV30 (rp v8) or RV40 (rp v9).
|
||||
|
||||
FPS: variable, just like in ASF.
|
||||
|
||||
Note, that similarity of real and asf has some background - they worked
|
||||
together on the (never finished/used) ASF v2 spec for some time.
|
||||
|
||||
- GIF files:
|
||||
The GIF format is a common format for web graphics that supports
|
||||
animation. These are read through libungif or compatible library.
|
||||
Variable frame delays are supported, but seeking is not supported.
|
||||
Seeking will be supported once an index of gif frames can be built.
|
||||
@@ -0,0 +1,228 @@
|
||||
So, I'll describe how this stuff works.
|
||||
|
||||
The main modules:
|
||||
|
||||
1. stream.c: this is the input layer, this reads the input media (file, stdin,
|
||||
vcd, dvd, network etc). what it has to know: appropriate buffering by
|
||||
sector, seek, skip functions, reading by bytes, or blocks with any size.
|
||||
The stream_t (stream.h) structure describes the input stream, file/device.
|
||||
|
||||
There is a stream cache layer (cache2.c), it's a wrapper for the stream
|
||||
API. It does fork(), then emulates stream driver in the parent process,
|
||||
and stream user in the child process, while proxying between them using
|
||||
preallocated big memory chunk for FIFO buffer.
|
||||
|
||||
2. demuxer.c: this does the demultiplexing (separating) of the input to
|
||||
audio, video or dvdsub channels, and their reading by buffered packages.
|
||||
The demuxer.c is basically a framework, which is the same for all the
|
||||
input formats, and there are parsers for each of them (mpeg-es,
|
||||
mpeg-ps, avi, avi-ni, asf), these are in the demux_*.c files.
|
||||
The structure is the demuxer_t. There is only one demuxer.
|
||||
|
||||
2.a. demux_packet_t, that is DP.
|
||||
Contains one chunk (avi) or packet (asf,mpg). They are stored in memory as
|
||||
in linked list, cause of their different size.
|
||||
|
||||
2.b. demuxer stream, that is DS.
|
||||
Struct: demux_stream_t
|
||||
Every channel (a/v/s) has one. This contains the packets for the stream
|
||||
(see 2.a). For now, there can be 3 for each demuxer :
|
||||
- audio (d_audio)
|
||||
- video (d_video)
|
||||
- DVD subtitle (d_dvdsub)
|
||||
|
||||
2.c. stream header. There are 2 types (for now): sh_audio_t and sh_video_t
|
||||
This contains every parameter essential for decoding, such as input/output
|
||||
buffers, chosen codec, fps, etc. There are each for every stream in
|
||||
the file. At least one for video, if sound is present then another,
|
||||
but if there are more, then there'll be one structure for each.
|
||||
These are filled according to the header (avi/asf), or demux_mpg.c
|
||||
does it (mpg) if it founds a new stream. If a new stream is found,
|
||||
the ====> Found audio/video stream: <id> messages is displayed.
|
||||
|
||||
The chosen stream header and its demuxer are connected together
|
||||
(ds->sh and sh->ds) to simplify the usage. So it's enough to pass the
|
||||
ds or the sh, depending on the function.
|
||||
|
||||
For example: we have an asf file, 6 streams inside it, 1 audio, 5
|
||||
video. During the reading of the header, 6 sh structs are created, 1
|
||||
audio and 5 video. When it starts reading the packet, it chooses the
|
||||
stream for the first found audio & video packet, and sets the sh
|
||||
pointers of d_audio and d_video according to them. So later it reads
|
||||
only these streams. Of course the user can force choosing a specific
|
||||
stream with
|
||||
-vid and -aid switches.
|
||||
A good example for this is the DVD, where the english stream is not
|
||||
always the first, so every VOB has different language :)
|
||||
That's when we have to use for example the -aid 128 switch.
|
||||
|
||||
Now, how this reading works?
|
||||
- demuxer.c/demux_read_data() is called, it gets how many bytes,
|
||||
and where (memory address), would we like to read, and from which
|
||||
DS. The codecs call this.
|
||||
- this checks if the given DS's buffer contains something, if so, it
|
||||
reads from there as much as needed. If there isn't enough, it calls
|
||||
ds_fill_buffer(), which:
|
||||
- checks if the given DS has buffered packages (DP's), if so, it moves
|
||||
the oldest to the buffer, and reads on. If the list is empty, it
|
||||
calls demux_fill_buffer() :
|
||||
- this calls the parser for the input format, which reads the file
|
||||
onward, and moves the found packages to their buffers.
|
||||
Well it we'd like an audio package, but only a bunch of video
|
||||
packages are available, then sooner or later the:
|
||||
DEMUXER: Too many (%d in %d bytes) audio packets in the buffer
|
||||
error shows up.
|
||||
|
||||
2.d. video.c: this file/function handle the reading and assembling of the
|
||||
video frames. each call to video_read_frame() should read and return a
|
||||
single video frame, and it's duration in seconds (float).
|
||||
The implementation is splitted to 2 big parts - reading from mpeg-like
|
||||
streams and reading from one-frame-per-chunk files (avi, asf, mov).
|
||||
Then it calculates duration, either from fixed FPS value, or from the
|
||||
PTS difference between and after reading the frame.
|
||||
|
||||
2.e. other utility functions: there are some useful code there, like
|
||||
AVI muxer, or mp3 header parser, but leave them for now.
|
||||
|
||||
So everything is ok 'till now. It can be found in libmpdemux/ library.
|
||||
It should compile outside of mplayer tree, you just have to implement few
|
||||
simple functions, like mp_msg() to print messages, etc.
|
||||
See libmpdemux/test.c for example.
|
||||
|
||||
See also formats.txt, for description of common media file formats and their
|
||||
implementation details in libmpdemux.
|
||||
|
||||
Now, go on:
|
||||
|
||||
3. mplayer.c - ooh, he's the boss :)
|
||||
Its main purpose is connecting the other modules, and maintaining A/V
|
||||
sync.
|
||||
|
||||
The given stream's actual position is in the 'timer' field of the
|
||||
corresponding stream header (sh_audio / sh_video).
|
||||
|
||||
The structure of the playing loop :
|
||||
while(not EOF) {
|
||||
fill audio buffer (read & decode audio) + increase a_frame
|
||||
read & decode a single video frame + increase v_frame
|
||||
sleep (wait until a_frame>=v_frame)
|
||||
display the frame
|
||||
apply A-V PTS correction to a_frame
|
||||
handle events (keys,lirc etc) -> pause,seek,...
|
||||
}
|
||||
|
||||
When playing (a/v), it increases the variables by the duration of the
|
||||
played a/v.
|
||||
- with audio this is played bytes / sh_audio->o_bps
|
||||
Note: i_bps = number of compressed bytes for one second of audio
|
||||
o_bps = number of uncompressed bytes for one second of audio
|
||||
(this is = bps*samplerate*channels)
|
||||
- with video this is usually == 1.0/fps, but I have to note that
|
||||
fps doesn't really matters at video, for example asf doesn't have that,
|
||||
instead there is "duration" and it can change per frame.
|
||||
MPEG2 has "repeat_count" which delays the frame by 1-2.5 ...
|
||||
Maybe only AVI and MPEG1 has fixed fps.
|
||||
|
||||
So everything works right until the audio and video are in perfect
|
||||
synchronity, since the audio goes, it gives the timing, and if the
|
||||
time of a frame passed, the next frame is displayed.
|
||||
But what if these two aren't synchronized in the input file?
|
||||
PTS correction kicks in. The input demuxers read the PTS (presentation
|
||||
timestamp) of the packages, and with it we can see if the streams
|
||||
are synchronized. Then MPlayer can correct the a_frame, within
|
||||
a given maximal bounder (see -mc option). The summary of the
|
||||
corrections can be found in c_total .
|
||||
|
||||
Of course this is not everything, several things suck.
|
||||
For example the soundcards delay, which has to be corrected by
|
||||
MPlayer! The audio delay is the sum of all these:
|
||||
- bytes read since the last timestamp:
|
||||
t1 = d_audio->pts_bytes/sh_audio->i_bps
|
||||
- if Win32/ACM then the bytes stored in audio input buffer
|
||||
t2 = a_in_buffer_len/sh_audio->i_bps
|
||||
- uncompressed bytes in audio out buffer
|
||||
t3 = a_buffer_len/sh_audio->o_bps
|
||||
- not yet played bytes stored in the soundcard's (or DMA's) buffer
|
||||
t4 = get_audio_delay()/sh_audio->o_bps
|
||||
|
||||
From this we can calculate what PTS we need for the just played
|
||||
audio, then after we compare this with the video's PTS, we have
|
||||
the difference!
|
||||
|
||||
Life didn't get simpler with AVI. There's the "official" timing
|
||||
method, the BPS-based, so the header contains how many compressed
|
||||
audio bytes or chunks belong to one second of frames.
|
||||
In the AVI stream header there are 2 important fields, the
|
||||
dwSampleSize, and dwRate/dwScale pairs:
|
||||
- If the dwSampleSize is 0, then it's VBR stream, so its bitrate
|
||||
isn't constant. It means that 1 chunk stores 1 sample, and
|
||||
dwRate/dwScale gives the chunks/sec value.
|
||||
- If the dwSampleSize is >0, then it's constant bitrate, and the
|
||||
time can be measured this way: time = (bytepos/dwSampleSize) /
|
||||
(dwRate/dwScale) (so the sample's number is divided with the
|
||||
samplerate). Now the audio can be handled as a stream, which can
|
||||
be cut to chunks, but can be one chunk also.
|
||||
|
||||
The other method can be used only for interleaved files: from
|
||||
the order of the chunks, a timestamp (PTS) value can be calculated.
|
||||
The PTS of the video chunks are simple: chunk number * fps
|
||||
The audio is the same as the previous video chunk was.
|
||||
We have to pay attention to the so called "audio preload", that is,
|
||||
there is a delay between the audio and video streams. This is
|
||||
usually 0.5-1.0 sec, but can be totally different.
|
||||
The exact value was measured until now, but now the demux_avi.c
|
||||
handles it: at the audio chunk after the first video, it calculates
|
||||
the A/V difference, and take this as a measure for audio preload.
|
||||
|
||||
3.a. audio playback:
|
||||
Some words on audio playback:
|
||||
Not the playing is hard, but:
|
||||
1. knowing when to write into the buffer, without blocking
|
||||
2. knowing how much was played of what we wrote into
|
||||
The first is needed for audio decoding, and to keep the buffer
|
||||
full (so the audio will never skip). And the second is needed for
|
||||
correct timing, because some soundcards delay even 3-7 seconds,
|
||||
which can't be forgotten about.
|
||||
To solve this, the OSS gives several possibilities:
|
||||
- ioctl(SNDCTL_DSP_GETODELAY): tells how many unplayed bytes are in
|
||||
the soundcard's buffer -> perfect for timing, but not all drivers
|
||||
support it :(
|
||||
- ioctl(SNDCTL_DSP_GETOSPACE): tells how much can we write into the
|
||||
soundcard's buffer, without blocking. If the driver doesn't
|
||||
support GETODELAY, we can use this to know how much the delay is.
|
||||
- select(): should tell if we can write into the buffer without
|
||||
blocking. Unfortunately it doesn't say how much we could :((
|
||||
Also, doesn't/badly works with some drivers.
|
||||
Only used if none of the above works.
|
||||
|
||||
4. Codecs. Consists of libmpcodecs/* and separate files or libs,
|
||||
for example libmpeg2, loader, mp3lib.
|
||||
|
||||
mplayer.c doesn't call them directly, but through the dec_audio.c and
|
||||
dec_video.c files, so the mplayer.c doesn't have to know anything about
|
||||
the codecs.
|
||||
|
||||
libmpcodecs contains wrapper for every codecs, some of them include the
|
||||
codec function implementation, some calls functions from other files
|
||||
included with mplayer, some calls optional external libraries.
|
||||
file naming convention in libmpcodecs:
|
||||
ad_*.c - audio decoder (called through dec_audio.c)
|
||||
vd_*.c - video decoder (called through dec_video.c)
|
||||
ve_*.c - video encoder (used by mencoder)
|
||||
vf_*.c - video filter (see option -vf)
|
||||
|
||||
On this topic, see also:
|
||||
libmpcodecs.txt - The structure of the codec-filter path, with explanation
|
||||
dr-methods.txt - Direct rendering, MPI buffer management for video codecs
|
||||
codecs.conf.txt - How to write/edit codec configuration file (codecs.conf)
|
||||
codec-devel.txt - Mike's hints about codec development - a bit OUTDATED
|
||||
hwac3.txt - about SP/DIF audio passthrough
|
||||
|
||||
5. libvo: this displays the frame.
|
||||
|
||||
for details on this, read libvo.txt
|
||||
|
||||
6. libao2: this control audio playing
|
||||
6.a audio plugins
|
||||
|
||||
for details on this, read libao2.txt
|
||||
@@ -0,0 +1,145 @@
|
||||
mails by A'rpi and Marcus Blomenkamp <Marcus.Blomenkamp@epost.de>
|
||||
describing how this ac3-passtrough hack work under linux and mplayer...
|
||||
-----------------------------------------------------------------------
|
||||
Hi,
|
||||
|
||||
> I received the following patch from Steven Brookes <stevenjb@mda.co.uk>.
|
||||
> He is working on fixing the digital audio output of the dxr3 driver and
|
||||
> told me he fixed some bugs in mplayer along the way. I don't know shit
|
||||
> about hwac3 output so all I did was to make sure the patch applied
|
||||
> against latest cvs.
|
||||
> This is from his e-mail to me:
|
||||
>
|
||||
> "Secondly there is a patch to dec_audio.c and
|
||||
> ac3-iec958 to fix the -ac hwac3 codec stuff and to use liba52 to sync it.
|
||||
|
||||
> Seems to work for everything I've thrown at and maintains sync for all audio
|
||||
> types through the DXR3."
|
||||
|
||||
patch applied (with some comments added and an unwanted change (in software
|
||||
a52 decoder) removed)
|
||||
|
||||
now i understand how this whole hwac3 mess work.
|
||||
it's very very tricky. it virtually decodes ac3 to LPCM packets, but really
|
||||
it keeps the original compressed data padded by zeros. this way it's
|
||||
constant bitrate, and sync is calculated just like for stereo PCM.
|
||||
(so it bypass LPCM-capable media converters...)
|
||||
|
||||
so, every ac3 frame is translated to 6144 byte long tricky LPCM packet.
|
||||
6144 = 4*(6*256) = 4 * samples_per_ac3_frame = LPCM size of uncompressed ac3
|
||||
frame.
|
||||
|
||||
i wanna know if it works for sblive and other ac3-capable cards too?
|
||||
(i can't test it, lack of ac3 decoder)
|
||||
|
||||
A'rpi / Astral & ESP-team
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
Hi folks.
|
||||
I spend some time fiddling with ac3 passthrough in mplayer. The
|
||||
traditional way of setting the output format to AFMT_AC3 was no ideal
|
||||
solution since not all digital io cards/drivers supported this format or
|
||||
honoured it to set the spdif non-audio bit. To make it short, it only
|
||||
worked with oss sblive driver IIRC.
|
||||
|
||||
Inspired by alsa's ac3dec program I found an alternative way by
|
||||
inspecting to which format the alsa device had been set. Suprise: it was
|
||||
simple 16bit_le 2_channel pcm. So setting the non-audio bit doesn't
|
||||
necessarily mean the point. The only important thing seems to be
|
||||
bit-identical output at the correct samplerate. Modern AV-Receivers seem
|
||||
to be quite tolerant/compatible.
|
||||
|
||||
So I changed the output format of hwac3 from
|
||||
|
||||
AFMT_AC3 channels=1
|
||||
to
|
||||
AFMT_S16_LE channels=2
|
||||
|
||||
and corrected the absolute time calculation. That was all to get it
|
||||
running for me.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
Hi there.
|
||||
|
||||
Perhaps I can clear up some mystification about AC3 passthrough in
|
||||
general and mplayer in special:
|
||||
|
||||
To get the external decoder solution working, it must be fed with data
|
||||
which is bitidentical to the chunks in the source ac3 file (compressed
|
||||
data is very picky about bit errors). Additionally - or better to say
|
||||
'historically' - the non-audio bit should be set in the spdif status
|
||||
fields to prevent old spdif hardware from reproducing ugly scratchy
|
||||
noise. Note: for current decoders (probably those with DTS capability)
|
||||
this safety bit isn't needed anymore. At least I can state that for my
|
||||
Sherwood RVD-6095RDS. I think it is due to DTS because DTS sound can
|
||||
reside on a ordinary AudioCD and an ordinary AudioCD-Player will always
|
||||
have it's audio-bit set.
|
||||
|
||||
The sample format of the data must be 2channel 16bit (little endian
|
||||
IIRC). Samplerates are 48kHz - although my receiver also accepts
|
||||
44100Hz. I do not know if this is due to an over-compatability of my
|
||||
receiver or if 44100 is also possible in the ac3 specs. For safety's
|
||||
sake lets keep this at 48000Hz. AC3 data chunks are inserted into the
|
||||
stream every 0x1600 bytes (don't bite me on that, look into
|
||||
'ac3-iec958.c': 'ac3_iec958_build_burst').
|
||||
|
||||
To come back to the problem: data must be played bit-identically through
|
||||
the soundcard at the correct samplerate and should optionally have it's
|
||||
non-audio bit set. There are two ways to accomplish this:
|
||||
|
||||
1) Some OSS guy invented the format AFMT_AC3. Soundcard drivers
|
||||
implementing this format should therefore adjust it's mixers and
|
||||
switches to produce the desired output. Unfortunately some soundcard
|
||||
drivers do not support this format correctly and most do not even
|
||||
support it at all (including ALSA).
|
||||
|
||||
2) The alternative approach currently in mplayer CVS is to simply set
|
||||
the output format to 48kHz16bitLE and rely on the user to have the
|
||||
soundcard mixers adjusted properly.
|
||||
|
||||
I do have two soundcards with digital IO facilities (CMI8738 and
|
||||
Trident4DWaveNX based) plus the mentioned decoder. I'm currently running
|
||||
Linux-2.4.17. Following configurations are happily running here:
|
||||
|
||||
1. Trident with ALSA drivers (OSS does not support Hoontech's dig. IO)
|
||||
2. CMI with ALSA drivers
|
||||
3. CMI with OSS drivers
|
||||
|
||||
For Linux I'd suggest using ALSA because of it's cleaner architecture
|
||||
and more consitent user interface. Not to mention that it'll be the
|
||||
standard sound support in Linux soon.
|
||||
|
||||
For those who want to stick to OSS drivers: The CMI8738 drivers works
|
||||
out-of-the-box, if the PCM/Wave mixer is set to 100%.
|
||||
|
||||
For ALSA I'd suggest using its OSS emulation. More on that later.
|
||||
ALSA-0.9 invented the idea of cards, devices and dubdevices. You can
|
||||
reach the digital interface of all supported cards consitently by using
|
||||
the device 'hw:x,2' (x counting from 0 is the number of your soundcard).
|
||||
So most people would end up at 'hw:0,2'. This device can only be opened
|
||||
in sample formats and rates which are directly supported in hardware
|
||||
hence no samplerate conversion is done keeping the stream as-is. However
|
||||
most consumer soundcards do not support 44kHz so it would definitively
|
||||
be a bad idea to use this as your standard device if you wanted to
|
||||
listen to some mp3s (most of them are 44kHz due to CD source). Here the
|
||||
OSS comes to play again. You can configure which OSS device (/dev/dsp
|
||||
and /dev/adsp) uses which ALSA device. So I'd suggest pointing the
|
||||
standard '/dev/dsp' to standard 'hw:0,0' which suports mixing and
|
||||
samplerate conversion. No further reconfiguration would be needed for
|
||||
your sound apps. For movies I'd point '/dev/adsp' to 'hw:0,2' and
|
||||
configure mplayer to use adsp instead of dsp. The samplerate constrain
|
||||
is no big deal here since movies usually are in 48Khz anyway. The
|
||||
configuration in '/etc/modules.conf' is no big deal also:
|
||||
|
||||
alias snd-card-0 snd-card-cmipci # insert your card here
|
||||
alias snd-card-1 snd-pcm-oss # load OSS emulation
|
||||
options snd-pcm-oss snd_dsp_map=0 snd_adsp_map=2 # do the mapping
|
||||
|
||||
This works flawlessly in combination with alsa's native
|
||||
SysVrc-init-script 'alsasound'. Be sure to disable any distribution
|
||||
dependent script (e.g. Mandrake-8.1 has an 'alsa' script which depends
|
||||
on ALSA-0.5).
|
||||
|
||||
Sorry for you *BSD'lers out there. I have no grasp on sound support there.
|
||||
|
||||
HTH Marcus
|
||||
@@ -0,0 +1,56 @@
|
||||
6. libao2: this control audio playing
|
||||
|
||||
As in libvo (see 5.) also here are some drivers, based on the same API:
|
||||
|
||||
static int control(int cmd, int arg);
|
||||
This is for reading/setting driver-specific and other special parameters.
|
||||
Not really used for now.
|
||||
|
||||
static int init(int rate,int channels,int format,int flags);
|
||||
The init of driver, opens device, sets sample rate, channels, sample format
|
||||
parameters.
|
||||
Sample format: usually AFMT_S16_LE or AFMT_U8, for more definitions see
|
||||
dec_audio.c and linux/soundcards.h files!
|
||||
|
||||
static void uninit(void);
|
||||
Guess what.
|
||||
Ok I help: closes the device, not (yet) called when exit.
|
||||
|
||||
static void reset(void);
|
||||
Resets device. To be exact, it's for deleting buffers' contents,
|
||||
so after reset() the previously received stuff won't be output.
|
||||
(called if pause or seek)
|
||||
|
||||
static int get_space(void);
|
||||
Returns how many bytes can be written into the audio buffer without
|
||||
blocking (making caller process wait). MPlayer occasionally checks the
|
||||
remaining space and tries to fill the buffer with play() if there's free
|
||||
space. The buffer size used should be sane; a buffer that is too small
|
||||
could run empty before MPlayer tries filling it again (normally once per
|
||||
video frame), a buffer that is too big would force MPlayer decode the file
|
||||
far ahead trying to find enough audio data to fill it.
|
||||
|
||||
static int play(void* data,int len,int flags);
|
||||
Plays a bit of audio, which is received throught the "data" memory area, with
|
||||
a size of "len". It has to copy the data, because they can be overwritten
|
||||
after the call is made. Doesn't have to use all the bytes; it has to
|
||||
return the number of bytes used used (copied to buffer). If
|
||||
flags|AOPLAY_FINAL_CHUNK is true then this is the last audio in the file.
|
||||
The purpose of this flag is to tell aos that round down the audio played
|
||||
from "len" to a multiple of some chunksize that this "len" should not be
|
||||
rounded down to 0 or the data will never be played (as MPlayer will never
|
||||
call play() with a larger len).
|
||||
|
||||
static float get_delay(void);
|
||||
Returns how long time it will take to play the data currently in the
|
||||
output buffer. Be exact, if possible, since the whole timing depends
|
||||
on this! In the worst case, return the maximum delay.
|
||||
|
||||
!!! Because the video is synchronized to the audio (card), it's very important
|
||||
!!! that the get_delay function is correctly implemented!
|
||||
|
||||
static void audio_pause(void);
|
||||
Pause playing but do not delete buffered data if possible.
|
||||
|
||||
static void audio_resume(void);
|
||||
Continue playing after audio_pause().
|
||||
@@ -0,0 +1,173 @@
|
||||
libvo --- the library to handle video output by A'rpi, 2002.04
|
||||
============================================
|
||||
|
||||
Note: before start on this, read colorspaces.txt !
|
||||
|
||||
The constants for different pixelformats are defined in img_format.h,
|
||||
their usage is mandatory.
|
||||
|
||||
WARNING: Please keep in mind that some of this information may be out-dated,
|
||||
so if you are working on a new vo, consider submitting preliminary patches
|
||||
very early on. Currently vo_gl is one of the more up-to-date VOs to use
|
||||
as reference if you are unsure about something and do not want to ask on the
|
||||
list.
|
||||
vo_vdpau and vo_direct3d may be a good choice, too, they use different
|
||||
approaches closer to the sometimes convoluted way DirectX works.
|
||||
|
||||
Each vo driver _has_ to implement these:
|
||||
|
||||
preinit():
|
||||
init the video system (to support querying for supported formats)
|
||||
|
||||
uninit():
|
||||
Uninit the whole system, this is on the same "level" as preinit.
|
||||
|
||||
control():
|
||||
Current controls (VOCTRL_QUERY_FORMAT must be implemented,
|
||||
VOCTRL_DRAW_IMAGE, VOCTRL_FULLSCREEN, VOCTRL_UPDATE_SCREENINFO
|
||||
should be implemented):
|
||||
VOCTRL_QUERY_FORMAT - queries if a given pixelformat is supported.
|
||||
It also returns various flags decsirbing the capabilities
|
||||
of the driver with teh given mode. for the flags, see
|
||||
file vfcaps.h !
|
||||
the most important flags, every driver must properly report
|
||||
these:
|
||||
0x1 - supported (with or without conversion)
|
||||
0x2 - supported without conversion (define 0x1 too!)
|
||||
0x100 - driver/hardware handles timing (blocking)
|
||||
also SET sw/hw scaling and osd support flags, and flip,
|
||||
and accept_stride if you implement VOCTRL_DRAW_IMAGE (see bellow)
|
||||
NOTE: VOCTRL_QUERY_FORMAT may be called _before_ first config()
|
||||
but is always called between preinit() and uninit()
|
||||
VOCTRL_GET_IMAGE
|
||||
libmpcodecs Direct Rendering interface
|
||||
You need to update mpi (mp_image.h) structure, for example,
|
||||
look at vo_x11, vo_sdl, vo_xv or mga_common.
|
||||
VOCTRL_DRAW_IMAGE
|
||||
replacement for the current draw_slice/draw_frame way of
|
||||
passing video frames. by implementing SET_IMAGE, you'll get
|
||||
image in mp_image struct instead of by calling draw_*.
|
||||
unless you return VO_TRUE for VOCTRL_DRAW_IMAGE call, the
|
||||
old-style draw_* functils will be called!
|
||||
Note: draw_slice is still mandatory, for per-slice rendering!
|
||||
VOCTRL_RESET - reset the video device
|
||||
This is sent on seeking and similar and is useful if you are
|
||||
using a device which prebuffers frames that need to flush them
|
||||
before refilling audio/video buffers.
|
||||
VOCTRL_PAUSE
|
||||
VOCTRL_RESUME
|
||||
VOCTRL_GUISUPPORT
|
||||
return true only if driver supports co-operation with
|
||||
MPlayer's GUI (not yet used by GUI)
|
||||
VOCTRL_SET_EQUALIZER
|
||||
set the video equalizer to the given values
|
||||
two arguments are provided: item and value
|
||||
item is a string, the possible values are (currently):
|
||||
brightness, contrast, saturation, hue
|
||||
VOCTRL_GET_EQUALIZER
|
||||
get the current video equalizer values
|
||||
two arguments are provided: item and value
|
||||
item is a string, the possible values are (currently):
|
||||
brightness, contrast, saturation, hue
|
||||
VOCTRL_ONTOP
|
||||
Makes the player window stay-on-top. Only supported (currently)
|
||||
by drivers which use X11, except SDL, as well as directx and
|
||||
gl2 under Windows.
|
||||
VOCTRL_BORDER
|
||||
Makes the player window borderless.
|
||||
VOCTRL_FULLSCREEN
|
||||
Switch from and to fullscreen mode
|
||||
VOCTRL_GET_PANSCAN
|
||||
VOCTRL_SET_PANSCAN
|
||||
Needed to implement pan-scan support ('w' and 'e' keys during
|
||||
playback in fullscreen mode)
|
||||
VOCTRL_START_SLICE
|
||||
Called before the first draw_slice of each frame, useful if
|
||||
you need to do some set-up work.
|
||||
VOCTRL_DRAW_EOSD
|
||||
Required for EOSD (ASS subtitle) support. Provides all
|
||||
information necessary to draw the EOSD for the current video
|
||||
frame.
|
||||
VOCTRL_GET_EOSD_RES
|
||||
Required for EOSD (ASS subtitle) support. Informs the ASS
|
||||
renderer about the properties of the drawing area (size,
|
||||
borders).
|
||||
VOCTRL_SET_DEINTERLACE
|
||||
VOCTRL_GET_DEINTERLACE
|
||||
Get or set deinterlacing status for VOs that support some kind
|
||||
of deinterlacing.
|
||||
VOCTRL_UPDATE_SCREENINFO
|
||||
Should set the xinerama_x, xinerama_y, vo_screenwidth and
|
||||
vo_screenheight appropriately for the currently used
|
||||
monitor and -xineramascreen option.
|
||||
Usually should simply call the w32_update_xinerama_info or
|
||||
update_xinerama_info function.
|
||||
By supporting this, the VO also requests the newer API
|
||||
that sets vo_dx, vo_dy etc. appropriately before config()
|
||||
is called.
|
||||
|
||||
config():
|
||||
Set up the video system. You get the dimensions and flags.
|
||||
width, height: size of the source image
|
||||
d_width, d_height: wanted scaled/display size (it's a hint)
|
||||
Flags:
|
||||
0x01 - force fullscreen (-fs)
|
||||
0x02 - allow mode switching (-vm)
|
||||
0x04 - allow software scaling (-zoom)
|
||||
0x08 - flipping (-flip)
|
||||
They're defined as VOFLAG_* (see libvo/video_out.h)
|
||||
|
||||
IMPORTANT NOTE: config() may be called 0 (zero), 1 or more (2,3...)
|
||||
times between preinit() and uninit() calls. You MUST handle it, and
|
||||
you shouldn't crash at second config() call or at uninit() without
|
||||
any config() call! To make your life easier, vo_config_count is
|
||||
set to the number of previous config() call, counted from preinit().
|
||||
It's set by the caller (vf_vo.c), you don't have to increase it!
|
||||
So, you can check for vo_config_count>0 in uninit() when freeing
|
||||
resources allocated in config() to avoid crash!
|
||||
|
||||
You should implement VOCTRL_UPDATE_SCREENINFO so that vo_dx, vo_dy,
|
||||
vo_dwidth and vo_dheight are already pre-set to values that take
|
||||
aspect and -geometry into account. It is also necessary to properly
|
||||
support multi-monitor setups (if based on x11_common, w32_common).
|
||||
|
||||
draw_slice(): this displays YV12 pictures (3 planes, one full sized that
|
||||
contains brightness (Y), and 2 quarter-sized which the colour-info
|
||||
(U,V). MPEG codecs (libmpeg2, opendivx) use this. This doesn't have
|
||||
to display the whole frame, only update small parts of it.
|
||||
If this is not supported, it must be signaled in QUERY_FORMAT with
|
||||
VOCAP_NOSLICES.
|
||||
|
||||
draw_frame(): this is the older interface, this displays only complete
|
||||
frames, and can do only packed format (YUY2, RGB/BGR).
|
||||
Win32 codecs use this (DivX, Indeo, etc).
|
||||
If you implement VOCTRL_DRAW_IMAGE, you do not need to implement draw_frame.
|
||||
|
||||
draw_osd(): this displays subtitles and OSD.
|
||||
It's a bit tricky to use it, since it's a callback-style stuff.
|
||||
It should call vo_draw_text() with screen dimension and your
|
||||
draw_alpha implementation for the pixelformat (function pointer).
|
||||
The vo_draw_text() checks the characters to draw, and calls
|
||||
draw_alpha() for each. As a help, osd.c contains draw_alpha for
|
||||
each pixelformats, use this if possible!
|
||||
Note that if you do not draw directly onto the video you should
|
||||
use vo_draw_text_ext() which allows you to specify the border
|
||||
values etc. needed to draw DVD menu highlights at the correct place.
|
||||
If you do not want to implement this, you can still use -vf
|
||||
expand=osd=1 to draw the OSD, or even implement code to insert
|
||||
this filter automatically.
|
||||
Make sure you set VFCAP_OSD depending on whether you implemented it
|
||||
or not.
|
||||
|
||||
NOTE: This one will be obsolete soon! But it's still useful when
|
||||
you want to do tricks, like rendering osd _after_ hardware scaling
|
||||
(tdfxfb) or render subtitles under of the image (vo_mpegpes, sdl)
|
||||
|
||||
NOTE2: above NOTE is probably wrong, there are currently no plans to
|
||||
obsolete draw_osd, though there is the more advanced EOSD support for
|
||||
ASS subtitles.
|
||||
|
||||
flip_page(): this is called after each frame, this displays the buffer for
|
||||
real. This is 'swapbuffers' when doublebuffering.
|
||||
Try to do as little work here as possible, since that affect jitter/
|
||||
A-V sync.
|
||||
@@ -0,0 +1,100 @@
|
||||
TITLE=Weird Al Yankovic - The Saga Begins (clip)
|
||||
# just to be informative (maybe future
|
||||
# use?)
|
||||
FILE=14233792,7972c637f619e01854ecb453b7339e3f # size,md5
|
||||
AUTHOR=Gabucino
|
||||
TYPE=VIDEO # maybe AUDIO in future (for displaying
|
||||
# mp3 lyrics while playing or whatever)
|
||||
FORMAT=TIME # this file contains measures based on
|
||||
# TIME, not frames.
|
||||
|
||||
# if FORMAT is a number, then it's frame based, i.e.:
|
||||
# FORMAT=25
|
||||
|
||||
NOTE=MPlayerSub test file v0.1
|
||||
|
||||
# first number : wait this much after previous subtitle disappeared
|
||||
# second number : display the current subtitle for this many seconds
|
||||
|
||||
15 3
|
||||
A long, long time ago...
|
||||
|
||||
0 3
|
||||
in a galaxy far away...
|
||||
|
||||
0 3
|
||||
Naboo was under an attack.
|
||||
|
||||
1 2.5
|
||||
And I thought me and
|
||||
Qui-Gon Jinn could
|
||||
|
||||
0 2.5
|
||||
talk the Federation into
|
||||
|
||||
0 4
|
||||
...maybe cutting them a
|
||||
little slack.
|
||||
|
||||
2 3
|
||||
But their response, it
|
||||
didn't thrill us,
|
||||
|
||||
0 3
|
||||
They locked the doors,
|
||||
and tried to kill us.
|
||||
|
||||
0 2.5
|
||||
We escaped from that gas,
|
||||
|
||||
0 3.5
|
||||
then met Jar-jar and
|
||||
Boss-Nass.
|
||||
|
||||
1 6
|
||||
We took a bongo from the
|
||||
scene and we went to
|
||||
Theed to see the Queen.
|
||||
|
||||
0 5
|
||||
We all wound' up on
|
||||
Tatooine.
|
||||
|
||||
0 6
|
||||
That's where, we've found
|
||||
this boy.
|
||||
|
||||
0 4
|
||||
Oh my, my this here
|
||||
Anakin guy,
|
||||
|
||||
0 5
|
||||
maybe Vader someday
|
||||
later now he's just
|
||||
a small fry.
|
||||
|
||||
0 4
|
||||
And he left his home and
|
||||
kissed his mommy goodbye,
|
||||
|
||||
0 5
|
||||
singing "Soon I'm gonna be
|
||||
a Jedi!"
|
||||
|
||||
6 6
|
||||
Did you know this junkyard
|
||||
slave isn't even old enough
|
||||
to shave,
|
||||
|
||||
0 3
|
||||
but he can use the Force,
|
||||
they say.
|
||||
|
||||
1 6
|
||||
Ahh, do you see him hitting
|
||||
on the queen though he's
|
||||
just nine and she's fourteen
|
||||
|
||||
0 6
|
||||
yeah, he's probably gonna
|
||||
marry her, someday!
|
||||
@@ -0,0 +1,19 @@
|
||||
software scaler filter docs
|
||||
|
||||
-ssf cgb=<float> chrominance gaussian blur
|
||||
useful for videos with some chroma (color) noise (TV captures, VHS, ...)
|
||||
|
||||
-ssf lgb=<float> -> luminance gaussian blur
|
||||
hmm, mostly special effect, could be used as lame noise reducer though
|
||||
|
||||
-ssf chs=<int> -> shift chrominance horizontally
|
||||
-ssf cvs=<int> -> shift chrominance vertically
|
||||
useful if the luma & chroma are not aligned exactly
|
||||
|
||||
-ssf cs=<float> -> chrominance sharpen
|
||||
-ssf ls=<float> -> luminance sharpen
|
||||
simple sharpening filter
|
||||
|
||||
note: these will only work if the swscaler is used at all (use -vf scale)
|
||||
|
||||
example: mplayer foobar.avi -vf scale -ssf lgb=3.0
|
||||
@@ -0,0 +1,68 @@
|
||||
|
||||
artifact types:
|
||||
---------------------------------------------------------------------
|
||||
ringing
|
||||
wave or noise like patterns around sharp edges
|
||||
bad: sinc, lanczos (with high filter length)
|
||||
acceptable: lanczos (with low filter length), cubic, spline
|
||||
ok: area, (fast)blinear, gauss, point
|
||||
|
||||
blur
|
||||
loss of detail / high frequency
|
||||
bad: gauss with high variance
|
||||
acceptable: (fast)bilinear, area
|
||||
ok: others
|
||||
|
||||
aliasing (only downscale)
|
||||
straight lines look like staircases
|
||||
areas of high detail look worse
|
||||
regular patterns turn into a funny looking mess (moire patterns)
|
||||
bad: fast bilinear, point, gauss with low variance
|
||||
acceptable: area
|
||||
ok: others
|
||||
|
||||
blocky (upscale only)
|
||||
looks like the image is made of rectangular blocks like a mosaic
|
||||
bad: point
|
||||
ok: others
|
||||
|
||||
recommendations: (based upon my personal opinion many ppl might disagree ...)
|
||||
---------------------------------------------------------------------
|
||||
|
||||
the recommended scalers for upscaling:
|
||||
fast_bilinear, point if speed is important
|
||||
cubic, spline, lanczos if quality is important
|
||||
|
||||
the recommended scalers for downscaling:
|
||||
fast_bilinear, point if speed is important
|
||||
gauss, bilinear if quality is important
|
||||
cubic, spline, lanczos if a sharper picture is important
|
||||
|
||||
note: when encoding at a limited amount of bits (not constant quantizer)
|
||||
then a slightly blurred input might look better after decoding than a slightly
|
||||
sharpened one, especially for lower bitrates
|
||||
|
||||
sws numbers / names / artifact types
|
||||
-------------------------------------------------------------------------
|
||||
r ringing
|
||||
b blurry
|
||||
a aliasing (downscale only)
|
||||
m mosaic (blocky) (upscale only)
|
||||
|
||||
-sws 0 fast bilinear bA
|
||||
-sws 1 bilinear b
|
||||
-sws 2 bicubic high sharpness r
|
||||
low sharpness b
|
||||
-sws 3 experimental ????
|
||||
-sws 4 nearest neighbour AM
|
||||
-sws 5 area ba
|
||||
-sws 6 luma bicubic / chroma bilinear r
|
||||
-sws 7 gauss low sharpness B
|
||||
high sharpness AM
|
||||
-sws 8 sinc R
|
||||
-sws 9 lanczos long filter R
|
||||
short filter b
|
||||
-sws 10 bicubic spline r
|
||||
|
||||
Notes:
|
||||
area upscale is identical to bilinear
|
||||
@@ -1,18 +0,0 @@
|
||||
# Phase 6 性能改动与证据
|
||||
|
||||
## 已采用
|
||||
|
||||
1. **事件驱动渲染更新**:`render.cpp` 不再每 16ms 无条件调用 `mpv_render_context_update`,只在 mpv callback/窗口事件唤醒时更新;为避免个别会话漏回调,最多每 250ms 做一次安全探测。5 次 startup 的 update 累计从优化前 617 降到最终实现 364,且 20 次 startup 未复现永久 BUFFERING。
|
||||
2. **核心快照合并**:`PlaybackEngine` 对 100ms 内的重复 `get_snapshot/get_tracks/get_media_info/get_network_info` 做合并,动作仍立即提交到 MPV,状态最多延迟一个合并窗口。200 次 play/pause 末次面板显示 `coreSyncSkipped=239`;无 error,状态为 PAUSED。
|
||||
3. **NAPI 诊断轮询降频**:Playback Lab 面板由 250ms 调整为 500ms;播放控制、音频 callback 和渲染线程不依赖该轮询。这样减少纯 UI 诊断序列化,不改变 MPV 时钟。旧/新间隔在 `Index.ets` 可审计,运行中由 `getStateCalls`、`serializeUsTotal` 记录。
|
||||
4. **session id 原子读取**:渲染线程不再为每次唤醒获取 `PlaybackEngine` 快照互斥锁,session 更新仍由核心快照写入 release/acquire atomic;首帧 session 隔离 smoke 和 stress 均通过。
|
||||
|
||||
## 未采用
|
||||
|
||||
- 不做主动丢帧、降低音频采样率或缩小视频分辨率;这些会改变播放质量。
|
||||
- 不做 GPU mapper、OHCodec 直出或 FFmpeg-Harmony 源码改动;实体设备 capability 和 fence 证据不足。
|
||||
- 不把 PSS、heap、CPU permille、2 小时长跑结果伪装成已测数据。
|
||||
|
||||
## 回归与开销
|
||||
|
||||
默认构建、软件构建和 FFmpeg-Harmony 构建均通过。默认 HAP 在模拟器上完成 startup/seek/audio 状态面板、load/stop 100 次和 play/pause 100 次。release/profile 构建未启用持续 tracing;诊断仅累加轻量计数和受控序列化时间。
|
||||
@@ -1,20 +0,0 @@
|
||||
# Phase 6 性能指标
|
||||
|
||||
所有时间均为单调时钟相对当前 load session 的毫秒数。`-1` 表示该事件没有发生或无法可靠观察;runner 会把负值转换为 `null`,不参与百分位统计。
|
||||
|
||||
| 类别 | 字段/来源 | 语义 | 模拟器可用性 |
|
||||
| --- | --- | --- | --- |
|
||||
| 启动 | `timeline.startupTotalMs` / `firstSwapMs` | load 到首个成功 EGL swap | 可用 |
|
||||
| 启动分段 | create、initialize、load、START_FILE、FILE_LOADED、decoder reconfig、render context | 各阶段首次事件 | 可用,缺失阶段为 -1 |
|
||||
| 网络 | `firstByteMs`、`networkWaitMs`、HTTP status、206/range | 只记录观察到的请求/日志证据 | HTTP fixture 可用,HTTPS/HLS pending |
|
||||
| seek | `seekCommandLatencyMs`、`seekRecoveryMs`、`seekFirstSwapMs` | seek request/command 到恢复首帧/首 swap | 相对 `+10s` 可用 |
|
||||
| buffering | enter/exit 次数、累计时长、单次最大时长 | cache-buffering 状态边沿 | 字段可用;本地短片通常为 0 |
|
||||
| 音频 | renderer start、首 callback、submitted/played、delay、starvation、flush/reset | 首 callback 时间由诊断轮询观察,不冒充 callback 内精确时间 | 模拟器字段可用,设备路由 pending |
|
||||
| 视频 | dropped、late、mistimed、decoder frames、render count | MPV stats 或 renderer 计数 | 计数接口可用,部分 MPV 值可能为 -1 |
|
||||
| 内存 | `/proc/<pid>/status` VmRSS/VmSize | 进程 RSS/虚拟地址空间 | 可用;PSS/精确 heap 为 null |
|
||||
| CPU | `/proc/<pid>/stat` utime+stime | 原始 jiffies | 原始值可用;未取得可靠 tick/采样归一化,不输出 permille |
|
||||
| 线程/资源 | Threads、`/proc/<pid>/fd` | 进程线程和 fd 快照 | 可用;fd=0 视为不可用 |
|
||||
| NAPI | getState 次数、序列化微秒、估算 payload | NAPI 状态导出成本 | 可用;payload 是上界估算,不是分配追踪 |
|
||||
| 渲染诊断 | render update/frame update、core sync/skipped | 优化前后计数及合并效果 | 可用 |
|
||||
|
||||
NAPI 返回使用 Number 以保持 Inspector 可序列化;大整数仅用于内部原子计数。任何未被设备或 API 真实提供的数据都保持 unavailable,不由模型推断。
|
||||
@@ -1,40 +0,0 @@
|
||||
# Phase 1 Dependency Matrix
|
||||
|
||||
基线:MPV `182fa6ca49f455cadb884858f386e2f00540aeb7`。状态来自当前 `meson.build`、实际 Meson 配置与最终产物,不沿用 Phase 0 假设。
|
||||
|
||||
| Dependency | Version / Commit | Required / Optional | Build System | License | Link | OHOS Status | pkg-config | Blocking libmpv |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| libavcodec | 63.8.101 / FFmpeg `3acec0a1` | Required | configure + Make | LGPL-2.1+ | Static | Built AArch64 | `libavcodec` | Yes |
|
||||
| libavfilter | 12.3.101 / FFmpeg `3acec0a1` | Required | configure + Make | LGPL-2.1+ | Static | Built AArch64 | `libavfilter` | Yes |
|
||||
| libavformat | 63.6.100 / FFmpeg `3acec0a1` | Required | configure + Make | LGPL-2.1+ | Static | Built AArch64 | `libavformat` | Yes |
|
||||
| libavutil | 61.6.100 / FFmpeg `3acec0a1` | Required | configure + Make | LGPL-2.1+ | Static | Built AArch64 | `libavutil` | Yes |
|
||||
| libswresample | 7.2.100 / FFmpeg `3acec0a1` | Required | configure + Make | LGPL-2.1+ | Static | Built AArch64 | `libswresample` | Yes |
|
||||
| libswscale | 10.2.100 / FFmpeg `3acec0a1` | Required | configure + Make | LGPL-2.1+ | Static | Built AArch64 | `libswscale` | Yes |
|
||||
| libplacebo | 7.360.1 / `cee9b076` | Required | Meson | LGPL-2.1+ | Static | Built AArch64; graphics backends off | `libplacebo` | Yes |
|
||||
| libass | 0.17.5 / `4a05d812` | Required | Meson | ISC | Static | Built AArch64 | `libass` | Yes |
|
||||
| FreeType | 2.14.3 / `0a0221a1` | libass transitive | Meson | FTL/GPL-2.0 dual | Static | Built AArch64 | `freetype2` | Yes via libass |
|
||||
| HarfBuzz | 14.4.0 / `36cb489c` | libass transitive | Meson | MIT | Static | Built AArch64 | `harfbuzz` | Yes via libass |
|
||||
| FriBidi | 1.0.16 / `68162bab` | libass transitive | Meson | LGPL-2.1+ | Static | Built AArch64 | `fribidi` | Yes via libass |
|
||||
| OpenSSL | 3.6.4 / `d3c1b116` | HTTPS transitive | Configure + Make | Apache-2.0 | Static | Built AArch64 | `openssl` | Yes for HTTPS |
|
||||
| zlib | SDK 1.2.13 | MPV optional; enabled | SDK | Zlib | Dynamic | SDK AArch64 `libz.so` | generated `zlib` | No |
|
||||
| threads / dl / m / rt | SDK API 24 | Platform required | SDK | SDK system | Dynamic/system | Compile verified | Meson compiler/system | Yes |
|
||||
| EGL / GLES | SDK API 24 | Phase 2 integration | SDK | SDK system | Not linked | Headers/libs available | No target `.pc` used | No |
|
||||
| libcurl, libarchive, libbluray, libavdevice | Optional | Disabled | Various | Various | None | Not built | Not queried or skipped | No |
|
||||
| CD/DVD, Lua, MuJS, uchardet, VapourSynth, zimg, rubberband | Optional | Disabled | Various | Various | None | Not built | Skipped | No |
|
||||
| ALSA, AudioUnit, CoreAudio, JACK, OpenAL, AAudio, OpenSLES, OSS, PipeWire, Pulse, sndio, WASAPI | Optional AO | Disabled | Various | Various | None | Not applicable | Skipped | No |
|
||||
| X11, Wayland, DRM/GBM, Cocoa, D3D11, Vulkan, VAAPI, VDPAU, CUDA, Android Media NDK | Optional VO/hwaccel | Disabled | Various | Various | None | Not applicable | Skipped | No |
|
||||
|
||||
实际依赖图:
|
||||
|
||||
```text
|
||||
OpenSSL ───────────────┐
|
||||
SDK zlib ──────────────┼─> FFmpeg ───────────────┐
|
||||
└─> FreeType ─> HarfBuzz ─┤
|
||||
FriBidi ──────────────────────────────┐ │
|
||||
FreeType + HarfBuzz + FriBidi ───────> libass ───┤
|
||||
libplacebo ──────────────────────────────────────┼─> libmpv.so
|
||||
SDK libc/pthread/dl/m/rt/z ──────────────────────┘
|
||||
SDK native_media_* + native_window <─ FFmpeg OHCodec
|
||||
```
|
||||
|
||||
所有 `.pc` 仅由 `scripts/pkg-config-ohos.sh` 从 OHOS prefix 解析。最终校验未发现 `/opt/homebrew`、`/usr/local`、Mach-O 或 `.dylib` target 输入。
|
||||
@@ -1,67 +0,0 @@
|
||||
# Phase 2 Playback Lab 报告
|
||||
|
||||
日期:2026-08-29
|
||||
分支:`harmony-port`
|
||||
|
||||
## 范围
|
||||
|
||||
`playback_lab/` 是独立 HarmonyOS 验证工程,仅链接 Phase 1 生成的 arm64 `libmpv.so.2`,不复用 Velix 主应用的页面或业务逻辑。当前只验证 GLES/EGL、软件解码和本地 MP4 首帧,不接入音频或硬解。
|
||||
|
||||
## 构建与产物
|
||||
|
||||
环境:DevEco Studio SDK API 24,HarmonyOS emulator 6.1.0.126,`aarch64-linux-ohos`。构建命令:
|
||||
|
||||
```sh
|
||||
./scripts/stage-mpv.sh
|
||||
DEVECO_SDK_HOME=/Applications/DevEco-Studio.app/Contents/sdk \
|
||||
JAVA_HOME=/Applications/DevEco-Studio.app/Contents/jbr/Contents/Home \
|
||||
PATH="$JAVA_HOME/bin:$PATH" \
|
||||
/Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw \
|
||||
--no-daemon assembleHap --mode module -p product=default
|
||||
```
|
||||
|
||||
结果:`BUILD SUCCESSFUL`。HAP:`playback_lab/entry/build/default/outputs/default/entry-default-unsigned.hap`,约 31 MiB,SHA-256 `877568c34a02a4d61b8c4ed7721dd2e6486cb675cd1a58a8eaf44c9b00de05f5`。包内包含 `libentry.so`、`libmpv.so.2` 和 `libc++_shared.so`;未提交 34 MiB 的 staged native 库。
|
||||
|
||||
构建仅保留两项预期警告:NAPI 动态模块在当前 SDK 尚未完成类型校验,以及调试 HAP 未配置正式签名;两者不影响本轮模拟器安装验证。
|
||||
|
||||
## 模拟器验证
|
||||
|
||||
目标:`127.0.0.1:5555`,虚拟设备进程配置为 Pura 90 Pro Max。
|
||||
|
||||
| 项目 | 结果 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| HAP 安装、启动 | 通过 | `hdc install -r`、`aa start` 成功 |
|
||||
| XComponent / OHNativeWindow | 通过 | 页面显示 `surface=READY`;Native 回调无崩溃 |
|
||||
| EGLDisplay / EGLConfig / EGLContext / WindowSurface / makeCurrent | 通过 | 页面显示 `egl=READY`;日志 `EGL vendor=Express ... renderer=Mali-G77` |
|
||||
| libmpv 初始化与 Render API | 通过 | 页面显示 `mpv=READY`;日志 `libmpv initialized` |
|
||||
| 本地 H.264 MP4 软件解码 | 通过 | 本地 `sample.mp4` 首帧及持续播放成功 |
|
||||
| Pause / Resume / Stop / Release | 通过 | UI 状态分别出现 `PAUSED`、`PLAYING`、`STOPPED`、`RELEASED` |
|
||||
| Seek | 通过 | 有效播放中 `-10s/+10s` 不报错;跳转按 duration 做边界裁剪 |
|
||||
| 释放后重新进入 | 通过 | `RELEASED` 后重新启动回到 `PLAYER_CREATED`,Surface/EGL/mpv 再次 READY |
|
||||
| BigInt 状态序列化 | 通过 | `renderCount` 改为 Number,Inspector 不再出现 BigInt 序列化错误 |
|
||||
|
||||
一次本地播放快照:`position=2.00`、`duration=5.05`、`fps=29.97`、`dropped=0`、`firstFrameMs=622`、`renderCount=52`。另一轮快照首帧为 117 ms;`firstFrameMs` 从 `load()` 调用开始计时,并在第一次 `eglSwapBuffers` 后记录。
|
||||
|
||||
## First Frame Timeline
|
||||
|
||||
1. T0:XComponent 创建并取得回调传入的 `OHNativeWindow`,增加 NativeObject 引用。
|
||||
2. T1:专用渲染线程创建 EGLDisplay、RGBA8 EGLConfig、ES3 EGLContext 和 EGLWindowSurface,执行 `eglMakeCurrent`。
|
||||
3. T2:同一渲染线程创建 mpv OpenGL Render Context,注册 update callback。
|
||||
4. T3:`loadfile` 完成本地文件打开,MPV 软件解码产生可渲染帧。
|
||||
5. T4:渲染线程执行 `mpv_render_context_render`、`eglSwapBuffers`,记录 `firstFrameMs` 和 `renderCount`。
|
||||
|
||||
## 尚未完成的真机验收
|
||||
|
||||
本轮只有模拟器,没有接入 HarmonyOS 实体手机,因此 Phase 2 不能标记为最终 COMPLETE。以下项目保持待验证:实体机 HAP 安装、实体机本地 1080P H.264/AAC、HTTP MP4、HTTPS MP4、HLS、20 次 Surface recreate、20 次进出、50 次 Play/Pause、50 次 Seek、横竖屏 20 次、30 分钟稳定性、CPU/RAM 曲线。
|
||||
|
||||
## 风险状态
|
||||
|
||||
| 风险 | 当前状态 |
|
||||
| --- | --- |
|
||||
| RISK-01 POSIX / DNS / network runtime | 未验证,网络链路留待实体机 |
|
||||
| RISK-02 XComponent / OHNativeWindow lifecycle | 模拟器已验证;实体机压力测试待做 |
|
||||
| RISK-03 EGL context / Surface / plain-gl | 模拟器已验证;旋转与重建待做 |
|
||||
| RISK-04 OHCodec buffer lifecycle | 保持开放;Phase 2 明确禁用硬解 |
|
||||
| RISK-05 CA / HAP packaging | 未签名调试 HAP 安装通过;正式签名待接入 |
|
||||
|
||||
新增 MPV upstream patch:0;未修改第三方源码。进入 Phase 3(`ao_harmony + OHAudio`)的前置条件是实体机首帧、控制和压力矩阵完成。
|
||||
@@ -1,47 +0,0 @@
|
||||
# Phase 4 状态
|
||||
|
||||
## 结论
|
||||
|
||||
**Phase 4 CODE COMPLETE / DEVICE VALIDATION PENDING**
|
||||
|
||||
GPU interop:**BLOCKED**(见 `OHCODEC-BLOCKER-001`)。
|
||||
|
||||
代码完成了 MPV 识别 FFmpeg OHCodec、H.264/HEVC decoder selection、能力检查、
|
||||
direct-surface 实验接入、软件回退、诊断和构建矩阵。当前没有实体设备,因此
|
||||
不能写成 hardware decode complete、zero-copy complete 或 HDR complete。
|
||||
|
||||
## 验证矩阵
|
||||
|
||||
| 项目 | 状态 |
|
||||
| --- | --- |
|
||||
| `AV_PIX_FMT_OHCODEC` → `IMGFMT_OHCODEC` | COMPILE VERIFIED |
|
||||
| `AV_HWDEVICE_TYPE_OHCODEC` 独立 backend | COMPILE VERIFIED |
|
||||
| H.264 / HEVC selection guard | COMPILE VERIFIED;DEVICE TEST REQUIRED |
|
||||
| API24 OHCodec capability 查询 | COMPILE VERIFIED;设备返回值待验 |
|
||||
| Direct Surface plumbing | COMPILE VERIFIED;需独占窗口 |
|
||||
| GPU interop mapper | BLOCKED:上游无可导入 non-surface output contract |
|
||||
| Software decode / OHAudio | CLEAN BUILD VERIFIED |
|
||||
| OHCodec-enabled / software / GL-probe | AArch64 BUILD VERIFIED |
|
||||
| Playback Lab HAP | BUILD VERIFIED;unsigned |
|
||||
| Emulator | APP START + EGL SMOKE VERIFIED;不是硬解验证 |
|
||||
| Physical device | PENDING |
|
||||
|
||||
## 产物与审计
|
||||
|
||||
- `build/ohos-arm64/prefix/lib/libmpv.so.2.5.0` 为 AArch64 ELF,保留 OHCodec、
|
||||
OHAudio 及诊断符号。
|
||||
- `scripts/build-mpv-ohos-software.sh` 使用独立 build 目录关闭 OHCodec,避免
|
||||
软件回退配置与硬解构建互相污染。
|
||||
- FFmpeg 保持锁定 upstream commit,未复制 SDK/第三方实现;许可证审计见
|
||||
`LICENSE_AUDIT.md`。
|
||||
- 当前 blocker、NativeBuffer 生命周期、EGL/fence/crop/stride 待验证项见
|
||||
`DOCS/OHCODEC_GPU_INTEROP_DESIGN.md` 与 `DOCS/HDR_PIPELINE_NOTES.md`。
|
||||
- Phase 4.5 FFmpeg export contract 独立维护于
|
||||
`../Velix-FFmpeg-Harmony`;MPV 只提供
|
||||
`scripts/build-mpv-ohos-ffmpeg-harmony.sh` 前缀切换,未接入 mapper。
|
||||
|
||||
## 下一阶段最大风险
|
||||
|
||||
实体设备上的 codec capability、surface recreate、output buffer ownership、
|
||||
acquire/release fence、crop/stride/color metadata,以及如何在不修改 FFmpeg
|
||||
surface contract 的前提下把硬件帧交给 MPV GPU composition。
|
||||
@@ -1,18 +0,0 @@
|
||||
# Phase 5 状态
|
||||
|
||||
状态:CODE COMPLETE / HTTP Range emulator verified / device and remaining network validation pending。
|
||||
|
||||
已完成:
|
||||
|
||||
- 默认软件解码路径保持 hwdec=no,未启用 harmony-ohcodec-gl。
|
||||
- 新增 include/mpv/harmony_playback.h 稳定 C API;公共结构不包含 mpv_handle、mpv_node、AVFrame。
|
||||
- 请求字段、会话 generation、线程安全控制、稳定状态/错误、轨道、媒体信息和网络缓存诊断已实现。
|
||||
- Playback Lab 已接入请求对象、脱敏 header 编辑器、速度/音量/静音、外部字幕、轨道/媒体/网络面板。
|
||||
- 文档、测试矩阵和构建矩阵已补齐。
|
||||
- default/software/FFmpeg-Harmony 三套 AArch64 libmpv 构建、稳定 API 符号校验与 Playback Lab Native/ArkTS/PackageHap 编译已通过;使用 DevEco 自带 JBR 的 `--no-daemon` 流程生成 unsigned HAP,并由 devecocli 安装模拟器。
|
||||
- 模拟器已启动 Playback Lab,完成本地 H.264/AAC MP4 首帧、软件解码、播放结束状态和渲染指标 smoke;通过宿主受控 HTTP Range server 完成 HTTP MP4 播放与 Range 请求验证;HTTPS/HLS/网络字幕/鉴权资源仍需真实网络源。
|
||||
- 当前构建日志显示 iconv feature disabled,因此字幕适配器只承诺 UTF-8;GBK/Big5/Shift-JIS 会返回稳定 SUBTITLE 错误。
|
||||
|
||||
尚待真实环境确认:HTTPS/HLS、重定向 header 继承、鉴权资源、网络字幕和物理设备音频/视频输出。不可从本地编译结果推断这些运行时结论。
|
||||
|
||||
许可:新增代码沿用 MPV 的 LGPL/ISC 边界,不引入商业字体或新的第三方网络库;公共头文件保持独立 ABI。Phase 6 最大风险是将 Provider 业务请求正确转换为通用请求,以及在实体设备上确认网络、音频路由和字幕字体 provider 行为。
|
||||
@@ -1,31 +0,0 @@
|
||||
# Phase 5 测试矩阵
|
||||
|
||||
| 场景 | 方式 | 结果 |
|
||||
|---|---|---|
|
||||
| 本地 MP4 H264/AAC | Playback Lab | 模拟器安装启动并完成首帧/播放/结束 smoke;网络与实体机待确认 |
|
||||
| 本地 MKV H264/AAC/SRT | Playback Lab | API/UI 编译覆盖;设备运行待确认 |
|
||||
| 本地 MKV HEVC/AAC/ASS(software) | software mpv | AArch64 构建通过;设备运行待确认 |
|
||||
| HTTP MP4 | 宿主受控 Range server + Playback Lab | 模拟器通过;观察到 `bytes=0-`、后续 byte range,请求完成且 state=ENDED;`rangeSupported=1` |
|
||||
| HTTPS MP4 | 受控测试源 | TLS 校验代码就绪;网络环境待确认 |
|
||||
| HLS Master | 受控测试源 | 复用 mpv/FFmpeg;网络环境待确认 |
|
||||
| HLS Variant/chunked | 受控测试源 | 复用 mpv/FFmpeg;网络环境待确认 |
|
||||
| 多音轨 MKV | Playback Lab | Track API/UI 已接入;设备运行待确认 |
|
||||
| 内封 SRT | Playback Lab | Track API/UI 已接入;设备运行待确认 |
|
||||
| 内封 ASS/SSA | Playback Lab | libass 路径保留原样式;设备运行待确认 |
|
||||
| 外挂 SRT | Playback Lab | URL 与本地 file 路径入口已接入;设备运行待确认 |
|
||||
| 外挂 ASS/SSA | Playback Lab | URL 与本地 file 路径入口已接入;设备运行待确认 |
|
||||
| 网络字幕/WebVTT | Playback Lab | API/UI 已接入;网络环境待确认 |
|
||||
| Authorization header | 受控测试源 | 脱敏与隔离代码覆盖;服务端待确认 |
|
||||
| Cookie header | 受控测试源 | 单会话 Cookie header;服务端待确认 |
|
||||
| Referer/User-Agent | 受控测试源 | 请求字段与 header 均支持;服务端待确认 |
|
||||
| Range seek / 大 seek | 宿主受控 Range server + Playback Lab | 模拟器通过 HTTP Range 请求;最近 seek 结果由 `seekResult` 暴露;HTTPS 大 seek 待继续验收 |
|
||||
| Redirect | FFmpeg-Harmony `f3a036c695` + 受控测试源 | 跨 origin 丢弃 Authorization/Cookie/Token/API-key/Referer;同源保留;受控重定向运行验证待补 |
|
||||
| 403 / 404 / 500 | 受控测试源 | 稳定 HTTP 错误码已接入;网络环境待确认 |
|
||||
| Broken media / reset / timeout / TLS | 受控测试源 | DEMUX/NETWORK/TLS 分类已接入;网络环境待确认 |
|
||||
| 默认 FFmpeg(OHCodec enabled) | scripts/build-mpv-ohos.sh | AArch64 ELF 与符号校验通过 |
|
||||
| software MPV(OHCodec disabled) | scripts/build-mpv-ohos-software.sh | AArch64 ELF 校验通过 |
|
||||
| FFmpeg-Harmony | scripts/build-mpv-ohos-ffmpeg-harmony.sh | AArch64 ELF 与符号校验通过 |
|
||||
| audio-enabled MPV | 默认脚本 `harmony-audio=enabled` | 与默认构建一并通过 |
|
||||
| Playback Lab HAP | hvigor assembleHap --no-daemon | CompileArkTS/Native/PackageHap 通过;无正式签名,devecocli 已安装模拟器 |
|
||||
|
||||
产品禁止以 UI 定时器伪造 buffering;只有 mpv 事件/属性可改变对应诊断字段。
|
||||
@@ -1,33 +0,0 @@
|
||||
# Phase 6 状态
|
||||
|
||||
状态:**CODE COMPLETE / EMULATOR BENCHMARKED / DEVICE BENCHMARK PENDING**。
|
||||
|
||||
Phase 6 交付范围是可重复的 Playback Lab 性能时间线、资源采样、NAPI 诊断、四项低风险优化和模拟器回归。没有修改 GPU mapper,也没有修改 `Velix-FFmpeg-Harmony`。
|
||||
|
||||
## 已完成
|
||||
|
||||
- 启动、seek、buffering、音频、渲染、NAPI 和资源指标已接入稳定快照;未能可靠取得的 PSS、精确 heap、归一化 CPU 均明确返回 `null` 或文档标记为 unavailable。
|
||||
- `benchmark/runner/run_emulator.py` 支持 startup、seek、load/stop stress、play/pause stress,输出重复统计(min/max/avg/median/P90/P95)和逐次资源采样。
|
||||
- 渲染循环改为 mpv update callback 驱动,并保留 250ms 安全探测;快照同步增加 100ms 合并窗口;session id 读取改为 atomic;诊断轮询从 250ms 调整为 500ms。
|
||||
- default、software、FFmpeg-Harmony 三套 AArch64 libmpv 均通过符号和 OHOS ELF 校验;Playback Lab HAP 编译、安装和模拟器启动通过。
|
||||
|
||||
## 模拟器结果
|
||||
|
||||
测试设备:`127.0.0.1:5555`,本地 H.264/AAC MP4,软件解码,`ao_harmony`。
|
||||
|
||||
| 场景 | 结果文件 | 关键结果 |
|
||||
| --- | --- | --- |
|
||||
| startup_local ×20 | `benchmark/results/startup_local-1787999362.json` | 首帧 P50 506ms,P95 1150ms;20/20 暴露时间线,无错误 |
|
||||
| seek_local ×50 | `benchmark/results/seek_local-1787999663.json` | 恢复 P50 277ms,P95 631ms;49/50 有恢复时间线,1 次 `SEEK` 命令错误 |
|
||||
| play_pause ×200 | `benchmark/results/play_pause-1788000475.json` | 无错误;末次 RSS 213228KB、线程 39、fd 1 |
|
||||
| load/stop ×100 | `benchmark/results/stress_lifecycle-1788000229.json` | 进程保持存活;RSS/线程/fd 采样完成,PSS 不可用 |
|
||||
|
||||
优化前后计数基线:同等 5 次 startup 中,渲染 update 累计由 617 降至最终版本 364;NAPI/核心同步计数通过面板快照记录。200 次 play/pause 无错误,末次 `coreSyncSkipped=239`,说明合并窗口实际生效。
|
||||
|
||||
最终 5 次 smoke 还观察到 `firstAudioCallbackMs` P50 256ms、`audioRendererStartMs` P50 720ms;这些值来自 500ms 诊断轮询,不能替代设备音频 trace。file:// 场景的 `networkWaitMs` 保持 -1,buffering 计数按真实状态边沿记录。
|
||||
|
||||
## 尚待实体设备
|
||||
|
||||
实体设备上的真实 PSS/heap、CPU 利用率、显示合成延迟、音频路由/A-V 偏差、OHCodec capability、长时间(2h)稳定性、HTTPS/HLS/鉴权/网络字幕仍未验证。Phase 7 建议先建立实体设备矩阵和受控 HTTPS/HLS fixture,再评估硬解直出和端到端 A/V 指标。
|
||||
|
||||
许可边界沿用 MPV LGPL/ISC;本阶段未引入新的第三方依赖或商业资源。
|
||||
@@ -1,13 +0,0 @@
|
||||
# PlaybackEngine
|
||||
|
||||
`PlaybackEngine` 是主 App 的唯一播放抽象,`MpvPlaybackEngine` 是 Core binding 的适配器,`PlaybackController` 负责页面状态刷新与生命周期编排。
|
||||
|
||||
业务层只使用:
|
||||
|
||||
- `PlaybackSource { kind, url, headers }`
|
||||
- `PlaybackState { state, position, duration, media, tracks, metrics }`
|
||||
- play/pause/stop/release、seek、音量/倍速、音轨/字幕操作
|
||||
|
||||
provider 接口暂不绑定 Emby、Jellyfin、百度网盘等服务。HTTP(S) 源支持有限 headers;复杂 header 编辑器、登录与播放列表不在 v0 范围。
|
||||
|
||||
默认解码策略为软件解码;`requestedDecoder=software` 是主 App 的固定默认值,OHCodec GL mapper 不在本阶段启用。
|
||||
@@ -1,13 +0,0 @@
|
||||
# Playback 公共 API
|
||||
|
||||
mp_harmony_playback.h 是上层唯一稳定契约,提供 PlaybackRequest、PlaybackState、Track、MediaInfo、PlaybackMetrics 和 PlaybackError 模型别名。PlaybackRequest 只携带 URL、标题、起始位置、User-Agent、Referer、Cookie、任意 HTTP headers、字幕源、语言偏好、轨道选择、速度和超时。空值或负值按头文件注释表示未设置。
|
||||
|
||||
公开控制命令:Play、Pause、TogglePause、SeekAbsolute、SeekRelative、SeekPercent、Stop、SetSpeed、SetVolume、Mute、SetAudioEnabled、SelectAudioTrack、SelectSubtitleTrack、DisableSubtitle、AddSubtitle、RemoveSubtitle、SetSubtitleDelay、SetSubtitleScale、SetSubtitlePosition、SetAssOverride、GetTracks、GetMediaInfo、GetNetworkInfo、GetPlaybackState。
|
||||
|
||||
所有控制入口串行化;请求中的字符串在调用返回前复制到 mpv 所需的临时节点,调用者可以立即释放输入内存。session id 随每次 load 增长,旧 playlist event 不得改变新会话状态。
|
||||
|
||||
Playback Lab 的 C++ 外壳只做 NAPI/渲染适配,所有请求、控制和状态快照均委托上述 C API;渲染器使用私有句柄桥接,不进入公共 ABI。
|
||||
|
||||
当前 OHOS 构建未启用 iconv,外挂字幕 encoding 只接受 UTF-8/UTF8;其他编码通过稳定 SUBTITLE 错误拒绝。
|
||||
|
||||
起播 `start_position_ms` 在 `MPV_EVENT_FILE_LOADED` 后执行 exact seek,避免异步 load 竞态;`title` 映射到 `force-media-title`。MediaInfo 同时保留历史 `width`/`height`/`color_space` 字段,并提供 `video_width`/`video_height`/`color_matrix` 别名。NetworkInfo 的 `range_supported` 为 -1/0/1(未知/未观察到 206/观察到 206),`seek_result` 为最近一次 seek 的 `ok` 或脱敏错误。
|
||||
@@ -1,14 +0,0 @@
|
||||
# Player lifecycle
|
||||
|
||||
产品调用顺序:
|
||||
|
||||
```text
|
||||
create → attachSurface → prepare(source) → play
|
||||
↘ pause / seekTo / seekBy / tracks / subtitles
|
||||
stop → prepare 或 release
|
||||
detachSurface → release
|
||||
```
|
||||
|
||||
`onForeground`、`onBackground`、`onSurfaceAvailable`、`onSurfaceDestroyed` 是显式适配接口。当前后台策略只释放/暂停 Surface 相关资源,不承诺后台播放、PiP 或通知栏控制。Surface 与 player 生命周期解耦:Surface 销毁不会自动销毁 Core player,新的 Surface 可重新 attach。
|
||||
|
||||
页面状态以 500ms 轮询读取,错误通过 `errorCode` 与 `lastError` 映射到 UI;首帧、缓冲、seek、音频与 renderer 指标仅在“显示调试统计”打开时显示。
|
||||
@@ -1,70 +0,0 @@
|
||||
# HarmonyOS Porting Plan
|
||||
|
||||
## 1. 源码扫描结论
|
||||
|
||||
MPV 核心播放、demux、filter、subtitle、A/V sync、command、client API 基本跨平台。平台耦合集中在 `meson.build`、`osdep/`、`audio/out/`、`video/out/`、`video/decode/` 与 hwdec interop。当前仓库搜索不到 Harmony/OHOS 代码。
|
||||
|
||||
MPV 当前检测逻辑 `posix = not win32`;非 Darwin POSIX 自动选择 `osdep/timer-linux.c`。OHOS 编译器同时定义 `__OHOS__` 与 `__linux__`,因此所有 Linux feature 必须由 Meson probe 或显式 Harmony gate 决定,不能只看 `__linux__`。
|
||||
|
||||
## 2. 文件级移植矩阵
|
||||
|
||||
| MPV source / file | 当前依赖 API / 行为 | HarmonyOS 替代或复用 | Patch | 风险 | 阶段 | 工作量 |
|
||||
|---|---|---|---:|---|---|---|
|
||||
| `meson.build` OS detection | win32/darwin/posix/android/linux 分支 | 增加 `ohos = host_machine.system() == 'ohos'`、`features['harmony']`、config `HAVE_HARMONY` | 是 | 高 | P1-01 | 1–2d |
|
||||
| `meson.build` platform sources | 非 Darwin POSIX选 Linux timer;Android 单独 EGL/media | 为 OHOS 明确选择 POSIX可复用源、Harmony AO/可选 context;不进入 Android 分支 | 是 | 高 | P1-01 | 1d |
|
||||
| `osdep/threads-posix.c` | pthread、cond、mutex、TLS | 直接使用 SDK `pthread.h`;线程名由 feature probe | 预计否/小 | 中 | P1-02 | 0.5–1d |
|
||||
| `osdep/timer-linux.c` | `clock_gettime`、`nanosleep` | API均可用;可先明确选该实现,后续重命名/拆成 POSIX timer 以便 upstream | 小 | 低 | P1-02 | 0.5d |
|
||||
| `osdep/path-unix.c` | POSIX paths、HOME/XDG 等桌面约定 | 文件 API复用;应用 data/cache 路径最终由宿主注入,不能依赖 HOME | 小/后续 | 中 | P1-03 | 1–2d |
|
||||
| `osdep/language-posix.c` | locale/environment | 先复用;设备语言由宿主 API注入作为后续增强 | 预计否 | 低 | P1-03 | 0.5d |
|
||||
| `osdep/subprocess-posix.c` | fork/exec/process | Harmony app 不需要 subprocess;若 probe失败明确选 `subprocess-dummy.c` 并返回 unsupported | 小 | 中 | P1-03 | 0.5d |
|
||||
| `osdep/terminal-unix.c` | tty/terminal | libmpv build 不需要交互 terminal;cplayer关闭 | 配置 | 低 | P1-01 | 0.2d |
|
||||
| `input/ipc-unix.c` | Unix domain socket | 首版 libmpv 可关闭/保留按 probe;产品 API不暴露 IPC | 小/配置 | 低 | P1-03 | 0.5d |
|
||||
| `stream/` + FFmpeg AVIO | POSIX socket、DNS、FFmpeg HTTP/TLS | socket/DNS复用;HTTP/HLS由 FFmpeg;TLS 使用交叉构建 OpenSSL | MPV 否 | 高 | P1-04 | 3–5d |
|
||||
| `demux/demux_lavf.c` | libavformat | 直接复用官方 FFmpeg OHOS build | 否 | 中 | P1-04 | 1d 验证 |
|
||||
| `sub/`、`sub/osd_libass.c` | libass、字体栈 | 直接复用;字体发现/应用字体目录需配置验证 | 小/配置 | 中 | P1-05 | 2–3d |
|
||||
| `include/mpv/client.h` | libmpv C API | 直接复用仅作内部依赖;最终 Velix API再封装 | 否 | 低 | P1 | 0.5d |
|
||||
| `include/mpv/render*.h` | OpenGL / software public render API | 直接使用 OpenGL API;宿主提供 GLES proc resolver/FBO | 否 | 中 | P2-01 | 2–4d lab glue |
|
||||
| `video/out/vo_libmpv.c` | libmpv render bridge | 直接复用 | 预计否 | 中 | P2-01 | 1d 验证 |
|
||||
| `video/out/opengl/libmpv_gl.c` | OpenGL Render API | 直接复用 GLES/EGL context;验证所需 GL symbols | 小/预计否 | 中 | P2-01 | 2d |
|
||||
| `video/out/opengl/context*.c` | Android/X11/Wayland/DRM/Windows context | 首版 libmpv plain-gl 不新增;如 MPV自管 context,再新增 `context_harmony.c` | 后续 | 中 | P2-02 | 3–5d |
|
||||
| `video/out/vulkan/context.c` | libplacebo/Vulkan context registry | 若采用 Vulkan新增 `context_harmony.c`,调用 `vkCreateSurfaceOHOS` | 后续是 | 高 | P4 | 7–12d |
|
||||
| `audio/out/ao.c` | AO driver registry | 注册 `audio_out_harmony` | 是 | 低 | P2-03 | 0.5d |
|
||||
| `audio/out/ao_aaudio.c` | Android AAudio callback模型 | 仅作结构参考;实际新增 `ao_harmony.c` 使用 OHAudio | 新文件 | 高 | P2-03 | 5–8d |
|
||||
| `audio/out/buffer.c` | MPV AO buffering | 直接复用,由 OHAudio callback消费 | 预计否 | 中 | P2-03 | 1–2d 验证 |
|
||||
| `video/fmt-conversion.c` | FFmpeg pixfmt↔MPV imgfmt | 增加 `AV_PIX_FMT_OHCODEC` 映射前先确认 MPV image semantics | 后续是 | 高 | P3-02 | 1–2d |
|
||||
| `video/decode/vd_lavc.c` | hw device选择、frames | 加入 `AV_HWDEVICE_TYPE_OHCODEC` 并传递 native window/device ctx | 后续是 | 高 | P3-02 | 3–6d |
|
||||
| `video/out/gpu/hwdec.c` | GPU interop registry | 注册 Harmony interop driver,仅在真实 buffer import 方案明确后 | 后续是 | 极高 | P3-03 | 7–15d |
|
||||
| `video/out/hwdec/` | VAAPI/DRM/VT/Android interop | 新增隔离的 `hwdec_ohcodec.c`,不散落 OHOS ifdef | 后续是 | 极高 | P3-03 | 10–20d |
|
||||
| `video/out/opengl/egl_helpers.c` | 通用 EGL config/context helpers | 优先复用;验证 GLES profile、10-bit config、context loss | 可能小 | 中 | P2-01 | 2d |
|
||||
| `misc/io_utils.c` / poll wrapper | poll/FD helper | POSIX poll 复用;epoll不作为无证据优化 | 预计否 | 低 | P1-02 | 0.5d |
|
||||
| logging (`common/msg.c`) | stderr/terminal | 首编译复用;lab阶段加 HiLog adapter,不能替换核心 logger | 后续小 | 低 | P2 | 1–2d |
|
||||
|
||||
## 3. 分阶段执行
|
||||
|
||||
### P1:First Build
|
||||
|
||||
1. P1-01:Meson 识别 OHOS,构建只产 libmpv。
|
||||
2. P1-02:逐项编译 POSIX 基础层;每个 blocker 单独记录。
|
||||
3. P1-03:明确 subprocess/IPC/path 不支持或可复用边界。
|
||||
4. P1-04:构建 FFmpeg software decode + network + TLS。
|
||||
5. P1-05:构建 libass/font stack、libplacebo,链接 libmpv。
|
||||
|
||||
门禁:AArch64 libmpv 真实产物、导出符号、依赖清单、无 Android API、无宿主机库。
|
||||
|
||||
### P2:Playback Lab 基线
|
||||
|
||||
XComponent + EGL + libmpv OpenGL Render API;新增 OHAudio AO;URL/local file、play/pause/seek/stop/release、日志和基础 metrics。无正式产品 UI。
|
||||
|
||||
### P3:硬件解码
|
||||
|
||||
先验证 FFmpeg `h264_oh` / `hevc_oh`,再决定 direct surface 或 GPU import。所有优化必须对比软件解码基线。
|
||||
|
||||
### P4:定点性能与 Vulkan
|
||||
|
||||
只有 Benchmark 证明 GLES/上传或合成是瓶颈时,研究 Vulkan/HDR/zero-copy;每个 patch 必须有前后数据。
|
||||
|
||||
## 4. 可直接复用与必须新增
|
||||
|
||||
可直接复用:libmpv client/render API、player core、demux、software decode glue、filters、A/V sync、subtitle/libass、playlist/property/command、POSIX threads/timer/socket/DNS/poll/mmap 的已验证子集、OpenGL renderer。
|
||||
|
||||
必须新增:Harmony Meson detection、OHAudio AO、Playback Lab 的 XComponent/EGL native glue。硬解阶段预计新增 OHCodec image/device/interoperability backend。Vulkan context 不是首版必需。
|
||||
@@ -1,35 +0,0 @@
|
||||
# Risk Assessment
|
||||
|
||||
## Top 10
|
||||
|
||||
| # | 风险 | 可能性 / 影响 | 证据 | 缓解与验收 |
|
||||
|---:|---|---|---|---|
|
||||
| 1 | MPV 无 OHOS 平台检测,OHOS 被泛 POSIX/Linux 逻辑误分类 | 高 / 高 | 当前 `meson.build` 无 harmony/ohos;编译器同时定义 `__linux__` | 显式 `features['harmony']`;每个 Linux feature 用 compile/link probe |
|
||||
| 2 | 交叉依赖链复杂且 pkg-config 污染宿主库 | 高 / 高 | 本机无 Meson/Ninja/pkg-config;MPV 强依赖 FFmpeg/libplacebo/libass | 单一 staging prefix、清空默认 `PKG_CONFIG_PATH`、产物 readelf 审计 |
|
||||
| 3 | HTTPS/TLS 无可直接复用的 FFmpeg Harmony backend | 高 / 高 | SDK有 `libnet_ssl.so`,FFmpeg不使用它 | 交叉构建 OpenSSL;真机证书/SNI/Range/HLS 测试 |
|
||||
| 4 | Surface 生命周期与 GL 线程竞态导致黑屏/崩溃 | 高 / 高 | XComponent异步 create/change/destroy,EGL context 有线程归属 | 单一 render thread 状态机;销毁屏障;旋转/后台压力测试 |
|
||||
| 5 | OHAudio callback 与 MPV buffer/clock 语义不匹配 | 中高 / 高 | MPV无 Harmony AO | realtime-safe callback;timestamp/delay 校准;seek/route switch 测试 |
|
||||
| 6 | FFmpeg OHCodec虽已 upstream,但 MPV完全不识别 OHCODEC | 高 / 高 | MPV无 `AV_PIX_FMT_OHCODEC` / `AV_HWDEVICE_TYPE_OHCODEC` | 软件基线后小步接入;先独立验证 FFmpeg backend |
|
||||
| 7 | Direct Surface decode 绕过 MPV shader/ASS/色彩管理 | 高 / 高 | FFmpeg OHCodec向 window直接 render | 优先研究 OHNativeBuffer GPU import;direct surface仅作验证路径 |
|
||||
| 8 | 4K/10-bit/HDR 能力因机型/驱动不同,SDK存在不等于设备支持 | 高 / 高 | capability API要求运行时查询 | 保存设备矩阵、profile/level/format/extension;不做泛化承诺 |
|
||||
| 9 | GPL/LGPL 与静态链接/FFmpeg选项污染商业发布 | 中高 / 极高 | MPV默认 GPLv2+;开关不自动产生 LGPL授权 | 默认 GPL 管理;保存完整 build manifest;发布前法务审计 |
|
||||
| 10 | arm64 OHOS ABI/符号/打包规则与普通 Linux不同 | 中 / 高 | target 是 `aarch64-linux-ohos`,系统库命名含 `.z.so` | 小探针→依赖→libmpv;检查 SONAME、NEEDED、符号可见性和 HAP 装载 |
|
||||
|
||||
## 其他风险
|
||||
|
||||
- 字体发现和字体包体积影响 ASS 首帧及中日韩字幕正确性。
|
||||
- 网络切换、代理、IPv6、慢速 Range、HLS discontinuity 对稳定性影响大。
|
||||
- MPV master 与 FFmpeg master 同时变化,需锁 commit 并记录组合。
|
||||
- API 24 SDK header含更低 API接口,但实际目标机系统版本仍要匹配。
|
||||
- Vulkan headers/loader存在不代表驱动质量和 HDR swapchain 可用。
|
||||
|
||||
## 决策门禁
|
||||
|
||||
| 决策 | 必需证据 |
|
||||
|---|---|
|
||||
| 进入 Phase 1 | Phase 0 文档完成;origin/upstream/branch明确;依赖与 license 策略确认 |
|
||||
| 开始 Playback Lab | libmpv arm64真实产物及 build report |
|
||||
| 启用 OHCodec | software decode 基线 + 官方 FFmpeg OHCodec 独立验证 |
|
||||
| 宣称 low-copy/zero-copy | 帧路径、buffer ownership、GPU import、同步与 copy 测量证据 |
|
||||
| 采用 Vulkan | GLES benchmark证明瓶颈且 Vulkan原型在目标机显著改善 |
|
||||
| 商业发布 | 实际链接清单、许可证正文、源码义务、法务审核全部完成 |
|
||||
@@ -1,20 +0,0 @@
|
||||
# SDK packaging
|
||||
|
||||
使用 `scripts/package-velix-core-sdk.sh` 生成 staging 目录。脚本按 profile 选择已构建的 `libmpv`,编译 binding,复制公开 headers、运行库、许可证,并生成包含 API 版本、commit、profile、尺寸和 SHA-256 的 `metadata/build-info.json`。
|
||||
|
||||
支持 profile:
|
||||
|
||||
```sh
|
||||
./scripts/package-velix-core-sdk.sh --profile default
|
||||
./scripts/package-velix-core-sdk.sh --profile software
|
||||
./scripts/package-velix-core-sdk.sh --profile ffmpeg-harmony
|
||||
```
|
||||
|
||||
ABI 检查重点:
|
||||
|
||||
- `libvelix_core_binding.so` 只导出 3 个 `velix_core_get_*` ABI 符号;NAPI 模块描述由系统注册段加载,不把内部 C++ 符号作为 ABI;
|
||||
- `libmpv.so.2` 保持自身运行时导出,不将其头文件类型传给主 App;
|
||||
- 所有动态依赖必须存在于 `lib/arm64-v8a` 或 OpenHarmony 系统库中;
|
||||
- staging 与构建目录不应进入 Git,发布包必须保留 LGPL/GPL/第三方声明。
|
||||
|
||||
验证:`./scripts/verify-velix-core-sdk.sh`。
|
||||
@@ -1,15 +0,0 @@
|
||||
# Seek Pipeline
|
||||
|
||||
```text
|
||||
seek request
|
||||
-> mpv seek command
|
||||
-> SEEK event / demux recovery
|
||||
-> VIDEO_RECONFIG
|
||||
-> PLAYBACK_RESTART
|
||||
-> first video frame
|
||||
-> first render / EGL swap
|
||||
```
|
||||
|
||||
`seekCommandLatencyMs` 是 API request 到 command 提交的耗时;`seekRecoveryMs` 是 request 到 `PLAYBACK_RESTART` 的耗时;`seekFirstVisibleFrameMs` 是 request 到首个成功 swap 的耗时。若 MPV 没有产生对应事件,字段为 -1。每次新 seek 会重置上一次 seek 字段,不把旧会话值带入新会话。
|
||||
|
||||
模拟器 runner 使用 `+10s` 相对 seek,50 次中 49 次产生 recovery,1 次返回稳定 `SEEK / error running command`;该失败保留在 JSON,不被隐藏。精确/百分比 seek 入口仍由公共 API 暴露,但短样片不足以让输入框自动化可靠覆盖,需更长受控 fixture。
|
||||
@@ -1,19 +0,0 @@
|
||||
# Startup Pipeline
|
||||
|
||||
```text
|
||||
session setup
|
||||
-> mpv_create / mpv_initialize
|
||||
-> load command
|
||||
-> START_FILE
|
||||
-> network open / first byte (network only)
|
||||
-> FILE_LOADED (demux ready)
|
||||
-> VIDEO_RECONFIG / AUDIO_RECONFIG
|
||||
-> render context ready
|
||||
-> first video frame available
|
||||
-> first render begin/end
|
||||
-> first EGL swap (startupTotalMs)
|
||||
```
|
||||
|
||||
时间线在 core 内以 `clock_gettime(CLOCK_MONOTONIC)` 记录,所有阶段只写首次发生值。文件输入没有网络阶段时保持 -1;网络阶段只在真实 MPV log/event 证据出现时写入。`startupTotalMs` 在首个成功 `eglSwapBuffers` 写入,`firstFrameMs` 保留外壳兼容字段并与首 swap 对齐。
|
||||
|
||||
音频 renderer start 和首 callback 由 OHAudio stats poll 观察;这两个字段可能晚于真实 callback,因此用于阶段诊断,不替代设备级 audio trace。
|
||||
@@ -1,7 +0,0 @@
|
||||
# 字幕管线
|
||||
|
||||
内部字幕和外部字幕统一由 mpv/libass 管线处理。外部源通过 sub-add 加入当前 session,可选中或移除,不销毁播放 session;sub-remove 仅移除指定轨道。language/title 通过 sub-add 元数据传入,forced/default 映射为 mpv 的同名 track flags。
|
||||
|
||||
目标格式:SRT、ASS/SSA、WebVTT;ASS 默认保留原样式与 libass override 语义。上层可开关、选择字幕、调整 delay、scale、position、override(具体控件按实际可用属性开放)。
|
||||
|
||||
当前 OHOS 构建未启用 iconv,因此只接受 UTF-8/UTF8;GBK、Big5、Shift-JIS 等输入明确返回稳定 SUBTITLE 错误,不静默走 Latin-1 fallback。启用并验证 iconv 后再扩展编码白名单。Playback Lab 同时提供网络 URL 与本地 file 路径入口。
|
||||
@@ -1,5 +0,0 @@
|
||||
# Track 模型
|
||||
|
||||
上层只接收固定 Track 字段:id、type、title、language、codec、default、forced、selected、external。mpv_node 只在实现层解析,不跨 NAPI/C API 边界。
|
||||
|
||||
音频通过 aid 选择,字幕通过 sid 选择或设置为 no。语言偏好使用 mpv 的 alang/slang,可接受 zh、zho、chi、en、eng、ja、jpn 等媒体元数据值。不可用的字段保持空值或 false。
|
||||
@@ -1,10 +0,0 @@
|
||||
# Velix 主 App 集成
|
||||
|
||||
主 App 工程为 `../Velix`,当前是独立的 Stage Model/API 24 工程,目录本身没有 Git 元数据。集成脚本提供两种依赖模式:
|
||||
|
||||
- `scripts/sync-velix-core-sdk.sh --local`:从相邻 Core 重新构建并 staging,适合本地开发。
|
||||
- `scripts/sync-velix-core-sdk.sh --release --sdk PATH`:消费已经发布的 SDK 目录,适合 release 验证。
|
||||
|
||||
`scripts/build-velix-app.sh` 会先同步 SDK,再执行 `devecocli build`。主 App 只将 `libvelix_core_binding.so`、`libmpv.so.2` 与 `libc++_shared.so` 放进 `entry/libs/arm64-v8a`,不引入 Core/FFmpeg 源码。
|
||||
|
||||
ArkTS 入口为 `domain/playback/PlaybackEngine.ets` → `MpvPlaybackEngine.ets` → native binding;页面为 `pages/PlayerPage.ets`。XComponent 的 `libraryname` 为 `velix_core_binding`,Surface 回调由 Core binding 注册,页面不重复实现 EGL renderer。
|
||||
@@ -1,290 +0,0 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
This file lists all changes that can cause compatibility issues when using
|
||||
mpv through the client API (libmpv and ``client.h``). Since the client API
|
||||
interfaces to input handling (commands, properties) as well as command line
|
||||
options, you should also look at ``interface-changes.rst``.
|
||||
|
||||
Normally, changes to the C API that are incompatible to previous iterations
|
||||
receive a major version bump (i.e. the first version number is increased),
|
||||
while C API additions bump the minor version (i.e. the second number is
|
||||
increased). Changes to properties/commands/options may also lead to a minor
|
||||
version bump, in particular if they are incompatible.
|
||||
|
||||
The version number is the same as used for MPV_CLIENT_API_VERSION (see
|
||||
``client.h`` how to convert between major/minor version numbers and the flat
|
||||
32 bit integer).
|
||||
|
||||
Also, read the section ``Compatibility`` in ``client.h``, and compatibility.rst.
|
||||
|
||||
Options, commands, properties
|
||||
=============================
|
||||
|
||||
Changes to these are not listed here, but in ``interface-changes.rst``. (Before
|
||||
client API version 1.17, they were listed here partially.)
|
||||
|
||||
This listing includes changes to the bare C API and behavior only, not what
|
||||
you can access with them.
|
||||
|
||||
API changes
|
||||
===========
|
||||
|
||||
::
|
||||
|
||||
--- mpv 0.40.0 ---
|
||||
2.5 - Deprecate MPV_RENDER_PARAM_AMBIENT_LIGHT. no replacement.
|
||||
--- mpv 0.39.0 ---
|
||||
2.4 - mpv_render_param with the MPV_RENDER_PARAM_ICC_PROFILE argument no
|
||||
longer has incorrect assumptions about memory allocation and can be
|
||||
correctly used.
|
||||
--- mpv 0.38.0 ---
|
||||
2.3 - partially revert the changes from API version 1.27, remove libmpv as
|
||||
the default VO and move it to the bottom of the auto-probing order.
|
||||
This restores the prior behavior on all platforms other than macOS,
|
||||
but still auto selects libmpv/cocoa-cb on macOS if it was built with
|
||||
support for cocoa-cb.
|
||||
--- mpv 0.37.0 ---
|
||||
2.2 - add mpv_time_ns()
|
||||
--- mpv 0.36.0 ---
|
||||
2.1 - add mpv_del_property()
|
||||
--- mpv 0.35.0 ---
|
||||
2.0 - remove headers/functions of the obsolete opengl_cb API
|
||||
- remove mpv_opengl_init_params.extra_exts field
|
||||
- remove deprecated mpv_detach_destroy. Use mpv_destroy instead.
|
||||
- remove obsolete mpv_suspend and mpv_resume
|
||||
- remove deprecated SCRIPT_INPUT_DISPATCH, PAUSE and UNPAUSE, TRACKS_CHANGED
|
||||
TRACK_SWITCHED, METADATA_UPDATE, CHAPTER_CHANGE events
|
||||
--- mpv 0.33.0 ---
|
||||
1.109 - add MPV_RENDER_API_TYPE_SW and related (software rendering API)
|
||||
- deactivate the opengl_cb API (always fails to initialize now)
|
||||
The opengl_cb API was deprecated over 2 years ago. Use the render API
|
||||
instead.
|
||||
1.108 - Deprecate MPV_EVENT_IDLE
|
||||
- add mpv_event_start_file
|
||||
- add the following fields to mpv_event_end_file: playlist_entry_id,
|
||||
playlist_insert_id, playlist_insert_num_entries
|
||||
- add mpv_event_to_node()
|
||||
- add mpv_client_id()
|
||||
1.107 - Remove the deprecated qthelper.hpp. This was obviously not part of the
|
||||
libmpv API, only an "additionally" provided helper, thus this is not
|
||||
considered an API change. If you are maintaining a project that relies
|
||||
on this header, you can simply download this file and adjust the
|
||||
include statement to use it instead:
|
||||
|
||||
https://raw.githubusercontent.com/mpv-player/mpv/v0.32.0/libmpv/qthelper.hpp
|
||||
|
||||
It is a good idea to write better wrappers for your use, though.
|
||||
--- mpv 0.31.0 ---
|
||||
1.107 - Deprecate MPV_EVENT_TICK
|
||||
--- mpv 0.30.0 ---
|
||||
1.106 - Add cancel_fn to mpv_stream_cb_info
|
||||
1.105 - Fix deadlock problems with MPV_RENDER_PARAM_ADVANCED_CONTROL and if
|
||||
the "vd-lavc-dr" option is enabled (which it is by default).
|
||||
There were no actual API changes.
|
||||
API users on older API versions and mpv releases should set
|
||||
"vd-lavc-dr" to "no" to avoid these issues.
|
||||
API users must still adhere to the tricky rules documented in render.h
|
||||
to avoid other deadlocks.
|
||||
1.104 - Deprecate struct mpv_opengl_drm_params. Replaced by mpv_opengl_drm_params_v2
|
||||
- Deprecate MPV_RENDER_PARAM_DRM_DISPLAY. Replaced by MPV_RENDER_PARAM_DRM_DISPLAY_V2.
|
||||
1.103 - redo handling of async commands
|
||||
- add mpv_event_command and make it possible to return values from
|
||||
commands issued with mpv_command_async() or mpv_command_node_async()
|
||||
- add mpv_abort_async_command()
|
||||
1.102 - rename struct mpv_opengl_drm_osd_size to mpv_opengl_drm_draw_surface_size
|
||||
- rename MPV_RENDER_PARAM_DRM_OSD_SIZE to MPV_RENDER_PARAM_DRM_DRAW_SURFACE_SIZE
|
||||
--- mpv 0.29.0 ---
|
||||
1.101 - add MPV_RENDER_PARAM_ADVANCED_CONTROL and related API
|
||||
- add MPV_RENDER_PARAM_NEXT_FRAME_INFO and related symbols
|
||||
- add MPV_RENDER_PARAM_BLOCK_FOR_TARGET_TIME
|
||||
- add MPV_RENDER_PARAM_SKIP_RENDERING
|
||||
- add mpv_render_context_get_info()
|
||||
1.100 - bump API number to avoid confusion with mpv release versions
|
||||
- actually apply the GL_MP_MPGetNativeDisplay change for the new render
|
||||
API. This also means compatibility for anything but x11 and wayland
|
||||
through the old opengl-cb GL_MP_MPGetNativeDisplay method is now
|
||||
unsupported.
|
||||
- deprecate mpv_get_wakeup_pipe(). It's complex, but easy to replace
|
||||
using normal API (just set a wakeup callback to a function which
|
||||
writes to a pipe).
|
||||
- add a 1st class hook API, which replaces the hacky mpv_command()
|
||||
based one. The old API is deprecated and will be removed soon. The
|
||||
old API was never meant to be stable, while the new API is.
|
||||
1.29 - the behavior of mpv_terminate_destroy() and mpv_detach_destroy()
|
||||
changes subtly (see documentation in the header file). In particular,
|
||||
mpv_detach_destroy() will not leave the player running in all
|
||||
situations anymore (it gets closer to refcounting).
|
||||
- rename mpv_detach_destroy() to mpv_destroy() (the old function will
|
||||
remain valid as deprecated alias)
|
||||
- add mpv_create_weak_client(), which makes use of above changes
|
||||
- MPV_EVENT_SHUTDOWN is now returned exactly once if a mpv_handle
|
||||
should terminate, instead of spamming the event queue with this event
|
||||
1.28 - deprecate the render opengl_cb API, and replace it with render.h
|
||||
and render_gl.h. The goal is allowing support for APIs other than
|
||||
OpenGL. The old API is emulated with the new API.
|
||||
Likewise, the "opengl-cb" VO is renamed to "libmpv".
|
||||
mpv_get_sub_api() is deprecated along the opengl_cb API.
|
||||
The new API is relatively similar, but not the same. The rough
|
||||
equivalents are:
|
||||
mpv_opengl_cb_init_gl => mpv_render_context_create
|
||||
mpv_opengl_cb_set_update_callback => mpv_render_context_set_update_callback
|
||||
mpv_opengl_cb_draw => mpv_render_context_render
|
||||
mpv_opengl_cb_report_flip => mpv_render_context_report_swap
|
||||
mpv_opengl_cb_uninit_gl => mpv_render_context_free
|
||||
The VO opengl-cb is also renamed to "libmpv".
|
||||
Also, the GL_MP_MPGetNativeDisplay pseudo extension is not used by the
|
||||
render API anymore, and the old opengl-cb API only handles the "x11"
|
||||
and "wl" names anymore. Support for everything else has been removed.
|
||||
The new render API uses proper API parameters, e.g. for X11 you pass
|
||||
MPV_RENDER_PARAM_X11_DISPLAY directly.
|
||||
- deprecate the qthelper.hpp header file. This provided some C++ helper
|
||||
utility functions for Qt with use of libmpv. There is no reason to
|
||||
keep this in the mpv git repository, nor to make it part of the libmpv
|
||||
API. If you're using this header, you can safely copy it into your
|
||||
project - it uses only libmpv public API. Alternatively, it could be
|
||||
maintained in a separate repository by interested parties.
|
||||
1.27 - make opengl-cb the default VO. This causes a subtle behavior change
|
||||
if the API user called mpv_opengl_cb_init_gl(), but does not set
|
||||
the "vo" option. Before, it would still have used another VO (like
|
||||
on the CLI, e.g. vo=gpu). Now it'll behave as if vo=opengl-cb was
|
||||
used.
|
||||
--- mpv 0.28.0 ---
|
||||
1.26 - remove glMPGetNativeDisplay("drm") support
|
||||
- add mpv_opengl_cb_window_pos and mpv_opengl_cb_drm_params and
|
||||
support via glMPGetNativeDisplay() for using it
|
||||
- make --stop-playback-on-init-failure=no the default in libmpv (just
|
||||
like in mpv CLI)
|
||||
--- mpv 0.27.0 ---
|
||||
1.25 - remove setting "no-" options via mpv_set_option*(). (See corresponding
|
||||
deprecation in 0.23.0.)
|
||||
--- mpv 0.25.0 ---
|
||||
1.24 - add a MPV_ENABLE_DEPRECATED preprocessor symbol, which can be defined
|
||||
by the user to exclude deprecated API symbols from the C headers
|
||||
--- mpv 0.23.0 ---
|
||||
1.24 - the deprecated mpv_suspend() and mpv_resume() APIs now do nothing.
|
||||
--- mpv 0.22.0 ---
|
||||
1.23 - deprecate setting "no-" options via mpv_set_option*(). For example,
|
||||
instead of "no-video=" you should set "video=no".
|
||||
- do not override the SIGPIPE signal handler anymore. This was done as
|
||||
workaround for the FFmpeg TLS code, which has been fixed long ago.
|
||||
- deprecate mpv_suspend() and mpv_resume(). They will be stubbed out
|
||||
in mpv 0.23.0.
|
||||
- make mpv_set_property() work to some degree before mpv_initialize().
|
||||
It can now be used instead of mpv_set_option().
|
||||
- semi-deprecate mpv_set_option()/mpv_set_option_string(). You should
|
||||
use mpv_set_property() instead. There are some deprecated properties
|
||||
which conflict with some options (see client.h remarks on
|
||||
mpv_set_option()), for which mpv_set_option() might still be required.
|
||||
In future mpv releases, the conflicting deprecated options/properties
|
||||
will be removed, and mpv_set_option() will internally translate API
|
||||
calls to mpv_set_property().
|
||||
- qthelper.hpp: deprecate get_property_variant, set_property_variant,
|
||||
set_option_variant, command_variant, and replace them with
|
||||
get_property, set_property, command.
|
||||
--- mpv 0.19.0 ---
|
||||
1.22 - add stream_cb API for custom protocols
|
||||
--- mpv 0.18.1 ---
|
||||
---- - remove "status" log level from mpv_request_log_messages() docs. This
|
||||
is 100% equivalent to "v". The behavior is still the same, thus no
|
||||
actual API change.
|
||||
--- mpv 0.18.0 ---
|
||||
1.21 - mpv_set_property() changes behavior with MPV_FORMAT_NODE. Before this
|
||||
change it rejected mpv_nodes with format==MPV_FORMAT_STRING if the
|
||||
property was not a string or did not have special mechanisms in place
|
||||
the function failed. Now it always invokes the option string parser,
|
||||
and mpv_node with a basic data type works exactly as if the function
|
||||
is invoked with that type directly. This new behavior is equivalent
|
||||
to mpv_set_option().
|
||||
This also affects the mp.set_property_native() Lua function.
|
||||
- generally, setting choice options/properties with "yes"/"no" options
|
||||
can now be set as MPV_FORMAT_FLAG
|
||||
- reading a choice property as MPV_FORMAT_NODE will now return a
|
||||
MPV_FORMAT_FLAG value if the choice is "yes" (true) or "no" (false)
|
||||
This implicitly affects Lua and JSON IPC interfaces as well.
|
||||
- big changes to vo-cmdline on vo_opengl and vo_opengl_hq (but not
|
||||
vo_opengl_cb): options are now normally not reset, but applied on top
|
||||
of the current options. The special undocumented value "-" still
|
||||
works, but now resets all options to before any vo-cmdline command
|
||||
has been called.
|
||||
--- mpv 0.12.0 ---
|
||||
1.20 - deprecate "GL_MP_D3D_interfaces"/"glMPGetD3DInterface", and introduce
|
||||
"GL_MP_MPGetNativeDisplay"/"glMPGetNativeDisplay" (this is a
|
||||
backwards-compatible rename)
|
||||
--- mpv 0.11.0 ---
|
||||
--- mpv 0.10.0 ---
|
||||
1.19 - add "GL_MP_D3D_interfaces" pseudo extension to make it possible to
|
||||
use DXVA2 in OpenGL fullscreen mode in some situations
|
||||
- mpv_request_log_messages() now accepts "terminal-default" as parameter
|
||||
1.18 - add MPV_END_FILE_REASON_REDIRECT, and change behavior of
|
||||
MPV_EVENT_END_FILE accordingly
|
||||
- a bunch of interface-changes.rst changes
|
||||
1.17 - mpv_initialize() now blocks SIGPIPE (details see client.h)
|
||||
--- mpv 0.9.0 ---
|
||||
1.16 - add mpv_opengl_cb_report_flip()
|
||||
- introduce mpv_opengl_cb_draw() and deprecate mpv_opengl_cb_render()
|
||||
- add MPV_FORMAT_BYTE_ARRAY
|
||||
1.15 - mpv_initialize() will now load config files. This requires setting
|
||||
the "config" and "config-dir" options. In particular, it will load
|
||||
mpv.conf.
|
||||
- minor backwards-compatible change to the "seek" and "screenshot"
|
||||
commands (new flag syntax, old additional args deprecated)
|
||||
--- mpv 0.8.0 ---
|
||||
1.14 - add mpv_wait_async_requests()
|
||||
- the --msg-level option changes its native type from a flat string to
|
||||
a key-value list (setting/reading the option as string still works)
|
||||
1.13 - add MPV_EVENT_QUEUE_OVERFLOW
|
||||
1.12 - add class Handle to qthelper.hpp
|
||||
- improve opengl_cb.h API uninitialization behavior, and fix the qml
|
||||
example
|
||||
- add mpv_create_client() function
|
||||
1.11 - add OpenGL rendering interop API - allows an application to combine
|
||||
its own and mpv's OpenGL rendering
|
||||
Warning: this API is not stable yet - anything in opengl_cb.h might
|
||||
be changed in completely incompatible ways in minor API bumps
|
||||
--- mpv 0.7.0 ---
|
||||
1.10 - deprecate/disable everything directly related to script_dispatch
|
||||
(most likely affects nobody)
|
||||
1.9 - add enum mpv_end_file_reason for mpv_event_end_file.reason
|
||||
- add MPV_END_FILE_REASON_ERROR and the mpv_event_end_file.error field
|
||||
for slightly better error reporting on playback failure
|
||||
- add --stop-playback-on-init-failure option, and make it the default
|
||||
behavior for libmpv only
|
||||
- add qthelper.hpp set_option_variant()
|
||||
- mark the following events as deprecated:
|
||||
MPV_EVENT_TRACKS_CHANGED
|
||||
MPV_EVENT_TRACK_SWITCHED
|
||||
MPV_EVENT_PAUSE
|
||||
MPV_EVENT_UNPAUSE
|
||||
MPV_EVENT_METADATA_UPDATE
|
||||
MPV_EVENT_CHAPTER_CHANGE
|
||||
They are handled better with mpv_observe_property() as mentioned in
|
||||
the documentation comments. They are not removed and still work.
|
||||
1.8 - add qthelper.hpp
|
||||
1.7 - add mpv_command_node(), mpv_command_node_async()
|
||||
1.6 - modify "core-idle" property behavior
|
||||
- MPV_EVENT_LOG_MESSAGE now always sends complete lines
|
||||
- introduce numeric log levels (mpv_log_level)
|
||||
--- mpv 0.6.0 ---
|
||||
1.5 - change in X11 and "--wid" behavior again. The previous change didn't
|
||||
work as expected, and now the behavior can be explicitly controlled
|
||||
with the "input-x11-keyboard" option. This is only a temporary
|
||||
measure until XEmbed is implemented and confirmed working.
|
||||
Note: in 1.6, "input-x11-keyboard" was renamed to "input-vo-keyboard",
|
||||
although the old option name still works.
|
||||
1.4 - subtle change in X11 and "--wid" behavior
|
||||
(this change was added to 0.5.2, and broke some things, see #1090)
|
||||
--- mpv 0.5.0 ---
|
||||
1.3 - add MPV_MAKE_VERSION()
|
||||
1.2 - remove "stream-time-pos" property (no replacement)
|
||||
1.1 - remap dvdnav:// to dvd://
|
||||
- add "--cache-file", "--cache-file-size"
|
||||
- add "--colormatrix-primaries" (and property)
|
||||
- add "primaries" sub-field to image format properties
|
||||
- add "playback-time" property
|
||||
- extend the "--start" option; a leading "+", which was previously
|
||||
insignificant is now significant
|
||||
- add "cache-free" and "cache-used" properties
|
||||
- macOS: the "coreaudio" AO spdif code is split into a separate AO
|
||||
--- mpv 0.4.0 ---
|
||||
1.0 - the API is declared stable
|
||||
@@ -0,0 +1,139 @@
|
||||
Coding style
|
||||
============
|
||||
|
||||
mpv uses C99 with K&R formatting, with some exceptions.
|
||||
|
||||
General formatting
|
||||
------------------
|
||||
|
||||
- Use the K&R indent style.
|
||||
- Use 4 spaces of indentation, never use tabs (except in Makefiles).
|
||||
- Add a single space between keywords and binary operators. There are some other
|
||||
cases where spaces should be added. Example:
|
||||
|
||||
```C
|
||||
if ((a * b) > c) {
|
||||
// code
|
||||
some_function(a, b, c);
|
||||
}
|
||||
```
|
||||
- Break lines on 80 columns. There is a hard limit of 85 columns. You may ignore
|
||||
this limit if there's a strong case that not breaking the line will increase
|
||||
readability. Going over 85 columns might provoke endless discussions about
|
||||
whether such a limit is needed or not, so avoid it.
|
||||
- If the body of an if/for/while statement has more than 1 physical lines, then
|
||||
always add braces, even if they're technically redundant.
|
||||
|
||||
Bad:
|
||||
|
||||
```C
|
||||
if (a)
|
||||
// do something if b
|
||||
if (b)
|
||||
do_something();
|
||||
```
|
||||
|
||||
Good:
|
||||
|
||||
```C
|
||||
if (a) {
|
||||
// do something if b
|
||||
if (b)
|
||||
do_something();
|
||||
}
|
||||
```
|
||||
- If the body of an if statement uses braces, the else branch should also
|
||||
use braces (and reverse).
|
||||
|
||||
Example:
|
||||
|
||||
```C
|
||||
if (a) {
|
||||
// do something
|
||||
something();
|
||||
something_else();
|
||||
} else {
|
||||
one_line();
|
||||
}
|
||||
```
|
||||
- If an if condition spans multiple physical lines, then put the opening brace
|
||||
for the if body on the next physical line. (Also, preferably always add a
|
||||
brace, even if technically none is needed.)
|
||||
|
||||
Example:
|
||||
|
||||
```C
|
||||
if (very_long_condition_a &&
|
||||
very_long_condition_b)
|
||||
{
|
||||
code();
|
||||
}
|
||||
```
|
||||
- Remove any trailing whitespace.
|
||||
- If the file you're editing uses formatting different from from what is
|
||||
described here, it's probably an old file from times when nobody followed a
|
||||
consistent style. You're free to use the existing style, or the new style, or
|
||||
to send a patch to reformat the file to the new style before making functional
|
||||
changes.
|
||||
|
||||
General coding
|
||||
--------------
|
||||
|
||||
- Use C99. Also freely make use of C99 features if it's appropriate, such as
|
||||
stdbool.h.
|
||||
- Don't use GNU-only features. In some cases they may be warranted, if they
|
||||
are optional (such as attributes enabling printf-like format string checks).
|
||||
But in general, standard C99 should be used.
|
||||
- The same applies to libc functions. We have to be Windows-compatible too. Use
|
||||
functions guaranteed by C99 or POSIX only, unless your use is guarded by a
|
||||
configure check.
|
||||
- Prefer fusing declaration and initialization, rather than putting declarations
|
||||
on the top of a block. Obvious data flow is more important than avoiding
|
||||
mixing declarations and statements, which is just a C90 artifact.
|
||||
- tech-overview.txt might help to get an overview how mpv is structured.
|
||||
- If you add features that require intrusive changes, discuss them on the dev
|
||||
channel first. There might be a better way to add a feature and it can avoid
|
||||
wasted work.
|
||||
|
||||
Sending patches
|
||||
---------------
|
||||
|
||||
- Make a github pull request, or send a link to a plaintext patch created with
|
||||
``git format-patch``. diffs posted as pastebins (especially if the http link
|
||||
returns HTML) just cause extra work for everyone, because they lack commit
|
||||
message and authorship information.
|
||||
- Write informative commit messages. Use present tense to describe the
|
||||
situation with the patch applied, and past tense for the situation before
|
||||
the change.
|
||||
- The subject line (the first line in a commit message) should contain a
|
||||
prefix identifying the sub system, followed by a short description what
|
||||
impact this commit has. This subject line shouldn't be longer than 72
|
||||
characters, because it messes up the output of many git tools otherwise.
|
||||
|
||||
For example, you fixed a crash in af_volume.c:
|
||||
|
||||
Bad: ``fixed the bug (wtf?)``
|
||||
Good: ``af_volume: fix crash due to null pointer access``
|
||||
|
||||
Having a prefix gives context, and is especially useful when trying to find
|
||||
a specific change by looking at the history, or when running ``git blame``.
|
||||
- The body of the commit message (everything else after the subject line) should
|
||||
be as informative as possible and contain everything that isn't obvious. Don't
|
||||
hesitate to dump as much information as you can - it doesn't cost you
|
||||
anything. Put some effort into it. If someone finds a bug months or years
|
||||
later, and finds that it's caused by your commit (even though your commit was
|
||||
supposed to fix another bug), it would be bad if there wasn't enough
|
||||
information to test the original bug. The old bug might be reintroduced while
|
||||
fixing the new bug.
|
||||
|
||||
The commit message should be wrapped on 72 characters per line, because git
|
||||
tools usually do not break text automatically. On the other hand, you do not
|
||||
need to break text that would be unnatural to break (like data for test cases,
|
||||
or long URLs).
|
||||
|
||||
Important: put an empty line between the subject line and the commit message.
|
||||
If this is missing, it will break display in common git tools.
|
||||
- Try to separate cosmetic and functional changes. It's ok to make a few
|
||||
additional cosmetic changes in the same file you're working on, but don't do
|
||||
something like reformatting a whole file and hiding an actual functional
|
||||
change in the same commit.
|
||||
@@ -1,195 +0,0 @@
|
||||
CLI and API compatibility policy
|
||||
================================
|
||||
|
||||
Human users and API users rely on the mpv/libmpv/scripting/IPC interface not
|
||||
breaking their use case. On the other hand, active development occasionally
|
||||
requires breaking things, such as removing old options or changing options in
|
||||
a way that may break.
|
||||
|
||||
This document lists rules when, what, and how incompatible changes can be made.
|
||||
It's interesting both for mpv developers, who want to change user-visible parts,
|
||||
and mpv users, who want to know what is guaranteed to remain stable.
|
||||
|
||||
Any of the rules below may be overridden by statements in more specific
|
||||
documentation (for example, if the manpage says that a particular option may be
|
||||
removed any time, it means that, and the option probably won't even go through
|
||||
deprecation).
|
||||
|
||||
Additions
|
||||
---------
|
||||
|
||||
Additions are basically always allowed. API users etc. are supposed to deal with
|
||||
the possibility that for example new API functions are added. Some parts of the
|
||||
API may document how they are extended.
|
||||
|
||||
Options, commands, properties, events, hooks (command interface)
|
||||
----------------------------------------------------------------
|
||||
|
||||
All of these are important for interfacing both with end users and API users
|
||||
(which include Lua scripts, libmpv, and the JSON IPC). As such, they constitute
|
||||
a large part of the user interface and APIs.
|
||||
|
||||
Certain options and commands may have documented default values. These default
|
||||
values are considered a part of the API since scripts may already rely on these
|
||||
documented behaviors. Changing these defaults are considered incompatible
|
||||
changes and must be documented. Undocumented default values do not subject to
|
||||
this requirement, and it is recommended to discourage such usage in the related
|
||||
documentations if there is a need to frequently change such defaults.
|
||||
|
||||
All incompatible changes to this must be declared in interface-changes.rst,
|
||||
which include the types of changes, the impact of these changes, and suggested
|
||||
actions to address such impact so that the incompatibility is alleviated.
|
||||
(This may also list compatible additions, but it's not a requirement.)
|
||||
|
||||
Degrees of importance and compatibility preservation
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Critical and central parts of the command interface have the strictest
|
||||
requirements. It may not be reasonable to break them, and other means to achieve
|
||||
some change have to be found. For example, the "seek" command is a bit of a
|
||||
mess, but since changing it would likely affect almost every user, it may be
|
||||
impossible to break at least the commonly used syntax. If changed anyway, there
|
||||
should be a deprecation period of at least 1 year, during which the command
|
||||
still works, and possibly a warning should remain even after this.
|
||||
|
||||
Important/often used parts must be deprecated for at least 2 releases before
|
||||
they can be broken. There must be at least 1 release where the deprecated
|
||||
functionality still works, and a replacement is available (if technically
|
||||
reasonable). For example, a feature deprecated in mpv 0.30.0 may be removed in
|
||||
mpv 0.32.0. Minor releases do not count towards this.
|
||||
|
||||
Under extraordinary circumstances, such as missed incompatible changes that are
|
||||
already included in a release, critical security fixes, or a severe shortage of
|
||||
developer time to address the known incompatible changes, important/often used
|
||||
parts may be broken immediately, but the change must be extensively documented:
|
||||
all of the related documentations (including manpage, interface-changes.rst,
|
||||
etc., retrospectively modified if applicable) must clearly state the following:
|
||||
the fact that the change is a breaking change; the version when the breaking
|
||||
change happened; and the reason, impact, and suggested remedy actions.
|
||||
|
||||
Less useful parts can be broken immediately, but must come with some sort of
|
||||
removal warning.
|
||||
|
||||
Parts for debugging and testing may be removed any time, potentially even
|
||||
without any sort of documentation.
|
||||
|
||||
Currently, the importance of a part is not documented and not even well-defined,
|
||||
which is probably a mistake.
|
||||
|
||||
Renaming or removing options
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Typically, renaming an option can be done in a compatible way with OPT_REPLACED.
|
||||
You may need to check whether the corresponding properties still work (including
|
||||
messy details like observing properties for changes).
|
||||
|
||||
OPT_REMOVED can be used to inform the user of alternatives or reasons for the
|
||||
removal, which is better than an option not found error. Likewise,
|
||||
m_option.deprecation_message should be set to something helpful.
|
||||
|
||||
Both OPT_REPLACED and OPT_REMOVED can remain in the code for a long time, since
|
||||
they're unintrusive and hopefully make incompatible changes less painful for
|
||||
users.
|
||||
|
||||
Scripting APIs
|
||||
--------------
|
||||
|
||||
This affects internal scripting APIs (currently Lua and JavaScript).
|
||||
|
||||
Vaguely the same rules as with the command interface apply. Since there is a
|
||||
large number of scripts, an effort should be made to provide compatibility
|
||||
for old scripts, but it does not need to be stronger than that of the command
|
||||
interface.
|
||||
|
||||
Undocumented parts of the scripting APIs are _not_ guaranteed for compatibility.
|
||||
This applies especially for internals. Languages like Lua do not have strict
|
||||
access control (nor does the mpv code try to emulate any), so if a script
|
||||
accesses private parts, and breaks on the next mpv release, it's not mpv's
|
||||
problem.
|
||||
|
||||
JSON IPC
|
||||
--------
|
||||
|
||||
The JSON IPC is a thin protocol wrapping the libmpv API and the command
|
||||
interface. Compatibility-wise, it's about the same as the scripting APIs.
|
||||
The JSON protocol commands should remain as compatible as possible, and it
|
||||
should probably accept the current way commands are delimited (line breaks)
|
||||
forever.
|
||||
|
||||
The protocol may accept non-standard JSON extensions, but only standard JSON
|
||||
(possibly with restrictions) is guaranteed for compatibility. Clients which want
|
||||
to remain compatible should not use any extensions.
|
||||
|
||||
CLI
|
||||
---
|
||||
|
||||
Things such as default key bindings do not necessarily require compatibility.
|
||||
However, the release notes should be extremely clear on changes to "important"
|
||||
key bindings. Bindings which restore the old behavior should be added to
|
||||
restore-old-bindings.conf and restore-osc-bindings.conf.
|
||||
|
||||
Some option parsing is CLI-only and not available from libmpv or scripting. No
|
||||
compatibility guarantees come with them. However, the rules which mpv uses to
|
||||
distinguish between options and filenames must remain consistent (if the
|
||||
non-deprecated options syntax is used).
|
||||
|
||||
Terminal and log output
|
||||
-----------------------
|
||||
|
||||
There are no compatibility guarantees for the terminal output, or the text
|
||||
logged via ``MPV_EVENT_LOG_MESSAGE`` and similar APIs. In particular, scripts
|
||||
invoking mpv CLI are extremely discouraged from trying to parse text output,
|
||||
and should use other mechanisms such as the JSON IPC.
|
||||
|
||||
Protocols, filters, demuxers, etc.
|
||||
----------------------------------
|
||||
|
||||
Which of these are present is generally not guaranteed, and can even depend
|
||||
on compile time settings.
|
||||
|
||||
The filter list and their sub-options are considered part of the
|
||||
command-interface.
|
||||
|
||||
libmpv C API
|
||||
------------
|
||||
|
||||
The libmpv client API (such as ``<mpv/client.h>``) mostly gives access to
|
||||
the command interface. The API itself (if looked at as a component separate
|
||||
from the command interface) is intended to be extremely stable.
|
||||
|
||||
All API changes are documented in client-api-changes.rst.
|
||||
|
||||
API compatibility
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
The API is *always* compatible. Incompatible changes are only allowed on major
|
||||
API version changes (see ``MPV_CLIENT_API_VERSION``). A major version change is
|
||||
an extremely rare event, which means usually no API symbols are ever removed.
|
||||
|
||||
Essentially removing API functions by making them always return an error, or
|
||||
making it do nothing is allowed in cases where it is unlikely to break most
|
||||
clients, but requires a deprecation period of 2 releases. (This has happened to
|
||||
``mpv_suspend()`` for example.)
|
||||
|
||||
API symbols can be deprecated. This should be clearly marked in the doxygen
|
||||
with ``@deprecated``, and if possible, the affected API symbols should not be
|
||||
visible if the API user defines ``MPV_ENABLE_DEPRECATED`` to 0.
|
||||
|
||||
ABI compatibility
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ABI must never be broken, except on major API version changes. For example,
|
||||
constants don't change their values.
|
||||
|
||||
Structs are tricky. If a struct can be allocated by a user (such as ``mpv_node``),
|
||||
no fields can be added. (Unless it's an union, and the addition does not change
|
||||
the offset or alignment of any of the fields or the struct itself. This has
|
||||
happened to ``mpv_node`` in the past.) If a struct is allocated by libmpv only,
|
||||
new fields can be appended to the end (for example ``mpv_event``).
|
||||
|
||||
The ABI is only backward compatible. This means if a host application is linked
|
||||
to an older libmpv, and libmpv is updated to a newer version, it will still
|
||||
work (as in not causing any undefined behavior).
|
||||
|
||||
Forward compatibility (an application would work with an older libmpv than it
|
||||
was linked to) is not required.
|
||||
@@ -1,284 +0,0 @@
|
||||
# Compiling for Windows
|
||||
|
||||
Compiling for Windows is supported using GNU-like compilers (GCC/Clang). Clang
|
||||
is compatible with both the ``w64-windows-gnu`` [MinGW-w64](https://www.mingw-w64.org/)
|
||||
and ``pc-windows-msvc`` [Windows SDK](https://developer.microsoft.com/windows/downloads/windows-sdk)
|
||||
targets. It supports the production of both 32-bit and 64-bit binaries and is
|
||||
suitable for building on Windows as well as cross-compiling from Linux and Cygwin.
|
||||
|
||||
Although it is possible to build a complete MinGW-w64 toolchain yourself, there
|
||||
are build environments and scripts available to simplify the process, such as
|
||||
MSYS2 on Windows or a packaged toolchain provided by your favorite Linux
|
||||
distribution. Note that MinGW-w64 environments included in Linux distributions
|
||||
can vary in versions. As a general guideline, mpv only supports the MinGW-w64
|
||||
toolchain version included in the latest Ubuntu LTS release.
|
||||
|
||||
mpv employs Meson for building, and the process is the same as any standard Meson
|
||||
compilation.
|
||||
|
||||
For the most up-to-date reference on build scripts, you can refer to
|
||||
[build.yml](https://github.com/mpv-player/mpv/blob/master/.github/workflows/build.yml),
|
||||
which builds and tests all supported configurations: ``MinGW-w64``, ``Windows SDK``,
|
||||
and ``MSYS2`` builds.
|
||||
|
||||
## Cross-compilation
|
||||
|
||||
When cross-compiling, it is recommended to use a Meson ``--cross-file`` to set up the
|
||||
cross-compiling environment. For a basic example, please refer to
|
||||
[Cross-compilation](https://mesonbuild.com/Cross-compilation.html).
|
||||
|
||||
Alternatively, consider using [mpv-winbuild-cmake](https://github.com/shinchiro/mpv-winbuild-cmake),
|
||||
which bootstraps a MinGW-w64 toolchain and builds mpv along with its dependencies.
|
||||
|
||||
### Example with Meson
|
||||
|
||||
1. Create ``cross-file.txt`` with definitions for your toolchain and target platform.
|
||||
Refer to [x86_64-w64-mingw32.txt](https://mesonbuild.com/Cross-compilation.html)
|
||||
as a directly usable example.
|
||||
- **Important**: Beware of pkg-config usage. By default, it uses build machine
|
||||
files for dependency detection, even when ``--cross-file`` is used. It must
|
||||
be configured correctly. Refer to ``pkg_config_libdir`` and ``sys_root``
|
||||
in the [documentation](https://mesonbuild.com/Cross-compilation.html#defining-the-environment)
|
||||
for proper setup. **In this example pkg-config is not used/required.**
|
||||
2. Initialize subprojects. This step is optional; other methods are also
|
||||
available to provide the necessary dependencies.
|
||||
|
||||
``` bash
|
||||
# Update the subprojects database from Meson's WrapDB.
|
||||
meson wrap update-db
|
||||
|
||||
# Explicitly download wraps as nested projects may have older versions of them.
|
||||
meson wrap install expat
|
||||
meson wrap install harfbuzz
|
||||
meson wrap install libpng
|
||||
meson wrap install zlib
|
||||
|
||||
# Add wraps for mpv's required dependencies
|
||||
mkdir -p subprojects
|
||||
|
||||
cat <<EOF > subprojects/libplacebo.wrap
|
||||
[wrap-git]
|
||||
url = https://github.com/haasn/libplacebo
|
||||
revision = master
|
||||
depth = 1
|
||||
clone-recursive = true
|
||||
EOF
|
||||
|
||||
cat <<EOF > subprojects/libass.wrap
|
||||
[wrap-git]
|
||||
revision = master
|
||||
url = https://github.com/libass/libass
|
||||
depth = 1
|
||||
EOF
|
||||
|
||||
# For FFmpeg, use Meson's build system port; alternatively, you can compile
|
||||
# the upstream version yourself. See https://trac.ffmpeg.org/wiki/CompilationGuide
|
||||
cat <<EOF > subprojects/ffmpeg.wrap
|
||||
[wrap-git]
|
||||
url = https://gitlab.freedesktop.org/gstreamer/meson-ports/ffmpeg.git
|
||||
revision = meson-8.1
|
||||
depth = 1
|
||||
[provide]
|
||||
libavcodec = libavcodec_dep
|
||||
libavdevice = libavdevice_dep
|
||||
libavfilter = libavfilter_dep
|
||||
libavformat = libavformat_dep
|
||||
libavutil = libavutil_dep
|
||||
libswresample = libswresample_dep
|
||||
libswscale = libswscale_dep
|
||||
EOF
|
||||
```
|
||||
|
||||
3. Build
|
||||
|
||||
``` bash
|
||||
meson setup -Ddefault_library=static -Dprefer_static=true \
|
||||
-Dc_link_args='-static' -Dcpp_link_args='-static' \
|
||||
--cross-file cross-file.txt build
|
||||
|
||||
ninja -C build mpv.exe mpv.com
|
||||
```
|
||||
|
||||
This will produce fully portabiel, statically linked, ``mpv.exe`` and ``mpv.com``
|
||||
binaries.
|
||||
|
||||
#### Building libmpv
|
||||
|
||||
- To also build ``libmpv``, execute the following commands:
|
||||
|
||||
``` bash
|
||||
# For a static library
|
||||
meson configure build -Dlibmpv=true -Ddefault_library=static
|
||||
ninja -C build libmpv.a
|
||||
|
||||
# For a shared library
|
||||
meson configure build -Dlibmpv=true -Ddefault_library=shared
|
||||
ninja -C build libmpv-2.dll
|
||||
```
|
||||
|
||||
- Depending on the use case, you might want to use ``-Dgpl=false`` and review
|
||||
similar options for subprojects.
|
||||
- If any of Meson's subprojects are not linked statically, you might need to
|
||||
specify options like the following example for ffmpeg:
|
||||
``-Dffmpeg:default_library=static``.
|
||||
|
||||
#### Enabling more mpv features
|
||||
|
||||
The process above produces a basic mpv build. You can enable additional features.
|
||||
Check the Meson
|
||||
[WrapDB packages](https://mesonbuild.com/Wrapdb-projects.html) for available
|
||||
dependencies or by providing them through other means.
|
||||
|
||||
Enhancing mpv with more features is as simple as adding more arguments to the
|
||||
Meson setup command, for example:
|
||||
|
||||
``` bash
|
||||
-Dlua=enabled -Djavascript=enabled -Dlcms2=enabled -Dlibplacebo:lcms=enabled
|
||||
```
|
||||
|
||||
they will be automatically downloaded and built by Meson.
|
||||
|
||||
## Native Compilation with Clang (Windows SDK Build)
|
||||
|
||||
1. Install [Build Tools for Visual Studio](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2022)
|
||||
or the full [Visual Studio](https://visualstudio.microsoft.com/downloads/#visual-studio-community-2022):
|
||||
- From the installer, select the necessary components:
|
||||
- Clang compiler for Windows
|
||||
- C++ CMake tools for Windows
|
||||
- Windows SDK
|
||||
- Activate the developer shell. The target and host architecture must match
|
||||
(e.g. `amd64` for x86_64, `arm64` for ARM64):
|
||||
```
|
||||
& "<Visual Studio Path>\Common7\Tools\Launch-VsDevShell.ps1" -Arch amd64 -HostArch amd64 -SkipAutomaticLocation | Out-Null
|
||||
```
|
||||
2. Install the remaining build tools that are not part of the Visual Studio installer:
|
||||
- [Meson](https://mesonbuild.com/Getting-meson.html), the build system.
|
||||
- [NASM](https://www.nasm.us/), required to assemble the hand-written assembly
|
||||
in FFmpeg, dav1d and aom. Make sure it is in `PATH`.
|
||||
- [Rust](https://www.rust-lang.org/tools/install) (via `rustup`), required to
|
||||
build mpv's Rust components and the `subrandr` subproject. A **nightly**
|
||||
toolchain is needed, as the build relies on Cargo's unstable `-C` option:
|
||||
|
||||
```powershell
|
||||
rustup default nightly
|
||||
```
|
||||
|
||||
3. The following build script utilizes the Meson subprojects system to build mpv and its dependencies.
|
||||
To make sure all dependency versions are up-to-date, update the subprojects database from Meson's WrapDB.
|
||||
Also explicitly download several wraps as some nested projects may pull older versions of them.
|
||||
```
|
||||
meson wrap update-db
|
||||
|
||||
meson wrap install expat
|
||||
meson wrap install harfbuzz
|
||||
meson wrap install libpng
|
||||
meson wrap install zlib
|
||||
```
|
||||
4. Set environment variables so Meson uses the Clang/LLVM toolchain, or pass an
|
||||
equivalent `--native-file` to Meson.
|
||||
```powershell
|
||||
$env:CC = 'clang'
|
||||
$env:CXX = 'clang++'
|
||||
$env:CC_LD = 'lld-link'
|
||||
$env:CXX_LD = 'lld-link'
|
||||
$env:RUST_LD = 'lld-link'
|
||||
$env:WINDRES = 'llvm-rc'
|
||||
```
|
||||
Note that some dependencies (e.g. LuaJIT) may require `sed` to configure. Fortunately, it is already bundled in
|
||||
[Git for Windows](https://www.git-scm.com/download/win):
|
||||
```powershell
|
||||
$env:PATH += ';<Git Path>\usr\bin'
|
||||
```
|
||||
5. Execute [ci\build-win32.ps1](https://github.com/mpv-player/mpv/blob/master/ci/build-win32.ps1). Refer to the script for more details.
|
||||
|
||||
This process will produce a fully static ``mpv.exe`` and ``mpv.com``, as well as
|
||||
a static ``libmpv.a``.
|
||||
|
||||
## Native Compilation with MSYS2
|
||||
|
||||
For Windows developers seeking a quick setup, MSYS2 is an effective tool for
|
||||
compiling mpv natively on a Windows machine. The MSYS2 repositories provide
|
||||
binary packages for most of mpv's dependencies, simplifying the process to
|
||||
primarily involve building mpv itself.
|
||||
|
||||
### Installing MSYS2
|
||||
|
||||
1. Follow the installation steps from [MSYS2](https://www.msys2.org/).
|
||||
2. Initiate one of the [Environments](https://www.msys2.org/docs/environments/),
|
||||
with the CLANG64 (``clang64.exe``) being the recommended option.
|
||||
**Note:** This environment is distinct from the MSYS2 shell that opens
|
||||
automatically after the final installation dialog. You must close that
|
||||
initial shell and open a new one for the appropriate environment.
|
||||
|
||||
### Updating MSYS2
|
||||
|
||||
For guidance on updating MSYS2, please refer to the official documentation:
|
||||
[Updating MSYS2](https://www.msys2.org/docs/updating/).
|
||||
|
||||
### Installing mpv Dependencies
|
||||
|
||||
``` bash
|
||||
# Install pacboy and git
|
||||
pacman -S pactoys git
|
||||
|
||||
# Install MSYS2 build dependencies and a MinGW-w64 compiler
|
||||
pacboy -S python pkgconf cc meson
|
||||
|
||||
# Install key dependencies. libass and lcms2 are also included as dependencies
|
||||
# of ffmpeg.
|
||||
pacboy -S ffmpeg libjpeg-turbo libplacebo luajit vulkan-headers
|
||||
```
|
||||
|
||||
### Building mpv
|
||||
|
||||
To compile and install mpv, execute the following commands.
|
||||
The binaries will be installed in the directory ``/$MSYSTEM_PREFIX/bin``.
|
||||
|
||||
```bash
|
||||
# Set up the build directory with the desired configuration
|
||||
meson setup build -Dlibmpv=true --prefix=$MSYSTEM_PREFIX
|
||||
|
||||
# Compile
|
||||
meson compile -C build
|
||||
|
||||
# Optionally, install the compiled binaries
|
||||
meson install -C build
|
||||
```
|
||||
|
||||
## Running mpv
|
||||
|
||||
Depending on your build configuration, ``mpv.exe`` may rely on external
|
||||
libraries. To create a portable package, you will need to include these
|
||||
dependencies as well. The quickest way to determine which libraries are needed
|
||||
is to run ``mpv.exe`` and note any error messages that list the required ``.dll``
|
||||
files. You can find these libraries in the sysroot used for compilation, such as
|
||||
``/clang64/bin/`` in MSYS2.
|
||||
|
||||
## Linking libmpv with MSVC Programs
|
||||
|
||||
Building mpv/libmpv directly with the MSVC compiler (cl.exe) is not supported
|
||||
due to differences in compiler flags. Our build system is designed specifically
|
||||
for GNU-like compiler drivers. However, you can still build programs in
|
||||
Visual Studio and link them with libmpv.
|
||||
|
||||
When ``libmpv`` is built with the recommended Clang/``lld-link`` toolchain,
|
||||
``lld-link`` emits an import library (``mpv.lib``) next to the DLL in the build
|
||||
directory. Add that ``mpv.lib`` to your MSVC project.
|
||||
|
||||
To generate an import library from a DLL yourself, first create a ``.def`` file
|
||||
listing its exports. There are several ways to do this. One is ``gendef``, which
|
||||
writes a ``.def``, based on DLL.
|
||||
|
||||
```bash
|
||||
gendef libmpv-2.dll
|
||||
```
|
||||
|
||||
Then build the import library from it. ``/name`` must match the DLL filename, and
|
||||
``/machine`` must match the DLL's architecture (e.g. ``x64`` or ``arm64``):
|
||||
|
||||
```bash
|
||||
lib /def:libmpv-2.def /name:libmpv-2.dll /out:mpv.lib /machine:x64
|
||||
```
|
||||
|
||||
**Note:** Static linking is only feasible with matching compilers. For instance,
|
||||
if you build with Clang in Visual Studio, static linking is possible.
|
||||
@@ -1,314 +0,0 @@
|
||||
How to contribute
|
||||
=================
|
||||
|
||||
General
|
||||
-------
|
||||
|
||||
The main contact for mpv development is IRC, specifically #mpv
|
||||
and #mpv-devel on Libera.chat. GitHub is used for code review and
|
||||
long term discussions.
|
||||
|
||||
Sending patches
|
||||
---------------
|
||||
|
||||
- Make a GitHub pull request, or send a link to a plaintext patch created with
|
||||
``git format-patch``.
|
||||
- Plain diffs posted as pastebins are not acceptable! (Especially if the http
|
||||
link returns HTML.) They only cause extra work for everyone, because they lack
|
||||
commit message and authorship information.
|
||||
- Never send patches to any of the developers email addresses.
|
||||
- If your changes are not supposed to be merged immediately, mark them as
|
||||
"[RFC]" in the commit message or the pull request title.
|
||||
- Be sure to test your changes. If you didn't, please say so in the commit
|
||||
message and the pull request text.
|
||||
|
||||
Copyright of contributions
|
||||
--------------------------
|
||||
|
||||
- The copyright belongs to contributors. The project is a collaborative work. By
|
||||
sending your changes, you agree to license your contributions according to the
|
||||
requirements of this project.
|
||||
- All new code must be LGPLv2.1+ licensed, or come with the implicit agreement
|
||||
that it will be relicensed to LGPLv2.1+ later (see ``Copyright`` in the
|
||||
repository root directory).
|
||||
- 100% compatible licenses are allowed too.
|
||||
- Changes in files with more liberal licenses (such as BSD, MIT, or ISC) are
|
||||
assumed to be dual-licensed under LGPLv2.1+ and the license indicated in the
|
||||
file header.
|
||||
- You must be either the exclusive author of the patch, or acknowledge all
|
||||
authors involved in the commit message. If you take 3rd party code, authorship
|
||||
and copyright must be properly acknowledged. If you're making changes on
|
||||
behalf of your employer, and the employer owns the copyright, you must mention
|
||||
this. If the license of the code is not LGPLv2.1+, you must mention this.
|
||||
- These license statements are legally binding.
|
||||
- Don't use fake names (something that looks like an actual name, and may be
|
||||
someone else's name, but is not your legal name). Using a pseudonym is
|
||||
allowed if it can be used to identify or contact you, even if whatever
|
||||
account you used to submit the patch dies.
|
||||
- Do not add your name to the license header. This convention is not used by
|
||||
this project, and neither copyright law nor any of the used licenses require
|
||||
it.
|
||||
|
||||
Write good commit messages
|
||||
--------------------------
|
||||
|
||||
- Write informative commit messages. Use present tense to describe the
|
||||
situation with the patch applied, and past tense for the situation before
|
||||
the change.
|
||||
- The subject line (the first line in a commit message) must contain a
|
||||
prefix identifying the sub system, followed by a short description what
|
||||
impact this commit has. This subject line and the commit message body
|
||||
must not be longer than 72 characters per line, because it messes up the
|
||||
output of many git tools otherwise.
|
||||
|
||||
For example, you fixed a crash in af_volume.c:
|
||||
|
||||
- Bad: ``fixed the bug (wtf?)``
|
||||
- Good: ``af_volume: fix crash due to null pointer access``
|
||||
|
||||
Having a prefix gives context, and is especially useful when trying to find
|
||||
a specific change by looking at the history, or when running ``git blame``.
|
||||
|
||||
Sample prefixes: ``vo_gpu: ...``, ``command: ...``, ``DOCS/input: ...``,
|
||||
``TOOLS/osxbundle: ...``, ``osc.lua: ...``, etc. You can always check the git
|
||||
log for commits which modify specific files to see which prefixes are used.
|
||||
|
||||
- The first word after the ``:`` is lower case.
|
||||
- Don't end the subject line with a ``.``.
|
||||
- Put an empty line between the subject line and the commit message.
|
||||
If this is missing, it will break display in common git tools.
|
||||
- The body of the commit message (everything else after the subject line) must
|
||||
be as informative as possible and contain everything that isn't obvious. Don't
|
||||
hesitate to dump as much information as you can - it doesn't cost you
|
||||
anything. Put some effort into it. If someone finds a bug months or years
|
||||
later, and finds that it's caused by your commit (even though your commit was
|
||||
supposed to fix another bug), it would be bad if there wasn't enough
|
||||
information to test the original bug. The old bug might be reintroduced while
|
||||
fixing the new bug.
|
||||
|
||||
The commit message must be wrapped on 72 characters per line, because git
|
||||
tools usually do not break text automatically. On the other hand, you do not
|
||||
need to break text that would be unnatural to break (like data for test cases,
|
||||
or long URLs).
|
||||
- Another summary of good conventions: https://chris.beams.io/posts/git-commit/
|
||||
|
||||
Split changes into multiple commits
|
||||
-----------------------------------
|
||||
|
||||
- Follow git good practices, and split independent changes into several commits.
|
||||
It's usually OK to put them into a single pull request.
|
||||
- Try to separate cosmetic and functional changes. It's ok to make a few
|
||||
additional cosmetic changes in the same file you're working on. But don't do
|
||||
something like reformatting a whole file, and hiding an actual functional
|
||||
change in the same commit.
|
||||
- Splitting changes does _not_ mean that you should make them as fine-grained
|
||||
as possible. Commits should form logical steps in development. The way you
|
||||
split changes is important for code review and analyzing bugs.
|
||||
|
||||
Always squash fixup commits when making changes to pull requests
|
||||
----------------------------------------------------------------
|
||||
|
||||
- If you make fixup commits to your pull request, you should generally squash
|
||||
them with "git rebase -i". We prefer to have pull requests in a merge
|
||||
ready state.
|
||||
- We don't squash-merge (nor do we use GitHub's feature that does this) because
|
||||
pull requests with multiple commits are perfectly legitimate, and the only
|
||||
thing that makes sense in non-trivial cases.
|
||||
- With complex pull requests, it *may* make sense to keep them separate, but
|
||||
they should be clearly marked as such. Reviewing commits is generally easier
|
||||
with fixups squashed.
|
||||
- Reviewers are encouraged to look at individual commits instead of GitHub's
|
||||
"changes from all commits" view (which just encourages bad git and review
|
||||
practices).
|
||||
|
||||
Touching user-visible parts may require updating the mpv docs
|
||||
-------------------------------------------------------------
|
||||
|
||||
- Most user-visible things are normally documented in DOCS/man/. If your commit
|
||||
touches documented behavior, list of sub-options, etc., you need to adjust the
|
||||
documentation.
|
||||
- These changes usually go into the same commit that changes the code.
|
||||
- Changes to command line options (addition/modification/removal) must be
|
||||
documented in options.rst.
|
||||
- Changes to input properties or input commands must be documented in input.rst.
|
||||
- Changes to the libmpv API must be reflected in the libmpv's headers doxygen,
|
||||
and in client-api-changes.rst.
|
||||
|
||||
Interface change policy
|
||||
-----------------------
|
||||
|
||||
- All incompatible changes to the user interface (options, properties, commands)
|
||||
must be documented by making a new text file with a txt extension containing a
|
||||
small note in the DOCS/interface-changes directory.
|
||||
- The name of the file should be brief and related to the commit that makes the
|
||||
change. The content of the file should begin with the type of the change
|
||||
(add, remove, deprecate, change, rename, etc.). If the file contains multiple
|
||||
changes, the change which causes the most serious compatibility issues should
|
||||
be placed first.
|
||||
- Grouping multiple related changes in the same file is also OK. Just be sure to
|
||||
put each separate change on a different line.
|
||||
- Documenting additions in DOCS/interface-changes is optional but encouraged.
|
||||
- interface-changes.rst is never directly updated except when making new major
|
||||
releases.
|
||||
- See DOCS/interface-changes/example.txt for an example.
|
||||
|
||||
Code formatting
|
||||
---------------
|
||||
|
||||
mpv uses C11 with K&R formatting, with some exceptions.
|
||||
|
||||
- Use the K&R indent style.
|
||||
- Use 4 spaces of indentation, never use tabs (except in Makefiles).
|
||||
- Add a single space between keywords and binary operators. There are some other
|
||||
cases where spaces must be added. Example:
|
||||
|
||||
```C
|
||||
if ((a * b) > c) {
|
||||
// code
|
||||
some_function(a, b, c);
|
||||
}
|
||||
```
|
||||
- Break lines on 80 columns. There is a hard limit of 100 columns. You may ignore
|
||||
this limit if there's a strong case that not breaking the line will increase
|
||||
readability. Going over 100 columns might provoke endless discussions about
|
||||
whether such a limit is needed or not, so avoid it.
|
||||
- If the body of an if/for/while statement has more than 1 physical lines, then
|
||||
always add braces, even if they're technically redundant.
|
||||
|
||||
Bad:
|
||||
|
||||
```C
|
||||
if (a)
|
||||
// do something if b
|
||||
if (b)
|
||||
do_something();
|
||||
```
|
||||
|
||||
Good:
|
||||
|
||||
```C
|
||||
if (a) {
|
||||
// do something if b
|
||||
if (b)
|
||||
do_something();
|
||||
}
|
||||
```
|
||||
- If the if has an else branch, both branches must use braces, even if they're
|
||||
technically redundant.
|
||||
|
||||
Example:
|
||||
|
||||
```C
|
||||
if (a) {
|
||||
one_line();
|
||||
} else {
|
||||
one_other_line();
|
||||
}
|
||||
```
|
||||
- If an if condition spans multiple physical lines, then put the opening brace
|
||||
for the if body on the next physical line. (Also, preferably always add a
|
||||
brace, even if technically none is needed.)
|
||||
|
||||
Example:
|
||||
|
||||
```C
|
||||
if (very_long_condition_a &&
|
||||
very_long_condition_b)
|
||||
{
|
||||
code();
|
||||
} else {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
(If the if body is simple enough, this rule can be skipped.)
|
||||
- Remove any trailing whitespace.
|
||||
- Do not make stray whitespaces changes.
|
||||
|
||||
Header #include statement order
|
||||
-------------------------------
|
||||
|
||||
The order of ``#include`` statements in the source code is not very consistent.
|
||||
New code must follow the following conventions:
|
||||
|
||||
- Put standard includes (``#include <stdlib.h>`` etc.) on the top,
|
||||
- then after a blank line, add library includes (``#include <zlib.h>`` etc.)
|
||||
- then after a blank line, add internal includes (``#include "player/core.h"``)
|
||||
- sort them alphabetically within these sections
|
||||
|
||||
General coding
|
||||
--------------
|
||||
|
||||
- Use C11. Also freely make use of C11 features if it's appropriate, but do not
|
||||
use VLA and complex number types.
|
||||
- Don't use non-standard language (such as GNU C-only features). In some cases
|
||||
they may be warranted, if they are optional (such as attributes enabling
|
||||
printf-like format string checks). "#pragma once" is allowed as an exception.
|
||||
But in general, standard C11 must be used.
|
||||
- The same applies to libc functions. We have to be Windows-compatible too. Use
|
||||
functions guaranteed by C11 or POSIX only, unless your use is guarded by a
|
||||
configure check. Be mindful of MinGW-specifics since C11 support is not always
|
||||
guaranteed.
|
||||
- Prefer fusing declaration and initialization, rather than putting declarations
|
||||
on the top of a block. Obvious data flow is more important than avoiding
|
||||
mixing declarations and statements, which is just a C90 artifact.
|
||||
- If you add features that require intrusive changes, discuss them on the dev
|
||||
channel first. There might be a better way to add a feature and it can avoid
|
||||
wasted work.
|
||||
- Newly added code for any Apple Platform (macOS, iOS, etc), that uses Cocoa or
|
||||
any other object-oriented Framework or API, should be written in Swift instead
|
||||
of Objective-C. This also includes complete rewrites/refactors of existing
|
||||
code. Plain C API usages may stay as C, but can be written in Swift. Existing
|
||||
Objective-C code can stay as is, though Swift rewrites are welcome.
|
||||
|
||||
AI-assisted Contributions
|
||||
-------------------------
|
||||
|
||||
If you have used an AI/LLM for your contribution, you must disclose this in the
|
||||
PR description. Such contributions are not forbidden, but the submitter takes
|
||||
full responsibility for the code changes. This includes having full
|
||||
understanding of the code (knowing what was changed and why) and the ability to
|
||||
participate in the code review process with human-written responses. This also
|
||||
includes confirming that the code can be submitted under the same license as the
|
||||
relevant files (usually LGPLv2 or GPLv2).
|
||||
|
||||
Clearly vibe-coded patches will not be considered.
|
||||
|
||||
Code of Conduct
|
||||
---------------
|
||||
|
||||
Please note that this project is released with a Contributor Code of Conduct.
|
||||
By participating in this project you agree to abide by its terms.
|
||||
The Contributor Code of Conduct can be found here:
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct/
|
||||
|
||||
Rules for git push access
|
||||
-------------------------
|
||||
|
||||
Push access to the main git repository is handed out on an arbitrary basis. If
|
||||
you got access, the following rules must be followed:
|
||||
|
||||
- You are expected to follow the general development rules as outlined in this
|
||||
whole document.
|
||||
- You must be present on the IRC dev channel when you push something.
|
||||
- Anyone can push small fixes: typo corrections, small/obvious/uncontroversial
|
||||
bug fixes, edits to the user documentation or code comments, and so on.
|
||||
- You can freely make changes to parts of the code which you maintain. For
|
||||
larger changes, it's recommended to let others review the changes first.
|
||||
- You automatically maintain code if you wrote or modified most of it before
|
||||
(e.g. you made larger changes to it before, did partial or full rewrites, did
|
||||
major bug fixes, or you're the original author of the code). If there is more
|
||||
than one maintainer, you may need to come to an agreement with the others how
|
||||
to handle this to avoid conflict.
|
||||
- If you make a pull requests (especially if it's to code you maintain), and you
|
||||
want reviews, explicitly ping the people from which you expect reviews.
|
||||
- As a maintainer, you can approve pull requests by others to "your" code.
|
||||
- If you approve or merge 3rd party changes, make sure they follow the general
|
||||
development rules.
|
||||
- Changes to user interface and public API must always be approved by the
|
||||
project leader.
|
||||
- Seasoned project members are allowed to revert commits that broke the build,
|
||||
or broke basic functionality in a catastrophic way, and the developer who
|
||||
broke it is unavailable. (Depending on severity.)
|
||||
- Adhere to the CoC.
|
||||
- The project leader is not bound by these rules.
|
||||
@@ -0,0 +1,54 @@
|
||||
Cross compiling mpv to Windows is supported with MinGW-w64. This can be used to
|
||||
produce both 32 bit and 64 bit executables. MinGW-w64 is available from
|
||||
http://mingw-w64.sourceforge.net.
|
||||
|
||||
You have to run mpv's configure with these arguments:
|
||||
DEST_OS=win32 TARGET=i686-w64-mingw32 ./waf configure
|
||||
|
||||
Using mingw-w64-cmake to setup a MinGW-w64 environment is recommended (this will
|
||||
also build mpv and its dependencies): https://github.com/lachs0r/mingw-w64-cmake
|
||||
|
||||
Alternatively, use MXE: http://mxe.cc
|
||||
With MXE, you have to modify the file settings.mk to target MinGW-w64 (even if
|
||||
you compile to 32 bit).
|
||||
|
||||
Warning: the original MinGW (http://www.mingw.org) is unsupported.
|
||||
|
||||
Note that MinGW environments included in Linux distributions are often broken,
|
||||
outdated and useless, and usually don't use MinGW-w64.
|
||||
|
||||
Example with MXE
|
||||
================
|
||||
|
||||
# Download MXE. Note that compiling the required packages requires about 1 GB
|
||||
# or more!
|
||||
|
||||
cd /opt
|
||||
git clone https://github.com/mxe/mxe mingw
|
||||
cd mingw
|
||||
|
||||
# Edit the MXE target, so that MinGW-w64 for 32 bit targets is built.
|
||||
|
||||
echo "MXE_TARGETS := i686-w64-mingw32" > settings.mk
|
||||
|
||||
# Build required packages. The following provide a minimum required to build
|
||||
# mpv. (Not all of the following packages are strictly required.)
|
||||
|
||||
make gcc
|
||||
make ffmpeg
|
||||
make libass
|
||||
make jpeg
|
||||
make pthreads
|
||||
|
||||
# Build mpv. The target will be used to automatically select the name of the
|
||||
# build tools involved (e.g. it will use i686-w64-mingw32-gcc).
|
||||
|
||||
git clone https://github.com/mpv-player/mpv.git
|
||||
cd mpv
|
||||
export PATH=/opt/mingw/usr/bin/:$PATH
|
||||
DEST_OS=win32 TARGET=i686-w64-mingw32 ./waf configure
|
||||
./waf build
|
||||
|
||||
# This should work. Note however that MXE’s ffmpeg package might be very old
|
||||
# in order to avoid breaking e.g. xine-lib, so you might want to update that
|
||||
# or build it manually as well.
|
||||
+8
-301
@@ -27,12 +27,13 @@ The general simplified syntax is::
|
||||
<filename>,<start in seconds>,<length in seconds>
|
||||
|
||||
If the start time is omitted, 0 is used. If the length is omitted, the
|
||||
estimated remaining duration of the source file is used.
|
||||
estimated duration of the source file is used.
|
||||
|
||||
Note::
|
||||
|
||||
Usage of relative or absolute paths as well as any protocol prefixes may be
|
||||
prevented for security reasons.
|
||||
mpv can't use ordered chapter files or libquvi-resolved URLs in EDL
|
||||
entries. Usage of relative or absolute paths as well as any protocol
|
||||
prefixes is prevented for security reasons.
|
||||
|
||||
|
||||
Syntax of mpv EDL files
|
||||
@@ -51,8 +52,7 @@ The rest of the lines belong to one of these classes:
|
||||
1) An empty or commented line. A comment starts with ``#``, which must be the
|
||||
first character in the line. The rest of the line (up until the next line
|
||||
break) is ignored. An empty line has 0 bytes between two line feed bytes.
|
||||
2) A header entry if the line starts with ``!``.
|
||||
3) A segment entry in all other cases.
|
||||
2) A segment entry in all other cases.
|
||||
|
||||
Each segment entry consists of a list of named or unnamed parameters.
|
||||
Parameters are separated with ``,``. Named parameters consist of a name,
|
||||
@@ -64,8 +64,8 @@ Syntax::
|
||||
segment_entry ::= <param> ( <param> ',' )*
|
||||
param ::= [ <name> '=' ] ( <value> | '%' <number> '%' <valuebytes> )
|
||||
|
||||
The ``name`` string can consist of any characters, except ``=%,;\n!``. The
|
||||
``value`` string can consist of any characters except of ``,;\n!``.
|
||||
The ``name`` string can consist of any characters, except ``=%,;\n``. The
|
||||
``value`` string can consist of any characters except of ``,;\n``.
|
||||
|
||||
The construct starting with ``%`` allows defining any value with arbitrary
|
||||
contents inline, where ``number`` is an integer giving the number of bytes in
|
||||
@@ -78,7 +78,7 @@ The parameter name defines the meaning of the parameter:
|
||||
2) ``start``, a time value that specifies the start offset into the source file.
|
||||
3) ``length``, a time value that specifies the length of the segment.
|
||||
|
||||
See the section below for the format of timestamps.
|
||||
(Currently, time values are floating point values in seconds.)
|
||||
|
||||
Unnamed parameters carry implicit names. The parameter position determines
|
||||
which of the parameters listed above is set. For example, the second parameter
|
||||
@@ -95,299 +95,6 @@ to ``20``, ``param3`` to ``value,escaped``, ``param4`` to ``value2``.
|
||||
Instead of line breaks, the character ``;`` can be used. Line feed bytes and
|
||||
``;`` are treated equally.
|
||||
|
||||
Header entries start with ``!`` as first character after a line break. Header
|
||||
entries affect all other file entries in the EDL file. Their format is highly
|
||||
implementation specific. They should generally follow the file header, and come
|
||||
before any file entries.
|
||||
|
||||
Disabling chapter generation and copying
|
||||
========================================
|
||||
|
||||
By default, chapters from the source ranges are copied to the virtual file's
|
||||
chapters. Also, a chapter is inserted after each range. This can be disabled
|
||||
with the ``no_chapters`` header.
|
||||
|
||||
Example::
|
||||
|
||||
!no_chapters
|
||||
|
||||
|
||||
MP4 DASH
|
||||
========
|
||||
|
||||
This is a header that helps implementing DASH, although it only provides a low
|
||||
level mechanism.
|
||||
|
||||
If this header is set, the given url designates an mp4 init fragment. It's
|
||||
downloaded, and every URL in the EDL is prefixed with the init fragment on the
|
||||
byte stream level. This is mostly for use by mpv's internal ytdl support. The
|
||||
ytdl script will call youtube-dl, which in turn actually processes DASH
|
||||
manifests. It may work only for this very specific purpose and fail to be
|
||||
useful in other scenarios. It can be removed or changed in incompatible ways
|
||||
at any times.
|
||||
|
||||
Example::
|
||||
|
||||
!mp4_dash,init=url
|
||||
|
||||
The ``url`` is encoded as parameter value as defined in the general EDL syntax.
|
||||
It's expected to point to an "initialization fragment", which will be prefixed
|
||||
to every entry in the EDL on the byte stream level.
|
||||
|
||||
The current implementation will
|
||||
|
||||
- ignore stream start times
|
||||
- use durations as hint for seeking only
|
||||
- not adjust source timestamps
|
||||
- open and close segments (i.e. fragments) as needed
|
||||
- not add segment boundaries as chapter points
|
||||
- require full compatibility between all segments (same codec etc.)
|
||||
|
||||
Another header part of this mechanism is ``no_clip``. This header is similar
|
||||
to ``mp4_dash``, but does not include on-demand opening/closing of segments,
|
||||
and does not support init segments. It also exists solely to support internal
|
||||
ytdl requirements. Using ``no_clip`` with segments is not recommended and
|
||||
probably breaks. ``mp4_dash`` already implicitly does a variant of ``no_clip``.
|
||||
|
||||
The ``mp4_dash`` and ``no_clip`` headers are not part of the core EDL format.
|
||||
They may be changed or removed at any time, depending on mpv's internal
|
||||
requirements.
|
||||
|
||||
Separate files for tracks
|
||||
=========================
|
||||
|
||||
The special ``new_stream`` header lets you specify separate parts and time
|
||||
offsets for separate tracks. This can for example be used to source audio and
|
||||
video track from separate files.
|
||||
|
||||
Example::
|
||||
|
||||
# mpv EDL v0
|
||||
video.mkv
|
||||
!new_stream
|
||||
audio.mkv
|
||||
|
||||
This adds all tracks from both files to the virtual track list. Upon playback,
|
||||
the tracks will be played at the same time, instead of appending them. The files
|
||||
can contain more than 1 stream; the apparent effect is the same as if the second
|
||||
part after the ``!new_stream`` part were in a separate ``.edl`` file and added
|
||||
with ``--external-file``.
|
||||
|
||||
Note that all metadata between the stream sets created by ``new_stream`` is
|
||||
disjoint. Global metadata is taken from the first part only.
|
||||
|
||||
In context of mpv, this is redundant to the ``--audio-file`` and
|
||||
``--external-file`` options, but (as of this writing) has the advantage that
|
||||
this will use a unified cache for all streams.
|
||||
|
||||
The ``new_stream`` header is not part of the core EDL format. It may be changed
|
||||
or removed at any time, depending on mpv's internal requirements.
|
||||
|
||||
If the first ``!new_stream`` is redundant, it is ignored. This is the same
|
||||
example as above::
|
||||
|
||||
# mpv EDL v0
|
||||
!new_stream
|
||||
video.mkv
|
||||
!new_stream
|
||||
audio.mkv
|
||||
|
||||
Note that ``!new_stream`` must be the first header. Whether the parser accepts
|
||||
(i.e. ignores) or rejects other headers before that is implementation specific.
|
||||
|
||||
Track metadata
|
||||
==============
|
||||
|
||||
The special ``track_meta`` header can set some specific metadata fields of the
|
||||
current ``!new_stream`` partition. The tags are applied to all tracks within
|
||||
the partition. It is not possible to set the metadata for individual tracks (the
|
||||
feature was needed only for single-track media).
|
||||
|
||||
It provides following parameters change track metadata:
|
||||
|
||||
``lang``
|
||||
Set the language tag.
|
||||
|
||||
``title``
|
||||
Set the title tag.
|
||||
|
||||
``byterate``
|
||||
Number of bytes per second this stream uses. (Purely informational.)
|
||||
|
||||
``program_id``
|
||||
Assign this track to a program (integer, default: -1 meaning unset).
|
||||
|
||||
``index``
|
||||
The numeric index of the track this should map to (default: -1). This is
|
||||
the 0-based index of the virtual stream as seen by the player, enumerating
|
||||
all audio/video/subtitle streams. If nothing matches, this is silently
|
||||
discarded. The special index -1 (the default) has two meanings: if there
|
||||
was a previous meta data entry (either ``!track_meta`` or ``!delay_open``
|
||||
element since the last ``!new_stream``), then this element manipulates
|
||||
the previous meta data entry. If there was no previous entry, a new meta
|
||||
data entry that matches all streams is created.
|
||||
|
||||
Example::
|
||||
|
||||
# mpv EDL v0
|
||||
!track_meta,lang=bla,title=blabla
|
||||
file.mkv
|
||||
!new_stream
|
||||
!track_meta,title=ducks
|
||||
sub.srt
|
||||
|
||||
If ``file.mkv`` has an audio and a video stream, both will use ``blabla`` as
|
||||
title. The subtitle stream will use ``ducks`` as title.
|
||||
|
||||
The ``track_meta`` header is not part of the core EDL format. It may be changed
|
||||
or removed at any time, depending on mpv's internal requirements.
|
||||
|
||||
Global metadata
|
||||
===============
|
||||
|
||||
The special ``global_tags`` header can set metadata fields (aka tags) of the EDL
|
||||
file. This metadata is supposed to be informational, much like for example ID3
|
||||
tags in audio files. Due to lack of separation of different kinds of metadata it
|
||||
is unspecified what names are allowed, how they are interpreted, and whether
|
||||
some of them affect playback functionally. (Much of this is unfortunately
|
||||
inherited from FFmpeg. Another consequence of this is that FFmpeg "normalized"
|
||||
tags are recognized, or stuff like replaygain tags.)
|
||||
|
||||
Example::
|
||||
|
||||
!global_tags,title=bla,something_arbitrary=even_more_arbitrary
|
||||
|
||||
Any parameter names are allowed. Repeated use of this adds to the tag list. If
|
||||
``!new_stream`` is used, the location doesn't matter.
|
||||
|
||||
May possibly be ignored in some cases, such as delayed media opening.
|
||||
|
||||
Delayed media opening
|
||||
=====================
|
||||
|
||||
The special ``delay_open`` header can be used to open the media URL of the
|
||||
stream only when the track is selected for the first time. This is supposed to
|
||||
be an optimization to speed up opening of a remote stream if there are many
|
||||
tracks for whatever reasons.
|
||||
|
||||
This has various tricky restrictions, and also will defer failure to open a
|
||||
stream to "later". By design, it's supposed to be used for single-track streams.
|
||||
|
||||
Using multiple segments requires you to specify all offsets and durations (also
|
||||
it was never tested whether it works at all). Interaction with ``mp4_dash`` may
|
||||
be strange.
|
||||
|
||||
You can describe multiple sub-tracks by using multiple ``delay_open`` headers
|
||||
before the same source URL. (If there are multiple sub-tracks of the same media
|
||||
type, then the mapping to the real stream is probably rather arbitrary.) If the
|
||||
source contains tracks not described, a warning is logged when the delayed
|
||||
opening happens, and the track is hidden.
|
||||
|
||||
This has the following parameters:
|
||||
|
||||
``media_type``
|
||||
Required. Must be set to ``video``, ``audio``, or ``sub``. (Other tracks in
|
||||
the opened URL are ignored.)
|
||||
|
||||
``codec``
|
||||
The mpv codec name that is expected. Although mpv tries to initialize a
|
||||
decoder with it currently (and will fail track selection if it does not
|
||||
initialize successfully), it is not used for decoding - decoding still uses
|
||||
the information retrieved from opening the actual media information, and may
|
||||
be a different codec (you should try to avoid this, of course). Defaults to
|
||||
``null``.
|
||||
|
||||
Above also applies for similar fields such as ``w``. These fields are
|
||||
mostly to help with user track pre-selection.
|
||||
|
||||
``flags``
|
||||
A ``+`` separated list of boolean flags. Currently defined flags:
|
||||
|
||||
``default``
|
||||
Set the default track flag.
|
||||
|
||||
``forced``
|
||||
Set the forced track flag.
|
||||
|
||||
Other values are ignored after triggering a warning.
|
||||
|
||||
``w``, ``h``
|
||||
For video codecs: expected video size. See ``codec`` for details.
|
||||
|
||||
``fps``
|
||||
For video codecs: expected video framerate, as integer. (The rate is usually
|
||||
only crudely reported, and it makes no sense to expect exact values.)
|
||||
|
||||
``samplerate``
|
||||
For audio codecs: expected sample rate, as integer.
|
||||
|
||||
The ``delay_open`` header is not part of the core EDL format. It may be changed
|
||||
or removed at any time, depending on mpv's internal requirements.
|
||||
|
||||
Timestamp format
|
||||
================
|
||||
|
||||
Currently, time values are floating point values in seconds.
|
||||
|
||||
As an extension, you can set the ``timestamps=chapters`` option. If this option
|
||||
is set, timestamps have to be integers, and refer to chapter numbers, starting
|
||||
with 0. The default value for this parameter is ``seconds``, which means the
|
||||
time is as described in the previous paragraph.
|
||||
|
||||
Example::
|
||||
|
||||
# mpv EDL v0
|
||||
file.mkv,2,4,timestamps=chapters
|
||||
|
||||
Plays chapter 3 and ends with the start of chapter 7 (4 chapters later).
|
||||
|
||||
Implicit chapters
|
||||
=================
|
||||
|
||||
mpv will add one chapter per segment entry to the virtual timeline.
|
||||
|
||||
By default, the chapter's titles will match the entries' filenames.
|
||||
You can override set the ``title`` option to override the chapter title for
|
||||
that segment.
|
||||
|
||||
Example::
|
||||
|
||||
# mpv EDL v0
|
||||
cap.ts,5,240
|
||||
OP.mkv,0,90,title=Show Opening
|
||||
|
||||
The virtual timeline will have two chapters, one called "cap.ts" from 0-240s
|
||||
and a second one called "Show Opening" from 240-330s.
|
||||
|
||||
Entry which defines the track layout
|
||||
====================================
|
||||
|
||||
Normally, you're supposed to put only files with compatible layouts into an EDL
|
||||
file. However, at least the mpv implementation accepts entries that use
|
||||
different codecs, or even have a different number of audio/video/subtitle
|
||||
tracks. In this case, it's not obvious, which virtual tracks the EDL show should
|
||||
expose when being played.
|
||||
|
||||
Currently, mpv will apply an arbitrary heuristic which tracks the EDL file
|
||||
should expose.
|
||||
|
||||
You can set the ``layout`` option to ``this`` to make a specific entry define
|
||||
the track layout.
|
||||
|
||||
Example::
|
||||
|
||||
# mpv EDL v0
|
||||
file_with_2_streams.ts,5,240
|
||||
file_with_5_streams.mkv,0,90,layout=this
|
||||
|
||||
The way the different virtual EDL tracks are associated with the per-segment
|
||||
ones is highly implementation-defined, and uses a heuristic. If a segment is
|
||||
missing a track, there will be a "hole", and bad behavior may result. Improving
|
||||
this is subject to further development (due to being fringe cases, they don't
|
||||
have a high priority).
|
||||
|
||||
If future versions of mpv change this again, this option may be ignored.
|
||||
|
||||
Syntax of EDL URIs
|
||||
==================
|
||||
|
||||
|
||||
+51
-58
@@ -3,50 +3,44 @@ General usage
|
||||
|
||||
::
|
||||
|
||||
mpv infile --o=outfile [--of=outfileformat] [--ofopts=formatoptions] [--orawts] \
|
||||
mpv infile -o outfile [-of outfileformat] [-ofopts formatoptions] \
|
||||
[-ofps outfps | -oautofps] [-oharddup] [-ocopyts | -orawts] [-oneverdrop] \
|
||||
[(any other mpv options)] \
|
||||
--ovc=outvideocodec [--ovcopts=outvideocodecoptions] \
|
||||
--oac=outaudiocodec [--oacopts=outaudiocodecoptions]
|
||||
-ovc outvideocodec [-ovcopts outvideocodecoptions] \
|
||||
-oac outaudiocodec [-oacopts outaudiocodecoptions]
|
||||
|
||||
Help for these options is provided if giving help as parameter, as in::
|
||||
|
||||
mpv --ovc=help
|
||||
mpv -ovc help
|
||||
|
||||
The suboptions of these generally are identical to ffmpeg's (as option parsing
|
||||
is simply delegated to ffmpeg). The option --ocopyts enables copying timestamps
|
||||
is simply delegated to ffmpeg). The option -ocopyts enables copying timestamps
|
||||
from the source as-is, instead of fixing them to match audio playback time
|
||||
(note: this doesn't work with all output container formats); --orawts even turns
|
||||
(note: this doesn't work with all output container formats); -orawts even turns
|
||||
off discontinuity fixing.
|
||||
|
||||
Note that if neither --ofps nor --oautofps is specified, VFR encoding is assumed
|
||||
and the time base is 24000fps. --oautofps sets --ofps to a guessed fps number
|
||||
Note that if neither -ofps nor -oautofps is specified, VFR encoding is assumed
|
||||
and the time base is 24000fps. -oautofps sets -ofps to a guessed fps number
|
||||
from the input video. Note that not all codecs and not all formats support VFR
|
||||
encoding, and some which do have bugs when a target bitrate is specified - use
|
||||
--ofps or --oautofps to force CFR encoding in these cases.
|
||||
-ofps or -oautofps to force CFR encoding in these cases.
|
||||
|
||||
Of course, the options can be stored in a profile, like this .config/mpv/mpv.conf
|
||||
Of course, the options can be stored in a profile, like this .mpv/config
|
||||
section::
|
||||
|
||||
[myencprofile]
|
||||
vf-add = scale=480:-2
|
||||
ovc = libx264
|
||||
ovcopts-add = preset=medium
|
||||
ovcopts-add = tune=fastdecode
|
||||
ovcopts-add = preset=medium,tune=fastdecode
|
||||
ovcopts-add = crf=23
|
||||
ovcopts-add = maxrate=1500k
|
||||
ovcopts-add = bufsize=1000k
|
||||
ovcopts-add = rc_init_occupancy=900k
|
||||
ovcopts-add = refs=2
|
||||
ovcopts-add = maxrate=1500k,bufsize=1000k,rc_init_occupancy=900k,refs=2
|
||||
ovcopts-add = profile=baseline
|
||||
oac = aac
|
||||
oacopts-add = b=96k
|
||||
|
||||
It's also possible to define default encoding options by putting them into
|
||||
the section named ``[encoding]``.
|
||||
|
||||
One can then encode using this profile using the command::
|
||||
|
||||
mpv infile --o=outfile.mp4 --profile=myencprofile
|
||||
mpv infile -o outfile.mp4 -profile myencprofile
|
||||
|
||||
Some example profiles are provided in a file
|
||||
etc/encoding-profiles.conf; as for this, see below.
|
||||
@@ -60,33 +54,33 @@ for.
|
||||
|
||||
Typical MPEG-4 Part 2 ("ASP", "DivX") encoding, AVI container::
|
||||
|
||||
mpv infile --o=outfile.avi \
|
||||
--vf=fps=25 \
|
||||
--ovc=mpeg4 --ovcopts=qscale=4 \
|
||||
--oac=libmp3lame --oacopts=b=128k
|
||||
mpv infile -o outfile.avi \
|
||||
-ofps 25 \
|
||||
-ovc mpeg4 -ovcopts qscale=4 \
|
||||
-oac libmp3lame -oacopts ab=128k
|
||||
|
||||
Note: AVI does not support variable frame rate, so the fps filter must be used.
|
||||
The frame rate should ideally match the input (25 for PAL, 24000/1001 or
|
||||
30000/1001 for NTSC)
|
||||
Note: AVI does not support variable frame rate, so -ofps must be used. The
|
||||
frame rate should ideally match the input (25 for PAL, 24000/1001 or 30000/1001
|
||||
for NTSC)
|
||||
|
||||
Typical MPEG-4 Part 10 ("AVC", "H.264") encoding, Matroska (MKV) container::
|
||||
|
||||
mpv infile --o=outfile.mkv \
|
||||
--ovc=libx264 --ovcopts=preset=medium,crf=23,profile=baseline \
|
||||
--oac=libopus --oacopts=qscale=3
|
||||
mpv infile -o outfile.mkv \
|
||||
-ovc libx264 -ovcopts preset=medium,crf=23,profile=baseline \
|
||||
-oac libvorbis -oacopts qscale=3
|
||||
|
||||
Typical MPEG-4 Part 10 ("AVC", "H.264") encoding, MPEG-4 (MP4) container::
|
||||
|
||||
mpv infile --o=outfile.mp4 \
|
||||
--ovc=libx264 --ovcopts=preset=medium,crf=23,profile=baseline \
|
||||
--oac=aac --oacopts=b=128k
|
||||
mpv infile -o outfile.mp4 \
|
||||
-ovc libx264 -ovcopts preset=medium,crf=23,profile=baseline \
|
||||
-oac aac -oacopts ab=128k
|
||||
|
||||
Typical VP8 encoding, WebM (restricted Matroska) container::
|
||||
|
||||
mpv infile -o outfile.mkv \
|
||||
--of=webm \
|
||||
--ovc=libvpx --ovcopts=qmin=6,b=1000000k \
|
||||
--oac=libopus --oacopts=qscale=3
|
||||
-of webm \
|
||||
-ovc libvpx -ovcopts qmin=6,b=1000000k \
|
||||
-oac libvorbis -oacopts qscale=3
|
||||
|
||||
|
||||
Device targets
|
||||
@@ -95,29 +89,28 @@ Device targets
|
||||
As the options for various devices can get complex, profiles can be used.
|
||||
|
||||
An example profile file for encoding is provided in
|
||||
etc/encoding-profiles.conf in the source tree. mpv will read any file
|
||||
named ``encoding-profiles.conf`` in either the local or system
|
||||
configuration directories.
|
||||
etc/encoding-profiles.conf in the source tree. This file is installed and loaded
|
||||
by default (if libavfilter is enabled at compilation). If you want to modify
|
||||
it, you can replace and it with your own copy by doing::
|
||||
|
||||
Keep in mind that the default profile is the playback one. If you want to add
|
||||
options that apply only in encoding mode, put them into a ``[encoding]``
|
||||
section.
|
||||
mkdir -p ~/.mpv
|
||||
cp /etc/mpv/encoding-profiles.conf ~/.mpv/encoding-profiles.conf
|
||||
|
||||
Refer to the top of that file for more comments - in a nutshell, the following
|
||||
options are added by it::
|
||||
|
||||
--profile=enc-to-dvdpal # DVD-Video PAL, use dvdauthor -v pal+4:3 -a ac3+en
|
||||
--profile=enc-to-dvdntsc # DVD-Video NTSC, use dvdauthor -v ntsc+4:3 -a ac3+en
|
||||
--profile=enc-to-bb-9000 # MP4 for Blackberry Bold 9000
|
||||
--profile=enc-to-nok-6300 # 3GP for Nokia 6300
|
||||
--profile=enc-to-psp # MP4 for PlayStation Portable
|
||||
--profile=enc-to-iphone # MP4 for iPhone
|
||||
--profile=enc-to-iphone-4 # MP4 for iPhone 4 (double res)
|
||||
--profile=enc-to-iphone-5 # MP4 for iPhone 5 (even larger res)
|
||||
-profile enc-to-dvdpal DVD-Video PAL, use dvdauthor -v pal+4:3 -a ac3+en
|
||||
-profile enc-to-dvdntsc DVD-Video NTSC, use dvdauthor -v ntsc+4:3 -a ac3+en
|
||||
-profile enc-to-bb-9000 MP4 for Blackberry Bold 9000
|
||||
-profile enc-to-nok-6300 3GP for Nokia 6300
|
||||
-profile enc-to-psp MP4 for PlayStation Portable
|
||||
-profile enc-to-iphone MP4 for iPhone
|
||||
-profile enc-to-iphone-4 MP4 for iPhone 4 (double res)
|
||||
-profile enc-to-iphone-5 MP4 for iPhone 5 (even larger res)
|
||||
|
||||
You can encode using these with a command line like::
|
||||
|
||||
mpv infile --o=outfile.mp4 --profile=enc-to-bb-9000
|
||||
mpv infile -o outfile.mp4 -profile enc-to-bb-9000
|
||||
|
||||
Of course, you are free to override options set by these profiles by specifying
|
||||
them after the -profile option.
|
||||
@@ -127,20 +120,20 @@ What works
|
||||
==========
|
||||
|
||||
* Encoding at variable frame rate (default)
|
||||
* Encoding at constant frame rate using --vf=fps=RATE
|
||||
* 2-pass encoding (specify flags=+pass1 in the first pass's --ovcopts, specify
|
||||
* Encoding at constant frame rate using -ofps framerate -oharddup
|
||||
* 2-pass encoding (specify flags=+pass1 in the first pass's -ovcopts, specify
|
||||
flags=+pass2 in the second pass)
|
||||
* Hardcoding subtitles using vobsub, ass or srt subtitle rendering (just
|
||||
configure mpv for the subtitles as usual)
|
||||
* Hardcoding any other mpv OSD (e.g. time codes, using --osdlevel=3 and
|
||||
--vf=expand=::::1)
|
||||
* Hardcoding any other mpv OSD (e.g. time codes, using -osdlevel 3 and -vf
|
||||
expand=::::1)
|
||||
* Encoding directly from a DVD, network stream, webcam, or any other source
|
||||
mpv supports
|
||||
* Using x264 presets/tunings/profiles (by using profile=, tune=, preset= in the
|
||||
--ovcopts)
|
||||
-ovcopts)
|
||||
* Deinterlacing/Inverse Telecine with any of mpv's filters for that
|
||||
* Audio file converting: mpv --o=outfile.m4a infile.flac --no-video
|
||||
--oac=aac --oacopts=b=320k
|
||||
* Audio file converting: mpv -o outfile.mp3 infile.flac -no-video -oac
|
||||
libmp3lame -oacopts ab=320k
|
||||
|
||||
What does not work yet
|
||||
======================
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1 +0,0 @@
|
||||
change `ytdl_hook-all_formats` default to `yes`
|
||||
@@ -1 +0,0 @@
|
||||
make `--autocreate-playlist` only activate for regular files
|
||||
@@ -1 +0,0 @@
|
||||
make the `metadata/by-key` property writable
|
||||
@@ -1 +0,0 @@
|
||||
'command-list' now also returns a default value and available choices where applicable for each command argument.
|
||||
@@ -1 +0,0 @@
|
||||
make `mpv_command_node` accept `_name` for command name
|
||||
@@ -1 +0,0 @@
|
||||
add `--demuxer-hysteresis-bytes`
|
||||
@@ -1,3 +0,0 @@
|
||||
add `--disc-menu` option
|
||||
add `disc-menu-active` property
|
||||
add `discnav` command
|
||||
@@ -1,2 +0,0 @@
|
||||
add `--input-builtin-drag-and-drop` option
|
||||
add `dropped-file` property
|
||||
@@ -1,2 +0,0 @@
|
||||
add `dvda://` protocol for DVD-Audio playback
|
||||
add `--dvda-device` and `--dvda-page` options
|
||||
@@ -1 +0,0 @@
|
||||
add `vf=format=enhancement-layer` option
|
||||
@@ -1 +0,0 @@
|
||||
remove the deprecated `error` field from `end-file`
|
||||
@@ -1 +0,0 @@
|
||||
add `env` property that can be used to retrieve environment variables
|
||||
@@ -1 +0,0 @@
|
||||
deprecate `--foo`, instead use `--bar=foo` as a replacement
|
||||
@@ -1 +0,0 @@
|
||||
the `expand-properties` command modifier also applies to string lists now
|
||||
@@ -1 +0,0 @@
|
||||
`track-list/N/ff-index` may be unavailable if no known mapping exists
|
||||
@@ -1 +0,0 @@
|
||||
`--geometry` x/y position is now applied only on initial window creation, unless `--force-window-position=yes` is set.
|
||||
@@ -1 +0,0 @@
|
||||
add libcurl-based stream backend (http, https, ftp, ftps), with new options `--curl-enabled`, `--curl-http-version`, `--curl-max-redirects`, `--curl-max-retries`, `--curl-connect-timeout`, `--curl-buffer-size` and `--curl-max-request-size`
|
||||
@@ -1 +0,0 @@
|
||||
change `--hwdec-extra-frames` default to `auto`, sized from VO frame retention
|
||||
@@ -1 +0,0 @@
|
||||
implement `lavfi-tempo` an alternative speed changing audio filter
|
||||
@@ -1 +0,0 @@
|
||||
add `libplacebo-version` property
|
||||
Loaded 100 of 1376 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user