使用FAAD库解码AAC实例及 及 faad解码后的通道数不正确的问题
来源:互联网 发布:mac适合的浏览器 编辑:程序博客网 时间:2024/05/16 05:39
使用FAAD库解码AAC实例及 及 faad解码后的通道数不正确的问题
/** * faaddec.c * use faad library to decode AAC, only can decode frame with ADTS head */#include <stdio.h>#include <memory.h>#include "faad.h"#define FRAME_MAX_LEN 1024*5 #define BUFFER_MAX_LEN 1024*1024void show_usage(){ printf("usage\nfaaddec src_file dst_file");}/** * fetch one ADTS frame */int get_one_ADTS_frame(unsigned char* buffer, size_t buf_size, unsigned char* data ,size_t* data_size){ size_t size = 0; if(!buffer || !data || !data_size ) { return -1; } while(1) { if(buf_size < 7 ) { return -1; } if((buffer[0] == 0xff) && ((buffer[1] & 0xf0) == 0xf0) ) { size |= ((buffer[3] & 0x03) <<11); //high 2 bit size |= buffer[4]<<3; //middle 8 bit size |= ((buffer[5] & 0xe0)>>5); //low 3bit break; } --buf_size; ++buffer; } if(buf_size < size) { return -1; } memcpy(data, buffer, size); *data_size = size; return 0;}int main(int argc, char* argv[]){ static unsigned char frame[FRAME_MAX_LEN]; static unsigned char buffer[BUFFER_MAX_LEN] = {0}; char src_file[128] = {0}; char dst_file[128] = {0}; FILE* ifile = NULL; FILE* ofile = NULL; unsigned long samplerate; unsigned char channels; NeAACDecHandle decoder = 0; size_t data_size = 0; size_t size = 0; NeAACDecFrameInfo frame_info; unsigned char* input_data = buffer; unsigned char* pcm_data = NULL; //analyse parameter if(argc < 3) { show_usage(); return -1; } sscanf(argv[1], "%s", src_file); sscanf(argv[2], "%s", dst_file); ifile = fopen(src_file, "rb"); ofile = fopen(dst_file, "wb"); if(!ifile || !ofile) { printf("source or destination file"); return -1; } data_size = fread(buffer, 1, BUFFER_MAX_LEN, ifile); //open decoder decoder = NeAACDecOpen(); if(get_one_ADTS_frame(buffer, data_size, frame, &size) < 0) { return -1; } //initialize decoder NeAACDecInit(decoder, frame, size, &samplerate, &channels); printf("samplerate %d, channels %d\n", samplerate, channels); while(get_one_ADTS_frame(input_data, data_size, frame, &size) == 0) { // printf("frame size %d\n", size); //decode ADTS frame pcm_data = (unsigned char*)NeAACDecDecode(decoder, &frame_info, frame, size); if(frame_info.error > 0) { printf("%s\n",NeAACDecGetErrorMessage(frame_info.error)); } else if(pcm_data && frame_info.samples > 0) { printf("frame info: bytesconsumed %d, channels %d, header_type %d object_type %d, samples %d, samplerate %d\n", frame_info.bytesconsumed, frame_info.channels, frame_info.header_type, frame_info.object_type, frame_info.samples, frame_info.samplerate); fwrite(pcm_data, 1, frame_info.samples * frame_info.channels, ofile); //2个通道 fflush(ofile); } data_size -= size; input_data += size; } NeAACDecClose(decoder); fclose(ifile); fclose(ofile);return 0;}
之前用FAAC编码了一段PCM数据(源数据是16000采样率,单通道,16位取样),编码时设置的参数也是16000采样率,单通道,16位取样。。。然后用FAAD解码时,在NeAACDecInit的时候,是先在之前编码好的aac数据(ADTS头封装的)上往buffer中写入一帧的含ADTS头的数据,然后传入到NeAACDecInit()中初始化解码器,但不知道为什么,返回的采样率总是32000,通道数总是2,我已经查看过编码后的数据,其中与采样率、通道数相应的位,表示的就是16000采样率和1通道。。
后来跟踪源码才发现 FAAD的NeAACDecInit() 源代码,问题出现在这里
long NEAACDECAPI NeAACDecInit(NeAACDecHandle hpDecoder, unsignedchar *buffer, unsignedlong buffer_size, unsignedlong *samplerate, unsignedchar *channels){#if (defined(PS_DEC) || defined(DRM_PS))/* check if we have a mono file */if (*channels == 1){ /* upMatrix to 2 channels for implicit signalling of PS */ *channels = 2; // 这里channels改变为2,why?}#endifhDecoder->channelConfiguration = *channels;#ifdef SBR_DEC/* implicit signalling */if (*samplerate <= 24000 && (hDecoder->config.dontUpSampleImplicitSBR == 0)){ *samplerate *= 2; // samplerate 变为32000 hDecoder->forceUpSampling = 1;} <pre name="code" class="cpp">else if (*samplerate > 24000 && (hDecoder->config.dontUpSampleImplicitSBR == 0)) { hDecoder->downSampledSBR = 1;}#endif}
也就是 PS_DEC 和 SBR_DEC是define过的...也不是通过./configure 的时候生成的...
再仔细看上面代码的if语句
if (*samplerate <= 24000 && (hDecoder->config.dontUpSampleImplicitSBR == 0))
我们看看在neaacdec.h 文件中该结构体的定义
现在解决这个问题就简单了,初始化前把参数dontUpSampleImplicitSBR设置为1即可。
NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration(decoder);conf->defObjectType = LC;conf->defSampleRate = 8000; //real samplerate/2conf->outputFormat = FAAD_FMT_16BIT ; //conf->dontUpSampleImplicitSBR = 1;<p>NeAACDecSetConfiguration(decoder, conf);</p><p></p>
最后吐槽一下。在从官网下载的faad 说明文档 对NeAACDecConfiguration 这个结构体说明,
居然没有dontUpSampleImplicitSBR这个成员,太坑爹了
版权声明:本文为博主原创文章,未经博主允许不得转载。
0 0
- 使用FAAD库解码AAC实例及 及 faad解码后的通道数不正确的问题
- 使用FAAD库解码AAC实例及 及 faad解码后的通道数不正确的问题
- 使用FAAD库解码AAC实例
- aac的格式, 以及faad解码raw数据解码
- aac的格式, 以及faad解码raw数据解码
- AAC音频编码库FAAC和解码库FAAD移植
- 用faad解码AAC(ADTS封装)
- 用faad解码AAC(ADTS封装)
- 关于faad的编译
- faad2解码aac-解决采样频率和通道数不对的问题
- FAAD (FreeAppADay) 的一點經驗分享
- AAC文件格式及解码流程
- AAC文件格式及解码流程
- ffmpeg lame faad faac 的编译
- 使用libfdk-aac解码AAC-ELD格式的音频
- 使用libfdk-aac解码AAC-ELD格式的音频
- 使用libfdk-aac解码AAC-ELD格式的音频
- 使用libfdk-aac解码AAC-ELD格式的音频
- HDU 5739 Fantasia 2016多校
- 取样问题
- Android Volley完全解析(一),初识Volley的基本用法
- vim的安装及部分问题解决方法
- malloc calloc realloc的函数原型和功能
- 使用FAAD库解码AAC实例及 及 faad解码后的通道数不正确的问题
- DAO模式
- java中遇到的对String的分割--------split(新手记录平日所遇到的,请大神海涵)
- Word Ladder II 解题总结
- ZooKeeper的三种角色
- Android开源框架Universal-Image-Loader详解
- mxnet代码解析之computation graph
- CodeForces 288C--异或运算
- poj 1996多项式计算