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 从今天开始 每周不定期更新博客,把这一周在工作与学习中遇到的问题做个总结.俗话说 ...
随机推荐
- 手动删除oracle数据库
--===================== -- 手动删除oracle数据库 --===================== 杀掉进程用此方法比较好,能保证杀得干净,而不是用sql 里面的语句ki ...
- 参考《机器学习实战》高清中文PDF+高清英文PDF+源代码
机器学习是人工智能研究领域中一个极其重要的研究方向,在现今的大数据时代背景下,捕获数据并从中萃取有价值的信息或模式,成为各行业求生存.谋发展的决定性手段,这使得这一过去为分析师和数学家所专属的研究领域 ...
- 【Django】安装及配置
目录 MVC框架与MTV框架 Django的MTV模式 Django框架图示 安装及配置 创建一个Django项目 目录介绍 运行Django项目 启动Django报错 模版文件配置 静态文件配置 A ...
- mysql中group by和order by混用 结果不是理想结果
在使用mysql排序的时候会想到按照降序分组来获得一组数据,而使用order by往往得到的不是理想中的结果,那么怎么才能使用group by 和order by得到理想中的数据结果呢? 例如 有一个 ...
- leetcode笔记:Sort Colors
一. 题目描写叙述 Given an array with n objects colored red, white or blue, sort them so that objects of the ...
- Java Swing设置主窗体位置居中方法
01.第一种方法 int windowWidth = frame.getWidth(); //获得窗体宽 int windowHeight = frame.getHeight(); //获得窗体高 ...
- pip的认识
一.pip与python的关系:pip并不是一种语言,而是一个Python包管理工具,主要是用于安装 PyPI 上的软件包.安装好pip之后,使用pip install 命令即可方便的安装python ...
- 4.cocos场景和层的调用
调用关系: AppDeligate.cpp bool AppDelegate::applicationDidFinishLaunching() { // initialize director aut ...
- 洛谷P3383 【模板】线性筛素数(Miller_Rabin)
题目描述 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) 输入输出格式 输入格式: 第一行包含两个正整数N.M,分别表示查询的范围和查询的个数. 接下来M行每行 ...
- SKU=Stock Keeping Unit(库存量单位)。即库存进出计量的单位,可以是以件,盒,托盘等为单位
SKU=Stock Keeping Unit(库存量单位).即库存进出计量的单位,可以是以件,盒,托盘等为单位.SKU这是对于大型连锁超市DC(配送中心)物流管理的一个必要的方法.现在已经被引申为产品 ...