从本地读取YUV数据编码为H264格式的数据,然后再存入到本地,编码后的数据有带startcode。
与FFmpeg示例音频编码的流程基本一致。
(1)avcodec_find_encoder_by_name:根据指定的编码器名称查找注册的编码器。
(2)avcodec_alloc_context3:为AVCodecContext分配内存。
(3)avcodec_open2:打开编码器。
(4)avcodec_send_frame:将AVFrame非压缩数据给编码器。
(5)avcodec_receive_packet:获取到编码后的AVPacket数据,收到的packet需要自己释放内存。
(6)av_frame_get_buffer:为音频或视频帧分配新的buffer。在调用这个函数之前,必须在AVFame上设置好以下属性:format(视频为像素格式,音频为样本格式)、nb_samples(样本个数,针对音频)、channel_layout(通道类型,针对音频)、width/height(宽高,针对视频)。
(7)av_frame_make_writable:确保AVFrame是可写的,使用av_frame_make_writable()的问题是,在最坏的情况下,它会在您使用encode再次更改整个输入frame之前复制它. 如果frame不可写,av_frame_make_writable()将分配新的缓冲区,并复制这个输入input frame数据,避免和编码器需要缓存该帧时造成冲突。
(8)av_image_fill_arrays:存储一帧像素数据存储到AVFrame对应的data buffer。
(9)int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align);
作用:通过指定像素格式、图像宽、图像用来计算所需的内存大小。
参数align:此参数是设定内存对齐的对齐数,也就是按多大的字节进行内存对齐:
(10)int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align);
(11)int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], const uint8_t *src, enum AVPixelFormat pix_fmt, int width, int height, int align);
av_image_fill_arrays()函数本身不具备内存申请的功能,此函数类似于格式化已经申请的内存,即通av_malloc()函数申请的内存空间,或者av_frame_get_buffer()函数申请的内存空间。
编码出来的h264数据可以直接使用ffplay播放,也可以使用VLC播放。
(1)什么是视频码率?
视频码率是视频数据(包含视频色彩量、亮度量、像素量)每秒输出的位数。一般用的单位是kbps。
(2)设置码率的必要性
在网络视频应⽤中,视频质量和网络带宽占用是相矛盾的。通常情况下,视频流占用的带宽越高则视频质量也越高,需要的网络带宽也越大,解决这一矛盾的钥匙当然是视频编解码技术。评判一种视频编解码技术的优劣,是比较在相同的带宽条件下,哪个视频质量更好;在相同的视频质量条件下,哪个占用的网络带宽更少(文件体积小)。
是不是视频码率越高,质量越好呢?理论上是这样的。然而在肉眼分辨的范围内,当码率高到一定程度时,就没有什么差别了。所以码率设置有它的最优值,H.264(也叫AVC或x264)的文件中,视频的建议码率如下:
(2)手机设置码率建议
鉴于x264的参数众多,各种参数的配合复杂,为了使用者方便,x264建议如无特别需要可使用preset和tune设置。
这套开发者推荐的参数较为合理,可在此基础上在调整一些具体参数以符合实际需要,手动设定的参数会覆盖preset和tune的参数。
使用ffmpeg -h encoder=libx264 查询相关支持的参数。
(1)preset
预设是一系列参数的集合,这个集合能够在编码速度和压缩率之间做出权衡。
一个编码速度稍慢的预设会提供更高的压缩效率(压缩效率是以文件大小来衡量的)。这就是说,假如你想得到一个指定大小的文件或者采用恒定比特率编码模式,你可以采用一个较慢的预设来获得更好的质量。同样的,对于恒定质量编码模式,你可以通过选择一个较慢的预设轻松地节省比特率。如果你很有耐心,通常的建议是使用最慢的预设。目前所有的预设按照编码速度降序排列为:
ultrafast > superfast > veryfast > faster > fast > medium – default preset > slow > slower > veryslow > placebo - ignore this as it is not useful (see FAQ)
默认为medium级别。
(2)tune
une是x264中重要性仅次于preset的选项,它是视觉优化的参数,tune可以理解为视频偏好(或者视频类型),tune不是一个单一的参数,而是由一组参数构成-tune来改变参数设置。
当前的 tune包括:
如果你不确定使用哪个选项或者说你的输入与所有的tune皆不匹配,你可以忽略–tune 选项。
(3)profile
另外一个可选的参数是**-profile:v**,它可以将你的输出限制到一个特定的 H.264 profile。一些非常老的或者要被淘汰的设备仅支持有限的选项,比如只支持baseline或者main。
所有的profile 包括:
1)baseline profile:基本画质。支持I/P 帧,只支持无交错(Progressive)和CAVLC;
2)extended profile:进阶画质。支持I/P/B/SP/SI 帧,只支持无交错(Progressive)和CAVLC;
3)main profile:主流画质。提供I/P/B 帧,支持无交错(Progressive)和交错(Interlaced),也支持CAVLC 和CABAC 的支持;
4)high profile:高级画质。在main Profile 的基础上增加了8x8内部预测、自定义量化、 无损视频编码和更多的YUV 格式;
在相同配置情况下,High profile(HP)可以比Main profile(MP)节省10%的码流量,比MPEG-2MP节省60%的码流量,具有更好的编码性能。根据应用领域的不同:
1)baseline profile多应用于实时通信领域;
2)main profile多应用于流媒体领域;
3)high profile则多应用于广电和存储领域。