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

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

 

相关阅读推荐

视频直播关键技术:流畅、拥塞和延时追赶

视频直播技术详解:直播的推流调度

音视频通话:小议音频处理与压缩技术

视频编解码的理论和实践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,必须花很多时间去熟练使用它。

 

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

猜你喜欢

转载自blog.csdn.net/netease_im/article/details/83999185