轻松使用 ffmpeg sdk 实现各种格式的rgb以及yuv raw

简介:
有些时候大家需要一些yuv或者rgb 的 raw data的文件。ffmpeg项目中的libavcodec支持很多格式的raw相互转换,在早期的版本中,使用 img_convert,在新版本中,使用 sws_scale 完成。各种不同的格式在ffmpeg里面被称为 pixel formats,下面贴出来的就是:

PIX_FMT_YUV420P,    < Planar YUV 4:2:0 (1 Cr & Cb sample per 2x2 Y samples)/n"
PIX_FMT_YUV422,     < Packed pixel, Y0 Cb Y1 Cr /n"
PIX_FMT_RGB24,      < Packed pixel, 3 bytes per pixel, RGBRGB.../n"
PIX_FMT_BGR24,      < Packed pixel, 3 bytes per pixel, BGRBGR.../n"
PIX_FMT_YUV422P,    < Planar YUV 4:2:2 (1 Cr & Cb sample per 2x1 Y samples)/n"
PIX_FMT_YUV444P,    < Planar YUV 4:4:4 (1 Cr & Cb sample per 1x1 Y samples)/n"
PIX_FMT_RGBA32,     < Packed pixel, 4 bytes per pixel, BGRABGRA..., stored in cpu endianness/n"
PIX_FMT_YUV410P,    < Planar YUV 4:1:0 (1 Cr & Cb sample per 4x4 Y samples)/n"
PIX_FMT_YUV411P,    < Planar YUV 4:1:1 (1 Cr & Cb sample per 4x1 Y samples)/n"
IX_FMT_RGB565,     < always stored in cpu endianness /n"
PIX_FMT_RGB555,     < always stored in cpu endianness, most significant bit to 1 /n"
PIX_FMT_GRAY8,/n"
PIX_FMT_MONOWHITE, < 0 is white /n"
PIX_FMT_MONOBLACK, < 0 is black /n"
PIX_FMT_PAL8,       < 8 bit with RGBA palette /n"
PIX_FMT_YUVJ420P,   < Planar YUV 4:2:0 full scale (jpeg)/n"
PIX_FMT_YUVJ422P,   < Planar YUV 4:2:2 full scale (jpeg)/n"
PIX_FMT_YUVJ444P,   < Planar YUV 4:4:4 full scale (jpeg)/n"
PIX_FMT_UYVY422,    < Packed pixel, Cb Y0 Cr Y1 /n"
PIX_FMT_UYVY411,    < Packed pixel, Cb Y0 Y1 Cr Y2 Y3/n"
/////////////////////////////////////////////////////////////////

举例来说,
PIX_FMT_YUV444P,    < Planar YUV 4:4:4  
指的是文件的开始1/3是y分量,中间1/3是u分量,最后1/3是v分量。

PIX_FMT_RGB24,      < Packed pixel, 3 bytes per pixel, RGBRGB.../n"
指的是文件内的数据3个byte是一组,始终按照RGB方式排列。

PIX_FMT_RGBA32,     < Packed pixel, 4 bytes per pixel, BGRABGRA..., stored in cpu endianness/n"
指的是文件内的数据4个byte是一组,始终按照RGB+alpha byte方式排列,alpha表示透明度。
/////////////////////////////////////////////////////////////////

ffmpeg对于以上所有类型抽象成
typedef struct AVPicture {
     uint8_t *data[4];
     int linesize[4];
} AVPicture;

该结构体总共表示四个平面,
data[0]表示第一个平面的数据开始地址,
linesize[0]表示第一个平面的每一行有多少个字节。

这样PIX_FMT_YUV444P有三个Planar,最后一个平面空着不用就好了。

AVFrame这个结构体的包含AVPicture,此外,AVFrame还含有其他一些成员数据,比如。是否key_frame、已编码图像数 coded_picture_number、是否作为参考帧reference、宏块类型 *mb_type等等,这里就不详细叙述了。
/////////////////////////////////////////////////////////////////


鉴于img_convert在新版中已经不用,所以这里只介绍一下效率更高的。sws_scale。

来看看它的函数定义:
int sws_scale(struct SwsContext *ctx, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[])

其中src和srcStride定义了输入图像的四个平面的数据起始指针和四个平面中每一行包含的像素的个数。

dst和dstStride是输出变量,定义的是输出图像的四个平面的数据起始指针和四个平面包含的数据的大小。

为什么一个图像有四个平面,可以找一下YUV格式的一些详细介绍就可以明白。

当然,RGB格式是按照紧凑格式进行编码的,因此只有一个平面,也就是说只要设置src[0]就可以,src[1],src[2],src[3]都为 NULL。

我们就在设置src[0]和srcStride[0]的地方做文章。

按照一般处理src[0]和srcStride[0]分别设置为起始图像数据的开始和图像每一行的像素个数。

那如果把src[0] 设置为 width * ( height - 1)     srcStride[0] = -height 结果会如何呢?是不是就会把图像倒过来呢?

实际确实如此。进行图像倒置的操作尽然如此简单。这样避免了人为再添加一次图像的反转操作,提高了编码的性能。

/////////////////////////////////////////////////////////////////

不发命令行工具了,需要的mail给我.

这里提供一个windows平台下使用ffmpeg的快捷方法,下面这个开发包内直接提供lib给开发人员使用。
目录
相关文章
|
30天前
|
开发工具
使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c(三)
使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c(三)
33 0
|
30天前
|
存储 编解码 数据处理
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码(三)
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码
63 0
|
30天前
|
存储 编解码 数据处理
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码(二)
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码
69 0
|
30天前
|
存储 监控 开发工具
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为AVI视频格式(C++)
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为AVI视频格式(C++)
40 0
|
30天前
|
存储 传感器 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK修改图像像素格式Mono8或者Mono10(C++)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK修改图像像素格式Mono8或者Mono10(C++)
75 0
|
30天前
FFmpeg开发笔记(十八)FFmpeg兼容各种音频格式的播放
《FFmpeg开发实战》一书中,第10章示例程序playaudio.c原本仅支持mp3和aac音频播放。为支持ogg、amr、wma等非固定帧率音频,需进行三处修改:1)当frame_size为0时,将输出采样数量设为512;2)遍历音频帧时,计算实际采样位数以确定播放数据大小;3)在SDL音频回调函数中,确保每次发送len字节数据。改进后的代码在chapter10/playaudio2.c,可编译运行播放ring.ogg测试,成功则显示日志并播放铃声。
28 1
FFmpeg开发笔记(十八)FFmpeg兼容各种音频格式的播放
|
30天前
|
开发工具
使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c(二)
使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c(二)
23 0
|
30天前
|
编解码 IDE 开发工具
使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c(一)
使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c(一)
29 1
|
30天前
|
存储 缓存 编解码
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码(一)
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码
68 0
|
30天前
|
Linux 编译器 数据安全/隐私保护
Windows10 使用MSYS2和VS2019编译FFmpeg源代码-测试通过
FFmpeg作为一个流媒体的整体解决方案,在很多项目中都使用了它,如果我们也需要使用FFmpeg进行开发,很多时候我们需要将源码编译成动态库或者静态库,然后将库放入到我们的项目中,这样我们就能在我们的项目中使用FFmpeg提供的接口进行开发。关于FFmpeg的介绍这里就不过多说明。
109 0