Demux等过程中,ffmpeg会用av_dict_set,字典统计metadata信息,并print出来,这对我们跟代码,关注一些参数比较有用。
首先,此次是为了扩展vp6 encoder,没有找到官方源码,就参考的mencoder/mplayer,其中有个封装的动态库vp6vfw.dll,这是很容易找到的,其中要注意它编码的输入流是RGB,有个config.h头文件中定义了所有的需要的宏等,可以在一个成功编译并安装的mplayer中拷贝过来,注意版本对应。
测试demo时,简易makefile如下(其中含从mplayer中抽出的文件):
#---------------------------------------------------------------------------------------------------------#
#headers
vpath %.h libmpcodecs\
osdep\
loader\
loader/dmo\
loader/dshow\
loader/qtx\
loader/qtx/qtxsdk\
loader/wine
vpath %.c \
osdep\
libavutil\
libmpcodecs\
loader\
loader/dmo\
loader/dshow\
loader/qtx
#compilingoptions
DEFS += -D__FALLENINK__
#-w 忽略所有警告-Wall 显示所有警告-Werror警告当成错误处理
FLAGS += -w -lpthread -lm -g
#tools
CC = gcc
#defines
OBJECTS = demo_vp6enc.o\
vp6enc.o\
ve_vfw.o\
vfl.o\
drv.o\
win32.o\
module.o\
ext.o\
ldt_keeper.o\
cpudetect.o\
mmap_anon.o\
resource.o\
registry.o\
avstring.o\
path.o\
pe_image.o\
pe_resource.o\
mem.o
main : $(OBJECTS)
$(CC)$(FLAGS) -o main $(OBJECTS)
$(OBJECTS) : %.o : %.c
$(CC)$(DEFS) $(FLAGS) -c $< -o $@
.PHONY : clean
clean :
-rm main$(OBJECTS)
#---------------------------------------------------------------------------------------------------------#
然后看看,ffmpeg中需要做的。
可参考的地方有:
http://wiki.multimedia.cx/index.php?title=On2_VP6
http://blog.csdn.net/phenixzhong/article/details/7375838
代码相关:
在libavcodec/avcodec.h中,enum CodecID类型中添加对应枚举值(命名要尽量符合ffmpeg的风格),如:CODEC_ID_VP6VFW = 0x0ffff。
在libavcodec/allcodecs.c的avcodec_register_all()函数中添加vp6vfw解码器注册,比如:
REGISTER_ENCODER (VP6VFW, vp6vfw);
在libavformat/xxx.c文件中,这里比如,添加对于可包含vp6数据的文件格式对vp6vfw的识别,如static const AVCodecTag flv_video_codec_ids[];flv_write_packet中也需要添加;(这里修改各异)
创建vp6vfwenc.c源文件并实现必要的函数,且需要定义一个全局AVCodec变量,比如:
AVCodecff_vp6vfw_encoder = {
.name = "vp6vfw",
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_VP6VFW,
.priv_data_size = 0,//sizeof(VP56Context),
.init = __born,
.close = __die,
.decode = __working,
.capabilities = 0,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("On2 VP6(Fallenink version, implemented by vp6vfw.dll)"),
};
执行的输入选项,在ffmpeg.c中static const OptionDef options[]数组的"vcodec"对应着opt_video_codec函数。
编译相关:
Configure
test_deps _encoder _decoder????
添加了: vp6vfw \
ENCODER_LIST=$(find_things encoder ENC libavcodec/allcodecs.c)?????
echo "Creating config.mak and config.h..."????
Libavcodec下的makefile里:
添加一行,如:OBJS-$(CONFIG_VP6VFW_ENCODER) += vp6vfwenc.o
如有子目录,则参考其他子目录的makefile写法。
const AVClass *av_class; /**< information for av_log(). Set by url_open(). */
struct URLProtocol *prot;
{
if (!(h->flags & AVIO_FLAG_READ))
return AVERROR(EIO);
return retry_transfer_wrapper(h, buf, size, 1, h->prot->url_read);
}
global: av_*; ff_*; avutil_*;
local: *;
};
gcc 编译动态库,默认将所有函数都导出。
使用version-script,仅仅导出要使用的符号表
$gcc -o mylib.so --version-script a.map a.o b.o
{
global: 导出函数名;
local: *;
};
再在 ld 时用 --version-script 选项来 load 你 文件。都完事后再使用 readelf 观察static 与 dynamic section 发现只导出了你指定的函数名即符号。
1,only meaningful for ELF platforms that support shared libraries
2,could improve reduce the img size.
3,could improve the speed of load library, if library havn't been prelinked.