|
|
@ -28,7 +28,7 @@ extern "C" { |
|
|
|
#define SLEEP_TIME 1000 * 16 |
|
|
|
#define SLEEP_TIME 1000 * 16 |
|
|
|
#define MAX_AUDIO_FRAME_SIZE 48000 * 4 |
|
|
|
#define MAX_AUDIO_FRAME_SIZE 48000 * 4 |
|
|
|
|
|
|
|
|
|
|
|
const char *filter_descr = "superequalizer=6b=4:8b=5:10b=5"; |
|
|
|
//const char *filter_descr = "superequalizer=6b=4:8b=5:10b=5";
|
|
|
|
|
|
|
|
|
|
|
|
int init_volume_filter(AVFilterGraph **graph, AVFilterContext **src, AVFilterContext **sink, |
|
|
|
int init_volume_filter(AVFilterGraph **graph, AVFilterContext **src, AVFilterContext **sink, |
|
|
|
uint64_t channel_layout, AVSampleFormat inputFormat, int sample_rate) { |
|
|
|
uint64_t channel_layout, AVSampleFormat inputFormat, int sample_rate) { |
|
|
@ -128,7 +128,8 @@ int init_volume_filter(AVFilterGraph **graph, AVFilterContext **src, AVFilterCon |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int init_equalizer_filter(AVCodecContext *codecCtx, AVFilterGraph **graph, AVFilterContext **src, AVFilterContext **sink) { |
|
|
|
int init_equalizer_filter(const char *filter_desc, AVCodecContext *codecCtx, AVFilterGraph **graph, |
|
|
|
|
|
|
|
AVFilterContext **src, AVFilterContext **sink) { |
|
|
|
int ret = 0; |
|
|
|
int ret = 0; |
|
|
|
char args[512]; |
|
|
|
char args[512]; |
|
|
|
AVFilterContext *buffersrc_ctx; |
|
|
|
AVFilterContext *buffersrc_ctx; |
|
|
@ -177,7 +178,7 @@ int init_equalizer_filter(AVCodecContext *codecCtx, AVFilterGraph **graph, AVFil |
|
|
|
inputs->pad_idx = 0; |
|
|
|
inputs->pad_idx = 0; |
|
|
|
inputs->next = NULL; |
|
|
|
inputs->next = NULL; |
|
|
|
|
|
|
|
|
|
|
|
if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_descr, |
|
|
|
if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_desc, |
|
|
|
&inputs, &outputs, NULL)) < 0) { |
|
|
|
&inputs, &outputs, NULL)) < 0) { |
|
|
|
LOGE(TAG, "avfilter_graph_parse_ptr error:%d", ret); |
|
|
|
LOGE(TAG, "avfilter_graph_parse_ptr error:%d", ret); |
|
|
|
goto end; |
|
|
|
goto end; |
|
|
@ -195,7 +196,7 @@ end: |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
AUDIO_PLAYER_FUNC(void, play, jstring input_jstr) { |
|
|
|
AUDIO_PLAYER_FUNC(void, play, jstring input_jstr, jstring filter_jstr) { |
|
|
|
int got_frame = 0, ret = 0; |
|
|
|
int got_frame = 0, ret = 0; |
|
|
|
AVFilterGraph *audioFilterGraph; |
|
|
|
AVFilterGraph *audioFilterGraph; |
|
|
|
AVFilterContext *audioSrcContext; |
|
|
|
AVFilterContext *audioSrcContext; |
|
|
@ -203,6 +204,8 @@ AUDIO_PLAYER_FUNC(void, play, jstring input_jstr) { |
|
|
|
|
|
|
|
|
|
|
|
const char *input_cstr = env->GetStringUTFChars(input_jstr, NULL); |
|
|
|
const char *input_cstr = env->GetStringUTFChars(input_jstr, NULL); |
|
|
|
LOGI(TAG, "input url=%s", input_cstr); |
|
|
|
LOGI(TAG, "input url=%s", input_cstr); |
|
|
|
|
|
|
|
const char *filter_desc = env->GetStringUTFChars(filter_jstr, NULL); |
|
|
|
|
|
|
|
LOGE(TAG, "filter_desc=%s", filter_desc); |
|
|
|
av_register_all(); |
|
|
|
av_register_all(); |
|
|
|
AVFormatContext *pFormatCtx = avformat_alloc_context(); |
|
|
|
AVFormatContext *pFormatCtx = avformat_alloc_context(); |
|
|
|
if (avformat_open_input(&pFormatCtx, input_cstr, NULL, NULL) != 0) { |
|
|
|
if (avformat_open_input(&pFormatCtx, input_cstr, NULL, NULL) != 0) { |
|
|
@ -220,7 +223,6 @@ AUDIO_PLAYER_FUNC(void, play, jstring input_jstr) { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
AVCodecContext *codecCtx = pFormatCtx->streams[audio_stream_idx]->codec; |
|
|
|
AVCodecContext *codecCtx = pFormatCtx->streams[audio_stream_idx]->codec; |
|
|
|
AVCodec *codec = avcodec_find_decoder(codecCtx->codec_id); |
|
|
|
AVCodec *codec = avcodec_find_decoder(codecCtx->codec_id); |
|
|
|
if (codec == NULL) { |
|
|
|
if (codec == NULL) { |
|
|
@ -234,7 +236,6 @@ AUDIO_PLAYER_FUNC(void, play, jstring input_jstr) { |
|
|
|
AVPacket *packet = (AVPacket *) av_malloc(sizeof(AVPacket)); |
|
|
|
AVPacket *packet = (AVPacket *) av_malloc(sizeof(AVPacket)); |
|
|
|
AVFrame *frame = av_frame_alloc(); |
|
|
|
AVFrame *frame = av_frame_alloc(); |
|
|
|
SwrContext *swrCtx = swr_alloc(); |
|
|
|
SwrContext *swrCtx = swr_alloc(); |
|
|
|
|
|
|
|
|
|
|
|
enum AVSampleFormat in_sample_fmt = codecCtx->sample_fmt; |
|
|
|
enum AVSampleFormat in_sample_fmt = codecCtx->sample_fmt; |
|
|
|
enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16; |
|
|
|
enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16; |
|
|
|
int in_sample_rate = codecCtx->sample_rate; |
|
|
|
int in_sample_rate = codecCtx->sample_rate; |
|
|
@ -247,8 +248,7 @@ AUDIO_PLAYER_FUNC(void, play, jstring input_jstr) { |
|
|
|
in_ch_layout, in_sample_fmt, in_sample_rate, |
|
|
|
in_ch_layout, in_sample_fmt, in_sample_rate, |
|
|
|
0, NULL); |
|
|
|
0, NULL); |
|
|
|
swr_init(swrCtx); |
|
|
|
swr_init(swrCtx); |
|
|
|
int out_channel_nb = av_get_channel_layout_nb_channels(out_ch_layout); |
|
|
|
int out_channel = av_get_channel_layout_nb_channels(out_ch_layout); |
|
|
|
|
|
|
|
|
|
|
|
jclass player_class = env->GetObjectClass(thiz); |
|
|
|
jclass player_class = env->GetObjectClass(thiz); |
|
|
|
if (!player_class) { |
|
|
|
if (!player_class) { |
|
|
|
LOGE(TAG, "player_class not found..."); |
|
|
|
LOGE(TAG, "player_class not found..."); |
|
|
@ -259,22 +259,20 @@ AUDIO_PLAYER_FUNC(void, play, jstring input_jstr) { |
|
|
|
if (!audio_track_method) { |
|
|
|
if (!audio_track_method) { |
|
|
|
LOGE(TAG, "audio_track_method not found..."); |
|
|
|
LOGE(TAG, "audio_track_method not found..."); |
|
|
|
} |
|
|
|
} |
|
|
|
jobject audio_track = env->CallObjectMethod(thiz, audio_track_method, out_sample_rate, |
|
|
|
jobject audio_track = env->CallObjectMethod(thiz, audio_track_method, out_sample_rate, out_channel); |
|
|
|
out_channel_nb); |
|
|
|
|
|
|
|
//call play method
|
|
|
|
//call play method
|
|
|
|
jclass audio_track_class = env->GetObjectClass(audio_track); |
|
|
|
jclass audio_track_class = env->GetObjectClass(audio_track); |
|
|
|
jmethodID audio_track_play_mid = env->GetMethodID(audio_track_class, "play", "()V"); |
|
|
|
jmethodID audio_track_play_mid = env->GetMethodID(audio_track_class, "play", "()V"); |
|
|
|
env->CallVoidMethod(audio_track, audio_track_play_mid); |
|
|
|
env->CallVoidMethod(audio_track, audio_track_play_mid); |
|
|
|
//get write method
|
|
|
|
//get write method
|
|
|
|
jmethodID audio_track_write_mid = env->GetMethodID(audio_track_class, "write", |
|
|
|
jmethodID audio_track_write_mid = env->GetMethodID(audio_track_class, "write", "([BII)I"); |
|
|
|
"([BII)I"); |
|
|
|
|
|
|
|
uint8_t *out_buffer = (uint8_t *) av_malloc(MAX_AUDIO_FRAME_SIZE); |
|
|
|
uint8_t *out_buffer = (uint8_t *) av_malloc(MAX_AUDIO_FRAME_SIZE); |
|
|
|
|
|
|
|
|
|
|
|
/* Set up the filter graph. */ |
|
|
|
/* Set up the filter graph. */ |
|
|
|
AVFrame *filter_frame = av_frame_alloc(); |
|
|
|
AVFrame *filter_frame = av_frame_alloc(); |
|
|
|
// ret = init_volume_filter(&audioFilterGraph, &audioSrcContext, &audioSinkContext,
|
|
|
|
// ret = init_volume_filter(&audioFilterGraph, &audioSrcContext, &audioSinkContext,
|
|
|
|
// in_ch_layout, in_sample_fmt, in_sample_rate);
|
|
|
|
// in_ch_layout, in_sample_fmt, in_sample_rate);
|
|
|
|
ret = init_equalizer_filter(codecCtx, &audioFilterGraph, &audioSrcContext, &audioSinkContext); |
|
|
|
ret = init_equalizer_filter(filter_desc, codecCtx, &audioFilterGraph, &audioSrcContext, &audioSinkContext); |
|
|
|
if (ret < 0) { |
|
|
|
if (ret < 0) { |
|
|
|
LOGE(TAG, "Unable to init filter graph:%d", ret); |
|
|
|
LOGE(TAG, "Unable to init filter graph:%d", ret); |
|
|
|
goto end; |
|
|
|
goto end; |
|
|
@ -304,7 +302,7 @@ AUDIO_PLAYER_FUNC(void, play, jstring input_jstr) { |
|
|
|
//convert audio format
|
|
|
|
//convert audio format
|
|
|
|
swr_convert(swrCtx, &out_buffer, MAX_AUDIO_FRAME_SIZE, |
|
|
|
swr_convert(swrCtx, &out_buffer, MAX_AUDIO_FRAME_SIZE, |
|
|
|
(const uint8_t **) /*frame*/filter_frame->data, /*frame*/filter_frame->nb_samples); |
|
|
|
(const uint8_t **) /*frame*/filter_frame->data, /*frame*/filter_frame->nb_samples); |
|
|
|
int out_buffer_size = av_samples_get_buffer_size(NULL, out_channel_nb, |
|
|
|
int out_buffer_size = av_samples_get_buffer_size(NULL, out_channel, |
|
|
|
/*frame*/filter_frame->nb_samples, out_sample_fmt, 1); |
|
|
|
/*frame*/filter_frame->nb_samples, out_sample_fmt, 1); |
|
|
|
|
|
|
|
|
|
|
|
jbyteArray audio_sample_array = env->NewByteArray(out_buffer_size); |
|
|
|
jbyteArray audio_sample_array = env->NewByteArray(out_buffer_size); |
|
|
@ -332,5 +330,5 @@ end: |
|
|
|
avcodec_free_context(&codecCtx); |
|
|
|
avcodec_free_context(&codecCtx); |
|
|
|
avformat_close_input(&pFormatCtx); |
|
|
|
avformat_close_input(&pFormatCtx); |
|
|
|
env->ReleaseStringUTFChars(input_jstr, input_cstr); |
|
|
|
env->ReleaseStringUTFChars(input_jstr, input_cstr); |
|
|
|
|
|
|
|
env->ReleaseStringUTFChars(filter_jstr, filter_desc); |
|
|
|
} |
|
|
|
} |