Upstream version 10.38.208.0
[platform/framework/web/crosswalk.git] / src / third_party / ffmpeg / README.chromium
1 Name: ffmpeg
2 URL: http://ffmpeg.org/
3 License: LGPL 2.1
4 License File: LICENSE.md
5 Upstream Git: git://source.ffmpeg.org/ffmpeg.git
6 Last Upstream Merge: afd62b3f184569492230e7f34ad55581c6b2d2c3, Aug 1 2014
7
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.
11
12 FFmpeg Git Layout:
13 ==================
14
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.
18
19     ffmpeg.gyp: See the section on ffmpeg.gyp below.
20
21     ffmpeg_generated.gypi: Pregenerated gyp listing of files necessary to build
22       every platform.  See chromium/scripts/generate_gyp.py for more details.
23
24     chromium/binaries/c99conv.exe: Prebuilt binary for converting FFmpeg sources
25       from C99 to C89 for compilation with Visual C++.
26
27     chromium/scripts: Utilities for building the gyp and config files.
28
29     chromium/config/...: Pregenerated FFmpeg config options for each platform
30       and architecture; e.g., ChromeOS: ARM-Neon, Linux: X64, etc.
31
32     chromium/patches/...: Chromium specific changes which haven't yet made it
33       upstream.  See chromium/patches/README for more details on each patch.
34
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.
39
40 Help w/ Common Tasks:
41 =====================
42
43 -- Submitting changes to Chromium's FFmpeg git repository.
44
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.
49
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
52 for review:
53
54   git push ssh://gerrit.chromium.org:29418/chromium/third_party/ffmpeg \
55   HEAD:refs/for/master
56
57 This will create a gerrit chanage. 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.
60
61 Note: You'll need a Gerrit account, see:
62
63   http://www.chromium.org/chromium-os/developer-guide/gerrit-guide
64
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.
69
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.
72
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.
75
76
77 -- Performing an upstream merge.
78
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
83   # to:
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.
88
89   git remote add upstream git://source.ffmpeg.org/ffmpeg.git
90   git fetch upstream
91   git merge upstream/master
92
93   # If conflicts:
94   git mergetool
95
96   <Except for a different push method, follow rest of "Submitting changes to
97   Chromium's FFmpeg git repository.">
98
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
102
103 Once complete you'll need to regenerate the configuration files for every
104 platform (see "Short 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
107 of tree commit.
108
109 -- Upstreaming a patch.
110
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 >
116
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.
120
121 -- Cherry-picking a patch from upstream.
122
123   # Tell our repo about the upstream one.
124   git remote add upstream git://source.ffmpeg.org/ffmpeg.git
125   git fetch upstream
126
127   # Create a new branch based off of master for committing our patch.
128   git checkout master -b my_new_branch
129
130   # Pull the patch out of upstream.
131   git cherry-pick <hash of commit in upstream>
132
133   <Follow rest of "Submitting changes to Chromium's FFmpeg git repository.">
134
135 Building:
136 =========
137
138 -- FFmpeg headers in the 'chromium/include' directory.
139
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.
142
143 Steps to reproduce:
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
152
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
155 similar effect.
156
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
161 libraries.
162
163
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
166
167    ./configure && make
168
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
173 post-processing.
174
175 Other than the configure step, FFmpeg just compiles its .c files, assembles a
176 few more using yasm, and that's it.  Exact instructions for reproducing
177 ffmpeg.gyp are in the "Detailed Directions" section.
178
179 Here is a list of gotchas that have shown up.
180   1) FFmpeg requires special configure (--disable-optimizations) in order
181      to be built with -O0 successfully due to some of the hand-written
182      assembler using ebp.  -O0 implies -fno-omit-frame-pointer which breaks
183      this. This will produce compiler errors like:
184        libavcodec/cabac.h:527: error: can't find a register in class
185        'GENERAL_REGS' while reloading 'asm'
186        cabac.h:527: error: 'asm' operand has impossible constraints
187
188   2) Sometimes, with -O0, invalid code will be exposed because dead-branch
189      pruning is disabled in gcc.  This can manifest itself as strange link
190      issues or compile issues.  Be careful to read all warnings in this case.
191
192   3) Since config.h is generated via ./configure, the generated file will
193      be sensitive to the configuration of the machine it was produced on.
194      In particular, yasm does not seem to always be detected if
195      cross-compiling for 32-bit on a 64-bit machine. Since yasm is built in
196      tree, make sure to force things with --enable-yasm.
197
198   4) yasm needs to be installed on mac and windows if not already there.
199
200   5) Similar to issue #3, ./configure may detect the presence of SDL and
201      adjust config.h accordingly. This is harmless because all the SDL
202      related code has been disabled in our configuration.
203
204   6) On Mac ia32, we want to be able to compile WITHOUT -fomit-frame-pointer
205      (so breakpad can function).  To do this, we need to disable the use of the
206      EBP register, otherwise some of FFmpeg's inline assembly will cause
207      compilation errors similar to gotcha #1.  For more details, see the file
208      comment in the munge_config_optimizations.sh. This script will fix up
209      the generated config.h to be building without -fomit-frame-pointer.
210
211   7) On Windows, FFmpeg must first be run through a preprocessor to be compiled
212      via MSVC++ because it doesn't support the C99 syntax used by FFmpeg.  The
213      converter is open source and built on libclang.  The c99conv.exe in the
214      chromium/scripts directory is a statically linked version of the converter
215      from: https://github.com/rbultje/c99-to-c89 . Compiling the dynamic linked
216      library is relatively easy, generating a statically linked one is not.  To
217      build the dynamic version you first need libclang:
218
219        git clone http://llvm.org/git/llvm.git
220        cd tools; git clone http://llvm.org/git/clang.git
221
222      Now you need to run cmake, see http://llvm.org/docs/GettingStartedVS.html,
223      step #5.  From there you can start the Visual Studio IDE with the .vcproj
224      or .sln files generated by cmake.  Then select "Release" from the build
225      drop down menu.  You're ready to build.  Right click on the libclang target
226      and select build.  Once complete you should have a libclang.dll in
227      <llvm root>\out\bin\Release.  Now you can build the c99-to-c89 converter
228      using the packed makefile.  If you're building the dynamic version you'll
229      need to ensure c99conv.exe and libclang.dll remain in the same directory.
230
231      Note: Building the statically linked version is painful and requires
232      changes to both the llvm project and the converter.  Proceed at your own
233      risk.  First, you need to modify the libclang project and change every
234      target's "Project Defaults" from "Dynamic Library .DLL" to "Static Library
235      (.lib)" and under "Code Generation" change every targets "Runtime Library"
236      from "Multi-threaded DLL (/MD)" to "Multi-threaded (/MT)" then rebuild the
237      libclang project.  Afterward, you will have a lot of lib files in <llvm
238      root>\out\lib\Release and will need to specify all of them under LIBS in
239      the c99-to-c89 makefile as well as Advapi32.lib and Shell32.lib.  Before
240      compiling c99conv.exe you will need to modify libclang a bit, open
241      "tools\clang\include\clang-c\Platform.h" and remove the
242      "__declspec(dllimport)" entry.  You can now compile as normal and will only
243      need to package the c99conv.exe.
244
245      It's not necessary to build the statically linked version, but it's nice to
246      only have a single binary checked in.
247
248   8) On various platforms, ffmpeg configure may detect external iconv library
249      and include it by default.  FFmpeg used by chromium does not depend on this
250      library, and the lib may not exist on target despite existing in the build
251      environment.  Hence, we need to change CONFIG_ICONV to 0 in the config.h
252      (and config.asm where appropriate.)  build_ffmpeg.sh does this with
253      configure parameter --disable-iconv.  See http://crbug.com/223295
254
255
256 Short Directions:
257 =================
258   1) Create config.h and config.asm as needed.
259      On Linux (with Chromium's yasm build output in $PATH) run
260        ./chromium/scripts/build_ffmpeg.py linux ia32
261        ./chromium/scripts/build_ffmpeg.py linux x64
262        ./chromium/scripts/build_ffmpeg.py linux-noasm x64
263
264      On Linux with MIPS cross-toolchain in $PATH
265        ./chromium/scripts/build_ffmpeg.py linux mipsel
266
267      On Linux chroot run
268        ./chromium/scripts/build_ffmpeg.py linux arm
269        ./chromium/scripts/build_ffmpeg.py linux arm-neon
270
271      On Mac run
272        ./chromium/scripts/build_ffmpeg.py mac ia32
273        ./chromium/scripts/build_ffmpeg.py mac x64
274
275      On Windows run
276        ./chromium/scripts/build_ffmpeg.py win ia32
277        ./chromium/scripts/build_ffmpeg.py win x64
278
279   2) Finally, collect all these directories and copy all config files
280      into the source tree using
281
282        ./chromium/scripts/copy_config.sh
283
284 Detailed Directions:
285 ====================
286   1) Run the configure in a directory out of the tree with the arguments you
287      want.  To see what was used before, find the config.h for the platform
288      of interest in:
289
290        src/third_party/ffmpeg/source/config/[branding]/[platform]/[variant]
291
292      The value of the FFMPEG_CONFIGURATION macro should have the configure
293      commandline that generated the file.
294
295      Note that if you are trying to build a 32-bit FFmpeg for linux on a
296      64-bit box, the extra flags you want to pass to ./configure are
297
298        --arch=i686 --extra-cflags=-m32 --extra-ldflags=-m32
299
300      Also, as noted in gotcha #4, explicitly setting --enable-yasm is
301      a good idea. (These flags have been added to build_ffmpeg.sh.)
302
303   2) Copy the newly generated config.h and version.h into the correct platform
304      location:
305
306        src/third_party/ffmpeg/chromium/config/[branding]/[platform]/[variant]
307
308      Make sure to double-check that config.h and version.h are the only files
309      of interest.  By that, I mean check that the other generated files are
310      makefiles, documentation, .pc files, or something else that is not
311      relevant to our build.
312
313      TODO(ajwong): Check if we can modify version.h to tag our builds.
314
315   3) If on ia32, handle gotcha #6 by munging the geneated config.h file to
316      disable use of EBP.  Call the munge_config_optimizations.sh script on
317      the config.h for each ia32 variant. (This has been implemented in
318      build_ffmpeg.sh.)
319
320      ** This script is not idempotent. Don't run it twice **
321
322      Remember, this is only necessary for ia32 config.h files.  Running this
323      on config.h files for other platforms (in particular, for x64) will
324      likely result in unecessarily slow code, or compile failures.
325
326   4) Handle gotcha #8 by using --disable-iconv configure option.
327      This is implemented in build_ffmpeg.sh.
328
329   5) Next, capture all the output from a build of libavcodec.so and
330      libavformat.so.  We will use the build log as a reference for making
331      the ffmpeg.gyp file.
332
333        make libavcodec/libavcodec.so libavformat/libavformat.so \
334           > ffmpeg_build_log 2> ffmpeg_build_err
335
336      For Mac, replace the ".so" in the files above with ".dylib".
337
338      To get detailed output you might have to comment in common.mak
339
340        #$(foreach VAR,$(BRIEF), \
341        #    $(eval override $(VAR) = $($(VAR))))
342
343   6) Check ffmpeg_build_err to see if there are any significant
344      anomalies.  FFmpeg source generates a lot of compiler warnings; it
345      is safe to ignore those.
346
347   7) Examine all non-gcc commands to see if we're missing anything
348      interesting:
349
350        grep -v '^gcc' ffmpeg_build_log
351
352      There should be yasm commands for assembling two yasm files, but nothing
353      else.  Include those yasm files in the sources list for gyp.  That means
354
355        grep -v '^gcc\|^yasm'
356
357      should generate nothing beyond "cd" and "ln" commands.
358
359   8) Verify that the all the gcc commands have the same compiler flags.
360      Do that with the following "one-liner":
361
362        grep - '^gcc' ffmpeg_build_log |
363        grep -v ' -MM ' |
364        grep -v ' -shared ' |
365        sed -e 's/ -MF .*$//' |
366        sort | uniq -c
367
368      This should find all gcc commands, exclude the dependency generation
369      lines, the link lines, and strip the output/input file names leaving
370      just the compiler flags + invocation.  You should only see one "line"
371      of output.  If there is more than one, figure out if the differences
372      in compiler flags are significant, and then use your best judgment.
373
374   9) Examine the output from step 7 and update the compiler flags in
375      ffmpeg.gyp. For easier cut/paste, append the following to the previous
376      command line to isolate each flag on its own line and add
377      single-quotes:
378
379        tr -s ' ' | tr ' ' '\n' | sed -e "s/\(.*\)/'\1',/" | sort -u
380
381  10) Next, examine the link flags to see if anything interesting appears.
382
383         grep ' -shared ' ffmpeg_build_log  |
384         tr ' ' '\n' |
385         grep -Ev '^[^-].*' |
386         grep -v rpath |
387         grep -Ev '^-L' |
388         sort -u
389
390      This should find all link lines, move each flag to its own line,
391      remove any argument that isn't a flag, remove all the rpaths (not
392      useful for us anyways), and remove all the -L lines (also not useful
393      for us).
394
395      The most interesting will likely be the -Wl,.* lines. Update the
396      ldflags section in ffmpeg.gyp accordingly.
397
398  11) Lastly, Find all the build .c files and update the sources line (this is
399      very similar to step 7):
400
401        grep -E '^gcc' ffmpeg_build_log |
402        grep -v ' -MM ' |
403        grep -v ' -shared ' |
404        sed -e "s|.* -o .* \(.*\)$|'source/patched-ffmpeg/\1',|" |
405        sort
406
407  12) Attempt to build. :)
408
409 *13) Update the the sources! clause to exclude files that should only be built
410      for Chromium.  For this, you basically need to do the steps above once
411      with the configure options for Chrome, then once with the options for
412      Chromium and diff the list of .c and .asm source files.