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. java jsp基础介绍

    1         Jsp基础 1.1           Jsp介绍 JSP(全称Java Server Pages)是一种web动态网页开发技术,通过标签和指令完成用户界面开发和交互操作.它使用J ...

  2. LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)

    题目描述 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4 输出:1->1-& ...

  3. SpringMVC——Servlet容器启动时初始化SpringMVC应用的原理

    在 Servlet 3.0标准中含有一个 ServletContainerInitializer接口,所有实现了这个接口的类会在容器启动的时候得到一个通知,并且会调用其 onStartup()方法,这 ...

  4. synchronized三种使用方式,及锁的类型验证

    Synchronized常用三种使用方式 1.修饰普通方法:锁对象即为当前对象 2.修饰静态方法:锁对象为当前Class对象 3.修饰代码块:锁对象为synchronized紧接着的小括号内的对象 一 ...

  5. android 实例-弱引用示例 Handler正确使用方法

    实际问题 android 习惯性问题:在使用handler的时候喜欢使用内部类形式. private final Handler handler = new Handler(){ @Override ...

  6. ThreadPoolExecutor 优雅关闭线程池的原理.md

    经典关闭线程池代码 ExecutorService executorService = Executors.newFixedThreadPool(10); executorService.shutdo ...

  7. javascript之Number对象

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. oracle 查看表空间使用比

    select b.file_name 物理文件名, b.tablespace_name 表空间, b.bytes / / 大小M, (b.bytes - sum(nvl(a.bytes, ))) / ...

  9. Selenium 2自动化测试实战30(unittest补充)

    unittest补充 1.用例执行的顺序 #test.py #coding:utf-8 from Demo1 import Count import unittest class TestBdd(un ...

  10. 阶段3 3.SpringMVC·_05.文件上传_6 文件上传之跨服务器上传代码

    参数HttpServletRequest也可以删掉  扩服务器的代码 注意选择jersey包下的 拿到文件资源.put过去. 最终代码 重新部署springMvc 图片服务器正常运行 客户端服务器 服 ...