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