对ffmpeg中的sws_scale的封装类-阿里云开发者社区

开发者社区> 人工智能> 正文
登录阅读全文

对ffmpeg中的sws_scale的封装类

简介:

直接使用ffmpeg中的sws_scale虽然已经不太复杂,但每次的手动初始化等操作,毕竟不够方便。我对这部分代码进行了封装。平时常见的需要处理的图像格式无非就是YUV420和RGB24、RGB32等格式,我的封装仅仅对它们进行。blog好像不能上传附件,因此我没法把ffmpeg的scale相关的静态库lib(静态库携带比动态库方便^_^)等上传了(发了一份给自己的qq邮箱留作备份了,发现这儿可以上传附件,全部源码也上传一份好了)。

下面的代码,可能需要ffmpeg的相关头文件支持,我对它们进行了一些精简,只需要一个头文件"swscale.h"即可。

   

FFScale.h源码如下:

ExpandedBlockStart.gif/***************************************************************************//**
* 版权所有 (C) 

* 文件名称: FFScale.h
* 文件标识: 
* 内容摘要: 使用ffmpeg中的sws_scale进行图片格式转换和resize的封装类。
* 其它说明: 本模块仅仅对常见的图像格式进行了转换,更多的图像格式,请直接使用
* ffmepg中的sws_scale。
*
* 本封装类使用方法如下:
* 1、定义一个CFFScale对象;
* 2、调用该对象的SetAttribut函数,设置输入输出图像的格式和Scale算法;
* 3、调用该对象的Scale函数,进行Scale操作。
*
* 注意:本模块假定YUV图像格式采用的连续的内存空间进行的图像存储,如
* 实际情况并非如此,则本模块不适应这种场合。
* 当前版本: V1.0
* 作 者: Cloud
* 完成日期: 2011-10-28
******************************************************************************
*/

#pragma once


//Scale算法
enum SwsAlogrithm
ExpandedBlockStart.gif{
    SWS_SA_FAST_BILINEAR    = 0x1,
    SWS_SA_BILINEAR            = 0x2,
    SWS_SA_BICUBIC            = 0x4,
    SWS_SA_X                = 0x8,
    SWS_SA_POINT            = 0x10,
    SWS_SA_AREA                = 0x20,
    SWS_SA_BICUBLIN            = 0x40,
    SWS_SA_GAUSS            = 0x80,
    SWS_SA_SINC                = 0x100,
    SWS_SA_LANCZOS            = 0x200,
    SWS_SA_SPLINE            = 0x400,
}
;

//视频图像格式
enum PicFormat
ExpandedBlockStart.gif{
    SWS_PF_NONE            = PIX_FMT_NONE,
    SWS_PF_YUV420P        = PIX_FMT_YUV420P,
    SWS_PF_RGB24        = PIX_FMT_RGB24,
    SWS_PF_BGR24        = PIX_FMT_BGR24,
    SWS_PF_ARGB            = PIX_FMT_ARGB,
    SWS_PF_RGBA            = PIX_FMT_RGBA,
    SWS_PF_ABGR            = PIX_FMT_ABGR,
    SWS_PF_BGRA            = PIX_FMT_BGRA,
}
;


class CFFScale
ExpandedBlockStart.gif{
public:
    CFFScale(void);
    ~CFFScale(void);

    //设置输入输出图片属性以及Scale算法
    void SetAttribute(PicFormat srcFormat, PicFormat dstFormat, SwsAlogrithm enAlogrithm = SWS_SA_FAST_BILINEAR);

    //Scale
    BOOL Scale(
        byte *pSrc, int nSrcW, int nSrcH, int nSrcPicth,
        byte *pDst, int nDstW, int nDstH, int nDstPicth
        );

private:

    //初始化
    BOOL Init();

    //反初始化
    void DeInit();

    SwsContext*    m_pSwsContext;        //SWS对象
    PicFormat m_srcFormat;            //源像素格式
    PicFormat m_dstFormat;            //目标像素格式
    SwsAlogrithm m_enAlogrithm;        //Resize算法

    int m_nSrcW, m_nSrcH;            //源图像宽高
    int m_nSrcPicth;                //源图像第一行数据的长度
    int m_nSrcSlice[4];                //源图像各分量数据起始地址偏移
    int m_nSrcStride[4];            //源图像各分量一行数据的长度

    int m_nDstW, m_nDstH;            //目标图像宽高
    int m_nDstPicth;                //目标图像第一行数据的长度
    int m_nDstSlice[4];                //目标图像各分量数据起始地址偏移
    int m_nDstStride[4];            //目标图像各分量一行数据的长度

}
;


