Java利用JNI呼叫FFMpeg對h264碼流進行解碼
前期配置工作:
使用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,即呼叫成功.