OLD | NEW |
1 This contains FFmpeg's public header files from the output of a "make install" | 1 This file describes how to produce the FFmpeg include directory, and how to |
2 command. The header files are from Chromium's copy of FFmpeg. | 2 create the ffmpeg.gyp file and related configurations. |
3 | 3 |
| 4 -- FFmpeg headers in the 'include' directory. |
| 5 |
| 6 The include directory contains FFmpeg's public header files from the output of |
| 7 a "make install" command. The header files are from Chromium's copy of FFmpeg. |
| 8 |
4 Steps to reproduce: | 9 Steps to reproduce: |
5 1) If on Windows, refer to our MinGW/MSYS environment setup: | 10 1) If on Windows, refer to our MinGW/MSYS environment setup: |
6 http://src.chromium.org/viewvc/chrome/trunk/deps/third_party/mingw/ | 11 http://src.chromium.org/viewvc/chrome/trunk/deps/third_party/mingw/ |
7 2) Grab Chromium's copy of FFmpeg: | 12 2) Grab Chromium's copy of FFmpeg: |
8 http://src.chromium.org/viewvc/chrome/trunk/deps/third_party/ffmpeg/ | 13 http://src.chromium.org/viewvc/chrome/trunk/deps/third_party/ffmpeg/ |
9 3) Follow the instructions to build and install. | 14 3) Follow the instructions to build and install. |
10 4) Go to your install location and copy the following into the Chromium tree: | 15 4) Go to your install location and copy the following into the Chromium tree: |
11 /path/to/install/include/libavcodec | 16 /path/to/install/include/libavcodec |
12 /path/to/install/include/libavformat | 17 /path/to/install/include/libavformat |
13 /path/to/install/include/libavutil | 18 /path/to/install/include/libavutil |
14 | 19 |
15 The project contains some hand-written DEF files used to generate import | 20 The project contains some hand-written DEF files used to generate import |
16 libraries to permit dynamically loading FFmpeg. The libaries are linked in | 21 libraries to permit dynamically loading FFmpeg. On Windows, the libraries are |
17 using /DELAYLOAD to avoid having the DLLs present at run-time. | 22 linked in using /DELAYLOAD to avoid having the DLLs present at run-time. On |
| 23 POSIX systems, dlopen() is used to achieve a similar effect. |
18 | 24 |
19 We don't use the import libraries generated from building FFmpeg because they | 25 We don't use the import libraries generated from building FFmpeg because they |
20 export every method by ordinal, which makes binary compatability with different | 26 export every method by ordinal, which makes binary compatibility with different |
21 builds of FFmpeg difficult if not impossible. Furthermore, it is much easier | 27 builds of FFmpeg difficult if not impossible. Furthermore, it is much easier |
22 to update a DEF file instead of rebuilding FFmpeg to generate new import | 28 to update a DEF file instead of rebuilding FFmpeg to generate new import |
23 libraries. | 29 libraries. |
| 30 |
| 31 |
| 32 -- Recreating the ffmpeg.gyp file and populating the config directory. |
| 33 The ffmpeg.gyp file is meant to be used in place of FFmpeg's |
| 34 |
| 35 ./configure && make |
| 36 |
| 37 steps. The file was created by inspecting the build log from above. |
| 38 The FFmpeg build is relatively straightforward. All files are built with |
| 39 the same CFLAGS. The config.h and version.h files are the only files generated |
| 40 by ./configure that are included elsewhere. They require a small bit of |
| 41 post-processing. |
| 42 |
| 43 Other than the configure step, FFmpeg just compiles its .c files, assembles a |
| 44 few more using yasm, and that's it. Exact instructions for reproducing |
| 45 ffmpeg.gyp are in the "Detailed Directions" section. |
| 46 |
| 47 Here is a list of gotchas that have shown up. |
| 48 1) FFmpeg requires special configure (--disable-optimizations) in order |
| 49 to be built with -O0 successfully due to some of the hand-written |
| 50 assembler using ebp. -O0 implies -fno-omit-frame-pointer which breaks |
| 51 this. This will produce compiler errors like: |
| 52 libavcodec/cabac.h:527: error: can't find a register in class |
| 53 'GENERAL_REGS' while reloading 'asm' |
| 54 cabac.h:527: error: 'asm' operand has impossible constraints |
| 55 |
| 56 2) On ia32, FFmpeg cannot be built with -fPIC, again due to assembly |
| 57 issues. There may be a workaround, but the performance impact is |
| 58 unknown. |
| 59 |
| 60 3) Sometimes, with -O0, invalid code will be exposed because dead-branch |
| 61 pruning is disabled in gcc. This can manifest itself as strange link |
| 62 issues or compile issues. Be careful to read all warnings in this case. |
| 63 |
| 64 4) Since config.h is generated via ./configure, the generated file will |
| 65 be sensitive to the configuration of the machine it was produced on. |
| 66 In particular, yasm does not seem to always be detected if |
| 67 cross-compiling for 32-bit on a 64-bit machine. Since yasm is built in |
| 68 tree, make sure to force things with --enable-yasm. |
| 69 |
| 70 5) Similar to issue #4, ./configure may detect the presence of SDL and |
| 71 adjust config.h accordingly. This is harmless because all the SDL |
| 72 related code has been disabled in our configuration. |
| 73 |
| 74 6) On ia32, we want to be able to compile with WITHOUT -fomit-frame-pointer |
| 75 (so breakpad can function). To do this, we need to disable the use of the |
| 76 EBP register, otherwise some of FFmpeg's inline assembly will cause |
| 77 compilation errors similar to gotcha #1. For more details, see the file |
| 78 comment in the munge_config_optimizations.sh. This script will fix up |
| 79 the generated config.h to be building without -fomit-frame-pointer. |
| 80 |
| 81 |
| 82 Detailed Directions: |
| 83 1) Get a clean version of the patched tree. This should be here: |
| 84 |
| 85 src/third_party/ffmpeg/source/patched-ffmpeg-mt |
| 86 |
| 87 2) Run the configure in a directory out of the tree with the arguments you |
| 88 want. To see what was used before, find the config.h for the platform |
| 89 of interest in: |
| 90 |
| 91 src/third_party/ffmpeg/source/config/[branding]/[platform]/[variant] |
| 92 |
| 93 The value of the FFMPEG_CONFIGURATION macro should have the configure |
| 94 commandline that generated the file. |
| 95 |
| 96 Note that if you are trying to build a 32-bit FFmpeg for linux on a |
| 97 64-bit box, the extra flags you want to pass to ./configure are |
| 98 |
| 99 --arch=i686 --extra-cflags=-m32 --extra-ldflags=-m32 |
| 100 |
| 101 Also, as noted in gotcha #4, explicitly setting --enable-yasm is |
| 102 a good idea. |
| 103 |
| 104 3) Copy the newly generated config.h and version.h into the correct platform |
| 105 location: |
| 106 |
| 107 src/third_party/ffmpeg/source/config/[branding]/[platform]/[variant] |
| 108 |
| 109 Make sure to double-check that config.h and version.h are the only files |
| 110 of interest. By that, I mean check that the other generated files are |
| 111 makefiles, documentation, .pc files, or something else that is not |
| 112 relevant to our build. |
| 113 |
| 114 TODO(ajwong): Check if we can modify version.h to tag our builds. |
| 115 |
| 116 3b) If on ia32, handle gotcha #6 by munging the geneated config.h file to |
| 117 disable use of EBP. Call the munge_config_optimizations.sh script on |
| 118 the config.h for each ia32 variant. |
| 119 |
| 120 ** This script is not idempotent. Don't run it twice ** |
| 121 |
| 122 Remember, this is only necessary for ia32 config.h files. Running this |
| 123 on config.h files for other platforms (in particular, for x64) will |
| 124 likely result in unecessarily slow code, or compile failures. |
| 125 |
| 126 4) Next, capture all the output from a build of libavcodec.so and |
| 127 libavformat.so. We will use the build log as a reference for making |
| 128 the ffmpeg.gyp file. |
| 129 |
| 130 make libavcodec/libavcodec.so libavformat/libavformat.so \ |
| 131 > ffmpeg_build_log 2> ffmpeg_build_err |
| 132 |
| 133 5) Check ffmpeg_build_err to see if there are any significant |
| 134 anomalies. FFmpeg source generates a lot of compiler warnings; it |
| 135 is safe to ignore those. |
| 136 |
| 137 6) Examine all non-gcc commands to see if we're missing anything |
| 138 interesting: |
| 139 |
| 140 grep -v '^gcc' ffmpeg_build_log |
| 141 |
| 142 There should be yasm commands for assembling two yasm files, but nothing |
| 143 else. Include those yasm files in the sources list for gyp. That means |
| 144 |
| 145 grep -v '^gcc\|^yasm' |
| 146 |
| 147 should generate nothing beyond "cd" and "ln" commands. |
| 148 |
| 149 7) Verify that the all the gcc commands have the same compiler flags. |
| 150 Do that with the following "one-liner": |
| 151 |
| 152 grep - '^gcc' ffmpeg_build_log | |
| 153 grep -v ' -MM ' | |
| 154 grep -v ' -shared ' | |
| 155 sed -e 's/ -o .*$//' | |
| 156 sort | uniq -c |
| 157 |
| 158 This should find all gcc commands, exclude the dependency generation |
| 159 lines, the link lines, and strip the output/input file names leaving |
| 160 just the compiler flags + invocation. You should only see one "line" |
| 161 of output. If there is more than one, figure out if the differences |
| 162 in compiler flags are significant, and then use your best judgment. |
| 163 |
| 164 Look at gotcha #2 in for notes about the -fPIC flag in particular. |
| 165 |
| 166 8) Examine the output from step 7 and update the compiler flags in |
| 167 ffmpeg.gyp. For easier cut/paste, append the following to the previous |
| 168 command line to isolate each flag on its own line and add |
| 169 single-quotes: |
| 170 |
| 171 tr -s ' ' | tr ' ' '\n' | sed -e "s/\(.*\)/'\1',/" | sort -u |
| 172 |
| 173 9) Next, examine the link flags to see if anything interesting appears. |
| 174 |
| 175 grep ' -shared ' ffmpeg_build_log | |
| 176 tr ' ' '\n' | |
| 177 grep -Ev '^[^-].*' | |
| 178 grep -v rpath | |
| 179 grep -Ev '^-L' | |
| 180 sort -u |
| 181 |
| 182 This should find all link lines, move each flag to its own line, |
| 183 remove any argument that isn't a flag, remove all the rpaths (not |
| 184 useful for us anyways), and remove all the -L lines (also not useful |
| 185 for us). |
| 186 |
| 187 The most interesting will likely be the -Wl,.* lines. Update the |
| 188 ldflags section in ffmpeg.gyp accordingly. |
| 189 |
| 190 10) Lastly, Find all the build .c files and update the sources line (this is |
| 191 very similar to step 7): |
| 192 |
| 193 grep -E '^gcc' ffmpeg_build_log | |
| 194 grep -v ' -MM ' | |
| 195 grep -v ' -shared ' | |
| 196 sed -e "s|.* -o .* \(.*\)$|'source/patched-ffmpeg-mt/\1',|" | |
| 197 sort |
| 198 |
| 199 11) Attempt to build. :) |
| 200 |
| 201 *12) Update the the sources! clause to exclude files that should only be built |
| 202 for Chromium. For this, you basically need to do the steps above once |
| 203 with the configure options for Chrome, then once with the options for |
| 204 Chromium and diff the list of .c and .asm source files. |
OLD | NEW |