解码AAC并转换为S16

#include <string.h>
#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <android/log.h>

#include <libavutil/common.h>
#include <libavcodec/avcodec.h>
#include <libswresample/swresample.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/frame.h>
#include <libavutil/pixfmt.h>
#include <libavutil/samplefmt.h>
#define  LOG_TAG    "FFMPEGSample"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
typedef enum __bool { false = 0, true = 1, } bool;

JNIEXPORT jint JNICALL Java_com_example_ffmpegaudio1_AudioAndroid_dalDecoder(JNIEnv * env, jclass obj){
	AVFormatContext	*pFormatCtx;
	int				i, audioStream;
	AVCodecContext	*pCodecCtx;
	AVCodec			*pCodec;


	char url[]="/sdcard/Test1.aac";

	FILE *file;
	file=fopen("/sdcard/out1.pcm","wb");
	av_register_all();
	avformat_network_init();
	pFormatCtx = avformat_alloc_context();

	if(avformat_open_input(&pFormatCtx,url,NULL,NULL)!=0){//返回负值时检查是否注册所有解码器av_register_all()
		LOGI("Couldn't open input stream");
		return -1;
	}

	if(av_find_stream_info(pFormatCtx)<0)
	{
		LOGI("Couldn't find stream information");
		return -1;
	}

	av_dump_format(pFormatCtx, 0, url, false);

	audioStream=-1;
	for(i=0; i < pFormatCtx->nb_streams; i++)
		if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO)//找到第一条音频流
		{
			audioStream=i;
			break;
		}

	if(audioStream==-1)
	{
		LOGI("Cann't find a audio stream");
		return -1;
	}

	pCodecCtx=pFormatCtx->streams[audioStream]->codec;

	pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
	if(pCodec==NULL)
	{
		LOGI("Codec not found");
		return -1;
	}

	if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
	{
		LOGI("Could not open codec");
		return -1;
	}


	AVPacket *packet=(AVPacket *)malloc(sizeof(AVPacket));
	av_init_packet(packet);

	AVFrame	*pFrame;
	pFrame=avcodec_alloc_frame();
	int out_linesize;

	int out_buffer_size=av_samples_get_buffer_size(&out_linesize, pCodecCtx->channels,pCodecCtx->frame_size,pCodecCtx->sample_fmt, 1);
	uint8_t out[out_buffer_size];
	uint8_t *out_buffer=out;
	uint32_t ret,len = 0;
	int got_picture;
	int index = 0;
	struct SwrContext *au_convert_ctx;
	au_convert_ctx = swr_alloc();
	au_convert_ctx=swr_alloc_set_opts(au_convert_ctx,AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, 44100,
		pCodecCtx->channel_layout,pCodecCtx->sample_fmt , pCodecCtx->sample_rate,0, NULL);
	swr_init(au_convert_ctx);
	while(av_read_frame(pFormatCtx, packet)>=0)
	{
		if(packet->stream_index==audioStream)
		{

			ret = avcodec_decode_audio4( pCodecCtx, pFrame,&got_picture, packet);
			if ( ret < 0 )
			{
                LOGI("Error in decoding audio frame");
                exit(0);
            }
			if ( got_picture > 0 )
			{
				swr_convert(au_convert_ctx,&out_buffer, out_linesize,(const uint8_t **)pFrame->data , pFrame->nb_samples);
				fwrite(out_buffer, 1, out_linesize, file);
			}

		}
		av_free_packet(packet);
	}

	avcodec_close(pCodecCtx);

	av_close_input_file(pFormatCtx);

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值