jni方法改为宏定义

jni方法改为宏定义
pull/107/head
xufulong 6 years ago
parent 2e7d905393
commit 4e122f2ca1
  1. 32
      app/src/main/cpp/audio_lame.c
  2. 30
      app/src/main/cpp/audio_player.c
  3. 4
      app/src/main/cpp/ffmpeg_cmd.c
  4. 25
      app/src/main/cpp/ffmpeg_jni_define.h
  5. 31
      app/src/main/cpp/video_player.c

@ -1,6 +1,7 @@
#include "include/lame/lame.h"
#include <jni.h>
#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);
}

@ -13,28 +13,26 @@
//重采样
#include "libswresample/swresample.h"
#include <android/log.h>
#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);

@ -1,8 +1,8 @@
#include <jni.h>
#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;

@ -0,0 +1,25 @@
//
// Created by frank on 2019/11/9.
//
#ifndef FFMPEGANDROID_FFMPEG_JNI_DEFINE_H
#define FFMPEGANDROID_FFMPEG_JNI_DEFINE_H
#include <android/log.h>
#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

@ -10,32 +10,31 @@
#include <unistd.h>
#include <libavutil/imgutils.h>
#include <android/log.h>
#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;
}
Loading…
Cancel
Save