下载最新的 ffmpeg, 我下的是 0.8.2
下载最新的 gas-preprocessor 脚本 (用来在 MAC OS X 下编译汇编代码的):
https://github.com/yuvi/gas-preprocessor
请将 gas-preprocessor.pl 脚本安装在 /usr/sbin 或者其他执行文件目录下, 并添加执行权限
分别使用下面的配置进行编译:
IOS4.3 armv7 版本 (iPhone 3Gs, iPhone4):
./configure --disable-doc --disable-ffmpeg --disable-ffplay --disable-ffserver --disable-avdevice --disable-swscale --disable-avfilter --disable-avformat --disable-debug --disable-encoders --enable-cross-compile --disable-decoders --disable-armv5te --enable-decoder=h264 --enable-pic --arch=arm --target-os=darwin --cc=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc --as='gas-preprocessor/gas-preprocessor.pl /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc' --sysroot=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk --cpu=cortex-a8 --extra-cflags='-arch armv7' --extra-ldflags='-arch armv7 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk'
IOS4.3 armv6 版本 (iPhone 3G):
./configure --disable-doc --disable-ffmpeg --disable-ffplay --disable-ffserver --disable-avdevice --disable-swscale --disable-avfilter --disable-avformat --disable-debug --disable-encoders --enable-cross-compile --disable-decoders --disable-armv5te --enable-decoder=h264 --enable-pic --arch=arm --target-os=darwin --cc=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc --as='gas-preprocessor/gas-preprocessor.pl /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc' --sysroot=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk --cpu=arm1176jzf-s --extra-cflags='-arch armv6' --extra-ldflags='-arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk'
IOS4.3 i386 版本 (用于模拟器):
./configure --disable-doc --disable-ffmpeg --disable-ffplay --disable-ffserver --disable-avdevice --disable-swscale --disable-avfilter --disable-avformat --disable-debug --disable-encoders --enable-cross-compile --disable-decoders --disable-armv5te --enable-decoder=h264 --enable-pic --cc=/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc --as='gas-preprocessor/gas-preprocessor.pl /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc' --extra-ldflags=-L/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/usr/lib/system --sysroot=/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk --target-os=darwin --arch=i386 --cpu=i386 --extra-cflags='-arch i386' --extra-ldflags='-arch i386'
将上述分别编译出来的库, 打包成一个统一的版本的方法:
lipo -create -arch armv6 armv6/libavcodec.a -arch armv7 armv7/libavcodec.a -arch i386 i386/libavcodec.a -output libavcodec.a
lipo -create -arch armv6 armv6/libavutil.a -arch armv7 armv7/libavutil.a -arch i386 i386/libavutil.a -output libavutil.a
添加 libavcodec.a, libavutil.a, libavcodec/avcodec.h, 以及 libavutil 下所有头文件到工程中 (请注意路径).
解码的方法 (代码片断如下, 完整代码请参考相关附件):
1
struct
AVCodec
*
fCodec
=
NULL;
//
Codec
2
struct
AVCodecContext
*
fCodecContext
=
NULL;
//
Codec Context
3
struct
AVFrame
*
fVideoFrame
=
NULL;
//
Frame
4
5
int
fDisplayWidth
=
0
;
6
int
fDisplayHeight
=
0
;
7
8
9
10
int
avcodec_decode_video(AVCodecContext
*
avctx, AVFrame
*
picture,
11
int
*
got_picture_ptr,
12
const
uint8_t
*
buf,
int
buf_size)
13
{
14
AVPacket avpkt;
15
av_init_packet(
&
avpkt);
16
avpkt.data
=
buf;
17
avpkt.size
=
buf_size;
18
//
HACK for CorePNG to decode as normal PNG by default
19
avpkt.flags
=
AV_PKT_FLAG_KEY;
20
return
avcodec_decode_video2(avctx, picture, got_picture_ptr,
&
avpkt);
21
}
22
23
24
25
int
avc_decode_init(
int
width,
int
height)
26
{
27
if
(fCodecContext
!=
NULL) {
28
return
0
;
29
}
30
avcodec_init();
31
avcodec_register_all();
32
fCodec
=
avcodec_find_decoder(CODEC_ID_H264);
33
34
fDisplayWidth
=
width;
35
fDisplayHeight
=
height;
36
37
CreateYUVTable();
38
39
fCodecContext
=
avcodec_alloc_context();
40
avcodec_open(fCodecContext, fCodec);
41
fVideoFrame
=
avcodec_alloc_frame();
42
43
return
1
;
44
}
45
46
47
48
int
avc_decode_release()
49
{
50
if
(fCodecContext) {
51
avcodec_close(fCodecContext);
52
free(fCodecContext
->
priv_data);
53
free(fCodecContext);
54
fCodecContext
=
NULL;
55
}
56
57
if
(fVideoFrame) {
58
free(fVideoFrame);
59
fVideoFrame
=
NULL;
60
}
61
62
DeleteYUVTable();
63
return
1
;
64
}
65
66
67
68
int
avc_decode(
char
*
buf,
int
nalLen,
char
*
out
)
69
{
70
byte_t
*
data
=
(byte_t
*
)buf;
71
int
frameSize
=
0
;
72
73
int
ret
=
avcodec_decode_video(fCodecContext, fVideoFrame,
&
frameSize, data, nalLen);
74
if
(ret
<=
0
) {
75
return
ret;
76
}
77
78
int
width
=
fCodecContext
->
width;
79
int
height
=
fCodecContext
->
height;
80
DisplayYUV_32((uint32_t
*
)
out
, width, height, fDisplayWidth);
81
return
ret;
82
}