translate audio_player.c into English

translate audio_player.c into English
pull/166/head
xufulong 5 years ago
parent c99305147c
commit 8922e50150
  1. 9
      app/src/main/cpp/audio_lame.c
  2. 230
      app/src/main/cpp/audio_player.c

@ -190,7 +190,8 @@ AUDIO_PLAYER_FUNC(void, lameInit,
jint inSampleRate, jint outChannel, jint outSampleRate, jint outBitrate,
jfloat scaleInput, jint mode, jint vbrMode, jint quality, jint vbrQuality,
jint abrMeanBitrate, jint lowPassFreq, jint highPassFreq, jstring id3tagTitle,
jstring id3tagArtist, jstring id3tagAlbum, jstring id3tagYear, jstring id3tagComment) {
jstring id3tagArtist, jstring id3tagAlbum, jstring id3tagYear,
jstring id3tagComment) {
glf = initialize(env, inSampleRate, outChannel, outSampleRate, outBitrate, scaleInput, mode,
vbrMode,
@ -201,17 +202,17 @@ AUDIO_PLAYER_FUNC(void, lameInit,
}
AUDIO_PLAYER_FUNC(jint, lameEncode,
jshortArray buffer_l, jshortArray buffer_r, jint samples, jbyteArray mp3buf) {
jshortArray buffer_l, jshortArray buffer_r, jint samples, jbyteArray mp3buf) {
return encode(env, glf, buffer_l, buffer_r, samples, mp3buf);
}
AUDIO_PLAYER_FUNC(jint, encodeBufferInterleaved,
jshortArray pcm, jint samples, jbyteArray mp3buf) {
jshortArray pcm, jint samples, jbyteArray mp3buf) {
return encodeBufferInterleaved(env, glf, pcm, samples, mp3buf);
}
AUDIO_PLAYER_FUNC(jint, lameFlush,
jbyteArray mp3buf) {
jbyteArray mp3buf) {
return flush(env, glf, mp3buf);
}

@ -4,15 +4,12 @@
#include <jni.h>
#include <stdlib.h>
#include <unistd.h>
//封装格式
#include <android/log.h>
#include "libavformat/avformat.h"
//解码
#include "libavcodec/avcodec.h"
//缩放
#include "libswscale/swscale.h"
//重采样
#include "libswresample/swresample.h"
#include <android/log.h>
#include "ffmpeg_jni_define.h"
#define TAG "AudioPlayer"
@ -20,133 +17,138 @@
#define MAX_AUDIO_FRAME_SIZE 48000 * 4
AUDIO_PLAYER_FUNC(void, play, jstring input_jstr) {
const char* input_cstr = (*env)->GetStringUTFChars(env,input_jstr,NULL);
LOGI(TAG, "input_cstr=%s", input_cstr);
//注册组件
av_register_all();
AVFormatContext *pFormatCtx = avformat_alloc_context();
//打开音频文件
if(avformat_open_input(&pFormatCtx,input_cstr,NULL,NULL) != 0){
LOGE(TAG, "无法打开音频文件");
return;
}
//获取输入文件信息
if(avformat_find_stream_info(pFormatCtx,NULL) < 0){
LOGE(TAG, "无法获取输入文件信息");
return;
}
//获取音频流索引位置
int i = 0, audio_stream_idx = -1;
for(; i < pFormatCtx->nb_streams;i++){
if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO){
audio_stream_idx = i;
break;
}
}
const char *input_cstr = (*env)->GetStringUTFChars(env, input_jstr, NULL);
LOGI(TAG, "input_cstr=%s", input_cstr);
//register all modules
av_register_all();
AVFormatContext *pFormatCtx = avformat_alloc_context();
//open the audio file
if (avformat_open_input(&pFormatCtx, input_cstr, NULL, NULL) != 0) {
LOGE(TAG, "Couldn't open the audio file!");
return;
}
//find all streams info
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
LOGE(TAG, "Couldn't find stream info!");
return;
}
//get the audio stream index in the stream array
int i = 0, audio_stream_idx = -1;
for (; i < pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
audio_stream_idx = i;
break;
}
}
//获取音频解码器
AVCodecContext *codecCtx = pFormatCtx->streams[audio_stream_idx]->codec;
AVCodec *codec = avcodec_find_decoder(codecCtx->codec_id);
if(codec == NULL){
LOGE(TAG, "无法获取解码器");
return;
}
//打开解码器
if(avcodec_open2(codecCtx,codec,NULL) < 0){
LOGE(TAG, "无法打开解码器");
return;
}
//压缩数据
AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket));
//解压缩数据
AVFrame *frame = av_frame_alloc();
//frame->16bit 44100 PCM 统一音频采样格式与采样率
SwrContext *swrCtx = swr_alloc();
//find audio decoder
AVCodecContext *codecCtx = pFormatCtx->streams[audio_stream_idx]->codec;
AVCodec *codec = avcodec_find_decoder(codecCtx->codec_id);
if (codec == NULL) {
LOGE(TAG, "Couldn't find audio decoder!");
return;
}
//open audio decoder
if (avcodec_open2(codecCtx, codec, NULL) < 0) {
LOGE(TAG, "Couldn't open audio decoder");
return;
}
//malloc packet memory
AVPacket *packet = (AVPacket *) av_malloc(sizeof(AVPacket));
//malloc frame memory
AVFrame *frame = av_frame_alloc();
//frame->16bit 44100 PCM
SwrContext *swrCtx = swr_alloc();
//输入的采样格式
enum AVSampleFormat in_sample_fmt = codecCtx->sample_fmt;
//输出采样格式16bit PCM
enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;
//输入采样率
int in_sample_rate = codecCtx->sample_rate;
//输出采样率
int out_sample_rate = in_sample_rate;
//声道布局(2个声道,默认立体声stereo)
uint64_t in_ch_layout = codecCtx->channel_layout;
//输出的声道布局(立体声)
uint64_t out_ch_layout = AV_CH_LAYOUT_STEREO;
//input sampleFormat
enum AVSampleFormat in_sample_fmt = codecCtx->sample_fmt;
//output sampleFormat: 16bit PCM
enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;
//input sampleRate
int in_sample_rate = codecCtx->sample_rate;
//output sampleRate
int out_sample_rate = in_sample_rate;
//input channel layout(2 channels, stereo by default)
uint64_t in_ch_layout = codecCtx->channel_layout;
//output channel layout
uint64_t out_ch_layout = AV_CH_LAYOUT_STEREO;
swr_alloc_set_opts(swrCtx,
out_ch_layout,out_sample_fmt,out_sample_rate,
in_ch_layout,in_sample_fmt,in_sample_rate,
0, NULL);
swr_init(swrCtx);
swr_alloc_set_opts(swrCtx,
out_ch_layout, out_sample_fmt, out_sample_rate,
in_ch_layout, in_sample_fmt, in_sample_rate,
0, NULL);
swr_init(swrCtx);
//输出的声道个数
int out_channel_nb = av_get_channel_layout_nb_channels(out_ch_layout);
//output channel number
int out_channel_nb = av_get_channel_layout_nb_channels(out_ch_layout);
jclass player_class = (*env)->GetObjectClass(env,thiz);
if(!player_class){
jclass player_class = (*env)->GetObjectClass(env, thiz);
if (!player_class) {
LOGE(TAG, "player_class not found...");
}
//AudioTrack对象
jmethodID audio_track_method = (*env)->GetMethodID(env,player_class,"createAudioTrack","(II)Landroid/media/AudioTrack;");
if(!audio_track_method){
//get AudioTrack by reflection
jmethodID audio_track_method = (*env)->GetMethodID(env, player_class, "createAudioTrack",
"(II)Landroid/media/AudioTrack;");
if (!audio_track_method) {
LOGE(TAG, "audio_track_method not found...");
}
jobject audio_track = (*env)->CallObjectMethod(env,thiz,audio_track_method,out_sample_rate,out_channel_nb);
jobject audio_track = (*env)->CallObjectMethod(env, thiz, audio_track_method, out_sample_rate,
out_channel_nb);
//调用play方法
jclass audio_track_class = (*env)->GetObjectClass(env,audio_track);
jmethodID audio_track_play_mid = (*env)->GetMethodID(env,audio_track_class,"play","()V");
(*env)->CallVoidMethod(env,audio_track,audio_track_play_mid);
//call play method
jclass audio_track_class = (*env)->GetObjectClass(env, audio_track);
jmethodID audio_track_play_mid = (*env)->GetMethodID(env, audio_track_class, "play", "()V");
(*env)->CallVoidMethod(env, audio_track, audio_track_play_mid);
//获取write()方法
jmethodID audio_track_write_mid = (*env)->GetMethodID(env,audio_track_class,"write","([BII)I");
//get write method
jmethodID audio_track_write_mid = (*env)->GetMethodID(env, audio_track_class, "write",
"([BII)I");
//16bit 44100 PCM 数据
uint8_t *out_buffer = (uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE);
uint8_t *out_buffer = (uint8_t *) av_malloc(MAX_AUDIO_FRAME_SIZE);
int got_frame = 0,index = 0, ret;
//不断读取编码数据
while(av_read_frame(pFormatCtx,packet) >= 0){
//解码音频类型的Packet
if(packet->stream_index == audio_stream_idx){
//解码
ret = avcodec_decode_audio4(codecCtx,frame,&got_frame,packet);
if(ret < 0){
int got_frame = 0, index = 0, ret;
//read audio frame
while (av_read_frame(pFormatCtx, packet) >= 0) {
//is audio stream index
if (packet->stream_index == audio_stream_idx) {
//do decode
ret = avcodec_decode_audio4(codecCtx, frame, &got_frame, packet);
if (ret < 0) {
break;
}
//解码一帧成功
if(got_frame > 0){
LOGI(TAG, "decode frame count=%d", index++);
//音频格式转换
swr_convert(swrCtx, &out_buffer, MAX_AUDIO_FRAME_SIZE,(const uint8_t **)frame->data,frame->nb_samples);
}
//decode success
if (got_frame > 0) {
LOGI(TAG, "decode frame count=%d", index++);
//convert audio format
swr_convert(swrCtx, &out_buffer, MAX_AUDIO_FRAME_SIZE,
(const uint8_t **) frame->data, frame->nb_samples);
int out_buffer_size = av_samples_get_buffer_size(NULL, out_channel_nb,
frame->nb_samples, out_sample_fmt, 1);
frame->nb_samples, out_sample_fmt,
1);
jbyteArray audio_sample_array = (*env)->NewByteArray(env,out_buffer_size);
jbyte* sample_byte_array = (*env)->GetByteArrayElements(env,audio_sample_array,NULL);
//拷贝缓冲数据
jbyteArray audio_sample_array = (*env)->NewByteArray(env, out_buffer_size);
jbyte *sample_byte_array = (*env)->GetByteArrayElements(env, audio_sample_array,
NULL);
//copy buffer data
memcpy(sample_byte_array, out_buffer, (size_t) out_buffer_size);
//释放数组
(*env)->ReleaseByteArrayElements(env,audio_sample_array,sample_byte_array,0);
//调用AudioTrack的write方法进行播放
(*env)->CallIntMethod(env,audio_track,audio_track_write_mid,
audio_sample_array,0,out_buffer_size);
//释放局部引用
(*env)->DeleteLocalRef(env,audio_sample_array);
//release byteArray
(*env)->ReleaseByteArrayElements(env, audio_sample_array, sample_byte_array, 0);
//call write method to play
(*env)->CallIntMethod(env, audio_track, audio_track_write_mid,
audio_sample_array, 0, out_buffer_size);
//delete local reference
(*env)->DeleteLocalRef(env, audio_sample_array);
usleep(1000 * 16);
}
}
av_free_packet(packet);
}
}
}
av_free_packet(packet);
}
LOGI(TAG, "decode audio finish");
av_frame_free(&frame);
av_free(out_buffer);
swr_free(&swrCtx);
avcodec_close(codecCtx);
avformat_close_input(&pFormatCtx);
(*env)->ReleaseStringUTFChars(env,input_jstr,input_cstr);
av_frame_free(&frame);
av_free(out_buffer);
swr_free(&swrCtx);
avcodec_close(codecCtx);
avformat_close_input(&pFormatCtx);
(*env)->ReleaseStringUTFChars(env, input_jstr, input_cstr);
}
Loading…
Cancel
Save