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

FFmpeg4.0笔记:封装ffmpeg的视频帧转换功能类CSws的更多相关文章

  1. FFmpeg4.0笔记:本地媒体文件解码、帧格式转换、重采样、编码、封装、转封装、avio、硬解码等例子

    Github https://github.com/gongluck/FFmpeg4.0-study/blob/master/official%20example/my_example.cpp #in ...

  2. FFmpeg解码视频帧为jpg图片保存到本地

    FFmpeg解码视频帧为jpg图片保存到本地 - CSDN博客 https://blog.csdn.net/qq_28284547/article/details/78151635

  3. C#使用FFmpeg 将视频格式转换成Gif图片示例

    根据EFmpeg封装的视频转换gif工具:https://my.oschina.net/tianma3798/blog/825317 一.本次使用参数说明 /* * 参数说明: * -i 源文件位置 ...

  4. NET 2.0(C#)调用ffmpeg处理视频的方法

    另外:ffmpeg的net封装库 http://www.intuitive.sk/fflib/ NET 2.0 调用FFMPEG,并异步读取输出信息的代码...public void ConvertV ...

  5. 基于C#利用ffmpeg提取视频帧

    利用ffmepg提取视频帧实际上是利用C#调用ffmepg命令行进行处理对应的视频,然后输出出视频帧 GetPicFromVideo("); static public string Get ...

  6. FFmpeg进行视频帧提取&音频重采样-Process.waitFor()引发的阻塞超时

    由于产品需要对视频做一系列的解析操作,利用FFmpeg命令来完成视频的音频提取.第一帧提取作为封面图片.音频重采样.字幕压缩等功能: 前一篇文章已经记录了FFmpeg在JAVA中的使用-音频提取&am ...

  7. 利用ffmpeg获取视频帧

    如果要对视频帧进行处理,可以先把视频帧读取出来. sh文件代码如下: #!/usr/bin/env sh VIDEO=/home/xxx/video/ FRAMES=/home/xxx/frame/ ...

  8. C#使用FFmpeg 将视频格式转换成MP4示例

    一.常用视频格式分辨率 640x480p 720p格式,分辨率为1280×720p / 60Hz,行频为45kHz 1080p格式,分辨率为1920×1080逐行扫描,专业格式 二.FFmpeg部分参 ...

  9. FFmpeg4.0笔记:封装ffmpeg的解封装功能类CDemux

    Github https://github.com/gongluck/FFmpeg4.0-study/tree/master/Cff CDemux.h /*********************** ...

随机推荐

  1. 技巧:在 C/C++中如何构造通用的对象链表[转]

    原文:技巧:在 C/C++中如何构造通用的对象链表 虚拟链表和类链表可以很好地实现这一点 您是否做过这样一个项目,它要求您在内存中保存数目不定的若干不同对象?对于某些情况,二叉树是最佳选择,但在通常情 ...

  2. js输入密文弹出数字键盘

    我们经常被产品要求,在移动端的web页面上的输入框输入密码时要弹出数字键盘,而不是全键盘,这个该怎么实现呢? 1.首先要弹出数字键盘,我们只能把input框的type从password改为tel 2. ...

  3. [CSP-S模拟测试]:C(三分+贪心)

    题目传送门(内部题46) 输入格式 第一行$3$个整数$n,m,t$.第二行$n$个整数,表示$P_i$.接下来$m$行每行两个整数,表示$L_i,R_i$. 输出格式 一行一个整数表示答案. 样例 ...

  4. iPhone/iPad调整事件递交

    UIKit 为应用程序提供了编程手段来简化事件处理或者完全关闭事件流.下面的列表总结了这些方法: 关闭触摸事件的递交. 缺省情况下,视图接收触摸事件,但是你可以设置它的userInteractionE ...

  5. 3 Java 冒泡排序法

    冒泡排序( Bubble Sort)是一种简单的排序算法.它重复访问要数列, 一次比较两个元素,如果他们的顺序错误就把交换过来.访问数列工作是 一次比较两个元素,如果他们的顺序错误就把交换过来.访问数 ...

  6. Ubuntu下qt5使用vlc

      一:Ubuntu下在线安装qt5,同时安装了qt creator 二:打开终端执行sudo apt-get install libvlc5 libvlc-dev libvlccore-dev 安装 ...

  7. airflow当触发具有多层subDAG的任务的时候,出现[Duplicate entry ‘xxxx’ for key dag_id]的错误的问题处理

    当触发一个具有多层subDAG的任务时,会发现执行触发的task任务运行失败,但是需要触发的目标DAG已经在运行了,dag log 错误内容: [2019-11-21 17:47:56,825] {b ...

  8. Example Bookstore schema showing how data is sharded DATABASE SHARDING

    w公共查询表复制至每一个碎片 http://www.agildata.com/database-sharding/ In the Bookstore example, the Primary Shar ...

  9. 设计模式--观察者模式--python

    观察者模式: 对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新. 主要解决: 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面.将这二者封装在 ...

  10. JavaScript日常学习2

    JavaScript 数据类型    字符串(String).数字(Number).布尔(Boolean).数组(Array).对象(Object).空(Null).未定义(Undefined). e ...