FFmpeg源代码简单分析 libswscale的sws getContext

本文详细分析了FFmpeg中libswscale库的sws_getContext()函数,该函数用于初始化SwsContext,涉及内存分配、参数设置和初始化过程。文中介绍了libswscale处理数据的流程,包括unscaled和scaled两种方式,并探讨了sws_alloc_context()和sws_init_context()的实现细节。此外,还提到了后续将分析的数据处理函数sws_scale()。
摘要由CSDN通过智能技术生成

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

=====================================================

FFmpeg的库函数源代码分析文章列表:

【架构图】

FFmpeg源代码结构图 - 解码

FFmpeg源代码结构图 - 编码

【通用】

FFmpeg 源代码简单分析:av_register_all()

FFmpeg 源代码简单分析:avcodec_register_all()

FFmpeg 源代码简单分析:内存的分配和释放(av_malloc()、av_free()等)

FFmpeg 源代码简单分析:常见结构体的初始化和销毁(AVFormatContext,AVFrame等)

FFmpeg 源代码简单分析:avio_open2()

FFmpeg 源代码简单分析:av_find_decoder()和av_find_encoder()

FFmpeg 源代码简单分析:avcodec_open2()

FFmpeg 源代码简单分析:avcodec_close()

【解码】

图解FFMPEG打开媒体的函数avformat_open_input

FFmpeg 源代码简单分析:avformat_open_input()

FFmpeg 源代码简单分析:avformat_find_stream_info()

FFmpeg 源代码简单分析:av_read_frame()

FFmpeg 源代码简单分析:avcodec_decode_video2()

FFmpeg 源代码简单分析:avformat_close_input()

【编码】

FFmpeg 源代码简单分析:avformat_alloc_output_context2()

FFmpeg 源代码简单分析:avformat_write_header()

FFmpeg 源代码简单分析:avcodec_encode_video()

FFmpeg 源代码简单分析:av_write_frame()

FFmpeg 源代码简单分析:av_write_trailer()

【其它】

FFmpeg源代码简单分析:日志输出系统(av_log()等)

FFmpeg源代码简单分析:结构体成员管理系统-AVClass

FFmpeg源代码简单分析:结构体成员管理系统-AVOption

FFmpeg源代码简单分析:libswscale的sws_getContext()

FFmpeg源代码简单分析:libswscale的sws_scale()

FFmpeg源代码简单分析:libavdevice的avdevice_register_all()

FFmpeg源代码简单分析:libavdevice的gdigrab

【脚本】

FFmpeg源代码简单分析:makefile

FFmpeg源代码简单分析:configure

【H.264】

FFmpeg的H.264解码器源代码简单分析:概述

=====================================================


打算写两篇文章记录FFmpeg中的图像处理(缩放,YUV/RGB格式转换)类库libswsscale的源代码。libswscale是一个主要用于处理图片像素数据的类库。可以完成图片像素格式的转换,图片的拉伸等工作。有关libswscale的使用可以参考文章:

最简单的基于FFmpeg的libswscale的示例(YUV转RGB)

libswscale常用的函数数量很少,一般情况下就3个:

sws_getContext():初始化一个SwsContext。

sws_scale():处理图像数据。

sws_freeContext():释放一个SwsContext。

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

尽管libswscale从表面上看常用函数的个数不多,它的内部却有一个大大的“世界”。做为一个几乎“万能”的图片像素数据处理类库,它的内部包含了大量的代码。因此计划写两篇文章分析它的源代码。本文首先分析它的初始化函数sws_getContext(),而下一篇文章则分析它的数据处理函数sws_scale()。


函数调用结构图

分析得到的libswscale的函数调用关系如下图所示。



Libswscale处理数据流程

Libswscale处理像素数据的流程可以概括为下图。


