在 Windows 7 下使用 Android NDK r5c 编译 FFmpeg 0.7.1
2011-06-26 13:48 by Scott Wong, 1301 visits, 收藏, 编辑在代号是 “Love”的 FFmpeg 0.8 正式版几个小时之后,代号为 “Peace”FFmpeg 0.7.1 也发布了。没想到啊,我还以为直接是从 0.7 RC1 升到 0.8,不会再有 FFmpeg 0.7.x 的版本了呢。爱与和平,呵呵,原来如此,0.7 RC1 的代号就是 “Love and Peace”。
因为之前已经写了 在 Mac OS X 下使用 Android NDK r5b 编译 FFmpeg 0.8 和 在 Ubuntu 下使用 Android NDK r4b 编译 FFmpeg 0.6.3 两篇随笔,所以干脆把 Windows 7 下的编译方法也写出来了。这样在3个操作系统下用3个 NDK 版本编译3个 FFmpeg 版本的方法就都有了,应该是互联网上最全的系列了。
之前一直没写如何在 Windows 下编译 FFmpeg 是因为在 Windows 下编译除了需要 NDK 之外还需要一个 Cygwin,配置起来虽然说不上麻烦但也确实不算容易。除了让人抓狂的路径问题之外,居然还有更变态参数长度限制,真是祸不单行,╮(╯▽╰)╭
下面我将介绍在 Windows 下使用 NDK 编译 FFmpeg 的方法,以及如何解决上面提到的那些问题。时间关系,没做深究,解决方法可能不算完美。要是你有更好的解决方法,希望你能告诉我,谢谢。
一、下载 Cygwin 2.738、Android NDK r5c 和 FFmpeg 0.7.1
二、安装 Cygwin 2.738
Cygwin 的安装过程还算简单,但要记得把 GUN make 3.81-2 和 GUN awk 3.1.8-1 安装上。
GUN awk 3.1.8-1 是默认安装的,不需要特意去勾选安装。
三、解压缩 Android NDK r5c 和 FFmpeg 0.8
- 将 android-ndk-r5c-windows.zip 解压缩到 C:\cygwin\home\ScottWong 目录下
- 将 ffmpeg-0.7.1.tar.bz2 解压缩到 C:\cygwin\home\ScottWong\ffmpeg 目录下
- 将 C:\cygwin\home\ScottWong\ffmpeg\ffmpeg-0.7.1 重命名为 C:\cygwin\home\ScottWong\ffmpeg\jni
四、编写 FFmpeg 配置脚本
将以下内容保存为 C:\cygwin\home\ScottWong\ffmpeg\jni\config.sh 文件。这里的编译参数是可以根据具体需求进行修改的。
1: ./configure \
2: --disable-static \
3: --enable-shared \
4: --enable-gpl \
5: --enable-version3 \
6: --enable-nonfree \
7: --disable-doc \
8: --disable-ffmpeg \
9: --disable-ffplay \
10: --disable-ffprobe \
11: --disable-ffserver \
12: --disable-avdevice \
13: --disable-avfilter \
14: --disable-postproc \
15: --enable-small \
16: --cross-prefix=/home/ScottWong/android-ndk-r5c/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi- \
17: --enable-cross-compile \
18: --target-os=linux \
19: --extra-cflags='-I/home/ScottWong/android-ndk-r5c/platforms/android-9/arch-arm/usr/include' \
20: --extra-ldflags='-L/home/ScottWong/android-ndk-r5c/platforms/android-9/arch-arm/usr/lib -nostdlib' \
21: --arch=arm \
22: --disable-symver \
23: --disable-debug \
24: --disable-stripping \
25:
26: sed -i 's/HAVE_LRINT 0/HAVE_LRINT 1/g' config.h
27: sed -i 's/HAVE_LRINTF 0/HAVE_LRINTF 1/g' config.h
28: sed -i 's/HAVE_ROUND 0/HAVE_ROUND 1/g' config.h
29: sed -i 's/HAVE_ROUNDF 0/HAVE_ROUNDF 1/g' config.h
30: sed -i 's/HAVE_TRUNC 0/HAVE_TRUNC 1/g' config.h
31: sed -i 's/HAVE_TRUNCF 0/HAVE_TRUNCF 1/g' config.h
32:
五、编写 Android.mk 编译文件
将以下内容保存为 C:\cygwin\home\ScottWong\ffmpeg\jni\Android.mk 文件。
1: LOCAL_PATH := $(call my-dir)
2:
3: include $(CLEAR_VARS)
4:
5: LOCAL_MODULE := ffmpeg
6:
7: include $(LOCAL_PATH)/config.mak
8:
9: LOCAL_CFLAGS := -DHAVE_AV_CONFIG_H -std=c99
10:
11: AVUTIL_C_FILES = adler32.c \
12: aes.c \
13: audioconvert.c \
14: avstring.c \
15: base64.c \
16: cpu.c \
17: crc.c \
18: des.c \
19: error.c \
20: eval.c \
21: fifo.c \
22: file.c \
23: imgutils.c \
24: intfloat_readwrite.c \
25: inverse.c \
26: lfg.c \
27: lls.c \
28: log.c \
29: lzo.c \
30: mathematics.c \
31: md5.c \
32: mem.c \
33: dict.c \
34: opt.c \
35: parseutils.c \
36: pixdesc.c \
37: random_seed.c \
38: rational.c \
39: rc4.c \
40: samplefmt.c \
41: sha.c \
42: tree.c \
43: utils.c \
44: arm/cpu.c
45:
46: AVUTIL_SRC_FILES = $(addprefix libavutil/, $(sort $(AVUTIL_C_FILES)))
47:
48: AVCODEC_C_FILES = allcodecs.c \
49: audioconvert.c \
50: avpacket.c \
51: bitstream.c \
52: bitstream_filter.c \
53: dsputil.c \
54: faanidct.c \
55: fmtconvert.c \
56: imgconvert.c \
57: jrevdct.c \
58: opt.c \
59: options.c \
60: parser.c \
61: raw.c \
62: rawdec.c \
63: resample.c \
64: resample2.c \
65: simple_idct.c \
66: utils.c \
67:
68: AVCODEC_C_FILES-$(CONFIG_AANDCT) += aandcttab.c
69: AVCODEC_C_FILES-$(CONFIG_AC3DSP) += ac3dsp.c
70: AVCODEC_C_FILES-$(CONFIG_CRYSTALHD) += crystalhd.c
71: AVCODEC_C_FILES-$(CONFIG_ENCODERS) += faandct.c jfdctfst.c jfdctint.c
72: AVCODEC_C_FILES-$(CONFIG_DCT) += dct.c dct32_fixed.c dct32_float.c
73: AVCODEC_C_FILES-$(CONFIG_DWT) += dwt.c
74: AVCODEC_C_FILES-$(CONFIG_DXVA2) += dxva2.c
75: FFT-FILES-$(CONFIG_HARDCODED_TABLES) += cos_tables.c cos_fixed_tables.c
76: AVCODEC_C_FILES-$(CONFIG_FFT) += avfft.c fft_fixed.c fft_float.c \
77: $(FFT-FILES-yes)
78: AVCODEC_C_FILES-$(CONFIG_GOLOMB) += golomb.c
79: AVCODEC_C_FILES-$(CONFIG_H264DSP) += h264dsp.c h264idct.c
80: AVCODEC_C_FILES-$(CONFIG_H264PRED) += h264pred.c
81: AVCODEC_C_FILES-$(CONFIG_HUFFMAN) += huffman.c
82: AVCODEC_C_FILES-$(CONFIG_LPC) += lpc.c
83: AVCODEC_C_FILES-$(CONFIG_LSP) += lsp.c
84: AVCODEC_C_FILES-$(CONFIG_MDCT) += mdct_fixed.c mdct_float.c
85: AVCODEC_C_FILES-$(CONFIG_MPEGAUDIODSP) += mpegaudiodsp.c \
86: mpegaudiodsp_fixed.c \
87: mpegaudiodsp_float.c
88: RDFT-FILES-$(CONFIG_HARDCODED_TABLES) += sin_tables.c
89: AVCODEC_C_FILES-$(CONFIG_RDFT) += rdft.c $(RDFT-FILES-yes)
90: AVCODEC_C_FILES-$(CONFIG_SINEWIN) += sinewin.c
91: AVCODEC_C_FILES-$(CONFIG_VAAPI) += vaapi.c
92: AVCODEC_C_FILES-$(CONFIG_VDPAU) += vdpau.c
93:
94: AVCODEC_C_FILES-$(CONFIG_A64MULTI_ENCODER) += a64multienc.c elbg.c
95: AVCODEC_C_FILES-$(CONFIG_A64MULTI5_ENCODER) += a64multienc.c elbg.c
96: AVCODEC_C_FILES-$(CONFIG_AAC_DECODER) += aacdec.c aactab.c aacsbr.c aacps.c \
97: aacadtsdec.c mpeg4audio.c kbdwin.c
98: AVCODEC_C_FILES-$(CONFIG_AAC_ENCODER) += aacenc.c aaccoder.c \
99: aacpsy.c aactab.c \
100: psymodel.c iirfilter.c \
101: mpeg4audio.c kbdwin.c
102: AVCODEC_C_FILES-$(CONFIG_AASC_DECODER) += aasc.c msrledec.c
103: AVCODEC_C_FILES-$(CONFIG_AC3_DECODER) += ac3dec.c ac3dec_data.c ac3.c kbdwin.c
104: AVCODEC_C_FILES-$(CONFIG_AC3_ENCODER) += ac3enc_combined.c ac3enc_fixed.c ac3enc_float.c ac3tab.c ac3.c kbdwin.c ac3enc.c
105: AVCODEC_C_FILES-$(CONFIG_AC3_FLOAT_ENCODER) += ac3enc_float.c ac3tab.c ac3tab.c ac3.c kbdwin.c
106: AVCODEC_C_FILES-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.c ac3tab.c ac3tab.c ac3.c ac3enc.c
107: AVCODEC_C_FILES-$(CONFIG_ALAC_DECODER) += alac.c
108: AVCODEC_C_FILES-$(CONFIG_ALAC_ENCODER) += alacenc.c
109: AVCODEC_C_FILES-$(CONFIG_ALS_DECODER) += alsdec.c bgmc.c mpeg4audio.c
110: AVCODEC_C_FILES-$(CONFIG_AMRNB_DECODER) += amrnbdec.c celp_filters.c \
111: celp_math.c acelp_filters.c \
112: acelp_vectors.c \
113: acelp_pitch_delay.c
114: AVCODEC_C_FILES-$(CONFIG_AMRWB_DECODER) += amrwbdec.c celp_filters.c \
115: celp_math.c acelp_filters.c \
116: acelp_vectors.c \
117: acelp_pitch_delay.c lsp.c
118: AVCODEC_C_FILES-$(CONFIG_AMV_DECODER) += sp5xdec.c mjpegdec.c mjpeg.c
119: AVCODEC_C_FILES-$(CONFIG_ANM_DECODER) += anm.c
120: AVCODEC_C_FILES-$(CONFIG_ANSI_DECODER) += ansi.c cga_data.c
121: AVCODEC_C_FILES-$(CONFIG_APE_DECODER) += apedec.c
122: AVCODEC_C_FILES-$(CONFIG_ASS_DECODER) += assdec.c ass.c ass_split.c
123: AVCODEC_C_FILES-$(CONFIG_ASS_ENCODER) += assenc.c ass.c
124: AVCODEC_C_FILES-$(CONFIG_ASV1_DECODER) += asv1.c mpeg12data.c
125: AVCODEC_C_FILES-$(CONFIG_ASV1_ENCODER) += asv1.c mpeg12data.c
126: AVCODEC_C_FILES-$(CONFIG_ASV2_DECODER) += asv1.c mpeg12data.c
127: AVCODEC_C_FILES-$(CONFIG_ASV2_ENCODER) += asv1.c mpeg12data.c
128: AVCODEC_C_FILES-$(CONFIG_ATRAC1_DECODER) += atrac1.c atrac.c
129: AVCODEC_C_FILES-$(CONFIG_ATRAC3_DECODER) += atrac3.c atrac.c
130: AVCODEC_C_FILES-$(CONFIG_AURA_DECODER) += cyuv.c
131: AVCODEC_C_FILES-$(CONFIG_AURA2_DECODER) += aura.c
132: AVCODEC_C_FILES-$(CONFIG_AVS_DECODER) += avs.c
133: AVCODEC_C_FILES-$(CONFIG_BETHSOFTVID_DECODER) += bethsoftvideo.c
134: AVCODEC_C_FILES-$(CONFIG_BFI_DECODER) += bfi.c
135: AVCODEC_C_FILES-$(CONFIG_BINK_DECODER) += bink.c binkidct.c
136: AVCODEC_C_FILES-$(CONFIG_BINKAUDIO_DCT_DECODER) += binkaudio.c wma.c
137: AVCODEC_C_FILES-$(CONFIG_BINKAUDIO_RDFT_DECODER) += binkaudio.c wma.c
138: AVCODEC_C_FILES-$(CONFIG_BMP_DECODER) += bmp.c msrledec.c
139: AVCODEC_C_FILES-$(CONFIG_BMP_ENCODER) += bmpenc.c
140: AVCODEC_C_FILES-$(CONFIG_C93_DECODER) += c93.c
141: AVCODEC_C_FILES-$(CONFIG_CAVS_DECODER) += cavs.c cavsdec.c cavsdsp.c \
142: mpeg12data.c mpegvideo.c
143: AVCODEC_C_FILES-$(CONFIG_CDGRAPHICS_DECODER) += cdgraphics.c
144: AVCODEC_C_FILES-$(CONFIG_CINEPAK_DECODER) += cinepak.c
145: AVCODEC_C_FILES-$(CONFIG_CLJR_DECODER) += cljr.c
146: AVCODEC_C_FILES-$(CONFIG_CLJR_ENCODER) += cljr.c
147: AVCODEC_C_FILES-$(CONFIG_COOK_DECODER) += cook.c
148: AVCODEC_C_FILES-$(CONFIG_CSCD_DECODER) += cscd.c
149: AVCODEC_C_FILES-$(CONFIG_CYUV_DECODER) += cyuv.c
150: AVCODEC_C_FILES-$(CONFIG_DCA_DECODER) += dca.c synth_filter.c dcadsp.c
151: AVCODEC_C_FILES-$(CONFIG_DCA_ENCODER) += dcaenc.c
152: AVCODEC_C_FILES-$(CONFIG_DFA_DECODER) += dfa.c
153: AVCODEC_C_FILES-$(CONFIG_DNXHD_DECODER) += dnxhddec.c dnxhddata.c
154: AVCODEC_C_FILES-$(CONFIG_DNXHD_ENCODER) += dnxhdenc.c dnxhddata.c \
155: mpegvideo_enc.c motion_est.c \
156: ratecontrol.c mpeg12data.c \
157: mpegvideo.c
158: AVCODEC_C_FILES-$(CONFIG_DPX_DECODER) += dpx.c
159: AVCODEC_C_FILES-$(CONFIG_DPX_ENCODER) += dpxenc.c
160: AVCODEC_C_FILES-$(CONFIG_DSICINAUDIO_DECODER) += dsicinav.c
161: AVCODEC_C_FILES-$(CONFIG_DSICINVIDEO_DECODER) += dsicinav.c
162: AVCODEC_C_FILES-$(CONFIG_DVBSUB_DECODER) += dvbsubdec.c
163: AVCODEC_C_FILES-$(CONFIG_DVBSUB_ENCODER) += dvbsub.c
164: AVCODEC_C_FILES-$(CONFIG_DVDSUB_DECODER) += dvdsubdec.c
165: AVCODEC_C_FILES-$(CONFIG_DVDSUB_ENCODER) += dvdsubenc.c
166: AVCODEC_C_FILES-$(CONFIG_DVVIDEO_DECODER) += dv.c dvdata.c
167: AVCODEC_C_FILES-$(CONFIG_DVVIDEO_ENCODER) += dv.c dvdata.c
168: AVCODEC_C_FILES-$(CONFIG_DXA_DECODER) += dxa.c
169: AVCODEC_C_FILES-$(CONFIG_EAC3_DECODER) += eac3dec.c eac3dec_data.c
170: AVCODEC_C_FILES-$(CONFIG_EAC3_ENCODER) += eac3enc.c ac3enc.c ac3enc_float.c \
171: ac3tab.c ac3.c kbdwin.c
172: AVCODEC_C_FILES-$(CONFIG_EACMV_DECODER) += eacmv.c
173: AVCODEC_C_FILES-$(CONFIG_EAMAD_DECODER) += eamad.c eaidct.c mpeg12.c \
174: mpeg12data.c mpegvideo.c \
175: error_resilience.c
176: AVCODEC_C_FILES-$(CONFIG_EATGQ_DECODER) += eatgq.c eaidct.c
177: AVCODEC_C_FILES-$(CONFIG_EATGV_DECODER) += eatgv.c
178: AVCODEC_C_FILES-$(CONFIG_EATQI_DECODER) += eatqi.c eaidct.c mpeg12.c \
179: mpeg12data.c mpegvideo.c \
180: error_resilience.c
181: AVCODEC_C_FILES-$(CONFIG_EIGHTBPS_DECODER) += 8bps.c
182: AVCODEC_C_FILES-$(CONFIG_EIGHTSVX_EXP_DECODER) += 8svx.c
183: AVCODEC_C_FILES-$(CONFIG_EIGHTSVX_FIB_DECODER) += 8svx.c
184: AVCODEC_C_FILES-$(CONFIG_EIGHTSVX_RAW_DECODER) += 8svx.c
185: AVCODEC_C_FILES-$(CONFIG_ESCAPE124_DECODER) += escape124.c
186: AVCODEC_C_FILES-$(CONFIG_FFV1_DECODER) += ffv1.c rangecoder.c
187: AVCODEC_C_FILES-$(CONFIG_FFV1_ENCODER) += ffv1.c rangecoder.c
188: AVCODEC_C_FILES-$(CONFIG_FFVHUFF_DECODER) += huffyuv.c
189: AVCODEC_C_FILES-$(CONFIG_FFVHUFF_ENCODER) += huffyuv.c
190: AVCODEC_C_FILES-$(CONFIG_FLAC_DECODER) += flacdec.c flacdata.c flac.c vorbis_data.c
191: AVCODEC_C_FILES-$(CONFIG_FLAC_ENCODER) += flacenc.c flacdata.c flac.c vorbis_data.c
192: AVCODEC_C_FILES-$(CONFIG_FLASHSV_DECODER) += flashsv.c
193: AVCODEC_C_FILES-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.c
194: AVCODEC_C_FILES-$(CONFIG_FLASHSV2_ENCODER) += flashsv2enc.c
195: AVCODEC_C_FILES-$(CONFIG_FLIC_DECODER) += flicvideo.c
196: AVCODEC_C_FILES-$(CONFIG_FOURXM_DECODER) += 4xm.c
197: AVCODEC_C_FILES-$(CONFIG_FRAPS_DECODER) += fraps.c
198: AVCODEC_C_FILES-$(CONFIG_FRWU_DECODER) += frwu.c
199: AVCODEC_C_FILES-$(CONFIG_GIF