ffmpeg中libswscale的应用

libswscale介绍

雷神对于libswscale的描述:最简单的基于FFmpeg的libswscale的示例(YUV转RGB

FFmpeg中的 sws_scale() 函数主要是用来做视频像素格式和分辨率的转换,其优势在于:可以在同一个函数里实现:1.图像色彩空间转换, 2:分辨率缩放,3:前后图像滤波处理。不足之处在于:效率相对较低,不如libyuv或shader,其关联的函数主要有:
/**
Allocate and return an SwsContext. You need it to perform
scaling/conversion operations using sws_scale().

@param srcW the width of the source image /* 输入图像的宽度 /
@param srcH the height of the source image / 输入图像的高度 /
@param srcFormat the source image format / 输入图像的像素格式 /
@param dstW the width of the destination image / 输出图像的宽度 /
@param dstH the height of the destination image / 输出图像的高度 /
@param dstFormat the destination image format / 输出图像的像素格式 /
@param flags specify which algorithm and options to use for rescaling / 选择缩放算法(只有当输入输出图像大小不同时有效),一般选择SWS_FAST_BILINEAR /
@param srcFilter /输入图像的滤波器信息,默认为null/
@param dstFilter /输出图像的滤波信息,默认为null/
@param param extra parameters to tune the used scaler/ 特定缩放算法需要的参数(?),默认为NULL */
For SWS_BICUBIC param[0] and [1] tune the shape of the basis
function, param[0] tunes f(1) and param[1] f´(1)
For SWS_GAUSS param[0] tunes the exponent and thus cutoff
frequency
For SWS_LANCZOS param[0] tunes the width of the window function
@return a pointer to an allocated context, or NULL in case of error
@note this function is to be removed after a saner alternative is written
*/
struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
int dstW, int dstH, enum AVPixelFormat dstFormat,
int flags, SwsFilter *srcFilter,
SwsFilter *dstFilter, const double *param);

与其类似的函数还有: sws_getCachedContext ,区别在于: sws_getContext 可以用于多路码流转换,为每个不同的码流都指定一个不同的转换上下文,而 sws_getCachedContext 只能用于一路码流转换。

/**
Scale the image slice in srcSlice and put the resulting scaled
slice in the image in dst. A slice is a sequence of consecutive
rows in an image.

Slices have to be provided in sequential order, either in
top-bottom or bottom-top order. If slices are provided in
non-sequential order the behavior of the function is undefined.

@param c the scaling context previously created with
sws_getContext()
@param srcSlice the array containing the pointers to the planes of
the source slice
@param srcStride the array containing the strides for each plane of
the source image
@param srcSliceY the position in the source image of the slice to
process, that is the number (counted starting from
zero) in the image of the first row of the slice
@param srcSliceH the height of the source slice, that is the number
of rows in the slice
@param dst the array containing the pointers to the planes of
the destination image
@param dstStride the array containing the strides for each plane of
the destination image
@return the height of the output slice
*/
int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[],
const int srcStride[], int srcSliceY, int srcSliceH,
uint8_t *const dst[], const int dstStride[]);

1.参数 SwsContext *c, 转换格式的上下文。也就是 sws_getContext 函数返回的结果。
2.参数 const uint8_t const srcSlice[], 输入图像的每个颜色通道的数据指针。其实就是解码后的AVFrame中的data[]数组。因为不同像素的存储格式不同,所以srcSlice[]维数也有可能不同。
以YUV420P为例,它是planar格式,它的内存中的排布如下:
YYYYYYYY UUUU VVVV
使用FFmpeg解码后存储在AVFrame的data[]数组中时:
data[0]——-Y分量, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8……
data[1]——-U分量, U1, U2, U3, U4……
data[2]——-V分量, V1, V2, V3, V4……
linesize[]数组中保存的是对应通道的数据宽度 ,
linesize[0]——-Y分量的宽度(一行中的字节数)
linesize[1]——-U分量的宽度(一行中的字节数)
linesize[2]——-V分量的宽度 (一行中的字节数)
而RGB24,它是packed格式,它在data[]数组中则只有一维,它在存储方式如下:
data[0]: R1, G1, B1, R2, G2, B2, R3, G3, B3, R4, G4, B4……
这里要特别注意,linesize[0]的值并不一定等于图片的宽度,有时候为了对齐各解码器的CPU,实际尺寸会大于图片的宽度,这点在我们编程时(比如OpengGL硬件转换/渲染)要特别注意,否则解码出来的图像会异常。
3.参数const int srcStride[],输入图像的每个颜色通道的跨度。.也就是每个通道的行字节数,对应的是解码后的AVFrame中的linesize[]数组。根据它可以确立下一行的起始位置,不过stride和width不一定相同,这是因为:
a.由于数据帧存储的对齐,有可能会向每行后面增加一些填充字节这样 stride = width + N;
b.packet色彩空间下,每个像素几个通道数据混合在一起,例如RGB24,每个像素3字节连续存放,因此下一行的位置需要跳过3
width字节。
4.参数int srcSliceY, int srcSliceH,定义在输入图像上处理区域,srcSliceY是起始位置,srcSliceH是处理多少行。如果srcSliceY=0,srcSliceH=height,表示一次性处理完整个图像。这种设置是为了多线程并行,例如可以创建两个线程,第一个线程处理 [0, h/2-1]行,第二个线程处理 [h/2, h-1]行。并行处理加快速度。
5.参数uint8_t *const dst[], const int dstStride[]定义输出图像信息(输出的每个颜色通道数据指针,每个颜色通道行字节数)

实际代码中应用

g_video_service.ir_scaler = sws_getContext(
image->width, image->height, AV_PIX_FMT_BAYER_BGGR16BE,
intermedia_image.depthir.width, intermedia_image.depthir.height, AV_PIX_FMT_YUV420P,
0, NULL, NULL, NULL);
/这里描述了转换前的图像宽高、图像格式,以及转换后输出的宽高、图像格式,0为用到的拉伸算法,还不太明白,其他可以使用的算法定义在头文件swscale.h中/

const uint8_t* src_slice[1] = {(const uint8_t*)image->data};//指针数组,AV_PIX_FMT_BAYER_BGGR16BE格式的数据在一个数组当中
int src_stride[1] = {image->bytes_per_line};//stride为一行的字节数

uint8_t* dst_slice[3] = {
intermedia_image.depthir.y_ptr,
intermedia_image.depthir.u_ptr,
intermedia_image.depthir.v_ptr
};
int dst_stride[3] = {
intermedia_image.depthir.y_stride,
intermedia_image.depthir.u_stride,
intermedia_image.depthir.v_stride
};
sws_scale(ir_scaler, src_slice, src_stride, 0, image->height, dst_slice, dst_stride);
第4个参数0,第5个参数为image->height表示处理整张图片

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值