FFScale.cpp源码如下:

#include "StdAfx.h"
#include "FFScale.h"

#pragma comment(lib, "Scale/libavutil.lib")
#pragma comment(lib, "Scale/libswscale.lib")
#pragma comment(lib, "Scale/libgcc.lib")
#pragma comment(lib, "Scale/libmingwex.lib")

//构造
CFFScale::CFFScale(void)
ExpandedBlockStart.gif{
    m_pSwsContext = NULL;
    m_srcFormat = SWS_PF_NONE;    
    m_dstFormat = SWS_PF_NONE;    
    m_enAlogrithm = SWS_SA_FAST_BILINEAR;

    m_nSrcW = m_nSrcH = 0;            
    m_nSrcPicth = 0;                
    m_nDstW = m_nDstH = 0;
    m_nDstPicth = 0;
    for (int i=0; i<4; i++)
ExpandedSubBlockStart.gif    {
        m_nSrcSlice[i] = -1;
        m_nSrcStride[i] = 0;
        m_nDstSlice[i] = -1;
        m_nDstStride[i] = 0; 
    }

}


//析构
CFFScale::~CFFScale(void)
ExpandedBlockStart.gif{
    DeInit();
}


ExpandedBlockStart.gif/***************************************************************************//**
* 函数名称:    SetAttribute
* 功能描述:    设置输入输出图片属性以及Scale算法。
* 参 数:    srcFormat    >> 源图像格式;
* 参 数:    dstFormat    >> 目标图像格式;
* 参 数:    enAlogrithm    >> Scale算法;
* 返回值:    
* 其它说明:    
* 修改日期        修改人            修改内容
* ------------------------------------------------------------------------------
* 2011-10-28    Cloud         创建
******************************************************************************
*/

void CFFScale::SetAttribute(PicFormat srcFormat, PicFormat dstFormat, SwsAlogrithm enAlogrithm)
ExpandedBlockStart.gif{
    m_srcFormat = srcFormat;
    m_dstFormat = dstFormat;
    m_enAlogrithm = enAlogrithm;
    DeInit();
}


ExpandedBlockStart.gif/***************************************************************************//**
* 函数名称:    Init
* 功能描述:    初始化。
* 返回值:    执行成功返回TRUE,否则返回FALSE。
* 其它说明:    
* 修改日期        修改人            修改内容
* ------------------------------------------------------------------------------
* 2011-10-28    Cloud         创建
******************************************************************************
*/

BOOL CFFScale::Init()
ExpandedBlockStart.gif{
    //必须预先设置过输入输出格式
    if (SWS_PF_NONE == m_srcFormat || SWS_PF_NONE == m_dstFormat)
ExpandedSubBlockStart.gif    {
        return FALSE;
    }


    //反初始化
    DeInit();

    //创建sws对象
    m_pSwsContext = sws_getContext(
        m_nSrcW,
        m_nSrcH,
        (PixelFormat)m_srcFormat,
        m_nDstW,
        m_nDstH,
        (PixelFormat)m_dstFormat,
        (int)m_enAlogrithm,
        NULL, 
        NULL, 
        NULL);
    if (NULL == m_pSwsContext)
ExpandedSubBlockStart.gif    {
        return FALSE;
    }


    //初始化源Slice和Stride
    if (m_srcFormat == SWS_PF_YUV420P)
ExpandedSubBlockStart.gif    {
        m_nSrcSlice[0] = 0;
        m_nSrcSlice[1] = m_nSrcW * m_nSrcH;
        m_nSrcSlice[2] = m_nSrcW * m_nSrcH * 5 / 4;
        m_nSrcSlice[3] = -1;

        m_nSrcStride[0] = m_nSrcW;
        m_nSrcStride[1] = m_nSrcW / 2;
        m_nSrcStride[2] = m_nSrcW / 2;
        m_nSrcStride[3] = 0;

    }

    else
ExpandedSubBlockStart.gif    {
        m_nSrcSlice[0] = 0;
        m_nSrcSlice[1] = -1;
        m_nSrcSlice[2] = -1;
        m_nSrcSlice[3] = -1;

        m_nSrcStride[0] = m_nSrcPicth;
        m_nSrcStride[1] = 0;
        m_nSrcStride[2] = 0;
        m_nSrcStride[3] = 0;
    }


    //初始化目标Slice和Stride
    if (m_dstFormat == SWS_PF_YUV420P)
ExpandedSubBlockStart.gif    {
        m_nDstSlice[0] = 0;
        m_nDstSlice[1] = m_nDstW * m_nDstH;
        m_nDstSlice[2] = m_nDstW * m_nDstH * 5 / 4;
        m_nDstSlice[3] = -1;

        m_nDstStride[0] = m_nDstW;
        m_nDstStride[1] = m_nDstW / 2;
        m_nDstStride[2] = m_nDstW / 2;
        m_nDstStride[3] = 0;

    }

    else
ExpandedSubBlockStart.gif    {
        m_nDstSlice[0] = 0;
        m_nDstSlice[1] = -1;
        m_nDstSlice[2] = -1;
        m_nDstSlice[3] = -1;

        m_nDstStride[0] = m_nDstPicth;
        m_nDstStride[1] = 0;
        m_nDstStride[2] = 0;
        m_nDstStride[3] = 0;
    }

    return TRUE;
}


