AAC编解码
AAC编码可以使用faac
/**
初始化 @param sampleRate 音频采样率
@param channels 通道数
@param bitSize 音频采样精度 16
*/
- (void)initWithSampleRate:(int)sampleRate channels:(int)channels bitSize:(int)bitSize
{
nSampleRate = sampleRate;
nChannels = channels;
nPCMBitSize = bitSize; hEncoder = faacEncOpen(nSampleRate,nChannels,&nInputSamples,&nMaxOutputBytes);
if(hEncoder == NULL)
{
error = -;
}
int pcmBufSize = (int)(nInputSamples*(nPCMBitSize/)); // 固定计算方式
pcmBuf = (unsigned char *)malloc(pcmBufSize * sizeof(unsigned char)); // pcmBufSize* 1个字节
memset(pcmBuf,,pcmBufSize);
aacBuf = (unsigned char *)malloc(nMaxOutputBytes * sizeof(unsigned char));
memset(aacBuf,,nMaxOutputBytes); faacEncConfigurationPtr config = faacEncGetCurrentConfiguration(hEncoder);
config->aacObjectType = LOW; //LC编码 编码类型
config->inputFormat = FAAC_INPUT_16BIT; //输入数据类型
config->outputFormat = ; //录制MP4文件时,0要用raw流; 1是ADTS
int ret = faacEncSetConfiguration(hEncoder, config);
if (ret < ) {
error = -;
}
}
/**
编码 @param data pcm
@param dataSize 长度
*/
-(void)encoderWithData:(unsigned char *)data dataSize:(int)dataSize
{
if (error<) {
return;
} // 2048 4096
int pcmBufSize = (int)(nInputSamples*(nPCMBitSize/)); // 固定计算方式 if(data == NULL||dataSize<=|| dataSize > pcmBufSize){
NSLog(@"error:dataSize大于填充大小");
return;
} int copyLength = ; if(remainBufSize > dataSize){
copyLength = dataSize;
}
else{
copyLength = remainBufSize;
}
memcpy((&pcmBuf[]) + remainWriteSize,data,copyLength); remainBufSize -= copyLength;
remainWriteSize += copyLength; if(remainBufSize > ){
return;
}
int ret = faacEncEncode(hEncoder,(int*)(pcmBuf),(unsigned int)nInputSamples,aacBuf,(unsigned int)nMaxOutputBytes);
if (ret<) {
return;
}
if ([self.delegate respondsToSelector:@selector(AACEncoderData:dataSize:)]) {
if (ret>) {
[self.delegate AACEncoderData:aacBuf dataSize:ret];
} } memset(pcmBuf, , pcmBufSize);
remainWriteSize = ;
remainBufSize = pcmBufSize;
if((dataSize - copyLength) > ){
memcpy((&pcmBuf[]), data+copyLength, dataSize - copyLength);
remainWriteSize = dataSize - copyLength; // 已经填了多少
remainBufSize = pcmBufSize - (dataSize - copyLength); // 还差多少填满 2048
}
}
AAC解码可以使用faad
@implementation AACDecoder
- (instancetype)init
{
self = [super init];
if (self) {
decoder = NeAACDecOpen();
samplerate = ;
channels = ;
pcmData = NULL;
size = ;
}
return self;
}
/**
解码 @param data aac
@param dataSize 长度
*/
-(void)decoderWithData:(unsigned char *)data dataSize:(int)dataSize
{
if (!loaded) { if(getOneADTSFrame(data, dataSize, frame, &size)== )
{
NeAACDecInit(decoder, frame, size, &samplerate, &channels);
printf("samplerate %lu, channels %d\n", samplerate, channels);
loaded = YES;
}
}
while(getOneADTSFrame(data,dataSize,frame,&size) == )
{
pcmData = (unsigned char*)NeAACDecDecode(decoder, &frameInfo,frame,size);
if(frameInfo.error > )
{
printf("%s\n",NeAACDecGetErrorMessage(frameInfo.error)); }
else if(pcmData && frameInfo.samples > )
{
printf("frame info: bytesconsumed %lu, channels %d, header_type %d\
object_type %d, samples %lu, samplerate %lu\n",
frameInfo.bytesconsumed,
frameInfo.channels, frameInfo.header_type,
frameInfo.object_type, frameInfo.samples,
frameInfo.samplerate); if ([self.delegate respondsToSelector:@selector(AACDcoderData:dataSize:)]) {
[self.delegate AACDcoderData:pcmData dataSize:(int)(frameInfo.samples * frameInfo.channels)];
}
}
dataSize -= size;
data += size;
}
if ([self.delegate respondsToSelector:@selector(AACDcoderEnd)]) {
[self.delegate AACDcoderEnd];
} } - (void)dealloc
{
NeAACDecClose(decoder);
}
/**
* fetch one ADTS frame 获取一个ADTS Frame
*/
int getOneADTSFrame(unsigned char* buffer, size_t buf_size, unsigned char* data ,size_t* data_size)
{
size_t size = ; if(!buffer || !data || !data_size )
{
return -;
} while()
{
if(buf_size < )
{
return -;
} if((buffer[] == 0xff) && ((buffer[] & 0xf0) == 0xf0) )
{
size |= ((buffer[] & 0x03) <<); //high 2 bit
size |= buffer[]<<; //middle 8 bit
size |= ((buffer[] & 0xe0)>>); //low 3bit
break;
}
--buf_size;
++buffer;
} if(buf_size < size)
{
return -;
} memcpy(data, buffer, size);
*data_size = size; return ;
}
AAC编解码的更多相关文章
- 转载:AAC编解码概述
转自:http://www.cnblogs.com/gaozehua/archive/2012/05/03/2479960.html 编码概述 其整体AAC 编解码系统,如图所示,其编码流程概述如下: ...
- 各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式
编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放 license收费等 ...
- 视音频编解码学习工程:AAC格式分析器
=====================================================视音频编解码学习工程系列文章列表: 视音频编解码学习工程:H.264分析器 视音频编解码学习工 ...
- 【FFMPEG】各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式
目录(?)[-] 编解码学习笔记二codec类型 编解码学习笔记三Mpeg系列Mpeg 1和Mpeg 2 编解码学习笔记四Mpeg系列Mpeg 4 编解码学习笔记五Mpeg系列AAC音频 编解码学习笔 ...
- ffmpeg编解码音频AAC
本次项目的需求:手机端和PC端共享同一个音视频网络源. 所以编解码需要满足手机上编码和解码原来PC端的音视频流. 这里先封装安卓手机端音频的编解码. 编译工作依然是在linux下 ubuntu 12. ...
- [总结]FFMPEG视音频编解码零基础学习方法--转
ffmpeg编解码学习 目录(?)[-] ffmpeg程序的使用ffmpegexeffplayexeffprobeexe 1 ffmpegexe 2 ffplayexe 3 ffprobeexe ...
- FFMPEG视音频编解码零基础学习方法
在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...
- FFMPEG视音频编解码零基础学习方法-b
感谢大神分享,虽然现在还看不懂,留着大家一起看啦 PS:有不少人不清楚“FFmpeg”应该怎么读.它读作“ef ef em peg” 0. 背景知识 本章主要介绍一下FFMPEG都用在了哪里(在这里仅 ...
- android MediaCodec 音频编解码的实现——转码
原文地址:http://blog.csdn.net/tinsanmr/article/details/51049179 从今天开始 每周不定期更新博客,把这一周在工作与学习中遇到的问题做个总结.俗话说 ...
随机推荐
- 记录一下sql两个表关联的查询使用方法
SELECT * FROM t_yymp_user_info where user_id = (select b.user_id from t_yymp_auth_role as a,t_yymp_a ...
- web.config添加identity impersonate="true"导致拒绝访问
例:<identity impersonate="tr" userName="AD\name" password="word"/> ...
- vue-cli · Failed to download repo vuejs-templates/webpack-simple: tunneling socket could not be established, cause=connect ECONNREFUSED 127.0.0.1:8086 && vue init webpack-simple xxx
vue init webpack-simple mywork报错如下: vue-cli · Failed to download repo vuejs-templates/webpack-simple ...
- Zabbix钉钉小机器人报警
1.下载钉钉所需要的脚本golang-zabbix-robot-64,浏览器访问https://www.appgao.com/files/192.html: 图一 脚本下载 2.将脚本路径添加到 ...
- CentOS7/RedHat7的Apache配置介绍
这里我们介绍yum安装httpd yum install -y httpd ************* [root@100 ~]# systemctl restart httpd [root@100 ...
- HBase概念学习(八)开发一个类twitter系统之表设计
这边文章先将可能的需求分析一下,设计出HBase表,下一步再開始编写client代码. TwiBase系统 1.背景 为了加深HBase基本概念的学习,參考HBase实战这本书实际动手做了这个样例. ...
- Unity3D:粒子系统Particle System
1. GameObject → Create Other → Particle System. 2. 选中 Particle System,可看到下列屬性: 3.Particle System: ...
- 深入浅出微服务框架dubbo(一):基础篇
一.基础篇 1.1 开篇说明 dubbo是一个分布式服务框架,致力于提供高性能透明化RPC远程调用方案,提供SOA服务治理解决方案.本文旨在将对dubbo的使用和学习总结起来,深入源码探究原理,以备今 ...
- js --- for in 和 for of
前言:for of是ES6新增的循环方法.前面已经说到了 [JavaScript]for.forEach .for in.each循环详解.那for of又是怎么使用的? 一.使用例子 使用例子(一) ...
- CSS3的属性选择器
CSS3中新增了许多选择器,今天零度给大家说说CSS3的属性选择器. 与CSS2相比,CSS3新增了3种属性选择器:[attr^=value].[attr$=value].[attr*=value]: ...