2 URL: http://ffmpeg.org/
4 License File: LICENSE.md
5 Upstream Git: git://source.ffmpeg.org/ffmpeg.git
6 Last Upstream Merge: 5e3da256184e13502b3428f94e180888436d157b, Sep 11 2014
8 This file documents the layout of the Chromium copy of FFmpeg git, some common
9 tasks, how to produce the FFmpeg include directory, and how to create the
10 ffmpeg.gyp file and related configurations.
15 Chromium's copy of FFmpeg is a fork of the upstream git repository, see the tags
16 above for up-to-date cut information. All of the chromium specific bits, minus
17 the gyp files, are located under the chromium/ folder off the root.
19 ffmpeg.gyp: See the section on ffmpeg.gyp below.
21 ffmpeg_generated.gypi: Pregenerated gyp listing of files necessary to build
22 every platform. See chromium/scripts/generate_gyp.py for more details.
24 chromium/binaries/c99conv.exe: Prebuilt binary for converting FFmpeg sources
25 from C99 to C89 for compilation with Visual C++.
27 chromium/scripts: Utilities for building the gyp and config files.
29 chromium/config/...: Pregenerated FFmpeg config options for each platform
30 and architecture; e.g., ChromeOS: ARM-Neon, Linux: X64, etc.
32 chromium/patches/...: Chromium specific changes which haven't yet made it
33 upstream. See chromium/patches/README for more details on each patch.
35 Historically, the .patch files were staged on top of a source tarball
36 instead of the Git repository we have now. The .patch files are kept for
37 tracking purposes. The new system only requires that you add an entry to
38 the README file with a link to the tracking issue and code review.
43 -- Submitting changes to Chromium's FFmpeg git repository.
45 The goal of Chromium's FFmpeg repository is to just be a mirror of the upstream
46 Git repository. Which means every change made must be upstreamed. If you make
47 a change, please add an entry to chromium/patches/README with a link to the
48 tracking issue and code review for your change.
50 Unfortunately the normal Chromium CL submission process through Rietveld does
51 not work with Git DEPS like FFmpeg, so you must use Gerrit to upload your change
54 git push ssh://gerrit.chromium.org:29418/chromium/third_party/ffmpeg \
57 This will create a gerrit change. Make sure to "git commit --amend" and
58 add "Change-Id: XXX" as the last line so that future pushes do not create new
59 changes. You can get the "XXX" from the gerrit web interface.
61 Note: You'll need a Gerrit account, see:
63 http://www.chromium.org/chromium-os/developer-guide/gerrit-guide
65 You also need to add an ssh key at
66 https://gerrit.chromium.org/gerrit/#/settings/ssh-keys . Generate a key
67 following the GitHub guide linked from there, then copy the contents of your
68 ~/.ssh/id_rsa.pub file to that gerrit page.
70 If your change adds new files to the repository, you'll need to regenerate the
71 GYP defines by following the directions in chromium/scripts/generate_gyp.py.
73 After all that's done and your change has landed in the Git repository, you'll
74 need to roll DEPS before the change will show up in Chrome.
77 -- Performing an upstream merge.
79 The upstream merge process follows the normal Git merge process:
80 # First, modify the origin url to enable push of merge result later.
81 # e.g., change remote.origin.url from:
82 # https://chromium.googlesource.com/chromium/third_party/ffmpeg.git
84 # ssh://gerrit.chromium.org:29418/chromium/third_party/ffmpeg.git
85 # One way is to use custom_deps in .gclient. Another might be to run
86 # git config -e within this folder and edit the URLs if already synced,
87 # though this alternative could have danger.
89 git remote add upstream git://source.ffmpeg.org/ffmpeg.git
91 git merge upstream/master
96 <Except for a different push method, follow rest of "Submitting changes to
97 Chromium's FFmpeg git repository.">
99 # Use git push for submission so commit history is kept. Might require merge
100 # approval on your Gerrit account. Do not commit any other way.
101 git push origin master
103 Once complete you'll need to regenerate the configuration files for every
104 platform (see "Directions" in the "Building" section below). You'll also
105 need to regenerate the gyp files (see chromium/scripts/generate_gyp.py). After
106 all that is done, you can update Chromium's root DEPS file to point to the tip
109 -- Upstreaming a patch.
111 <checkout copy of upstream repo>
112 git checkout <hash of last Chromium FFmpeg, see tag above> -b my_patch
113 git apply <patch. pulled from code review or cherry-picked from this repo>
114 git rebase origin/master
115 < Follow FFmpeg guide: http://ffmpeg.org/developer.html#Submitting-patches-1 >
117 Once your change has been upstreamed, please update the chromium/patches/README
118 file with the status. The next time an upstream merge is done, the committer
119 will clear out all the patches which have been upstreamed.
121 -- Cherry-picking a patch from upstream.
123 # Tell our repo about the upstream one.
124 git remote add upstream git://source.ffmpeg.org/ffmpeg.git
127 # Create a new branch based off of master for committing our patch.
128 git checkout master -b my_new_branch
130 # Pull the patch out of upstream.
131 git cherry-pick <hash of commit in upstream>
133 <Follow rest of "Submitting changes to Chromium's FFmpeg git repository.">
138 -- FFmpeg headers in the 'chromium/include' directory.
140 The include directory contains FFmpeg's public header files from the output of
141 a "make install" command. The header files are from Chromium's copy of FFmpeg.
144 1) If on Windows, refer to our MinGW/MSYS environment setup:
145 http://src.chromium.org/viewvc/chrome/trunk/deps/third_party/mingw/
146 2) Chromium's copy of FFmpeg, should already have it if you're reading this.
147 3) Follow the instructions to build and install.
148 4) Go to your install location and copy the following into the Chromium tree:
149 /path/to/install/include/libavcodec
150 /path/to/install/include/libavformat
151 /path/to/install/include/libavutil
153 On Windows, the libraries are linked in using /DELAYLOAD to avoid having the
154 DLLs present at run-time. On POSIX systems, dlopen() is used to achieve a
157 We don't use the import libraries generated from building FFmpeg because they
158 export every method by ordinal, which makes binary compatibility with different
159 builds of FFmpeg difficult if not impossible. Furthermore, it is much easier
160 to update a DEF file instead of rebuilding FFmpeg to generate new import
164 -- Recreating the ffmpeg.gyp file and populating the config directory.
165 The ffmpeg.gyp file is meant to be used in place of FFmpeg's
169 steps. The file was created by inspecting the build log from above.
170 The FFmpeg build is relatively straightforward. All files are built with
171 the same CFLAGS. The config.h and version.h files are the only files generated
172 by ./configure that are included elsewhere. They require a small bit of
175 Other than the configure step, FFmpeg just compiles its .c files, assembles a
176 few more using yasm, and that's it.
178 Here is a list of gotchas that have shown up.
179 1) FFmpeg requires special configure (--disable-optimizations) in order
180 to be built with -O0 successfully due to some of the hand-written
181 assembler using ebp. -O0 implies -fno-omit-frame-pointer which breaks
182 this. This will produce compiler errors like:
183 libavcodec/cabac.h:527: error: can't find a register in class
184 'GENERAL_REGS' while reloading 'asm'
185 cabac.h:527: error: 'asm' operand has impossible constraints
187 2) Sometimes, with -O0, invalid code will be exposed because dead-branch
188 pruning is disabled in gcc. This can manifest itself as strange link
189 issues or compile issues. Be careful to read all warnings in this case.
191 3) Since config.h is generated via ./configure, the generated file will
192 be sensitive to the configuration of the machine it was produced on.
193 In particular, yasm does not seem to always be detected if
194 cross-compiling for 32-bit on a 64-bit machine. Since yasm is built in
195 tree, make sure to force things with --enable-yasm.
197 4) yasm needs to be installed on mac and windows if not already there.
199 5) Similar to issue #3, ./configure may detect the presence of SDL and
200 adjust config.h accordingly. This is harmless because all the SDL
201 related code has been disabled in our configuration.
203 6) On Mac ia32, we want to be able to compile WITHOUT -fomit-frame-pointer
204 (so breakpad can function). To do this, we need to disable the use of the
205 EBP register, otherwise some of FFmpeg's inline assembly will cause
206 compilation errors similar to gotcha #1. For more details, see the file
207 comment in the munge_config_optimizations.sh. This script will fix up
208 the generated config.h to be building without -fomit-frame-pointer.
210 7) On Windows, FFmpeg must first be run through a preprocessor to be compiled
211 via MSVC++ because it doesn't support the C99 syntax used by FFmpeg. The
212 converter is open source and built on libclang. The c99conv.exe in the
213 chromium/scripts directory is a statically linked version of the converter
214 from: https://github.com/rbultje/c99-to-c89 . Compiling the dynamic linked
215 library is relatively easy, generating a statically linked one is not. To
216 build the dynamic version you first need libclang:
218 git clone http://llvm.org/git/llvm.git
219 cd tools; git clone http://llvm.org/git/clang.git
221 Now you need to run cmake, see http://llvm.org/docs/GettingStartedVS.html,
222 step #5. From there you can start the Visual Studio IDE with the .vcproj
223 or .sln files generated by cmake. Then select "Release" from the build
224 drop down menu. You're ready to build. Right click on the libclang target
225 and select build. Once complete you should have a libclang.dll in
226 <llvm root>\out\bin\Release. Now you can build the c99-to-c89 converter
227 using the packed makefile. If you're building the dynamic version you'll
228 need to ensure c99conv.exe and libclang.dll remain in the same directory.
230 Note: Building the statically linked version is painful and requires
231 changes to both the llvm project and the converter. Proceed at your own
232 risk. First, you need to modify the libclang project and change every
233 target's "Project Defaults" from "Dynamic Library .DLL" to "Static Library
234 (.lib)" and under "Code Generation" change every targets "Runtime Library"
235 from "Multi-threaded DLL (/MD)" to "Multi-threaded (/MT)" then rebuild the
236 libclang project. Afterward, you will have a lot of lib files in <llvm
237 root>\out\lib\Release and will need to specify all of them under LIBS in
238 the c99-to-c89 makefile as well as Advapi32.lib and Shell32.lib. Before
239 compiling c99conv.exe you will need to modify libclang a bit, open
240 "tools\clang\include\clang-c\Platform.h" and remove the
241 "__declspec(dllimport)" entry. You can now compile as normal and will only
242 need to package the c99conv.exe.
244 It's not necessary to build the statically linked version, but it's nice to
245 only have a single binary checked in.
247 8) On various platforms, ffmpeg configure may detect external iconv library
248 and include it by default. FFmpeg used by chromium does not depend on this
249 library, and the lib may not exist on target despite existing in the build
250 environment. Hence, we need to change CONFIG_ICONV to 0 in the config.h
251 (and config.asm where appropriate.) build_ffmpeg.sh does this with
252 configure parameter --disable-iconv. See http://crbug.com/223295
257 1) Create config.h and config.asm as needed. For each different environment
258 you need to have a copy of the merge-mxx branch available. More details
259 for this first step can be found in the comments in
260 chromium/scripts/generate_gyp.py.
262 On Linux, Chromium enlistment (with Chromium's yasm build output in $PATH)
264 ./chromium/scripts/build_ffmpeg.py linux ia32
265 ./chromium/scripts/build_ffmpeg.py linux x64
266 ./chromium/scripts/build_ffmpeg.py linux-noasm x64
268 ninja -C out/Release yasm
269 export PATH=`pwd`/out/Release:$PATH
271 On Linux with MIPS cross-toolchain in $PATH (optional)
272 ./chromium/scripts/build_ffmpeg.py linux mipsel
274 On Linux, ChromeOS enlistment (inside chroot) run
275 ./chromium/scripts/build_ffmpeg.py linux arm
276 ./chromium/scripts/build_ffmpeg.py linux arm-neon
278 On Mac, Chromium enlistment, run
279 ./chromium/scripts/build_ffmpeg.py mac ia32
280 ./chromium/scripts/build_ffmpeg.py mac x64
282 On Windows, Chromium enlistment, run
283 ./chromium/scripts/build_ffmpeg.py win ia32
284 ./chromium/scripts/build_ffmpeg.py win x64
286 2) Collect all these directories and copy all config files
287 into the source tree using
289 ./chromium/scripts/copy_config.sh
291 You should keep the build.* directories around in case you need to
292 regenerate this (or the gyp files in the next step) for one or more
295 3) Finally, rebuild the .gyp and .gn build files.
297 ./chromium/scripts/generate_gyp.py
298 ./chromium/scripts/generate_gyp.py --output_gn