ExpandedBlockStart.gif/***************************************************************************//**
* 函数名称:    DeInit
* 功能描述:    反初始化。
* 返回值:    
* 其它说明:    
* 修改日期        修改人            修改内容
* ------------------------------------------------------------------------------
* 2011-10-28    Cloud         创建
******************************************************************************
*/

void CFFScale::DeInit()
ExpandedBlockStart.gif{
    if (NULL != m_pSwsContext)
ExpandedSubBlockStart.gif    {
        sws_freeContext(m_pSwsContext);
    }

    m_pSwsContext = NULL;
}


ExpandedBlockStart.gif/***************************************************************************//**
* 函数名称:    Scale
* 功能描述:    Scale
* 参 数:    pSrc            >> 源图像内存起始地址;
* 参 数:    nSrcW            >> 源图像宽度;
* 参 数:    nSrcH            >> 源图像高度;
* 参 数:    nSrcPicth        >> 源图像每行数据的长度(YUV格式的该值不被采纳);
* 参 数:    pDst            << 目标图像内存起始地址;
* 参 数:    nDstW            >> 目标图像宽度;
* 参 数:    nDstH            >> 目标图像高度;
* 参 数:    nDstPicth        >> 目标图像每行数据的长度(YUV格式的该值不被采纳);
* 返回值:    执行成功返回TRUE,否则返回FALSE。
* 其它说明:    
* 修改日期        修改人            修改内容
* ------------------------------------------------------------------------------
* 2011-10-28    Cloud         创建
******************************************************************************
*/

BOOL CFFScale::Scale(byte *pSrc, int nSrcW, int nSrcH, int nSrcPicth, byte *pDst, int nDstW, int nDstH, int nDstPicth)
ExpandedBlockStart.gif{
    //如果任何参数发生变化,则需要重新初始化
    if (nSrcW != m_nSrcW || nSrcH != m_nSrcH || m_nSrcPicth != m_nSrcPicth
        || nDstW != m_nDstW || nDstH != m_nDstH || m_nDstPicth != m_nDstPicth)
ExpandedSubBlockStart.gif    {
        m_nSrcW = nSrcW;
        m_nSrcH = nSrcH;
        m_nSrcPicth = nSrcPicth;
        m_nDstW = nDstW;
        m_nDstH = nDstH;
        m_nDstPicth = nDstPicth;
        DeInit();
    }


    //如果未能成功初始化,返回失败
    if (NULL == m_pSwsContext && !Init())
ExpandedSubBlockStart.gif    {
        return FALSE;
    }


    //真正的Scale操作
    byte *srcSlice[4], *dstSlice[4];
    for (int i=0; i<4; i++)
ExpandedSubBlockStart.gif    {
        srcSlice[i] = m_nSrcSlice[i] < 0 ? NULL : (pSrc + m_nSrcSlice[i]);
        dstSlice[i] = m_nDstSlice[i] < 0 ? NULL : (pDst + m_nDstSlice[i]);
    }

    return sws_scale
        (
        m_pSwsContext,
        srcSlice,
        m_nSrcStride,
        0,
        m_nSrcH,
        dstSlice,
        m_nDstStride
        ) == m_nSrcH;
}

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
人工智能
使用钉钉扫一扫加入圈子
+ 订阅

了解行业+人工智能最先进的技术和实践,参与行业+人工智能实践项目

其他文章