From 4e122f2ca11322a29dc4ba5842e9ff80660ad8ab Mon Sep 17 00:00:00 2001 From: xufulong <839789740@qq.com> Date: Sat, 9 Nov 2019 02:32:03 +0800 Subject: [PATCH] =?UTF-8?q?jni=E6=96=B9=E6=B3=95=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E5=AE=8F=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit jni方法改为宏定义 --- app/src/main/cpp/audio_lame.c | 32 ++++++++++++---------------- app/src/main/cpp/audio_player.c | 30 ++++++++++++-------------- app/src/main/cpp/ffmpeg_cmd.c | 4 ++-- app/src/main/cpp/ffmpeg_jni_define.h | 25 ++++++++++++++++++++++ app/src/main/cpp/video_player.c | 31 ++++++++++++--------------- 5 files changed, 69 insertions(+), 53 deletions(-) create mode 100644 app/src/main/cpp/ffmpeg_jni_define.h diff --git a/app/src/main/cpp/audio_lame.c b/app/src/main/cpp/audio_lame.c index 136bb4f..9bc6553 100644 --- a/app/src/main/cpp/audio_lame.c +++ b/app/src/main/cpp/audio_lame.c @@ -1,6 +1,7 @@ #include "include/lame/lame.h" #include +#include "ffmpeg_jni_define.h" lame_global_flags *glf; @@ -180,18 +181,16 @@ void close_lame(lame_global_flags *glf) { } -JNIEXPORT void JNICALL Java_com_frank_ffmpeg_AudioPlayer_lameInitDefault - (JNIEnv *env, jclass jclazz) { +AUDIO_PLAYER_FUNC(void, lameInitDefault) { glf = initializeDefault(env); } -JNIEXPORT void JNICALL Java_com_frank_ffmpeg_AudioPlayer_lameInit( - JNIEnv *env, jclass cls, 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) { +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) { glf = initialize(env, inSampleRate, outChannel, outSampleRate, outBitrate, scaleInput, mode, vbrMode, @@ -201,24 +200,21 @@ JNIEXPORT void JNICALL Java_com_frank_ffmpeg_AudioPlayer_lameInit( id3tagComment); } -JNIEXPORT jint JNICALL Java_com_frank_ffmpeg_AudioPlayer_lameEncode( - JNIEnv *env, jclass cls, jshortArray buffer_l, - jshortArray buffer_r, jint samples, jbyteArray mp3buf) { +AUDIO_PLAYER_FUNC(jint, lameEncode, + jshortArray buffer_l, jshortArray buffer_r, jint samples, jbyteArray mp3buf) { return encode(env, glf, buffer_l, buffer_r, samples, mp3buf); } -JNIEXPORT jint JNICALL Java_com_frank_ffmpeg_AudioPlayer_encodeBufferInterleaved( - JNIEnv *env, jclass cls, jshortArray pcm, - jint samples, jbyteArray mp3buf) { +AUDIO_PLAYER_FUNC(jint, encodeBufferInterleaved, + jshortArray pcm, jint samples, jbyteArray mp3buf) { return encodeBufferInterleaved(env, glf, pcm, samples, mp3buf); } -JNIEXPORT jint JNICALL Java_com_frank_ffmpeg_AudioPlayer_lameFlush( - JNIEnv *env, jclass cls, jbyteArray mp3buf) { +AUDIO_PLAYER_FUNC(jint, lameFlush, + jbyteArray mp3buf) { return flush(env, glf, mp3buf); } -JNIEXPORT void JNICALL Java_com_frank_ffmpeg_AudioPlayer_lameClose( - JNIEnv *env, jclass cls) { +AUDIO_PLAYER_FUNC(void, lameClose) { close_lame(glf); } \ No newline at end of file diff --git a/app/src/main/cpp/audio_player.c b/app/src/main/cpp/audio_player.c index ec1d16a..99d22f4 100644 --- a/app/src/main/cpp/audio_player.c +++ b/app/src/main/cpp/audio_player.c @@ -13,28 +13,26 @@ //重采样 #include "libswresample/swresample.h" #include +#include "ffmpeg_jni_define.h" -#define TAG "MediaPlayer" -#define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO, TAG, FORMAT, ##__VA_ARGS__); -#define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR, TAG, FORMAT, ##__VA_ARGS__); +#define TAG "AudioPlayer" #define MAX_AUDIO_FRAME_SIZE 48000 * 4 -JNIEXPORT void JNICALL Java_com_frank_ffmpeg_AudioPlayer_play - (JNIEnv *env, jobject jthiz, jstring input_jstr){ +AUDIO_PLAYER_FUNC(void, play, jstring input_jstr) { const char* input_cstr = (*env)->GetStringUTFChars(env,input_jstr,NULL); - LOGI("input_cstr=%s", input_cstr); + 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){ - LOGI("%s","无法打开音频文件"); + LOGE(TAG, "无法打开音频文件"); return; } //获取输入文件信息 if(avformat_find_stream_info(pFormatCtx,NULL) < 0){ - LOGI("%s","无法获取输入文件信息"); + LOGE(TAG, "无法获取输入文件信息"); return; } //获取音频流索引位置 @@ -50,12 +48,12 @@ JNIEXPORT void JNICALL Java_com_frank_ffmpeg_AudioPlayer_play AVCodecContext *codecCtx = pFormatCtx->streams[audio_stream_idx]->codec; AVCodec *codec = avcodec_find_decoder(codecCtx->codec_id); if(codec == NULL){ - LOGI("%s","无法获取解码器"); + LOGE(TAG, "无法获取解码器"); return; } //打开解码器 if(avcodec_open2(codecCtx,codec,NULL) < 0){ - LOGI("%s","无法打开解码器"); + LOGE(TAG, "无法打开解码器"); return; } //压缩数据 @@ -87,16 +85,16 @@ JNIEXPORT void JNICALL Java_com_frank_ffmpeg_AudioPlayer_play //输出的声道个数 int out_channel_nb = av_get_channel_layout_nb_channels(out_ch_layout); - jclass player_class = (*env)->GetObjectClass(env,jthiz); + jclass player_class = (*env)->GetObjectClass(env,thiz); if(!player_class){ - LOGE("player_class not found..."); + 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){ - LOGE("audio_track_method not found..."); + LOGE(TAG, "audio_track_method not found..."); } - jobject audio_track = (*env)->CallObjectMethod(env,jthiz,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); @@ -121,7 +119,7 @@ JNIEXPORT void JNICALL Java_com_frank_ffmpeg_AudioPlayer_play } //解码一帧成功 if(got_frame > 0){ - LOGI("decode frame count=%d",index++); + LOGI(TAG, "decode frame count=%d", index++); //音频格式转换 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, @@ -143,7 +141,7 @@ JNIEXPORT void JNICALL Java_com_frank_ffmpeg_AudioPlayer_play } av_free_packet(packet); } - LOGI("decode audio finish"); + LOGI(TAG, "decode audio finish"); av_frame_free(&frame); av_free(out_buffer); swr_free(&swrCtx); diff --git a/app/src/main/cpp/ffmpeg_cmd.c b/app/src/main/cpp/ffmpeg_cmd.c index e05a4a7..6ec89dc 100644 --- a/app/src/main/cpp/ffmpeg_cmd.c +++ b/app/src/main/cpp/ffmpeg_cmd.c @@ -1,8 +1,8 @@ #include #include "ffmpeg/ffmpeg.h" +#include "ffmpeg_jni_define.h" -JNIEXPORT jint JNICALL Java_com_frank_ffmpeg_FFmpegCmd_handle -(JNIEnv *env, jclass obj, jobjectArray commands){ +FFMPEG_FUNC(jint, handle, jobjectArray commands) { int argc = (*env)->GetArrayLength(env, commands); char **argv = (char**)malloc(argc * sizeof(char*)); int i; diff --git a/app/src/main/cpp/ffmpeg_jni_define.h b/app/src/main/cpp/ffmpeg_jni_define.h new file mode 100644 index 0000000..e4018e2 --- /dev/null +++ b/app/src/main/cpp/ffmpeg_jni_define.h @@ -0,0 +1,25 @@ +// +// Created by frank on 2019/11/9. +// + +#ifndef FFMPEGANDROID_FFMPEG_JNI_DEFINE_H +#define FFMPEGANDROID_FFMPEG_JNI_DEFINE_H + +#include + +#define LOGI(TAG, FORMAT, ...) __android_log_print(ANDROID_LOG_INFO, TAG, FORMAT, ##__VA_ARGS__); +#define LOGE(TAG, FORMAT,...) __android_log_print(ANDROID_LOG_ERROR, TAG, FORMAT, ##__VA_ARGS__); + +#define AUDIO_PLAYER_FUNC(RETURN_TYPE, FUNC_NAME, ...) \ + JNIEXPORT RETURN_TYPE JNICALL Java_com_frank_ffmpeg_AudioPlayer_ ## FUNC_NAME \ + (JNIEnv *env, jobject thiz, ##__VA_ARGS__)\ + +#define FFMPEG_FUNC(RETURN_TYPE, FUNC_NAME, ...) \ + JNIEXPORT RETURN_TYPE JNICALL Java_com_frank_ffmpeg_FFmpegCmd_ ## FUNC_NAME \ + (JNIEnv *env, jobject thiz, ##__VA_ARGS__)\ + +#define VIDEOO_PLAYER_FUNC(RETURN_TYPE, FUNC_NAME, ...) \ + JNIEXPORT RETURN_TYPE JNICALL Java_com_frank_ffmpeg_VideoPlayer_ ## FUNC_NAME \ + (JNIEnv *env, jobject thiz, ##__VA_ARGS__)\ + +#endif //FFMPEGANDROID_FFMPEG_JNI_DEFINE_H diff --git a/app/src/main/cpp/video_player.c b/app/src/main/cpp/video_player.c index 1f20bc5..30a8181 100644 --- a/app/src/main/cpp/video_player.c +++ b/app/src/main/cpp/video_player.c @@ -10,32 +10,31 @@ #include #include #include +#include "ffmpeg_jni_define.h" -#define TAG "MediaPlayer" -#define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO, TAG, FORMAT, ##__VA_ARGS__); -#define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR, TAG, FORMAT, ##__VA_ARGS__); +#define TAG "VideoPlayer" //播放倍率 float play_rate = 1; //视频总时长 long duration = 0; -JNIEXPORT jint JNICALL Java_com_frank_ffmpeg_VideoPlayer_play - (JNIEnv * env, jclass clazz, jstring filePath, jobject surface){ +VIDEOO_PLAYER_FUNC(jint, play, jstring filePath, jobject surface){ const char * file_name = (*env)->GetStringUTFChars(env, filePath, JNI_FALSE); + LOGE(TAG, "open file:%s\n", file_name); //注册所有组件 av_register_all(); //分配上下文 AVFormatContext * pFormatCtx = avformat_alloc_context(); //打开视频文件 if(avformat_open_input(&pFormatCtx, file_name, NULL, NULL)!=0) { - LOGE("Couldn't open file:%s\n", file_name); + LOGE(TAG, "Couldn't open file:%s\n", file_name); return -1; } //检索多媒体流信息 if(avformat_find_stream_info(pFormatCtx, NULL)<0) { - LOGE("Couldn't find stream information."); + LOGE(TAG, "Couldn't find stream information."); return -1; } //寻找视频流的第一帧 @@ -47,14 +46,14 @@ JNIEXPORT jint JNICALL Java_com_frank_ffmpeg_VideoPlayer_play } } if(videoStream==-1) { - LOGE("couldn't find a video stream."); + LOGE(TAG, "couldn't find a video stream."); return -1; } //获取视频总时长 if (pFormatCtx->duration != AV_NOPTS_VALUE) { duration = (long) (pFormatCtx->duration / AV_TIME_BASE); - LOGE("duration=%d", duration); + LOGE(TAG, "duration==%ld", duration); } //获取codec上下文指针 @@ -62,11 +61,11 @@ JNIEXPORT jint JNICALL Java_com_frank_ffmpeg_VideoPlayer_play //寻找视频流的解码器 AVCodec * pCodec = avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec==NULL) { - LOGE("couldn't find Codec."); + LOGE(TAG, "couldn't find Codec."); return -1; } if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0) { - LOGE("Couldn't open codec."); + LOGE(TAG, "Couldn't open codec."); return -1; } // 获取native window @@ -78,14 +77,14 @@ JNIEXPORT jint JNICALL Java_com_frank_ffmpeg_VideoPlayer_play ANativeWindow_setBuffersGeometry(nativeWindow, videoWidth, videoHeight, WINDOW_FORMAT_RGBA_8888); ANativeWindow_Buffer windowBuffer; if(avcodec_open2(pCodecCtx, pCodec, NULL)<0) { - LOGE("Couldn't open codec."); + LOGE(TAG, "Couldn't open codec."); return -1; } //申请内存 AVFrame * pFrame = av_frame_alloc(); AVFrame * pFrameRGBA = av_frame_alloc(); if(pFrameRGBA == NULL || pFrame == NULL) { - LOGE("Couldn't allocate video frame."); + LOGE(TAG, "Couldn't allocate video frame."); return -1; } // buffer中数据用于渲染,且格式为RGBA @@ -149,13 +148,11 @@ JNIEXPORT jint JNICALL Java_com_frank_ffmpeg_VideoPlayer_play } //设置播放速率 -JNIEXPORT jint JNICALL Java_com_frank_ffmpeg_VideoPlayer_setPlayRate - (JNIEnv * env, jclass clazz, jfloat playRate){ +VIDEOO_PLAYER_FUNC(jint, setPlayRate, jfloat playRate){ play_rate = playRate; } //获取视频总时长 -JNIEXPORT jint JNICALL Java_com_frank_ffmpeg_VideoPlayer_getDuration - (JNIEnv * env, jclass clazz){ +VIDEOO_PLAYER_FUNC(jint, getDuration){ return duration; } \ No newline at end of file