bzr branch
http://gegoxaren.bato24.eu/bzr/%2Bjunk/build-libffmpeg-for-chromium
1
by Gustav Hartvigsson
initial coode |
1 |
--- |
3
by Gustav Hartvigsson
Made sure the title is fine (with space after |
2 |
title: How to build `libffmpeg.so`\ \linebreak
|
1
by Gustav Hartvigsson
initial coode |
3 |
for use in Chrome(ium) and derivatives. |
4 |
author: Gustav (Gego of Xaren) |
|
5 |
date: 2020-06-07 |
|
6 |
geometry: margin=2cm |
|
7 |
papersize: a4 |
|
8 |
mainfont: DejaVu Serif |
|
2
by Gustav Hartvigsson
Added first set of tests. (More to come). |
9 |
fontsize: 11pt
|
1
by Gustav Hartvigsson
initial coode |
10 |
---
|
11 |
||
12 |
# Abstract
|
|
13 |
When streaming games to a web browser, the decode lag[^decode-lag] can be very |
|
14 |
high on older systems when using generic x86_64/AMD64. This can be mitigated |
|
15 |
by compiling `libffmpeg.so` from source using a specific set of optimisations.
|
|
16 |
||
17 |
[^decode-lag]: The delay that occurs from when the browser gets the data to |
|
18 |
decode and when the browser renders the image to the screen. |
|
19 |
||
20 |
This note provides information on how to compiling `ffmpeg` and it's libraries
|
|
21 |
from source and how to produce `libffmpeg.so` on a GNU/Linux system, as the
|
|
22 |
standard `make script` does not produce it.
|
|
23 |
||
2
by Gustav Hartvigsson
Added first set of tests. (More to come). |
24 |
This note will show the differences between different versions of `libffmpeg.so`
|
25 |
in terms of decode lag, and discuss the findings. |
|
1
by Gustav Hartvigsson
initial coode |
26 |
|
27 |
# Introduction and Motivation
|
|
28 |
The author of was playing games on Stadia[^stadia] and using a plug-in for |
|
29 |
Chrome(ium) measured that the decode time was higher than optimal when playing |
|
30 |
intensive games (in the order of 10+ ms) running on his older |
|
31 |
hardware[^hardware] without hardware acceleration, and the quite high CPU usage. |
|
2
by Gustav Hartvigsson
Added first set of tests. (More to come). |
32 |
The author wanted to see if using a specific microarchitecture (m-arch) when |
33 |
compiling the library would lower the decode lag. |
|
1
by Gustav Hartvigsson
initial coode |
34 |
|
35 |
[^stadia]: Google's cloud gaming service. |
|
36 |
||
37 |
[^hardware]: CPU: AMD FX-8350 @ 4.000GHz, GPU: AMD Radeon RX 570 (8GB). |
|
38 |
||
39 |
There there is no real documentation on how to produce `libffmpeg.so` by hand,
|
|
40 |
only a patch submitted to ffmpeg that was rejected |
|
41 |
[(Le Cuirot, 2017)](#ref:LeCuirot). Le Cuirot's patch became basis for this |
|
42 |
document. |
|
43 |
||
44 |
# How to build `libffmpeg.so`
|
|
45 |
||
46 |
The fist step is to download the source code for ffmpeg. This can be done in |
|
47 |
a number of ways, in this example the archive provided on ffmpeg's homepage will |
|
48 |
be used. |
|
49 |
||
50 |
```bash
|
|
51 |
# change directory to some place.
|
|
52 |
wget https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2
|
|
53 |
tar -xf ffmpeg-snapshot.tar.bz2 |
|
54 |
cd ffmpeg |
|
55 |
```
|
|
56 |
||
57 |
In this example the target CPU is the FX-8350, which uses the |
|
58 |
Piledriver microarchitecture [(Wikipedia, Piledriver)](#ref:WikPiledriver), |
|
59 |
which is AMD's 15th microarchitecture family. This would make it one of the |
|
60 |
`bdver` class microarchitectures
|
|
2
by Gustav Hartvigsson
Added first set of tests. (More to come). |
61 |
[(GCC Manual, 2021)](#ref:GccManual). |
1
by Gustav Hartvigsson
initial coode |
62 |
|
63 |
Configure the build system for ffmpeg to use the correct architecture. This |
|
64 |
could be a bit of trail-and-error to figure out, when building: target the |
|
65 |
highest microarchitecture that in the cpu family that may work, (Here other |
|
66 |
flags are provided to include most things with our build.) and then build the |
|
67 |
programs and libraries: |
|
68 |
||
69 |
```bash
|
|
70 |
./configure --enable-nonfree --enable-gpl --enable-version3\ |
|
71 |
--enable-hardcoded-tables\ |
|
72 |
--enable-pic --enable-lto\ |
|
73 |
--arch=amd64 --cpu=bdver4\ |
|
74 |
--disable-doc
|
|
75 |
make -j8
|
|
76 |
```
|
|
77 |
||
78 |
In the code listing above the microarchitecture is provided to the `--cpu=`
|
|
79 |
flag. |
|
80 |
||
81 |
Then testing to see if it works: |
|
82 |
||
83 |
```bash
|
|
84 |
./ffplay "path to testfile.mp4" |
|
85 |
# and
|
|
86 |
./ffplay "path to testfile.webm" |
|
87 |
```
|
|
88 |
||
89 |
In this case the test resulted in a segmentation fault, so using `--cpu=bdver3`
|
|
90 |
was tested instead, and worked. The configuration used can be seen below. |
|
91 |
Additional added a some `-mtune` and `-O2` options to make sure that the |
|
92 |
binaries are tuned to the architecture and optimised. |
|
93 |
||
94 |
```bash
|
|
95 |
./configure --enable-nonfree --enable-gpl --enable-version3\ |
|
96 |
--enable-hardcoded-tables\ |
|
97 |
--enable-pic --enable-lto\ |
|
98 |
--extra-cflags='-mtune=bdver3 -O2'\ |
|
99 |
--extra-cxxflags='-mtune=bdver3 -O2'\ |
|
100 |
--extra-objcflags='-mtune=bdver3 -O2'\ |
|
101 |
--arch=amd64 --cpu=bdver3\ |
|
102 |
--disable-doc
|
|
103 |
```
|
|
104 |
Note that it may seem that the command has frozen, but just give it a few |
|
105 |
seconds. |
|
106 |
||
107 |
Building of the final library is very easy: |
|
108 |
||
109 |
```bash
|
|
110 |
gcc -shared -fPIC\ |
|
111 |
libavcodec/libavcodec.a\ |
|
112 |
libavdevice/libavdevice.a\ |
|
113 |
libavfilter/libavfilter.a\ |
|
114 |
libavformat/libavformat.a\ |
|
115 |
libavutil/libavutil.a\ |
|
116 |
libpostproc/libpostproc.a\ |
|
117 |
libswresample/libswresample.a\ |
|
118 |
libswscale/libswscale.a\ |
|
119 |
-o libffmpeg.so |
|
120 |
```
|
|
121 |
||
5
by Gustav Hartvigsson
Did the last test for one of the versions of libffmpeg. |
122 |
\pagebreak |
1
by Gustav Hartvigsson
initial coode |
123 |
# Testing and Results
|
2
by Gustav Hartvigsson
Added first set of tests. (More to come). |
124 |
The web browser used is UngoogledChromium in a flatpak sandbox, started using |
125 |
the following command: |
|
126 |
```bash
|
|
127 |
flatpak run com.github.Eloston.UngoogledChromium |
|
128 |
```
|
|
129 |
||
130 |
In `chrome://flags/` the following flags were set.
|
|
131 |
||
132 |
||
133 |
| **flag** | **value** | |
|
134 |
|----------------------------|-----------| |
|
135 |
| #ignore-gpu-blocklist | enabled |
|
|
136 |
| #enable-reader-mode | enabled |
|
|
137 |
| #enable-gpu-rasterization | enabled |
|
|
138 |
| #enable-vulkan | enabled |
|
|
139 |
||
140 |
||
141 |
Replacing the `libffmpeg.so` was done as follows:
|
|
142 |
```bash
|
|
143 |
cd ~/.local/share/flatpak/app/\ |
|
144 |
com.github.Eloston.UngoogledChromium/\
|
|
145 |
current/active/files/chromium/ |
|
146 |
||
147 |
mv libffmpeg.so old_libffmpeg.so_old |
|
148 |
||
149 |
# Change dirctory to where the new libffmpeg.so was created
|
|
150 |
||
151 |
cp libffmpeg.so ~/.local/share/flatpak/app/\ |
|
152 |
com.github.Eloston.UngoogledChromium/\
|
|
153 |
current/active/files/chromium/ |
|
154 |
```
|
|
155 |
||
156 |
Measuring of decode time was done using the Stadia Enhanced[^StadiaEnhanced], |
|
157 |
that provides a way of monitoring -- among other thing -- how long it takes to |
|
158 |
decode a frame (the decode lag). The test consisted of playing _DOOM: Eternal - |
|
159 |
The Ancient Gods: Part 1_ in an almost canned test that consisted of playing |
|
160 |
the same for 25 minutes and manually looking at the information provided by |
|
161 |
the Stadia Enhanced plug-in. Generally, the decode time goes up the longer the |
|
162 |
play session is, but seems level off after 25 minutes. |
|
163 |
||
164 |
[^StadiaEnhanced]: [https://github.com/ChristopherKlay/StadiaEnhanced](https://github.com/ChristopherKlay/StadiaEnhanced) |
|
165 |
||
166 |
Between each session the computer idled for a bit before the next test was done. |
|
167 |
||
168 |
Bellow follows the results, each subsection starts with what flags were used to |
|
169 |
build the version of ffmpeg used in that test, the exception being the 'original' |
|
170 |
test, that will only provide decode times. |
|
171 |
||
172 |
All tests with configuration options shown have been compiled |
|
173 |
with `--enable-nonfree --enable-gpl --enable-version3`.
|
|
174 |
||
5
by Gustav Hartvigsson
Did the last test for one of the versions of libffmpeg. |
175 |
\pagebreak |
176 |
## Original (TODO)
|
|
177 |
||
2
by Gustav Hartvigsson
Added first set of tests. (More to come). |
178 |
This version of `libffmpeg.so` was provided with UngoogledChromium.
|
179 |
||
5
by Gustav Hartvigsson
Did the last test for one of the versions of libffmpeg. |
180 |
**Test Results**
|
181 |
||
182 |
| **Test #** | **decode time (ms)** | |
|
183 |
|------------|----------------------| |
|
184 |
| 1 | | |
|
185 |
| 2 | | |
|
186 |
| 3 | | |
|
187 |
||
188 |
||
2
by Gustav Hartvigsson
Added first set of tests. (More to come). |
189 |
## Hardware tables and microarchitecture optimised
|
5
by Gustav Hartvigsson
Did the last test for one of the versions of libffmpeg. |
190 |
|
2
by Gustav Hartvigsson
Added first set of tests. (More to come). |
191 |
**configuration options**
|
192 |
||
193 |
```
|
|
194 |
--enable-hardcoded-tables
|
|
195 |
--extra-cflags='-mtune=bdver3 -O2'
|
|
196 |
--extra-cxxflags='-mtune=bdver3 -O2'
|
|
197 |
--extra-objcflags='-mtune=bdver3 -O2'
|
|
198 |
--arch=amd64
|
|
199 |
--cpu=bdver3
|
|
200 |
```
|
|
201 |
||
202 |
**Test Results**
|
|
203 |
||
204 |
| **Test #** | **decode time (ms)** | |
|
205 |
|------------|----------------------| |
|
206 |
| 1 | 10.4 | |
|
207 |
| 2 | 10.0 | |
|
5
by Gustav Hartvigsson
Did the last test for one of the versions of libffmpeg. |
208 |
| 3 | 10.15 | |
209 |
||
210 |
## Microarchitecture optimised (TODO)
|
|
211 |
||
212 |
**configuration optimisations**
|
|
213 |
||
214 |
```
|
|
215 |
--enable-hardcoded-tables
|
|
216 |
--extra-cflags='-mtune=bdver3 -O2'
|
|
217 |
--extra-cxxflags='-mtune=bdver3 -O2'
|
|
218 |
--extra-objcflags='-mtune=bdver3 -O2'
|
|
219 |
--arch=amd64
|
|
220 |
--cpu=bdver3
|
|
221 |
```
|
|
222 |
||
223 |
**Test Results**
|
|
224 |
||
225 |
| **Test #** | **decode time (ms)** | |
|
226 |
|------------|----------------------| |
|
227 |
| 1 | | |
|
228 |
| 2 | | |
|
229 |
| 3 | | |
|
230 |
||
231 |
\pagebreak |
|
232 |
# Discussion (TODO)
|
|
2
by Gustav Hartvigsson
Added first set of tests. (More to come). |
233 |
|
234 |
||
235 |
\pagebreak |
|
1
by Gustav Hartvigsson
initial coode |
236 |
# Refrences
|
237 |
[](){#ref:LeCuirot} _Le Cuirot, J,_ 2017, [FFmpeg-devel] build: Allow libffmpeg
|
|
238 |
to be built for Chromium-based browsers, URL: |
|
239 |
[https://patchwork.ffmpeg.org/project /ffmpeg/patch/20170728100716.8143-1-chewi@gentoo.org/](https://patchwork.ffmpeg.org/project/ffmpeg/patch/20170728100716.8143-1-chewi@gentoo.org/) |
|
240 |
, date read: 2021-06-07. |
|
241 |
||
242 |
[](){#ref:WikPiledriver} _Wikipedia,_ Piledriver (microarchitecture), URL:
|
|
243 |
[https://en.wikipedia.org/wiki/Piledriver_(microarchitecture)](https://en.wikipedia.org/wiki/Piledriver_(microarchitecture)) |
|
244 |
, date read: 2021-06-07. |
|
245 |
||
246 |
[](){#ref:GccManual} _GCC Manual,_ 2021, version 11.1, pp. 142-152, URL:
|
|
247 |
[https://gcc.gnu.org/onlinedocs/gcc-11.1.0/gcc.pdf](https://gcc.gnu.org/onlinedocs/gcc-11.1.0/gcc.pdf) |
|
248 |
, date read: 2021-06-07. |
|
249 |