音视频编码说明1音视频编码参数1.1音频编码参数音频编码格式采用AAC格式,其参数设置比较简单,主要设置参数如下:(1)音频样本格式的设置c->sample_fmt = AV_SAMPLE_FMT_S16;sample_fmt是一个enum类型,包含了多种样本格式,样本格式的设置应保持与Android应用层音频采样格式一致。
此处,我们设置为AV_SAMPLE_FMT_S16,Android应用层采样格式也是16位的ENCODING_PCM_16BIT格式。
(2)音频码率设置c->bit_rate = 64000;此参数为应用层提供参数接口,由应用层根据编码效果来设定。
此处参考值为64000。
(3)音频采样率设置c->sample_rate = 44100;此参数为应用层提供参数接口,由应用层获取实际机型可用的采样率来决定。
采样率越低,音频效果越差,反之,越好。
音频采样率一般有8000,44100, 47250, 48000, 47250,32000, 11025, 16000,22050等值,此处参考值为44100HZ,现在基本所有机器都支持44100采样,而且音频效果也很好。
(4)音频通道设置c->channels = 2;此参数为应用层提供参数接口,根据应用层需求来设置。
当设置1时为单声道模式,设置2时为立体声道模式。
此处参考值为2.1.2视频编码参数视频编码参数相对音频编码参数复杂,其中一些参数关系到视频编码的质量和编码速度,为此需要设置一套最优的参数以确保质量和速度达到一个平衡点。
(1)视频编码基本参数设置<1> DEC_ID_H264;视频编码格式采用H264格式。
<2> c->width = 480;c->height = 480;width和height两个参数为应用层提供参数接口,根据具体需求来设置编码后视频的大小,即最终视频的width和height。
应用层也可以考虑通过调节width和height的大小来改变视频编码的速度,例如480*320的大小比480*480的大小编码速度快很多。
此处默认是480*480大小。
<3> c->time_base.den = 15;c->time_base.num = 1;这两个参数决定视频播放帧率,即每秒播放多少帧的视频,time_base.num固定为1, time_base.den为应用层提供参数接口。
一般应用层录取视频帧率和播放视频帧率一致。
此参数的设置需要考虑到编码速度的问题,经过反复测试,15帧/s是一个比较合适的值。
<4> c->pix_fmt = AV_PIX_FMT_YUV420P;视频像素格式,采用AV_PIX_FMT_YUV420P格式。
(2)重要参数设置以上视频参数是必须设置的基本参数,以下介绍的参数将会直接影响到视频的质量和编码速度。
详细如下:<1> c->thread_count编码线程数,将帧分块,由不同的线程去完成。
此参数为应用层提供参数接口,大小需要根据设备CPU核心数来动态设定。
经过反复测试,此处大小设置为 thread_count=CPU核心数*1.5时编码速度达到比较好的水平。
<2> opt_set_funcs系列函数的利用opt_set_funcs系列函数有以下10个:int av_opt_set (void *obj, const char *name, const char *val, int search_flags);int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags);int av_opt_set_double(void *obj, const char *name,double val,int search_flags);int av_opt_set_q(void *obj, const char *name, AVRational val, int search_flags);int av_opt_set_bin (void *obj, const char *name, const uint8_t *val, int size, int search_flags);int av_opt_set_image_size(void*obj, const char*name, int w, int h, int search_flags); int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags);int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, intsearch_flags);int av_opt_set_video_rate(void *obj, const char *name, AVRational val, intsearch_flags);int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags);我们可以在ffmpeg源码库libavutil\opt.h查看函数的声明,目前只用到前两个av_opt_set、av_opt_set_int来设置x264里的一些编码参数。
av_opt_set(c->priv_data, "preset", "ultrafast", 0);通过preset参数可以设置编码速度的等级,preset的级别有ultrafast、superfast、veryfast、faster、fast、medium、slow、slower、veryslow、placebo,从快到慢。
其实,这里的每个参数都是由一组x264参数设置组合而成。
例如ultrafast参数是由以下参数设置组合的:- ultrafast:\n"" --no-8x8dct --aq-mode 0 --b-adapt 0\n"" --bframes 0 --no-cabac --no-deblock\n"" --no-mbtree --me dia --no-mixed-refs\n"" --partitions none --rc-lookahead 0 --ref 1\n"" --scenecut 0 --subme 0 --trellis 0\n""--no-weightb --weightp 0\n"这些参数可以在x264源码库里x264.c文件中查看到。
大部分参数的含义可以参看或者.preset参数为应用层也提供了参数接口,应用层根据编码速度和质量的进行选取合适的等级。
经过反复测试,设置为ultrafast这个值,再配合其他参数参考值能达到最优效果。
✧av_opt_set(c->priv_data, " x264opts", " force-cfr", 0);设置force_crf参数,此参数是设置tune参数zerolatency值中挖掘出来的。
Zerolatency参数也是由一组参数组合而成,能起到的作用是解决延迟问题,实现实时编码。
其组合参数如下: - zerolatency:\n"" --bframes 0 --force-cfr --no-mbtree\n"" --sync-lookahead 0 --sliced-threads\n"" --rc-lookahead 0\n"其中有的参数与ultrafast中的参数重复,经过反复测试,设置force_crf和设置tune值为zerolatency效果是一样的。
✧av_opt_set_int(c->priv_data, " qp", qpValue, 0);其中qpValue是一个int类型的值,qp表示固定量化因子,取值范围0到51。
经常取值在20-40之间,越小质量越好,要求的码率越高,0表示无损压缩。
此参数为应用层提供了参数接口,应用层根据视频质量和编码速度来选取合适的大小。
经过反复测试,取值25能达到质量和速度的平衡。
码率控制的方法有三种,出了qp控制方法外还有bitrate及crf 方法。
三种码率控制方法见下表1.表1.三种码率控制方法对比说明:起初使用的码率控制方法是bitrate固定码率的方法,其取值为W*h*15*2*0.07是参考doubango计算方法,其中w是视频图像的宽,h是视频图像的高,15是帧率,2是中等质量等级,0.07一个权重系数,经过反复测试取此值达到速度与质量平衡时的速度并不是非常满意,为了寻求更快的编码速度,测试了qp方法和crf方法。
测试crf方法采用默认值23时,速度比较慢,取值增大时质量也变得很差,因此没有找打一个好的平衡点,舍弃了此种方法。
最终选取了qp控制方法,当取值为25时,在1.2GHZ双核CPU测试手机(本文中提到的测试都是基于此设备的)上速度和质量达到预想效果,速度接近15帧/s。
在开发中,这三种码率控制的方法应该根据实际需求来选取。
1.3编码参数设置总结对于音频参数的设置比较简单,视频参数的设置比较难,主要是因为要考虑到视频编码速度的问题。
虽然之后的编码处理方面也会有些问题会影响编码速度,但是设置好了编码参数也就成功了一大半了。
这些参数的设置都要根据实际的需求来设置,在没有经验的情况下需要反复的测试,找到最合适的参数值。
2编码设置完编码参数和初始化其他工作后,就可以把采集的音视频数据进行编码了。
音频编码比较简单,在此不用介绍,下面主要介绍视频的编码工作。
2.1视频编码的需求视频编码的需求如下:a.将移动设备采集来的视频数据像素格式转变为AV_PIX_FMT_YUV420P类型的格式;b.对视频图像大小进行裁剪成目标图片大小;c.当设备由横屏变为竖屏录像时,需要对视频图像进行旋转操作;d.最后对处理好的视频数据进行真正的编码,并写入文件。