扫盲

AAC实际上是高级音频编码的缩写,它是MPEG-2规范的一部分。但2000年,MPEG-4标准出台,AAC从新整合了其特性,故现又称 MPEG-4 AAC,即m4a。以上也就是说以.aac和.m4a结尾的都可以称为aac。

目前成熟的解码器

  • opencore的opencore-aacdec
  • ffmpeg 的aac解码器,当然还包括很多其他格式的音频视频解码器。
  • faad 解码器

目的:把faad的aac解码器移植到android平台上来。

方法:参考demo移植解码器。

实现方式:

附上部分代码

首先定义结构体:

#define MAX_BUFFER 20480 //20K

#define MIN_BUFFER 2048/* FAAD file buffering routines */
typedef struct {long bytes_into_buffer;long bytes_consumed;long file_offset;long size;unsigned char *buffer;int at_eof;FILE *infile;
} aac_buffer;struct AACFileHandle
{FILE* file;//文件int size;//文件长度int bitrate;//比特率int samplerate;//抽样率float duration;//播放时长int channelNum;//声道数int fileType;//文件类型(1:ADTS,2: ADIF)int mp4file;int track;long sampleId;mp4ff_t *infile;mp4AudioSpecificConfig *mp4ASC;mp4ff_callback_t *mp4cb;aac_buffer buffer;//aac缓存信息NeAACDecHandle hDecoder;
};

打开文件操作:

int mp4file = 0;

 int index = findFreeHandle( );if( index == -1 )return -1;//取得文件全路径const char* fileString = env->GetStringUTFChars(file, NULL);FILE* fileHandle = fopen( fileString, "rb" );//以只读的方式打开文件env->ReleaseStringUTFChars(file, fileString);//释放文件路径if( fileHandle == 0 )//如果打开文件失败返回-1return -1;//*********************以上打开文件完毕********************************AACFileHandle* aacHandle = new AACFileHandle();if(aacHandle == NULL){return -1;}memset(aacHandle, 0, sizeof(AACFileHandle));//读取文件头,判断是否是MP4unsigned char header[8];fread(header, 1, 8, fileHandle);rewind(fileHandle);if (header[4] == 'f' && header[5] == 't' && header[6] == 'y' && header[7] == 'p')mp4file = 1;aacHandle->mp4file = mp4file;if (!mp4file){if(open_aac_file(fileHandle, aacHandle) < 0){fclose(fileHandle);delete aacHandle;return -1;}}else{//mp4 aacif(open_mp4_file(fileHandle, aacHandle) < 0){fclose(fileHandle);delete aacHandle;return -1;}}handles[index] = aacHandle;
//  AACD_TRACE("index :" + index);return index;

解码操作:

AACD_TRACE("start");//加传入参数的判断if(aacHandle == NULL || size <=0){//这部分返回0是因为外部判断的是0return 0;}
//  size = size >>1;
//  if(fp == NULL)
//  {
//      fp = fopen("sdcard/temp222.wav", "a+b");
//  }int pos =0;AACD_TRACE("read_aac_samples, isSeeking %d",isSeeking);jshort * target = env->GetShortArrayElements(buffer, NULL);if(aacHandle->buffer.bytes_into_buffer == 0){fill_buffer(&aacHandle->buffer, 1);}int times = 0;void *sample_buffer = NULL;while(pos < size && aacHandle->buffer.bytes_into_buffer != 0){if(isSeeking)return -1;NeAACDecFrameInfo frameInfo;sample_buffer = NeAACDecDecode(aacHandle->hDecoder, &frameInfo, aacHandle->buffer.buffer, aacHandle->buffer.bytes_into_buffer);if((frameInfo.error == 0) && (frameInfo.samples >= 0) && sample_buffer != NULL){times++;if((pos + frameInfo.samples) > size){AACD_TRACE("samples: %d, pos: %d, size %d", frameInfo.samples, pos, size);break;}aacHandle->sampleId += 1;
//          if(pos + frameInfo.samples < size){
//              AACD_TRACE("samples %d", frameInfo.samples);
//              aacHandle->buffer.bytes_consumed = 0;memmove((void *)(target + pos), (void *)sample_buffer, sizeof(short) * frameInfo.samples);
//              memset(sample_buffer, 0, sizeof(short) * frameInfo.samples);pos += frameInfo.samples;             advance_buffer(&aacHandle->buffer, frameInfo.bytesconsumed);fill_buffer(&aacHandle->buffer, 1);
//          }else{
//              int othersize = 0;
//              unsigned long bytesconsumed = 0;
//              if(frameInfo.samples < (size -pos)){
//                  othersize = frameInfo.samples;
//              }else{
//                  othersize = (size -pos);
//              }
//              AACD_TRACE( "othersize %d", othersize);
//              memcpy((void *)(target + pos), (void *)sample_buffer, sizeof(short) * othersize);
//              advance_buffer(&aacHandle->buffer, frameInfo.bytesconsumed*othersize/size);
//              pos += othersize;
//              fill_buffer(&aacHandle->buffer);
//              AACD_TRACE( "decodingothers %d", frameInfo.samples);
//              break;
//          }}else if(frameInfo.error != 0){AACD_TRACE("read error %d, consumed bytes: %d", frameInfo.error, frameInfo.bytesconsumed);advance_buffer(&aacHandle->buffer, frameInfo.bytesconsumed);if (frameInfo.bytesconsumed == 0) {fseek(aacHandle->buffer.infile,aacHandle->buffer.file_offset,SEEK_SET);aacHandle->buffer.bytes_into_buffer = 0;break;}
//          if(aacHandle->mp4file){
//              mp4ff_set_sample_position(aacHandle->infile, aacHandle->track, aacHandle->sampleId);
//          }}}AACD_TRACE("times : %d, pos %d, size %d", times, pos, size);env->ReleaseShortArrayElements(buffer, target, 0);return times > 0 ? pos: -1;

