#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;
}
解码AAC并转换为S16
最新推荐文章于 2023-06-28 18:48:43 发布