Android 编译FFmpeg x264
2017-06-09 19:40
423 查看
原文:http://blog.csdn.net/matrix_laboratory/article/details/56490404
(1)X264/FFmpeg + NDK编译
(2)ffmpeg.so + 编解码C代码
(3)Android.mk 编译
(4)JNI
(5)Java代码调用
基本流程如下图所示:
![](https://img-blog.csdn.net/20170221184712857?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWF0cml4X2xhYm9yYXRvcnk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
本文涉及FFmpeg,x264编译。
首先需要配置NDK开发环境,略
(1)设置$NDK环境变量
2
3
4
5
1
2
3
4
5
(2)检查系统类型
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
(3)配置Sysroot和cross_prefix
2
1
2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
这里面需要注意的是:
(1)PREFIX指定的是编译输出路径,不指定默认是/usr/local/lib和/usr/local/include
这里讲ffmpeg和x264统一放在工程根目录中build文件夹
(2)编译时不能进行多线程,否则汇编优化报错,如下:
1
make: [common/arm/deblock-a.o] Error 127 (ignored)
/Users/guohe/Android/android-ndk/toolchains/arm-Linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc
-I. -I. -c -DSTACK_ALIGNMENT=4 -DPIC -DHIGH_BIT_DEPTH=0 -DBIT_DEPTH=8 -o common/arm/predict-a.o common/arm/predict-a.S
/bin/sh: j4: command not found
Linux中编译x264:
2
3
1
2
3
通过对比发现:Android中编译x264,最基本的就是配置SYSROOT和CROSS_PREFIX
1
2
3
4
5
6
1
2
3
4
5
6
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
注:
(1)跨平台编译特殊配置
–sysroot=SYSROOT–cross−prefix=CROSS_PREFIX
–target-os=linux
(2)支持x264
–enable-encoder=libx264 \
–enable-libx264 \
–extra-cflags=-IPREFIX/include –extra−ldflags=−LPREFIX/lib
(3)编译优化
–enable-asm \
–enable-neon \
至此,ffmpeg和x264已经编译完成,编译结果如下:
![](https://img-blog.csdn.net/20170222103446039?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWF0cml4X2xhYm9yYXRvcnk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](https://img-blog.csdn.net/20170222103459133?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWF0cml4X2xhYm9yYXRvcnk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](https://img-blog.csdn.net/20170222104919217?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWF0cml4X2xhYm9yYXRvcnk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
ffmpeg,x264已经编译完成,下面就聊聊怎么用ffmpeg库进行开发。
下面展示一个基于FFmpeg开发的解码程序,其功能是从一个视频中解码5帧数据。
2
1
2
Android.mk主要包含几下几块:
(1)引入库文件
libavcodec.a libavdevice.a libavfilter.a libavformat.a libavutil.a libpostproc.a libswresample.a libswscale.a libx264.a
2
3
4
5
6
1
2
3
4
5
6
(2)编译源文件
需要设置:
LOCAL_MODULE //库名称
LOCAL_SRC_FILES //源代码文件
LOCAL_LDLIBS //额外链接的库
LOCAL_CFLAGS //CFlags
(3)编译何种类型
1
(4)详细脚本如下
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
Native程序一般分为两块:
(1)JNI调用接口
2
3
4
5
6
7
1
2
3
4
5
6
7
(2)功能模块
略
详细代码如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
进入jni目录,执行:
1
编译结果:
编译完成后,在lib目录下可以看到编译的so文件,在Android.mk中设置的库文件名为ffmpeg,那么编译的文件应该是”libffmpeg.so”
(1)加载库文件
2
3
1
2
3
(2)JNI接口
所有的JNI接口都有native关键字
1
(3)详细代码
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1. Android FFmpeg开发基本流程
(1)X264/FFmpeg + NDK编译 (2)ffmpeg.so + 编解码C代码
(3)Android.mk 编译
(4)JNI
(5)Java代码调用
基本流程如下图所示:
本文涉及FFmpeg,x264编译。
2. NDK配置
首先需要配置NDK开发环境,略 (1)设置$NDK环境变量
# Detect NDK if [[ -z "$NDK" ]]; then echo "The NDK dir is empty, If the shell can not run normally, you should set the NDK variable to your local ndk.dir" exit 1 fi1
2
3
4
5
1
2
3
4
5
(2)检查系统类型
# Detect OS OS=`uname` HOST_ARCH=`uname -m` export CCACHE=; type ccache >/dev/null 2>&1 && export CCACHE=ccache if [ $OS == 'Linux' ]; then export HOST_SYSTEM=linux-$HOST_ARCH elif [ $OS == 'Darwin' ]; then export HOST_SYSTEM=darwin-$HOST_ARCH fi1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
(3)配置Sysroot和cross_prefix
SYSROOT=$NDK/platforms/android-16/arch-arm CROSS_PREFIX=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/$HOST_SYSTEM/bin/arm-linux-androideabi-1
2
1
2
2. x264编译
2.1 下载源代码
git clone http://git.videolan.org/git/x264.git1
1
2.2 编译脚本
#!/bin/bash echo "###### 开始编译 x264 ######" SOURCE=$TARGET_X264_DIR cd $SOURCE #PREFIX指定的是编译输出路径,不指定默认是/usr/local/lib和/usr/local/include #PREFIX=../build EXTRA_CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=neon -D__ARM_ARCH_7__ -D__ARM_ARCH_7A__" EXTRA_LDFLAGS="-nostdlib" ./configure \ --prefix=$PREFIX \ --cross-prefix=$CROSS_PREFIX \ --extra-cflags="$EXTRA_CFLAGS" \ --extra-ldflags="$EXTRA_LDFLAGS" \ --enable-static \ --enable-pic \ --enable-strip \ --disable-cli \ --host=arm-linux \ --sysroot=$SYSROOT make clean make && make install1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
这里面需要注意的是:
(1)PREFIX指定的是编译输出路径,不指定默认是/usr/local/lib和/usr/local/include
这里讲ffmpeg和x264统一放在工程根目录中build文件夹
(2)编译时不能进行多线程,否则汇编优化报错,如下:
make -j41
1
make: [common/arm/deblock-a.o] Error 127 (ignored)
/Users/guohe/Android/android-ndk/toolchains/arm-Linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc
-I. -I. -c -DSTACK_ALIGNMENT=4 -DPIC -DHIGH_BIT_DEPTH=0 -DBIT_DEPTH=8 -o common/arm/predict-a.o common/arm/predict-a.S
/bin/sh: j4: command not found
2.3. 结论
Linux中编译x264:sudo ./configure --enable-shared --prefix=/usr/local sudo make sudo make install1
2
3
1
2
3
通过对比发现:Android中编译x264,最基本的就是配置SYSROOT和CROSS_PREFIX
3. 编译FFmpeg
3.1 下载源代码
git clone git://source.ffmpeg.org/ffmpeg.git $FFMPEG_SOURCE_DIR1
1
3.2 编译脚本
ADD_H264_FEATURE="--enable-encoder=aac \ --enable-decoder=aac \ --enable-encoder=libx264 \ --enable-libx264 \ --extra-cflags=-I$PREFIX/include \ --extra-ldflags=-L$PREFIX/lib "1
2
3
4
5
6
1
2
3
4
5
6
./configure \ --prefix=$PREFIX \ --enable-pthreads \ --enable-gpl \ --enable-version3 \ --enable-nonfree \ --enable-static \ --enable-small \ --enable-asm \ --enable-neon \ --cross-prefix=$CROSS_PREFIX \ --target-os=linux \ --arch=arm \ --enable-cross-compile \ --sysroot=$SYSROOT \ $ADD_H264_FEATURE make clean make -j4 make install1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
注:
(1)跨平台编译特殊配置
–sysroot=SYSROOT–cross−prefix=CROSS_PREFIX
–target-os=linux
(2)支持x264
–enable-encoder=libx264 \
–enable-libx264 \
–extra-cflags=-IPREFIX/include –extra−ldflags=−LPREFIX/lib
(3)编译优化
–enable-asm \
–enable-neon \
3.3 编译结果
至此,ffmpeg和x264已经编译完成,编译结果如下:
4. NDK + FFmpeg开发
ffmpeg,x264已经编译完成,下面就聊聊怎么用ffmpeg库进行开发。 下面展示一个基于FFmpeg开发的解码程序,其功能是从一个视频中解码5帧数据。
4.1 复制编译FFmpeg,x264库与头文件
cp $PREFIX/lib/*.a ./jni/lib cp -r $PREFIX/include/* ./jni/1
2
1
2
4.2 编写Android.mk
Android.mk主要包含几下几块: (1)引入库文件
libavcodec.a libavdevice.a libavfilter.a libavformat.a libavutil.a libpostproc.a libswresample.a libswscale.a libx264.a
#static version of libavutil include $(CLEAR_VARS) LOCAL_MODULE:= libavutil_static LOCAL_SRC_FILES:= lib/libavutil.a LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) include $(PREBUILT_STATIC_LIBRARY)1
2
3
4
5
6
1
2
3
4
5
6
(2)编译源文件
需要设置:
LOCAL_MODULE //库名称
LOCAL_SRC_FILES //源代码文件
LOCAL_LDLIBS //额外链接的库
LOCAL_CFLAGS //CFlags
(3)编译何种类型
include $(BUILD_SHARED_LIBRARY)1
1
(4)详细脚本如下
LOCAL_PATH := $(call my-dir)1
#include $(call all-subdir-makefiles)
#static version of libavcodec
include $(CLEAR_VARS)
LOCAL_MODULE:= libavcodec_static
LOCAL_SRC_FILES:= lib/libavcodec.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
include $(PREBUILT_STATIC_LIBRARY)
#static version of libavformat
include $(CLEAR_VARS)
LOCAL_MODULE:= libavformat_static
LOCAL_SRC_FILES:= lib/libavformat.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
include $(PREBUILT_STATIC_LIBRARY)
#static version of libswscale
include $(CLEAR_VARS)
LOCAL_MODULE:= libswscale_static
LOCAL_SRC_FILES:= lib/libswscale.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
include $(PREBUILT_STATIC_LIBRARY)
#static version of libavutil include $(CLEAR_VARS) LOCAL_MODULE:= libavutil_static LOCAL_SRC_FILES:= lib/libavutil.a LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) include $(PREBUILT_STATIC_LIBRARY)
#static version of libavdevice
include $(CLEAR_VARS)
LOCAL_MODULE:= libavdevice_static
LOCAL_SRC_FILES:= lib/libavdevice.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
include $(PREBUILT_STATIC_LIBRARY)
#static version of libavfilter
include $(CLEAR_VARS)
LOCAL_MODULE:= libavfilter_static
LOCAL_SRC_FILES:= lib/libavfilter.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
include $(PREBUILT_STATIC_LIBRARY)
#static version of libswresample
include $(CLEAR_VARS)
LOCAL_MODULE:= libswresample_static
LOCAL_SRC_FILES:= lib/libswresample.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
include $(PREBUILT_STATIC_LIBRARY)
#static version of libpostproc
include $(CLEAR_VARS)
LOCAL_MODULE:= libpostproc_static
LOCAL_SRC_FILES:= lib/libpostproc.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
include $(PREBUILT_STATIC_LIBRARY)
#static version of libx264
include $(CLEAR_VARS)
LOCAL_MODULE:= libx264_static
LOCAL_SRC_FILES:= lib/libx264.a
LOCAL_CFLAGS := -march=armv7-a -mfloat-abi=softfp -mfpu=neon -O3 -ffast-math -funroll-loops
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg
LOCAL_SRC_FILES := decoder.c encoder.c
LOCAL_LDLIBS := -llog -lz
LOCAL_CFLAGS := -march=armv7-a -mfloat-abi=softfp -mfpu=neon -O3 -ffast-math -funroll-loops
LOCAL_WHOLE_STATIC_LIBRARIES := libavformat_static \
libavcodec_static \
libavutil_static \
libpostproc_static \
libswscale_static \
libswresample_static \
libx264_static \
libavfilter_static \
libavdevice_static \
include $(BUILD_SHARED_LIBRARY)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
4.3 解码程序
Native程序一般分为两块: (1)JNI调用接口
/* * Class: com_example_jnidemo_MainActivity * Method: info * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_com_example_jnidemo_MainActivity_info (JNIEnv *, jobject, jstring);1
2
3
4
5
6
7
1
2
3
4
5
6
7
(2)功能模块
略
详细代码如下:
#include <jni.h> #include <android/log.h> #include <stdio.h> #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavformat/avio.h> #include <libavutil/fifo.h> #include <libavutil/avutil.h> #include <libavutil/mem.h> #include <libswscale/swscale.h> #include "com_example_jnidemo_MainActivity.h" #define LOG_TAG "FFMPEG INFO" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) { FILE* pFile; char szFileName[32]; int y; sprintf(szFileName,"/mnt/sdcard/test/frame%d.ppm",iFrame); LOGI("filename : %s",szFileName); pFile = fopen(szFileName,"w"); if(pFile == NULL){ LOGI("can not open file %s",szFileName); return ; } fprintf(pFile,"P6\n%d %d\n255\n",width,height); for(y=0;y<width;++y){ LOGI("Write file AVFrame"); fwrite(pFrame->data[0]+y*pFrame->linesize[0],1,width*3,pFile); } fclose(pFile); LOGI("close file %s",szFileName); } JNIEXPORT void JNICALL Java_com_example_jnidemo_MainActivity_info(JNIEnv *env, jobject obj, jstring jpath){ const jbyte* path = (*env)->GetStringUTFChars(env,jpath,NULL); AVFormatContext *pFormatCtx = NULL; int i, videoStream; AVCodecContext *pCodecCtxOrig = NULL; AVCodecContext *pCodecCtx = NULL; AVCodec *pCodec = NULL; AVFrame *pFrame = NULL; AVFrame *pFrameRGB = NULL; AVPacket packet; int frameFinished; int numBytes; uint8_t *buffer = NULL; struct SwsContext *sws_ctx = NULL; av_register_all(); // if(avformat_open_input(&pFormatCtx, path, NULL, NULL)!=0) // { // LOGE("Could not open the file : %s",path); // return ; // } int err_code; if(err_code=avformat_open_input(&pFormatCtx, path, NULL, NULL)) { char buf[256]; av_strerror(err_code, buf, 1024); LOGE("Couldn't open file %s: %d(%s)", path, err_code, buf); return; } if(avformat_find_stream_info(pFormatCtx, NULL)<0) return ; av_dump_format(pFormatCtx, 0, path, 0); videoStream=-1; for(i=0; i<pFormatCtx->nb_streams; i++) if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { videoStream=i; break; } if(videoStream==-1) return ; pCodecCtxOrig=pFormatCtx->streams[videoStream]->codec; pCodec=avcodec_find_decoder(pCodecCtxOrig->codec_id); if(pCodec==NULL) { LOGE("Unsupported codec!\n"); return ; } pCodecCtx = avcodec_alloc_context3(pCodec); if(avcodec_copy_context(pCodecCtx, pCodecCtxOrig) != 0) { LOGE("Couldn't copy codec context"); return ; } if(avcodec_open2(pCodecCtx, pCodec, NULL)<0) return ; pFrame=av_frame_alloc(); pFrameRGB=av_frame_alloc(); if(pFrameRGB==NULL) return ; numBytes=avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height); buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); avpicture_fill((AVPicture *)pFrameRGB, buffer, AV_PIX_FMT_RGB24,pCodecCtx->width, pCodecCtx->height); sws_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24, SWS_BILINEAR, NULL, NULL, NULL ); i=0; while(av_read_frame(pFormatCtx, &packet)>=0) { if(packet.stream_index==videoStream) { avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); if(frameFinished) { sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize); if(++i<=5) SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i); } } av_free_packet(&packet); } av_free(buffer); av_frame_free(&pFrameRGB); av_frame_free(&pFrame); avcodec_close(pCodecCtx); avcodec_close(pCodecCtxOrig); avformat_close_input(&pFormatCtx); (*env)->ReleaseStringUTFChars(env,jpath,path); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
4.4 编译native程序
进入jni目录,执行:$NDK_PATH/ndk-build1
1
编译结果:
编译完成后,在lib目录下可以看到编译的so文件,在Android.mk中设置的库文件名为ffmpeg,那么编译的文件应该是”libffmpeg.so”
4.5 JAVA调用JNI
(1)加载库文件static { System.loadLibrary("ffmpeg"); }1
2
3
1
2
3
(2)JNI接口
所有的JNI接口都有native关键字
private native void info(String path);1
1
(3)详细代码
package com.example.jnidemo; import android.app.Activity; import android.os.Bundle; import android.os.Environment; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String path = "/sdcard/test/test.mp4"; info(path); } private native void info(String path); static { System.loadLibrary("ffmpeg"); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
相关文章推荐
- 编译Android下可用的FFmpeg+x264
- qt for android从编译ffmpeg x264 aac 到在qtcreator上使用
- Ubuntu下用NDK编译移植FFmpeg 2.0(配置最新版x264)到Android平台
- [置顶] FFmpeg学习—Android 编译x264 库
- Ubuntu 下用NDK编译移植 ffmpeg 2.0 (配置最新版x264) 到android平台
- android ndk编译x264开源(用于android的ffmpeg中进行软编码)
- Android 编译FFmpeg x264
- <android编译ffmpeg+x264+faac> <Android/NDK环境下FFmpeg及AAC,MP3,X264的编译>
- 编译Android下可用的FFmpeg+x264
- Android/NDK环境下FFmpeg及AAC,MP3,X264的编译
- 在CentOS中编译FFmpeg for Android静态库(含fdk aac,x264)
- 在CentOS中编译FFmpeg for Android静态库(含fdk aac,x264)
- [置顶] FFmpeg学习—android 编译 ffmpeg 集成fdk-aac、x264 精简解码库
- ffmpeg支持x264的android平台编译
- Ubuntu 下用NDK编译移植 FFmpeg 2.0 (配置最新版x264) 到Android平台
- android ndk编译x264开源(用于android的ffmpeg中进行软编码)
- Ubuntu 下用NDK编译移植 ffmpeg 2.0 (配置最新版x264) 到android平台
- 编译用于Android的FFmpeg&x264
- android 下编译x264 以及ffmpeg
- Android 编译FFmpeg x264