aac解码器之郁闷(二)相关推荐

  1. 音视频开发(21)---基于RTMP推送实时AAC+H264流(二)

    基于RTMP推送实时AAC+H264流(二) https://blog.csdn.net/scnu20142005027/article/details/57428107 编码 图像采用H264编码, ...

  2. FFMPEG实现对AAC解码(采用封装格式实现)

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 原文:https://blog.csdn.net/hiwubihe/article/details/81261022 [音频编解码系列文章] 音 ...

  3. aftershokz蓝牙搜不到_小米MIUI系统无法开启蓝牙耳机aac解码的一种解决方法

    8/1更新:MIUI12现已经开放公测啦!直接去社区申请即可,答题90分,等几个小时很容易就能通过审核.不用费力刷机了,亲测MIUI12开发版可开启蓝牙aac ps.最近看评论区发现可能有个别型号蓝牙 ...

  4. 视频编解码学习之二:编解码框架

    http://www.cnblogs.com/xkfz007/archive/2012/07/29/2613824.html 第四章 视频编码基础 1. 压缩码流 语法:码流中各个元素的位置关系 01 ...

  5. 编解码注入、二次注入、DNSlog盲注

    1.编解码注入 靶场 sqlilabs-Less21 登录后,使用bp抓包 分析源码: 发现,如果正确登录,就会设置一个cookie,并且使用base64编码 分析cookie: 发现此处可以进行co ...

  6. ios - 音频AAC解码

    上一回说到音频AAC编码,这回我们把编码后的文件解码,解码的文件就是上一章录制的音频. 在iOS下进行音频解码及播放的大体流程如下: 1.打开 AAC 文件. 2.获取音频格式信息.如通道数,采样率等 ...

  7. 视频编解码学习笔记二—HM的使用及数字视频的格式

    一,软件下载 HEVC的官方参考软件是HM(HEVC Test Model). 下载HM需要使用到SVN. SVN是一个开源的版本控制系统.相当于一个版本控制器加备份服务器.可以回到修改以前某个时刻的 ...

  8. 音频之各种有损编码器的比较,AAC编码器之选择,频谱、差值比较,编码器下载

    音频有损编码有:aac,mp3,ogg(vobis),opus等.这里只讨论主流编码格式,aac编码器有faac,qaac,fhgacc,neroacc,fdkacc,falabaac等,其封装格式有 ...

  9. 视频编解码(十二):播放器编解码流程source、demux、decoder、output

    一.播放器编解码流程source.demux.decoder.output 说白了播放器大致分为4大部分:source.demux.decoder.output. 1.source: 数据源,数据的来 ...

  10. 基于FFmpeg的视频播放器之十二:seek

    seek是播放器的常用操作,也是衡量播放器好坏的重要标志之一. 一.效果 下面是对正在播放的4K视频执行seek操作 二.原理 1.av_seek_frame FFmpeg提供了av_seek_fra ...

最新文章

  1. 内存卡损坏 linux 修复,Linux系统恢复工具
  2. Google protobuf解析消息逻辑的版本问题
  3. J2EE dynamic web工程搭建 struts2
  4. matlab中的类标转换程序
  5. python pow和**_「Python学习笔记」Python函数高级应用
  6. 做一个中国式站长必须知道的五十个问题
  7. asp.net ftp上传文件到服务器,.net 文件上传到服务器上
  8. shiro包_Shiro--从一个简单的 Realm 开始权限认证
  9. B1.Java基础部分二
  10. imwrite函数 matlab_用matlab做一个脉动磁势分解的动画
  11. RTDS 推出 NovaCor
  12. 爬取了bilibili站644w视频信息之后的故事。
  13. linux pack文件镜像,使用buildpack-deps 构建自己的入容器镜像
  14. 微信公众号关注自动回复,关键词自动回复,一个PHP文件就可以搞定!
  15. 人工智能权威网站推荐
  16. COOC6.2增加同义词合并无意义词删除等功能
  17. vue全家桶都有哪些
  18. 大数据运营之财务数据模型设计
  19. C#开发微信门户及应用(46)-基于Bootstrap的微信门户应用管理系统功能介绍
  20. (资讯)华为员工利用Bug越权访问机密卖给第三方,获利1.6万元,被判有期徒刑一年

热门文章

  1. 浅谈三种使用Redis实现MQ的方式
  2. 打印网页去掉网址html,Print Edit WE插件,编辑\隐藏\删除网页元素,并支持保存和打印新页面...
  3. pythoncsv格式清洗与转换_Python中 CSV格式清洗与转换的实例代码
  4. html iframe 设置半透明_HTML基础教程:框架实例大合集
  5. QT的QWebEngineView内存泄漏
  6. 如何在linux系统下读写windows上的共享文件夹
  7. 学生成绩管理系统源码
  8. vision画流程图的软件_程序流程图用什么软件画?
  9. AUTOCAD二次开发VBA 基础到实例视频教程
  10. 对《Java编程思想》读者的一点建议