`
yangzc106
  • 浏览: 156402 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

aac解码器之郁闷(二)

 
阅读更多

 

扫盲

       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 )//如果打开文件失败返回-1
		return -1;

	//*********************以上打开文件完毕********************************
	AACFileHandle* aacHandle = new AACFileHandle();
	if(aacHandle == NULL){
		return -1;
	}
	memset(aacHandle, 0, sizeof(AACFileHandle));
	//读取文件头,判断是否是MP4
	unsigned 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 aac
		if(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是因为外部判断的是0
		return 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解码器

    最新aac解码器,想研究arm端aac编码的,请联系bj_zhang@aliyun.com

    AAC编解码源码.zip

    6. **解码器**:解码器将压缩的AAC数据恢复成原始的音频样本,过程与编码相反,包括熵解码、逆DCT转换、时域重构等步骤。 学习和分析这个源码,开发者可以了解到如何将AAC编码算法集成到实际项目中,例如开发音频编...

    DirectShow过滤器-AAC解码器

    本过滤器将AAC音频流(包括MEDIASUBTYPE_RAW_AAC1和MEDIASUBTYPE_MPEG_ADTS_AAC)解码为PCM音频流,由输出引脚输出。 参见介绍文章:...

    基于ARM9平台优化的 AAC, HE-AAC, HE-AAC V2 音频编解码器

    基于ARM9平台优化的AAC, HE-AAC, HE-AAC V2音频编解码器 本文主要介绍基于ARM9平台优化的AAC, HE-AAC, HE-AAC V2音频编解码器的技术特点和应用场景。 音频编解码技术概述 音频编解码技术是指将音频信号转换为数字...

    安卓aac解码播放

    7. **自定义解码器**:虽然Android系统通常支持AAC解码,但在某些老旧设备或特定需求下,可能需要编写自定义解码器。这涉及到JNI(Java Native Interface)和C/C++编程,以实现与Android系统的交互。 8. **性能优化...

    aac音频解码器

    AAC音频解码器是实现这种编码格式的逆过程,即把AAC编码的数据转化为人类可以听到的声音信号的关键组件。 AAC音频编码技术的核心在于使用了更复杂的信号处理算法,包括多频带立体声、感知量化和熵编码等。多频带...

    fdk-aac-dec-example_fdk-aac_typeben_aac-ld_aac-ld解码fdk-aac_aac_源

    标题中的“fdk-aac-dec-example_fdk-aac_typeben_aac-ld_aac-ld解码fdk-aac_aac_源”表明这是一个关于使用FDK-AAC库进行AAC-LD(低延迟AAC)解码的示例项目。这个项目的重点在于演示如何利用FDK-AAC库对AAC-LD编码的...

    AAC解码最全资料

    本文将深入探讨AAC解码算法原理、AAC文件格式以及与之相关的MPEG标准。 首先,AAC解码算法原理是理解AAC技术的核心。AAC通过采用更复杂的信号处理方法,如多频带激励线性预测(MFELP)和感知量化,来减少音频数据的...

    fdk aac aac编解码库

    **AAC编解码技术概述** 音频编码技术在数字媒体领域占据着重要的地位,尤其是在音频流媒体、游戏音效、移动通信等领域。Advanced Audio Coding(AAC)是一种高效的有损音频压缩格式,由MPEG开发,旨在提供比MP3更高...

    AAC解码程序及源码

    **AAC解码程序及源码详解** AAC(Advanced Audio Coding),即高级音频编码,是一种高效、高质量的音频压缩标准,广泛应用于数字音频广播、音乐下载、流媒体服务等领域。相较于MP3,AAC在同等比特率下能提供更好的...

    AAC解码源码

    AAC解码源码是实现AAC音频文件播放的关键部分,它将AAC编码的数据转化为人类可听的声音信号。本项目提供的AAC解码源码能够帮助开发者理解和实现AAC音频的解码流程。 解码过程通常分为以下几个步骤: 1. **帧解析**...

    AAC音频解码器

    AAC音频解码器是用于处理AAC(Advanced Audio Coding)音频格式的软件组件,它能够将AAC编码的音频数据转换为可播放的音频流。在数字媒体领域,AAC因其高效的压缩比和高质量的音质而被广泛应用,特别是在移动设备和...

    AAC解码算法原理详解(附代码)

    - **同步与元素解码**:首先,解码器需要找到AAC比特流中的帧起点,这通常通过查找特定的同步字来完成。接着,解析AAC帧的头部信息,获取必要的解码参数。 - **无噪解码**:根据ISO/IEC 13818-7和14496-3标准,...

    linux下aac解码成pcm

    本文将深入探讨如何使用开源库libfaad来解码AAC(Advanced Audio Coding)格式的音频文件,并将其转换为PCM(Pulse Code Modulation)格式。PCM是数字音频的基本表示形式,广泛应用于各种音频处理场景。 AAC是一种...

    一种低成本MPEG-4 AAC解码器的优化策略

    在系统级高层C模型的基础上,提出了在低成本SoC平台的软件优化策略,包括基于统计分析...本文论述了优化的软硬件平台、优化方法和优化过程,并实现MPEG4 AAC的实时解码。结果证明了该优化策略在性能和成本方面的有效性。

    AAC编解码源码AAC编解码源码

    **AAC编解码源码详解** 音频编码技术在数字媒体领域扮演着至关重要的角色,而Advanced Audio Coding(AAC)作为一种高效、高质量的音频压缩标准,广泛应用于音乐、视频流媒体、游戏等领域。本篇文章将深入探讨AAC编...

    AAC编解码C语言实现

    在C语言中实现AAC编解码是一项技术挑战,涉及到数字信号处理、音频编码理论以及软件工程实践。 在C语言中实现AAC编解码,首先需要对AAC编码的基本原理有深入理解。AAC采用了感知音频编码技术,通过量化、预测和熵...

    AAC解码算法原理详解

    哈夫曼编码是一种高效的数据压缩方法,用于将音频数据压缩成更短的二进制码字,解码时进行逆操作恢复原始数据。 6. **反量化**: 将量化后的音频系数转换回连续的幅度值,这一过程是量化操作的逆过程。 7. **...

    AAC解码类.rar

    faad2是FFmpeg项目的一部分,是一个开源的AAC音频解码器,支持AAC-LC、HE-AAC等格式。在C#中,我们可以通过P/Invoke(Platform Invoke)技术调用C或C++编写的动态链接库(DLL),如faad2库,实现跨语言的调用。 ...

    AAC.rar_MP4 aac_aac decoder Audio_aac 编解码_aac音频_mpeg2 aac

    标题中的"AAC.rar_MP4 aac_aac decoder Audio_aac 编解码_aac音频_mpeg2 aac"提到了几个关键概念,分别是AAC(Advanced Audio Coding),MP4,AAC解码器,以及MPEG-2 AAC。这些是音频编码和处理领域的核心要素。 ...

Global site tag (gtag.js) - Google Analytics