Github

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

CSwr.h

/*******************************************************************
* Copyright(c) 2019
* All rights reserved.
*
* 文件名称: CSwr.h
* 简要描述: 重采样
*
* 作者: gongluck
* 说明:
*
*******************************************************************/ #ifndef __CSWR_H__
#define __CSWR_H__ #ifdef __cplusplus
extern "C"
{
#endif #include <libswresample/swresample.h> #ifdef __cplusplus
}
#endif #include <string>
#include <mutex> class CSwr
{
public:
virtual ~CSwr(); // 状态
enum STATUS { STOP, LOCKED };
// 设置源参数
bool set_src_opt(int64_t layout, int rate, enum AVSampleFormat fmt, std::string& err);
// 设置目标参数
bool set_dst_opt(int64_t layout, int rate, enum AVSampleFormat fmt, std::string& err);
// 锁定设置
bool lock_opt(std::string& err);
// 解除锁定
bool unlock_opt(std::string& err);
// 转换(out_count,in_count is per channel's samples)
int convert(uint8_t** out, int out_count, const uint8_t** in, int in_count, std::string& err); private:
STATUS status_ = STOP;
std::recursive_mutex mutex_; SwrContext* swrctx_ = nullptr; AVSampleFormat src_sam_fmt_ = AV_SAMPLE_FMT_NONE;
AVSampleFormat dst_sam_fmt_ = AV_SAMPLE_FMT_NONE;
int64_t src_layout_ = AV_CH_LAYOUT_MONO;
int64_t dst_layout_ = AV_CH_LAYOUT_MONO;
int src_rate_ = 0;
int dst_rate_ = 0;
}; #endif//__CSWR_H__

CSwr.cpp

/*******************************************************************
* Copyright(c) 2019
* All rights reserved.
*
* 文件名称: CSwr.cpp
* 简要描述: 重采样
*
* 作者: gongluck
* 说明:
*
*******************************************************************/ #include "common.h"
#include "CSwr.h" CSwr::~CSwr()
{
std::string err;
unlock_opt(err);
} bool CSwr::set_src_opt(int64_t layout, int rate, enum AVSampleFormat fmt, std::string& err)
{
LOCK();
CHECKSTOP(err);
err = "opt succeed."; src_layout_ = layout;
src_rate_ = rate;
src_sam_fmt_ = fmt; return true;
} bool CSwr::set_dst_opt(int64_t layout, int rate, enum AVSampleFormat fmt, std::string& err)
{
LOCK();
CHECKSTOP(err);
err = "opt succeed."; dst_layout_ = layout;
dst_rate_ = rate;
dst_sam_fmt_ = fmt; return true;
} bool CSwr::lock_opt(std::string& err)
{
LOCK();
CHECKSTOP(err);
err = "opt succeed."; swrctx_ = swr_alloc_set_opts(swrctx_, dst_layout_, dst_sam_fmt_, dst_rate_, src_layout_, src_sam_fmt_, src_rate_, 0, nullptr);
if (swrctx_ == nullptr)
{
err = "swr_alloc_set_opts return nullptr.";
return false;
} int ret = swr_init(swrctx_);
CHECKFFRET(ret);
status_ = LOCKED; return true;
} bool CSwr::unlock_opt(std::string& err)
{
LOCK();
err = "opt succeed."; swr_free(&swrctx_);
status_ = STOP;
src_sam_fmt_ = AV_SAMPLE_FMT_NONE;
dst_sam_fmt_ = AV_SAMPLE_FMT_NONE;
src_layout_ = AV_CH_LAYOUT_MONO;
dst_layout_ = AV_CH_LAYOUT_MONO;
src_rate_ = 0;
dst_rate_ = 0; return true;
} int CSwr::convert(uint8_t** out, int out_count, const uint8_t** in, int in_count, std::string& err)
{
LOCK();
CHECKNOTSTOP(err);
err = "opt succeed."; int ret = swr_convert(swrctx_, out, out_count, in, in_count);
CHECKFFRET(ret); return ret;
}

测试

