图像视频编码和FFmpeg(3)-----用FFmpeg进行图像格式转换和AVFrame简介

本文介绍如何使用FFmpeg进行图像格式转换,重点讲解AVFrame结构体及其在图像处理中的作用。通过示例代码展示如何分配和初始化AVFrame,以及利用SwsContext和sws_scale函数进行图像格式转换。
摘要由CSDN通过智能技术生成

        上一篇介绍了YUV格式,并给出了一个YUYV422转RGB24的例子。其实,FFmpeg有一个函数专门进行图像格式转换的。本文就介绍怎么用FFmpeg转换,因为在转换时还要用到AVFrame这个结构体,所以这里也会介绍AVFrame。在FFmpeg中,AVFrame是一个比较重要的结构体。

        AVFrame,顾名思义,这个结构体应该是保存视频帧的信息的。像一帧图像也是可以保存在AVFrame结构中。事实上,我们可以直接从一个YUV文件中,把一张YUV图像数据读到AVFrame中。本文后面的例子也是这样做的。

        为了弄懂AVFrame是怎么存放一张YUV图像的(当然AVFrame可以存放其他格式图像的),现在先看一下AVFrame结构体的主要成员。

typedef struct AVFrame
{
#define AV_NUM_DATA_POINTERS 8
    uint8_t * 	data [AV_NUM_DATA_POINTERS]; //指向图像数据

    int linesize [AV_NUM_DATA_POINTERS]; //行的长度

    int width; //图像的宽
    int height; //图像的高
    int format;  //图像格式
	 ……
}AVFrame;

        注意到data成员是一个指针数组。其指向的内容就是图像的实际数据。

        可以用av_frame_alloc(void)函数来分配一个AVFrame结构体。这个函数只是分配AVFrame结构体,但data指向的内存并没有分配,需要我们指定。这个内存的大小就是一张特定格式图像所需的大小,如前一篇博文中说到的,对于YUYV422格式,所需的大小是width * height * 2。所以AVFrame结构体的整个初始化过程如下:

AVFrame* frame = av_frame_alloc();

//这里FFmpeg会帮我们计算这个格式的图片,需要多少字节来存储
//相当于前一篇博文例子中的width * height * 2
int bytes_num = avpicture_get_size(AV_PIX_FMT_YUV420P, width, height); //AV_PIX_FMT_YUV420P是FFmpeg定义的标明YUV420P图像格式的宏定义

//申请空间来存放图片数据。包含源数据和目标数据
uint8_t* buff = (uint8_t*)av_malloc(bytes_num);

//前面的av_frame_alloc函数,只是为这个AVFrame结构体分配了内存,
//而该类型的指针指向的内存还没分配。这里把av_malloc得到的内存和AVFrame关联起来。
//当然,其还会设置AVFrame的其他成员
avpicture_fill((AVPicture*)frame, buff, AV_PIX_FMT_ YUV420P,width, height);

        看到这里,可能有些读者会疑问:data成员是一个指针数组(即数组里面的每一个元素都是一个指针),一个buff怎么够用(多对一的关系)。其实,这就是FFmpeg设计的一个巧妙之处。还记得前一篇博文说到的 图像物理存储有 planar和packed两种模式吗?这个data指针数组就是为了planar设计的。对于planar模式的YUV。data[0]指向Y分量的开始位置、data[1]指向U分量的开始位置、data[2]指向V分量的开始位置。对

  • 5
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值