Github

https://github.com/gongluck/FFmpeg4.0-study/tree/master/Cff

CSws.h

/*******************************************************************
* Copyright(c) 2019
* All rights reserved.
*
* 文件名称: CSws.h
* 简要描述: 帧转换
*
* 作者: gongluck
* 说明:
*
*******************************************************************/ #ifndef __CSWS_H__
#define __CSWS_H__ #ifdef __cplusplus
extern "C"
{
#endif #include <libswscale/swscale.h>
#include <libavutil/imgutils.h> // av_image_alloc #ifdef __cplusplus
}
#endif #include <string>
#include <mutex> class CSws
{
public:
virtual ~CSws(); // 状态
enum STATUS { STOP, LOCKED };
// 设置源参数
bool set_src_opt(AVPixelFormat pixfmt, int w, int h, std::string& err);
// 设置目标参数
bool set_dst_opt(AVPixelFormat pixfmt, int w, int h, std::string& err);
// 锁定设置
bool lock_opt(std::string& err);
// 解除锁定
bool unlock_opt(std::string& err);
// 转换
int scale(const uint8_t* const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t* const dst[], const int dstStride[], std::string& err); private:
STATUS status_ = STOP;
std::recursive_mutex mutex_; SwsContext* swsctx_ = nullptr; AVPixelFormat src_pix_fmt_ = AV_PIX_FMT_NONE;
AVPixelFormat dst_pix_fmt_ = AV_PIX_FMT_NONE;
int src_w_ = 0;
int src_h_ = 0;
int dst_w_ = 0;
int dst_h_ = 0;
}; #endif//__CSWS_H__

CSws.cpp

/*******************************************************************
* Copyright(c) 2019
* All rights reserved.
*
* 文件名称: CSws.cpp
* 简要描述: 帧转换
*
* 作者: gongluck
* 说明:
*
*******************************************************************/ #include "common.h"
#include "CSws.h" CSws::~CSws()
{
std::string err;
unlock_opt(err);
} bool CSws::set_src_opt(AVPixelFormat pixfmt, int w, int h, std::string& err)
{
LOCK();
CHECKSTOP(err);
err = "opt succeed."; src_pix_fmt_ = pixfmt;
src_w_ = w;
src_h_ = h; return true;
} bool CSws::set_dst_opt(AVPixelFormat pixfmt, int w, int h, std::string& err)
{
LOCK();
CHECKSTOP(err);
err = "opt succeed."; dst_pix_fmt_ = pixfmt;
dst_w_ = w;
dst_h_ = h; return true;
} bool CSws::lock_opt(std::string& err)
{
LOCK();
CHECKSTOP(err);
err = "opt succeed."; swsctx_ = sws_getContext(src_w_, src_h_, src_pix_fmt_, dst_w_, dst_h_, dst_pix_fmt_, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr);
if (swsctx_ == nullptr)
{
err = "sws_getContext return nullptr.";
return false;
}
status_ = LOCKED; return true;
} bool CSws::unlock_opt(std::string& err)
{
LOCK();
err = "opt succeed."; sws_freeContext(swsctx_);
swsctx_ = nullptr;
status_ = STOP;
src_w_ = 0;
src_h_ = 0;
dst_w_ = 0;
dst_h_ = 0; return true;
} int CSws::scale(const uint8_t* const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t* const dst[], const int dstStride[], std::string& err)
{
LOCK();
CHECKNOTSTOP(err);
err = "opt succeed."; int ret = sws_scale(swsctx_, srcSlice, srcStride, srcSliceY, srcSliceH, dst, dstStride);
CHECKFFRET(ret); return ret;
}

测试

// 视频帧转换
void test_sws()
{
bool ret = false;
std::string err;
std::ifstream yuv("in.yuv", std::ios::binary);
CSws sws; // 分配图像数据内存
uint8_t* src[4] = { 0 };
int srclinesize[4] = { 0 };
uint8_t* dst[4] = { 0 };
int dstlinesize[4] = { 0 }; int srcsize = av_image_alloc(src, srclinesize, 640, 432, AV_PIX_FMT_YUV420P, 1);
int dstsize = av_image_alloc(dst, dstlinesize, 320, 240, AV_PIX_FMT_BGR24, 1);
yuv.read(reinterpret_cast<char*>(src[0]), 640 * 432);
yuv.read(reinterpret_cast<char*>(src[1]), 640 * 432 / 4);
yuv.read(reinterpret_cast<char*>(src[2]), 640 * 432 / 4); ret = sws.set_src_opt(AV_PIX_FMT_YUV420P, 640, 432, err);
TESTCHECKRET(ret);
ret = sws.set_dst_opt(AV_PIX_FMT_BGR24, 320, 240, err);
TESTCHECKRET(ret);
ret = sws.lock_opt(err);
TESTCHECKRET(ret);
int size = sws.scale(src, srclinesize, 0, 432, dst, dstlinesize, err);
std::cout << "sws " << size << " line" << std::endl;
std::ofstream bgr("out.bgr", std::ios::binary);
bgr.write(reinterpret_cast<char*>(dst[0]), dstsize);
ret = sws.unlock_opt(err);
TESTCHECKRET(ret); // 清理
if (src != nullptr)
{
av_freep(&src[0]);
}
av_freep(&src);
if (dst != nullptr)
{
av_freep(&dst[0]);
}
av_freep(&dst);
}

最新文章

  1. Oracle:一个用户操作多个表空间中表的问题(转)
  2. SQL Server2008清除数据库日志
  3. SQL入门语句之LIKE、GLOB和LIMIT
  4. SpringMVC学习系列(11) 之 表单标签
  5. Maven_非法字符: &#39;\ufeff&#39; 解决方案
  6. Thinkphp整合最新Ueditor编辑器
  7. TreeMap与TreeSet的实现
  8. 块对象block小结
  9. Linux下tomcat管理查看控制台|杀死tomcat进程
  10. Oracle instant client在windows下的安装和使用
  11. 关于Vuex的初步使用
  12. SpringMVC之处理流程
  13. U盘文件被隐藏
  14. Carbon - 在线生成精美的代码片段图片(含插件)
  15. python unittest setUp 和 setUpClass 区别
  16. stat,fstate,lstat函数
  17. 深入理解net core中的依赖注入、Singleton、Scoped、Transient(三)
  18. [ 转载 ] Java基础11--Java总结篇系列:Java泛型
  19. BZOJ2314 士兵的放置
  20. (转)LVS安装使用详解

热门文章

  1. rename、remove
  2. 四、SpringBoot整合mybatis——配置mybatis驼峰命名规则自动转换
  3. [c++] C++多态(虚函数和虚继承)
  4. 第一章 大体知道java语法1----------能写java小算法
  5. (转载)Nginx Windows详细安装部署教程
  6. python3笔记目录大纲汇总
  7. 黑马lavarel教程---11、响应处理
  8. Qt加载本地字体 .ttc或.ttf
  9. 【Spring】mvc:annotation-driven 使用
  10. Popover 弹出框