FFmpeg(11)-基于FFmpeg进行音频重采样(swr_init(), swr_convert())
一.包含头文件和库文件
修改CMakeLists
# swresample
add_library(swresample SHARED IMPORTED)
set_target_properties(swresample PROPERTIES IMPORTED_LOCATION ${FF}/libswresample.so)
更新target_link_libraries
target_link_libraries( # Specifies the target library.
native-lib
avcodec
avformat
avutil
swscale
swresample # Links the target library to the log library
# included in the NDK.
${log-lib} )
在代码中包含头文件 #include <libswresample/swresample.h>
二.相关函数说明
a)
SwrContext *swr_alloc(void); // 分配重采样的上下文。
SwrContext *swr_alloc_set_opts(struct SwrContext *s, int64_t out_ch_layout, AVSampleFormat out_sample_fmt, int out_sample_rate
, int64_t in_ch_layout, AVSampleFormat in_sample_fmt, int in_sample_rate, int log_offset, void *log_ctx
);
参数1:重采样上下文
参数2:输出的layout, 如:5.1声道…
参数3:输出的样本格式。Float, S16, S24
参数4:输出的样本率。可以不变。
参数5:输入的layout。
参数6:输入的样本格式。
参数7:输入的样本率。
参数8,参数9,日志,不用管,可直接传0
针对音频的播放速度,可以通过样本率的改变而改变。
int swr_init(struct SwrContext *s); // 初始化上下文
void swr_free(struct SwrContext **s); // 释放上下文空间。
b)
swr_convert()
针对每一帧音频的处理。把一帧帧的音频作相应的重采样
int swr_convert(struct SwrContext *s, uint8_t **out, int out_count, const uint8_t **in, int in_count);
参数1:音频重采样的上下文
参数2:输出的指针。传递的输出的数组
参数3:输出的样本数量,不是字节数。单通道的样本数量。
参数4:输入的数组,AVFrame解码出来的DATA
参数5:输入的单通道的样本数量。
三.示例代码
// 初始化像素格式转换上下文
SwsContext *vctx = NULL;
int outWidth = ;
int outHeight = ;
char *rgb = new char[**];
char *pcm = new char[**]; // 初始化音频重采样上下文
SwrContext *actx = swr_alloc();
actx = swr_alloc_set_opts(
actx,
av_get_default_channel_layout(),
AV_SAMPLE_FMT_S16,
ac->sample_rate,
av_get_default_channel_layout(ac->channels),
ac->sample_fmt,
ac->sample_rate,
,
); ret = swr_init(actx);
if (ret != ) {
LOGE("swr_init failed");
} else {
LOGI("swr_init success");
} for (;;) { if (getNowMs() - start >= ) {
LOGI("now decoder fps is: %d", frameCount / );
start = getNowMs();
frameCount = ;
}
int ret = av_read_frame(ic, packet);
if (ret != ) {
LOGE("读取到结尾处");
int pos = * r2d(ic->streams[videoStream]->time_base);
// 改变播放进度
av_seek_frame(ic, videoStream, pos, AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_FRAME);
continue;
} // LOGI("Read a Packet. streamIndex=%d, size=%d, pts=%lld, flag=%d",
// packet->stream_index,
// packet->size,
// packet->pts,
// packet->flags
// ); AVCodecContext *cc = vc;
if (packet->stream_index == audioStream) cc = ac;
// 发送到线程中去解码(将packet写入到解码队列当中去)
ret = avcodec_send_packet(cc, packet);
// 清理
int p = packet->pts;
av_packet_unref(packet);
if (ret != ) {
// LOGE("avcodec_send_packet failed.");
continue;
} for(;;) {
// 从已解码成功的数据当中取出一个frame, 要注意send一次,receive不一定是一次
ret = avcodec_receive_frame(cc, frame);
if (ret != ) {
break;
}
if (cc == vc) {
frameCount++;
vctx = sws_getCachedContext(
vctx,
frame->width,
frame->height,
(AVPixelFormat)frame->format,
outWidth,
outHeight,
AV_PIX_FMT_RGBA,
SWS_FAST_BILINEAR,
, ,
);
if (!vctx) {
LOGE("sws_getCachedContext failed!");
} else {
// 开始像素格式转换
uint8_t *data[AV_NUM_DATA_POINTERS] = {};
data[] = (uint8_t *)rgb;
int lines[AV_NUM_DATA_POINTERS] = {};
lines[] = outWidth * ;
int h = sws_scale(
vctx,
(const uint8_t **)frame->data,
frame->linesize,
,
frame->height,
data, lines
);
LOGI("sws_scale = %d", h);
}
} else { // 音频部分
uint8_t *out[] = {};
out[] = (uint8_t *)pcm;
// 音频重采样
int len = swr_convert(
actx,
out,
frame->nb_samples,
(const uint8_t **)frame->data,
frame->nb_samples
);
LOGI("swr_convert = %d", len);
}
// LOGI("Receive a frame.........");
}
} delete rgb;
delete pcm;
FFmpeg(11)-基于FFmpeg进行音频重采样(swr_init(), swr_convert())的更多相关文章
- 基于傅里叶变换的音频重采样算法 (附完整c代码)
前面有提到音频采样算法: WebRTC 音频采样算法 附完整C++示例代码 简洁明了的插值音频重采样算法例子 (附完整C代码) 近段时间有不少朋友给我写过邮件,说了一些他们使用的情况和问题. 坦白讲, ...
- 基于sinc的音频重采样(二):实现
上篇(基于sinc的音频重采样(一):原理)讲了基于sinc方法的重采样原理,并给出了数学表达式,如下: (1) 本文讲如何基于这个数学表达式来做软件实现.软件实现的 ...
- FFmpeg进行视频帧提取&音频重采样-Process.waitFor()引发的阻塞超时
由于产品需要对视频做一系列的解析操作,利用FFmpeg命令来完成视频的音频提取.第一帧提取作为封面图片.音频重采样.字幕压缩等功能: 前一篇文章已经记录了FFmpeg在JAVA中的使用-音频提取&am ...
- 基于sinc的音频重采样(一):原理
我在前面的文章<音频开源代码中重采样算法的评估与选择>中说过sinc方法是较好的音频重采样方法,缺点是运算量大.https://ccrma.stanford.edu/~jos/resamp ...
- 最简单的基于FFMPEG+SDL的音频播放器 ver2 (采用SDL2.0)
===================================================== 最简单的基于FFmpeg的音频播放器系列文章列表: <最简单的基于FFMPEG+SDL ...
- FFMpeg笔记(三) 音频处理基本概念及音频重采样
Android放音的采样率固定为44.1KHz,录音的采样率固定为8KHz,因此底层的音频设备驱动需要设置好这两个固定的采样率.如果上层传过来的采样率不符的话,需要进行resample重采样处理. 几 ...
- 最简单的基于FFMPEG+SDL的音频播放器 ver2 (採用SDL2.0)
===================================================== 最简单的基于FFmpeg的音频播放器系列文章列表: <最简单的基于FFMPEG+SDL ...
- EasyDarwin开源音频解码项目EasyAudioDecoder:基于ffmpeg的安卓音频(AAC、G726)解码库(第一部分,ffmpeg-android的编译)
ffmpeg是一套开源的,完整的流媒体解决方案.基于它可以很轻松构建一些强大的应用程序.对于流媒体这个行业,ffmpeg就像圣经一样的存在.为了表达敬意,在这里把ffmpeg官网的一段简介搬过来,ff ...
- 最简单的基于FFMPEG的音频编码器(PCM编码为AAC)
http://blog.csdn.net/leixiaohua1020/article/details/25430449 本文介绍一个最简单的基于FFMPEG的音频编码器.该编码器实现了PCM音频采样 ...
随机推荐
- HttpServletRequest对象(一)
javaweb学习总结(十)——HttpServletRequest对象(一) 一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HT ...
- Easyui实用视频教程系列---Tree点击打开tab页面
Easyui实用视频教程系列---Tree点击打开tab页面 首先 我们 要搭建环境 easyui 环境 然后 把tree 给创建出来 在某个位置 粘贴 下面代码 <ul id="tt ...
- Swift 互斥锁写法
oc中的互斥锁@synchronized(self) { //需要执行的代码块} swift中的互斥锁objc_sync_enter(self)//需要执行的代码块objc_sync_exit(sel ...
- iOS UISlider滑动块触摸范围调整变大
正常情况下,我们自定义的滑动区域都不会太大,否则UI不美观,但是这样,又会手势不灵敏,用户体验变差. 如何解决? 这里有一种方案:封装一个继承UISlider的自定义类,重写thumbRectForB ...
- Solr Wiki文档
相比ElasticSearch,Solr的文档详尽丰富,同时也显得冗余啰嗦. Solr的官方文档有两个地方: Solr官方教程 Solr社区维基 本文主要列出一些Solr Wiki中的主要讨论主题,方 ...
- iOS与H5交互
H5与App原生交互,一般会是前端页面中的JavaScript与App使用的原生开发语言的交互.技术方案应能达到以下要求: 在js与原生进行交互的时候能保证正常的正向调用逻辑返回,反向可以处理异步回调 ...
- iOS 设备屏幕上实时打印 Log 的小工具
需求 写这个小工具的想法,主要来源于很多团队都会用友盟.TalkingData 等第三方框架做自定义事件统计:不过统计代码加好之后,没有很好的方法来让测试工程师验证一下事件加上了没有,调用次数有没有重 ...
- ROS学习(十二)—— 编写简单的消息发布器和订阅器(C++)
一.创建发布器节点 1 节点功能: 不断的在ROS网络中广播消息 2 创建节点 (1)打开工作空间目录 cd ~/catkin_ws/src/beginner_tutorials 创建一个发布器节点( ...
- php自动获取字符串编码函数mb_detect_encoding(转)
使用 mb_detect_encoding() 函数来判断字符串是什么编码的. 当在php中使用mb_detect_encoding函数进行编码识别时,很多人都碰到过识别编码有误的问题,例如对与GB2 ...
- 【Oracle】Oracle的内外连接
目录结构: contents structure [+] Oracle的内外连接 内连接 等值连接 非等值连接 自连接 外连接 外连接的特点 如何实现外连接 SQL99的内外连接 SQL99的内连接 ...