ffmpeg源码简析(十)libswscale中的SwsContext,sws_scale()

libswscale是一个主要用于处理图片像素数据的类库。可以完成图片像素格式的转换,图片的拉伸等工作。
libswscale常用的函数数量很少,一般情况下就3个:

sws_getContext():初始化一个SwsContext。

sws_scale():处理图像数据。
sws_freeContext():释放一个SwsContext。

其中sws_getContext()也可以用sws_getCachedContext()取代。

尽管libswscale从表面上看常用函数的个数不多,它的内部却有一个大大的“世界”。做为一个几乎“万能”的图片像素数据处理类库,它的内部包含了大量的代码。

ibswscale处理数据有两条最主要的方式:unscaled和scaled。unscaled用于处理不需要拉伸的像素数据(属于比较特殊的情况),scaled用于处理需要拉伸的像素数据。Unscaled只需要对图像像素格式进行转换;而Scaled则除了对像素格式进行转换之外,还需要对图像进行缩放。Scaled方式可以分成以下几个步骤:

XXX to YUV Converter:首相将数据像素数据转换为8bitYUV格式;
Horizontal scaler:水平拉伸图像,并且转换为15bitYUV;
Vertical scaler:垂直拉伸图像;
Output converter:转换为输出像素格式。

SwsContext
SwsContext是使用libswscale时候一个贯穿始终的结构体。但是我们在使用FFmpeg的类库进行开发的时候,是无法看到它的内部结构的。在libswscale\swscale.h中只能看到一行定义.它的定义位于libswscale\swscale_internal.h中

struct SwsContext; 

sws_getContext()

sws_getContext()是初始化SwsContext的函数。sws_getContext()的声明位于libswscale\swscale.h,如下所示。

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); 

该函数包含以下参数:

srcW:源图像的宽
srcH:源图像的高
srcFormat:源图像的像素格式
dstW:目标图像的宽
dstH:目标图像的高
dstFormat:目标图像的像素格式
flags:设定图像拉伸使用的算法

成功执行的话返回生成的SwsContext,否则返回NULL。
sws_getContext()的定义位于libswscale\utils.c,如下所示。

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)  
{  
    SwsContext *c;  

    if (!(c = sws_alloc_context()))  
        return NULL;  

    c->flags     = flags;  
    c->srcW      = srcW;  
    c->srcH      = srcH;  
    c->dstW      = dstW;  
    c->dstH      = dstH;  
    c->srcFormat = srcFormat;  
    c->dstFormat = dstFormat;  

    if (param) {  
        c->param[0] = param[0];  
        c->param[1] = param[1];  
    }  

    if (sws_init_context(c, srcFilter, dstFilter) < 0) {  
        sws_freeContext(c);  
        return NULL;  
    }  

    return c;  
} 

从sws_getContext()的定义中可以看出,它首先调用了一个函数sws_alloc_context()用于给SwsContext分配内存。然后将传入的源图像,目标图像的宽高,像素格式,以及标志位分别赋值给该SwsContext相应的字段。最后调用一个函数sws_init_context()完成初始化工作。

sws_init_context()除了对SwsContext中的各种变量进行赋值之外,主要按照顺序完成了以下一些工作:

1.  通过sws_rgb2rgb_init()初始化RGB转RGB(或者YUV转YUV)的函数(注意不包含RGB与YUV相互转换的函数)。
2.  通过判断输入输出图像的宽高来判断图像是否需要拉伸。如果图像需要拉伸,那么unscaled变量会被标记为1。
3.  通过sws_setColorspaceDetails()初始化颜色空间。
4.  一些输入参数的检测。例如:如果没有设置图像拉伸方法的话,默认设置为SWS_BICUBIC;如果输入和输出图像的宽高小于等于0的话,也会返回错误信息。
5.  初始化Filter。这一步根据拉伸方法的不同,初始化不同的Filter。
6.  如果flags中设置了“打印信息”选项SWS_PRINT_INFO,则输出信息。
7.  如果不需要拉伸的话,调用ff_get_unscaled_swscale()将特定的像素转换函数的指针赋值给SwsContext中的swscale指针。
8.  如果需要拉伸的话,调用ff_getSwsFunc()将通用的swscale()赋值给SwsContext中的swscale指针(这个地方有点绕,但是确实是这样的)。

sws_scale()

sws_scale()是用于转换像素的函数。它的声明位于libswscale\swscale.h,如下所示。

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[]);

sws_scale()的定义位于libswscale\swscale.c,如下所示。

    /** 
     * swscale wrapper, so we don't need to export the SwsContext. 
     * Assumes planar Y
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值