您的位置:首页 > 编程语言 > Java开发

Java利用JNI调用FFMpeg对h264码流进行解码

2016-08-21 14:23 981 查看
前期配置工作:

在Visual Studio端配置FFMpeg

在Visual Studio端配置OpenCV

解码部分主要源代码及说明

解码部分vs工程下载地址

使用JNI调用:

java端:

package com.recon.action;
public class Decode {

public native String loadfile(String s);
//传递字符串告知c++工程所要打开的h264文件
static
{
//Ffmpeg_Decode为之后c++所生成的动态库
}
public static void main(String[] args)
{
Decode d=new Decode();
String input = d.loadfile("C:\\Users\\xxx\\Desktop\\myData.h264");
/*此处为h264文件放置位置 */
System.out.println(input); //若调用成功则返回字符串
}
}


打开命令提示符 (
Win+R
输入cmd后回车)

到工程的.java文件的目录下 输入
javac Decode.java
生成
Decoe.class
文件

退回工程的src目录 输入
javah
命令和包名加类文件名字生成.h文件。(在我的工程中生成为
com_recon_action_Decode.h
文件)

(例如:输入
javah com.recon.action.Decode
) (必须是完整包名且不需要加后缀)

生成的头文件如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_recon_action_Decode */

#ifndef _Included_com_recon_action_Decode
#define _Included_com_recon_action_Decode
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_recon_action_Decode
* Method: loadfile
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_recon_action_Decode_loadfile
(JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif


该头文件所用到的jni.h文件在本机电脑所安装的jdk的include目录下即可找到(注意:jni.h文件还需要调用一个jni_md.h文件,该文件在同一include目录下的win32目录内可找到)

在工程中添加完以上三个头文件后,需要在第一个头文件(即使用java生成的那个)中将
#include <jni.h>
改为
#include "jni.h"


C++端:

将刚才在第三个链接中所下载的工程打开.

右键工程属性,将其配置类型从应用程序改为dll动态库文件.

按照第一个链接配置FFMpeg环境,第二个链接配置OpenCV.

配置完成之后,将
Ffmpeg_Decode_Main.cpp
文件稍作如下改动即可.

#include "Ffmpeg_Decode.h"
#include "com_recon_action_Decode.h"

JNIEXPORT jstring JNICALL Java_com_recon_action_Decode_loadfile(JNIEnv *env, jobject obj, jstring s)
//void main()
{
const char* stri;
stri = env->GetStringUTFChars(s,false);

if(stri == NULL) {
return NULL;//内存错误已抛出
}
int i = 0;
Ffmpeg_Decorder ffmpegobj;
ffmpegobj.Ffmpeg_Decorder_Init();//初始化解码器
File *pf = NULL;
//fopen_s(&pf, "myData.h264","rb");
fopen_s(&pf,stri,"rb");


(注释部分为未改动的代码)

(i变量为之后存储图片所要使用到的变量)

在文件末尾添加如下代码返回成功值.

env->ReleaseStringUTFChars(s,stri);
char* tmpstr = "load file succeeded";
jstring rtstr = env->NewStringUTF(tmpstr);
return rtstr;


由于我的工程要求需要将h264码流解码并且将视频按帧存储为图片,于是我在
Ffmpeg_Decode.cpp中cvShowImage("解码图像", img);
语句之后加入了如下代码:

char path[] = "F://pictures//";//为图片存储路径
char *file = ".jpg";//图片存储格式
char str[256];
_ltoa(i, str, 10);//整型与字符串转化
strcat(path, str);
strcat(path, file);
cvSaveImage(path, img);//opencv中自带的存储图片函数


(要在头文件的函数声明以及前面的函数调用中添加i变量的声明)

右键项目生成,在工程的Debug目录下可看到所生成的dll文件.将dll文件所在的目录(例如C:\Ffmpeg_Decode\Debug)添加到环境变量Path中(右键我的电脑–>属性–>高级系统设置–>环境变量–>系统变量)

重启eclipse(否则无法识别到路径),运行Decode,即调用成功.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息