乐趣区

视频编解码的理论和实践2Ffmpeg视频编解码

近几年,视频编解码技术在理论及应用方面都取得了重大的进展,越来越多的人想要了解编解码技术。因此,网易云信研发工程师为大家进行了归纳梳理,从理论及实践两个方面简单介绍视频编解码技术。

相关阅读推荐
《视频直播关键技术:流畅、拥塞和延时追赶》
《视频直播技术详解:直播的推流调度》
《音视频通话:小议音频处理与压缩技术》
《视频编解码的理论和实践 1:基础知识介绍》

1、Ffmpeg 介绍
《视频编解码的理论和实践 1:基础知识介绍》介绍了视频编码的基础知识,本篇文章,我们一起看看实际应用中的视频编码是如何操作的。
在实际工程项目中,ffmpeg 是应用最多的多媒体处理框架,它提供了音视频采集、编解码、图像处理,格式转换等功能,并且拥有很强的扩展能力,通过 ffmpeg 可以很容易集成第三方库(例如:x264、openh264 等),通过这种能力,它可以实现更强大的功能。Ffmpeg 由下面几个部分构成:
Libavformat:音视频格式处理
Libavcodec:音视频编解码
Libavfilter:音视频滤镜
Libavdevice:音视频设备采集
Libswscale:图像缩放、转换
Libswresample:音频重采样
Ffmpeg:一个命令行的转码工具
Ffplay:一个命令行播放器
Ffprobe:简单的媒体格式分析工具

2、Ffmpeg 视频编码
视频编码是 ffmpeg 提供的基本功能之一,通过 ffmpeg 可以很容易实现视频编码操作。使用 ffmpeg 进行视频编码之前需要把 x264、openh264 等第三方编解码库集成到 ffmpeg 中才能使用。编码步骤如下:
(1)注册编码器
(2)根据名字或者 ID 查找你想使用的编码器(例如 x264、x265、openh264 等)
(3)创建一个编码器上下文对象
(4)在编码器上下文对象中设置编码器参数
(5)打开编码器
(6)读取一帧图像进行编码,一直重复该过程,直到处理结束
(7)关闭编码器
示例代码如下:
avcodec_register_all(); // 注册所有可用的编码器
codec = avcodec_find_encoder_by_name(“libx264”); // 查找编码器
ctx = avcodec_alloc_context3(codec); // 创建编码器上下文
ctx->width = 1280; // 设置编码器参数
ctx->height = 720;
// …. 其他的参数设置
avcodec_open2(ctx, codec, NULL); // 打开编码器
while(read_frame(frame)){

AVPacket pkt; // 存放编码之后的数据
int got_output = 0; // 是否成功编码得到一个图像
avcodec_encode_video2(ctx, &pkt, frame, &got_output); // 编码
if(got_output){// 得到编码后的数据,进行后续操作

}
}
avcodec_free_context(&ctx); // 关闭编码器

可以看到,ffmpeg 隐藏了大部分的编码细节,调用者不需要了解预测、变换、量化、熵编码等细节,这些细节都已经被 ffmpeg 封装好了,开发者只要把编码参数设置好,然后调用相关的接口函数,即可实现视频编码功能。当然,这知识最基本的编码功能,要想在画面质量和压缩率之间取得平衡,必须了解视频编码的细节,然后设置相应的参数。

3、Ffmpeg 视频解码
Ffmpeg 自带了 H264 的视频解码器,开发者可选择直接使用 ffmpeg 自带的 H264 解码器或者第三方的解码库进行视频解码。和视频编码一样,解码操作的大部分细节都已经被 ffmpeg 隐藏起来了,开发者只需要设置好相关的解码参数,然后调用接口函数就可以实现解码功了。解码流程如下:
(1)注册解码器
(2)查找解码器
(3)创建解码器上下文对象
(4)设置解码参数
(5)打开解码器
(6)读取数据进行解码,直到结束
(7)关闭解码器
代码示例如下:
avcodec_register_all(); // 注册解码器
codec = avcodec_find_decoder_by_name(“h264”); // 查找解码器
ctx = avcodec_alloc_context3(codec); // 创建解码器上下文对象
//…设置解码参数
avcodec_open2(ctx, codec, NULL); // 打开解码器
while(read_packet(pkt)){

AVFrame frame; // 存放解码之后的图像数据
int got_frame = 0;
avcodec_decode_video2(ctx, frame, &got_frame, pkt); // 解码
if(got_frame){// 解码得到一帧图像,进行后续操作…}

}
avcodec_free_context(&ctx); // 关闭解码器

可以看到 ffmpeg 是个非常强大的多媒体处理框架,通过 ffmpeg 我们可以很容易进行音视频方面的处理。上面介绍的只是 ffmpeg 的冰山一角,要想熟练使用 ffmpeg,必须花很多时间去熟练使用它。

更多即时通讯、音视频技术的干货文章,请关注网易云信博客。

退出移动版