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 with(unlock)与with(readpast)
所有Select加 With (NoLock)解决阻塞死锁,在查询语句中使用 NOLOCK 和 READPAST 处理一个数据库死锁的异常时候,其中一个建议就是使用 NOLOCK 或者 READPAS ...
- Python正则表达式初识(十)附正则表达式总结
今天分享正则表达式最后一个特殊字符“\d”,具体的教程如下. 1.特殊字符“\d”十分常用,其代表的意思是数字.代码演示如下图所示. 其中“+”的意思是表示连续,在这里代表的意思是连续的数字.但是输出 ...
- 手把手教你在VMware虚拟机中安装Ubuntu14.04系统
在VMware中创建完虚拟机之后,一般需要给虚拟机安装系统,比较受青睐的系统有Ubuntu和Centos,关于Centos系统的安装之前已经写过了,感兴趣的小伙伴可以戳这篇文章:靠谱的centos7. ...
- 关于props default 数组/对象的默认值应当由一个工厂函数返回
export default {props: { xAxisData: { type: Array, default: [] }, },这是我的代码 报错是Invalid default va ...
- Svn备份与Bandizip压缩批处理程序
目的:为了定时备份多个svn仓库数据,使用批处理程序进行备份并Bandizip进行压缩保存到指定位置,操作完成后弹出成功提示. 为了完成以上目标,需要了解以下几个方面: 批处理命令 Svn命令 Ban ...
- 【Nginx从入门到实战】
目录 1. 网站服务 2. 所谓Nginx 3. 安装Nginx 4. Nginx配置文件详述 5. 开始玩转Nginx Nginx虚拟主机 Nginx状态信息(status)配置 Nginx错误页面 ...
- Android的SQLite的增删查改
原创作品,允许转载,转载时请务必声明作者信息和本声明.http://www.cnblogs.com/zhu520/p/8343675.html 本人小白,那个大神看到有问题可指出,谢谢.... 一:s ...
- IOS的四种数据存储方式及优劣
IOS有四种经常使用数据存储方式: 第一种方法:用NSUserDefaults存储配置信息 NSUserDefaults被设计用来存储设备和应用的配置信息.它通过一个工厂方法返回默认的.也是最经常使用 ...
- 正确地在QML应用中使用fontsize
我们知道我们有时须要显示text文本.可是,在QML应用中.我们应该怎样选择font的大小呢?在今天的这篇文章中,我们将展示在Ubuntu平台中的不同文字的大小.我们能够通过FontUtils来帮我们 ...
- Android中关于Volley的使用(十)对Request和Reponse的认识
我们知道,在网络Http通信中.一定会有一个Request.相同的,也一定会有一个Response.而我们在Volley中利用RequestQueue来加入请求之前,一定会先创建一个Request对象 ...