FFmpeg4.0笔记:封装ffmpeg的视频帧转换功能类CSws
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的更多相关文章
- FFmpeg4.0笔记:本地媒体文件解码、帧格式转换、重采样、编码、封装、转封装、avio、硬解码等例子
Github https://github.com/gongluck/FFmpeg4.0-study/blob/master/official%20example/my_example.cpp #in ...
- FFmpeg解码视频帧为jpg图片保存到本地
FFmpeg解码视频帧为jpg图片保存到本地 - CSDN博客 https://blog.csdn.net/qq_28284547/article/details/78151635
- C#使用FFmpeg 将视频格式转换成Gif图片示例
根据EFmpeg封装的视频转换gif工具:https://my.oschina.net/tianma3798/blog/825317 一.本次使用参数说明 /* * 参数说明: * -i 源文件位置 ...
- NET 2.0(C#)调用ffmpeg处理视频的方法
另外:ffmpeg的net封装库 http://www.intuitive.sk/fflib/ NET 2.0 调用FFMPEG,并异步读取输出信息的代码...public void ConvertV ...
- 基于C#利用ffmpeg提取视频帧
利用ffmepg提取视频帧实际上是利用C#调用ffmepg命令行进行处理对应的视频,然后输出出视频帧 GetPicFromVideo("); static public string Get ...
- FFmpeg进行视频帧提取&音频重采样-Process.waitFor()引发的阻塞超时
由于产品需要对视频做一系列的解析操作,利用FFmpeg命令来完成视频的音频提取.第一帧提取作为封面图片.音频重采样.字幕压缩等功能: 前一篇文章已经记录了FFmpeg在JAVA中的使用-音频提取&am ...
- 利用ffmpeg获取视频帧
如果要对视频帧进行处理,可以先把视频帧读取出来. sh文件代码如下: #!/usr/bin/env sh VIDEO=/home/xxx/video/ FRAMES=/home/xxx/frame/ ...
- C#使用FFmpeg 将视频格式转换成MP4示例
一.常用视频格式分辨率 640x480p 720p格式,分辨率为1280×720p / 60Hz,行频为45kHz 1080p格式,分辨率为1920×1080逐行扫描,专业格式 二.FFmpeg部分参 ...
- FFmpeg4.0笔记:封装ffmpeg的解封装功能类CDemux
Github https://github.com/gongluck/FFmpeg4.0-study/tree/master/Cff CDemux.h /*********************** ...
随机推荐
- typedef void(*Fun) (void)是什么意思 函数指针(回调函数) 和函数对象总结
https://blog.csdn.net/FreeApe/article/details/49124043 bool (*pf)(const string &,const string &a ...
- 关于SpringBoot跨域的问题
直接在启动类里面加这一段代码就行: @Bean public CorsFilter corsFilter() { final UrlBasedCorsConfigurationSource sourc ...
- webpack搭建多页面系统(一):对webpack 构建工具的理解
为什么使用webpack构建工具? 1.开发效率方面: 在一般的开发过程中,分发好任务后,每个人完成自己单独的页面,如果有的人开发完成之后,接手别人的任务,就有可能造成开发时候的冲突. 如果利用模块化 ...
- vue绑定样式
使用三目运算符绑定样式 本来以为使用vue模版写法,在绑定单个样式,也就是一个class类名的时候可以直接书写,就像这样 <div id="app"> <div ...
- Nginx 配置443 HTTPS
server { listen 443 ssl; server_name localhost; ssl on; ssl_certificate D://newlingshou//nginx-1.12. ...
- 一、基础篇--1.2Java集合-HashMap源码解析
https://www.cnblogs.com/chengxiao/p/6059914.html 散列表 哈希表是根据关键码值而直接进行访问的数据结构.也就是说,它能通过把关键码值映射到表中的一个位 ...
- H264编码原理以及I帧、B和P帧详解, H264码流结构分析
H264码流结构分析 http://blog.csdn.net/chenchong_219/article/details/37990541 1.码流总体结构: h264的功能分为两层,视频编码层(V ...
- k8s部署01-----what is k8s?
简介 1.Kubernetes代码托管在GitHub上:https://github.com/kubernetes/kubernetes/. 2.Kubernetes是一个开源的,容器集群管理系统,K ...
- tensorflow二进制文件读取与tfrecords文件读取
1.知识点 """ TFRecords介绍: TFRecords是Tensorflow设计的一种内置文件格式,是一种二进制文件,它能更好的利用内存, 更方便复制和移动,为 ...
- LoadRunner脚本编写之一
LoadRunner脚本编写之一 性能测试工程师要懂代码么?答案是必须的.好多测试员认为在loadrunner中编写脚本很难很牛X ,主要是大多测试人员并未做过开发工作,大学的那点程序基础也忘记的差不 ...