从图中可以看出,libswscale处理数据有两条最主要的方式: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中只能看到一行定义:
struct SwsContext;
一般人看到这个只有一行定义的结构体,会猜测它的内部一定十分简单。但是假使我们看一下FFmpeg的源代码,会发现这个猜测是完全错误的——SwsContext的定义是十分复杂的。它的定义位于libswscale\swscale_internal.h中,如下所示。
/* This struct should be aligned on at least a 32-byte boundary. */typedef struct SwsContext {
        /**     * info on struct for av_log     */    const AVClass *av_class;    /**     * Note that src, dst, srcStride, dstStride will be copied in the     * sws_scale() wrapper so they can be freely modified here.     */    SwsFunc swscale;    int srcW;                     ///< Width  of source      luma/alpha planes.    int srcH;                     ///< Height of source      luma/alpha planes.    int dstH;                     ///< Height of destination luma/alpha planes.    int chrSrcW;                  ///< Width  of source      chroma     planes.    int chrSrcH;                  ///< Height of source      chroma     planes.    int chrDstW;                  ///< Width  of destination chroma     planes.    int chrDstH;                  ///< Height of destination chroma     planes.    int lumXInc, chrXInc;    int lumYInc, chrYInc;    enum AVPixelFormat dstFormat; ///< Destination pixel format.    enum AVPixelFormat srcFormat; ///< Source      pixel format.    int dstFormatBpp;             ///< Number of bits per pixel of the destination pixel format.    int srcFormatBpp;             ///< Number of bits per pixel of the source      pixel format.    int dstBpc, srcBpc;    int chrSrcHSubSample;         ///< Binary logarithm of horizontal subsampling factor between luma/alpha and chroma planes in source      image.    int chrSrcVSubSample;         ///< Binary logarithm of vertical   subsampling factor between luma/alpha and chroma planes in source      image.    int chrDstHSubSample;         ///< Binary logarithm of horizontal subsampling factor between luma/alpha and chroma planes in destination image.    int chrDstVSubSample;         ///< Binary logarithm of vertical   subsampling factor between luma/alpha and chroma planes in destination image.    int vChrDrop;                 ///< Binary logarithm of extra vertical subsampling factor in source image chroma planes specified by user.    int sliceDir;                 ///< Direction that slices are fed to the scaler (1 = top-to-bottom, -1 = bottom-to-top).    double param[2];              ///< Input parameters for scaling algorithms that need them.    /* The cascaded_* fields allow spliting a scaler task into multiple     * sequential steps, this is for example used to limit the maximum     * downscaling factor that needs to be supported in one scaler.     */    struct SwsContext *cascaded_context[2];    int cascaded_tmpStride[4];    uint8_t *cascaded_tmp[4];    uint32_t pal_yuv[256];    uint32_t pal_rgb[256];    /**     * @name Scaled horizontal lines ring buffer.     * The horizontal scaler keeps just enough scaled lines in a ring buffer     * so they may be passed to the vertical scaler. The pointers to the     * allocated buffers for each line are duplicated in sequence in the ring     * buffer to simplify indexing and avoid wrapping around between lines     * inside the vertical scaler code. The wrapping is done before the     * vertical scaler is called.     */    //@{
        int16_t **lumPixBuf;          ///< Ring buffer for scaled horizontal luma   plane lines to be fed to the vertical scaler.    int16_t **chrUPixBuf;         ///< Ring buffer for scaled horizontal chroma plane lines to be fed to the vertical scaler.    int16_t **chrVPixBuf;         ///< Ring buffer for scaled horizontal chroma plane lines to be fed to the vertical scaler.    int16_t **alpPixBuf;          ///< Ring buffer for scaled horizontal alpha  plane lines to be fed to the vertical scaler.    int vLumBufSize;              ///< Number of vertical luma/alpha lines allocated in the ring buffer.    int vChrBufSize;              ///< Number of vertical chroma     lines allocated in the ring buffer.    int lastInLumBuf;             ///< Last scaled horizontal luma/alpha line from source in the ring buffer.    int lastInChrBuf;             ///< Last scaled horizontal chroma     line from source in the ring buffer.    int lumBufIndex;              ///< Index in ring buffer of the last scaled horizontal luma/alpha line from source.    int chrBufIndex;              ///< Index in ring buffer of the last scaled horizontal chroma     line from source.    //@}    uint8_t *formatConvBuffer;    /**     * @name Horizontal and vertical filters.     * To better understand the following fields, here is a pseudo-code of     * their usage in filtering a horizontal line:     * @code     * for (i = 0; i < width; i++) {     *     dst[i] = 0;     *     for (j = 0; j < filterSize; j++)     *         dst[i] += src[ filterPos[i] + j ] * filter[ filterSize * i + j ];     *     dst[i] >>= FRAC_BITS; // The actual implementation is fixed-point.     * }     * @endcode     */    //@{
        int16_t *hLumFilter;          ///< Array of horizontal filter coefficients for luma/alpha planes.    int16_t *hChrFilter;          ///< Array of horizontal filter coefficients for chroma     planes.    int16_t *vLumFilter;          ///< Array of vertical   filter coefficients for luma/alpha planes.    int16_t *vChrFilter;          ///< Array of vertical   filter coefficients for chroma     planes.    int32_t *hLumFilterPos;       ///< Array of horizontal filter starting positions for each dst[i] for luma/alpha planes.    int32_t *hChrFilterPos;       ///< Array of horizontal filter starting positions for each dst[i] for chroma     planes.    int32_t *vLumFilterPos;       ///< Array of vertical   filter starting positions for each dst[i] for luma/alpha planes.    int32_t *vChrFilterPos;       ///< Array of vertical   filter starting positions for each dst[i] for chroma     planes.    int hLumFilterSize;           ///< Horizontal filter size for luma/alpha pixels.    int hChrFilterSize;           ///< Horizontal filter size for chroma     pixels.    int vLumFilterSize;           ///< Vertical   filter size for luma/alpha pixels.    int vChrFilterSize;           ///< Vertical   filter size for chroma     pixels.    //@}    int lumMmxextFilterCodeSize;  ///< Runtime-generated MMXEXT horizontal fast bilinear scaler code size for luma/alpha planes.    int chrMmxextFilterCodeSize;  ///< Runtime-generated MMXEXT horizontal fast bilinear scaler
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值