ffmpeg-iOS编译及使用文档
1.终端编译
准备条件
先下载文件:https://github.com/libav/gas-preprocessor,
复制gas-preprocessor.pl到/usr/sbin下(Mac OS X10.11由于权限问题也可放在usr/bin下),
修改文件权限:chmod 777 /usr/bin/gas-preprocessor.pl(根据文件目录修改)
安装yasm
ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”安装
具体步骤如下:
1. 下载脚本:https://github.com/kewlbear/FFmpeg-iOS-build-script
2. 解压,进入FFmpeg-iOS-build-script文件目录找到文件 build-ffmpeg.sh
3. 执行服本文件:./build-ffmpeg.sh, 脚本会自动把ffmpeg源码从github上下载到文件目录并编译,其中,ffmpeg-x.x.x是源码,FFmpeg-iOS是编译出来的库,里面有我们需要的.a静态库,一共有7个。(因为我要编译支持AVS+的解码库,所以我选择了ffmpeg2.7.2(修改版)添加到FFmpeg-iOS-build-script目录下,并且修改脚本Pasted Graphic 1.tiff,这样就不会从github上下载源码了)。(编译会很漫长,十几分钟)
见修改文档--ffmpeg兼容bavs的实现方法
编译后文件目录如下:
Pasted Graphic.tiff
执行命令:
lipo -info libavcodec.a
查看.a包支持的架构,这几个包都支持了armv7 armv7s i386 x86_64 arm64这几个架构.
..编译完成后,终端进入FFmpeg-iOS-build-script目录,然后输入./build-ffmpeg.sh lipo,这个命令是讲.a文件合并成一个
5.把ffmpeg-iOS文件加入到工程中
6.添加一个头文件引用 #include “xxxx”
(视情况选择)添加一个api语句:av_register_all();给一个类文件.m后缀改为.mm,开启混编模式。
运行工程,如果没有报错,则表明编译成功
7.其他注意细节
编译的时候报错: ‘libavcodec/avcodec.h’ file not found ,拷贝library search path路径
(PROJECTDIR)/FFmpeg−iOS/lib修改Headersearchpaths里的路径:
(PROJECT_DIR)/FFmpeg-iOS/include
导入静态库加及所需的.framework入External libraries:
1
2
3
libz.dylib
libbz2.dylib
libiconv.dylib
Pasted Graphic 2.tiff
avs+真机测试出现错误(24个)
1.导入libbavs.a静态库,选择真机测试Pasted Graphic 3.tiff,否则查找不到bavs
2.xcode7 默认开启bitcode(iwatch需要),则会导致部分第三方框架报错(比如ffmpeg或友盟的错误)
youmeng/libMobClickLibrary.a(MobClick.o)’ does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7
这是要么更新库,要么可以在 build setting 中,搜索bitcode,并把 enable bitcode 设置为 NO 如下:
Pasted Graphic_1.tiff
ffmpeg需要支持本地解码和网络解码(http/udp/rstp…):
本地解码视频文件应放入沙盒
Pasted Graphic 4.tiffPasted Graphic 5.tiff
案例:kxmovie
未解决的问题:kxmovie_avs+播放无法网络视频,播放本地视频.mp4有时崩溃
附ffmpeg修改文档(支持avs+)
1.本文背景
本文主要介绍如何在ffmpeg中使用支持P16的bavs解码库。
2.基本原理
由于ffmpeg中已有一个cavs,但其支持的档次和功能特性都不够完善。因此,新开发的bavs将加入ffmpeg中,并可以很好地支持P2/P16的帧或场方式的解码,它将覆盖cavs的功能。为了保护bavs解码库,将以加密的动态库形式提供该库。但一些有关ffmpeg语法上的修改,将在下文中进行详细介绍。
3.ffmpeg需做的相应改动
3.1 libavformat
mpegts.c文件中,红色显示部分为修改:
static const StreamType ISO_types[] = {
{ 0x01, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO },
{ 0x02, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO },
{ 0x03, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3 },
{ 0x04, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3 },
{ 0x0f, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC },
{ 0x10, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG4 },
/* Makito encoder sets stream type 0x11 for AAC,
* so auto-detect LOAS/LATM instead of hardcoding it. */
if !CONFIG_LOAS_DEMUXER
{ 0x11, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC_LATM }, /* LATM syntax */
endif
{ 0x1b, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264 },
{ 0x42, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS },
{ 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC },
{ 0xea, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1 },
{ 0x42, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_BAVS },
{ 0 },
};
Riff.c文件中,
{ AV_CODEC_ID_KMVC, MKTAG(‘K’, ‘M’, ‘V’, ‘C’) },
{ AV_CODEC_ID_CAVS, MKTAG(‘C’, ‘A’, ‘V’, ‘S’) },
{ AV_CODEC_ID_BAVS, MKTAG(‘B’, ‘A’, ‘V’, ‘S’) },
Cavsvideodec.c文件中,
static int cavsvideo_probe(AVProbeData *p)
{
uint32_t code= -1;
int pic=0, seq=0, slice_pos = 0;
int i;
for(i=0; i<p->buf_size; i++){
code = (code<<8) + p->buf[i];
if ((code & 0xffffff00) == 0x100) {
if(code < CAVS_SEQ_START_CODE) {
/* slices have to be consecutive */
if(code < slice_pos)
return 0;
slice_pos = code;
} else {
slice_pos = 0;
}
if (code == CAVS_SEQ_START_CODE) {
seq++;
/* check for the only currently supported profile */
if 0
if(p->buf[i+1] != CAVS_PROFILE_JIZHUN)
return 0;
else
if(p->buf[i+1] == 0x48)
{
printf("[good news] : ffmpeg can support GuangDian profile now!\n");
}
else if( p->buf[i+1] != CAVS_PROFILE_JIZHUN && p->buf[i+1] != 0x48 )
{
return 0;
}
endif
} else if ((code == CAVS_PIC_I_START_CODE) ||
(code == CAVS_PIC_PB_START_CODE)) {
pic++;
} else if ((code == CAVS_UNDEF_START_CODE) ||
(code > CAVS_VIDEO_EDIT_CODE)) {
return 0;
}
}
}
if(seq && seq*9<=pic*10)
return AVPROBE_SCORE_MAX/2;
return 0;
}
同上---
ffmpeg-2.7.2版本的修改方式如下:
if 0
if (*ptr != CAVS_PROFILE_JIZHUN)
return 0;
else
if(*ptr == 0x48)
{
printf("[good news] : ffmpeg can support GuangDian profile now!\n");
}
else if(*ptr != CAVS_PROFILE_JIZHUN && *ptr != 0x48 )
{
return 0;
}
endif
3.2 libavcodec
codec_desc.c文件中,在static const AVCodecDescriptor codec_descriptors[]的最后加上数据成员:
{
.id = AV_CODEC_ID_BAVS,
.type = AVMEDIA_TYPE_VIDEO,
.name = “bavs”,
.long_name = NULL_IF_CONFIG_SMALL(“Chinese AVS (Audio Video Standard) (AVS1-P2, JiZhun profile)and (AVS1-P16, Guangdian profile)”),
.props = AV_CODEC_PROP_LOSSY,
},
Avcodec.h文件中,enum AVCodecID最后加上数据成员
AV_CODEC_ID_BAVS = AV_CODEC_ID_CAVS,
Allcodecs.c文件中,
REGISTER_DECODER(CAVS, cavs);
改为
REGISTER_DECODER(BAVS, bavs);
Cavs_parser.c中,cavs_find_frame_end函数中:
if(pic_found){
/* EOF considered as end of frame */
if (buf_size == 0)
return 0;
for(; i