// 音频重采样
void test_swr()
{
bool ret = false;
std::string err;
std::ifstream pcm("in.pcm", std::ios::binary);
CSwr swr; // 分配音频数据内存
uint8_t** src = nullptr;
int srclinesize = 0;
uint8_t** dst = nullptr;
int dstlinesize = 0; // 分配音频数据内存
int srcsize = av_samples_alloc_array_and_samples(&src, &srclinesize, 2, 44100, AV_SAMPLE_FMT_S16, 1);
int dstsize = av_samples_alloc_array_and_samples(&dst, &dstlinesize, 2, 48000, AV_SAMPLE_FMT_S16P, 1);
// 获取样本格式对应的每个样本大小(Byte)
int persize = av_get_bytes_per_sample(AV_SAMPLE_FMT_S16P);
// 获取布局对应的通道数
int channel = av_get_channel_layout_nb_channels(AV_CH_LAYOUT_STEREO); ret = swr.set_src_opt(AV_CH_LAYOUT_STEREO, 44100, AV_SAMPLE_FMT_S16, err);
TESTCHECKRET(ret);
ret = swr.set_dst_opt(AV_CH_LAYOUT_STEREO, 48000, AV_SAMPLE_FMT_S16P, err);
TESTCHECKRET(ret);
ret = swr.lock_opt(err);
TESTCHECKRET(ret); std::ofstream outpcm("out.pcm", std::ios::binary);
while (!pcm.eof())
{
pcm.read(reinterpret_cast<char*>(src[0]), srcsize);
int size = swr.convert(dst, dstlinesize, (const uint8_t**)(src), 44100, err);
// 拷贝音频数据
for (int i = 0; i < size; ++i) // 每个样本
{
for (int j = 0; j < channel; ++j) // 每个通道
{
outpcm.write(reinterpret_cast<const char*>(dst[j] + persize * i), persize);
}
}
} ret = swr.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的音频重采样功能类CSwr的更多相关文章

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

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

  2. FFmpeg(11)-基于FFmpeg进行音频重采样(swr_init(), swr_convert())

    一.包含头文件和库文件 修改CMakeLists # swresample add_library(swresample SHARED IMPORTED) set_target_properties( ...

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

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

  4. FFmpeg4.0笔记:封装ffmpeg的解码功能类CDecode

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

  5. FFmpeg4.0笔记:封装ffmpeg的视频帧转换功能类CSws

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

  6. FFmpeg4.0笔记:rtsp2rtmp

    Github https://github.com/gongluck/FFmpeg4.0-study.git #include <iostream> using namespace std ...

  7. FFmpeg4.0笔记:file2rtmp

    Github: https://github.com/gongluck/FFmpeg4.0-study.git #include <iostream> using namespace st ...

  8. FFmpeg4.0笔记:VS2019编译FFmpeg4.0源码

    0.下载TDM.msys和yasm 1.安装TDM-GCC-64 2.安装msys到TDM-GCC的安装目录中 3.将call "C:\Program Files (x86)\Microso ...

  9. FFmpeg4.0笔记:采集系统声音

    Github https://github.com/gongluck/FFmpeg4.0-study/tree/master/Cff // 采集系统声音 void test_systemsound() ...

随机推荐

  1. AcWing:165. 小猫爬山(dfs + 剪枝)

    翰翰和达达饲养了N只小猫,这天,小猫们要去爬山. 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_<). 翰翰和达达只好花钱让它们坐索道下山. 索道上的缆 ...

  2. $message的问题

    项目中出现$message的问题: 拉取数据成功后 this.$message.success("数据拉取成功")点击拉取第一次不出现,但是代码执行了,后来多次点击就出现了 原因: ...

  3. TypeScript----函数与类

    TypeScript中的类 传统的JavaScript程序使用函数和基于原型的继承来创建可重用的组件,但对于熟悉使用面向对象方式的程序员来讲就有些棘手,因为他们用的是基于类的继承并且对象是由类构建出来 ...

  4. [CSP-S模拟测试]:Drink(模拟)

    题目传送门(内部题10) 输入格式 输入第一行三个数$N,M,Q$分别表示棋盘的行数.列数和操作个数.接下来$N$行每行$M$个数表示一开始棋盘上宝物的价值.接下来$Q$行每行$3$个数$x,y,c$ ...

  5. python数据可视化示例柱状图

    from matplotlib import pyplot as plt import platform import pandas from pathlib import Path # 根据不同的平 ...

  6. Python 读文件:IOError: [Errno 0] Error

    Windows系统下,这种情况发生在读取文件,再写入过程中出现. 原因是读完文件后python不知道当前文件位置在哪里. 方法一是:在关闭文件前只做读或者写一种操作. 方法二是:在写入文件前使用fil ...

  7. 小程序web-view利用url给内嵌的网页传值

    这个方法跟网页上的一样,直接通过截取url中传过来的参数来取值 <web-view src="https://www.baidu.com/test.html?url=http://ww ...

  8. 前端单点登录(SSO)实现方法(二级域名与主域名)

    1.单点登录介绍 单点登录 SSO 全称 Singn Sign On .SSO 是指在多个应用系统中,用户只需要登录一次用户系统,就可以访问其他互相信任的应用系统.例如:在网易官网登录账户,那么再进入 ...

  9. k8s环境部署(一)

    环境介绍 1.单masrer节点 (安装下面图中介绍的四个组件) 2.俩个node节点(安装kubelet和docker) 3.为了支持master与node之前的通信,我们还需要在master上安装 ...

  10. SOA简介

    1.你可以把SOA理解为一种概念,总的来说就是面向服务的设计. 这个概念简单来理解就是把之前所谓的模块划分做成服务. 比如之前的日志模块,需要引用你的dll,调用你的写日志方法来写日志.这样当有多个系 ...