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编解码的更多相关文章

  1. 转载:AAC编解码概述

    转自:http://www.cnblogs.com/gaozehua/archive/2012/05/03/2479960.html 编码概述 其整体AAC 编解码系统,如图所示,其编码流程概述如下: ...

  2. 各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放 license收费等 ...

  3. 视音频编解码学习工程:AAC格式分析器

    =====================================================视音频编解码学习工程系列文章列表: 视音频编解码学习工程:H.264分析器 视音频编解码学习工 ...

  4. 【FFMPEG】各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式

    目录(?)[-] 编解码学习笔记二codec类型 编解码学习笔记三Mpeg系列Mpeg 1和Mpeg 2 编解码学习笔记四Mpeg系列Mpeg 4 编解码学习笔记五Mpeg系列AAC音频 编解码学习笔 ...

  5. ffmpeg编解码音频AAC

    本次项目的需求:手机端和PC端共享同一个音视频网络源. 所以编解码需要满足手机上编码和解码原来PC端的音视频流. 这里先封装安卓手机端音频的编解码. 编译工作依然是在linux下 ubuntu 12. ...

  6. [总结]FFMPEG视音频编解码零基础学习方法--转

    ffmpeg编解码学习   目录(?)[-] ffmpeg程序的使用ffmpegexeffplayexeffprobeexe 1 ffmpegexe 2 ffplayexe 3 ffprobeexe ...

  7. FFMPEG视音频编解码零基础学习方法

    在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...

  8. FFMPEG视音频编解码零基础学习方法-b

    感谢大神分享,虽然现在还看不懂,留着大家一起看啦 PS:有不少人不清楚“FFmpeg”应该怎么读.它读作“ef ef em peg” 0. 背景知识 本章主要介绍一下FFMPEG都用在了哪里(在这里仅 ...

  9. android MediaCodec 音频编解码的实现——转码

    原文地址:http://blog.csdn.net/tinsanmr/article/details/51049179 从今天开始 每周不定期更新博客,把这一周在工作与学习中遇到的问题做个总结.俗话说 ...

随机推荐

  1. How Blink works

    How Blink works Author: haraken@ Last update: 2018 Aug 14 Status: PUBLIC Working on Blink is not eas ...

  2. MHP 宿舍摄像头在门卫显示方案

    通过VPN拨入公司内网,实现访问外网摄像头. 1.  宿舍和MHP公司各增加一条上网线路(可用移动) 2.宿舍处理:  2台带TF卡 摄像头,加入到萤石云端   130万摄像头+64G TF卡 3.宿 ...

  3. 学习《SQL必知必会(第4版)》中文PDF+英文PDF+代码++福达BenForta(作者)

    不管是数据分析还是Web程序开发,都会接触到数据库,SQL语法简洁,使用方式灵活,功能强大,已经成为当今程序员不可或缺的技能. 推荐学习<SQL必知必会(第4版)>,内容丰富,文字简洁明快 ...

  4. webp学习http://isux.tencent.com/introduction-of-webp.html

    http://isux.tencent.com/introduction-of-webp.html http://jingyan.baidu.com/article/2d5afd699cd7de85a ...

  5. [Android实例] 高速静默更新,低流量耗费,让APP活跃起来!

    大家好.我是csdn的新人,给大家带来一个做了一个星期的SDK,能够实现将Android APP碎片化管理.自由更新,实时更新,低流量耗费的更新~~ Zag Whim Renewal A system ...

  6. [ Javascript ] JavaScript中的定时器(Timer) 是怎样工作的!

    作为入门者来说.了解JavaScript中timer的工作方式是非常重要的.通常它们的表现行为并非那么地直观,而这是由于它们都处在一个单一线程中.让我们先来看一看三个用来创建以及操作timer的函数. ...

  7. OJ刷题---猜算式

    题目要求: 输入代码: #include<iostream> using namespace std; void Calc(); int main() { Calc(); return 0 ...

  8. android framework 02

    Android底层开发1.安装Ubuntu系统2.Ubuntu配置开发环境: sudo apt-get install git-core gnupg flex bison gperf zip sudo ...

  9. 61.C++文件操作实现硬盘检索

    #include <iostream> #include <fstream> #include <memory> #include <cstdlib> ...

  10. OpenCV特征点检测——Surf(特征点篇)&flann

    学习OpenCV--Surf(特征点篇)&flann 分类: OpenCV特征篇计算机视觉 2012-04-20 21:55 19887人阅读评论(20)收藏举报 检测特征 Surf(Spee ...