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 从今天开始 每周不定期更新博客,把这一周在工作与学习中遇到的问题做个总结.俗话说 ...
随机推荐
- PowerDesigner删除外键关系,而不删除外键列[转] 及编码格式
PowerDesigner删除外键关系,而不删除外键列[转] 数据库 database -> generate database ->format 设置为utf-8 PowerDesi ...
- js预编译和函数执行
javascript 执行过程 1.语法检测(有没有基本的语法错误,例如中文,关键字错误...)2.词法分析(预编译) (1)创建全局GO(global object)对象 (2)对var声明的变量进 ...
- 【Linux下权限控制之chmod与chown命令】
chmod 用于配置文件/目录权限 命名格式:chmod [选项] 文件/目录名 . 权限类别: r 读取 可用数字4表示 w 写入 可用数字2表示 x 执行 可用数字1表示 . 归属类别: u 属主 ...
- Swift学习笔记(3)--基本运算符
基本运行符: +(加法.正数) - (减法.负数) * (乘法) / (除法) % (求余) : 在Swift中,求余可以是浮点数求余. &&(逻辑与) || (逻辑或) ^ (逻 ...
- flex RemoteObject 的两种使用方法
这里使用的是django1.6 和 postgreSQL9.0 FlashBuilder4.5 django方面就不说了,根据文档来做,建好模块,配置好数据库等等 创建 gateway 和 time ...
- 【Henu ACM Round#15 B】A and B and Compilation Errors
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 开3个map, 存在map里面: 然后迭代第一个和第二个map; 分别与第二个和第三个map比较就可以了 [代码] #include ...
- 小白学开发(iOS)OC_ SEL数据类型(2015-08-10)
// // main.m // SEL数据类型 // // Created by admin on 15/8/12. // Copyright (c) 2015年 admin. All rig ...
- Xposed框架之函数Hook学习
作者:Fly2015 Xposed是Android下Java层的开源Hook框架类似的有cydiasubstrate框架而且据说cydiasubstrate框架能实现Android的Java层和Nat ...
- Markdown---语法小记
在CSDN上的文章如今都习惯使用Markdown来编写比較方便美观.这里小结下常见的Markdown语法下: 1.标题: 方式1 # H1 ## H2 ### H3 #### H4 ##### H5 ...
- javafx drag
public class EffectTest extends Application { @Override public void start(Stage stage) { stage.setTi ...