如何在 IPHONE 下面用 FFMPEG 播放 H.264 流开发记录

下载最新的 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 }
posted @ 2012-04-12 23:15  jprothwell  阅读(941)  评论(1编辑  收藏  举报