兩個回調函數:
FRealDataCallBack 實現預覽回調數據
DecCallBack 解碼回調函數
在HCNetSDK.java補充相關函數和結構聲明
//播放庫函數聲明,PlayCtrl.dll interface PlayCtrl extends StdCallLibrary { PlayCtrl INSTANCE = (PlayCtrl) Native.loadLibrary("lib\\PlayCtrl", PlayCtrl.class); public static final int STREAME_REALTIME = 0; public static final int STREAME_FILE = 1; // 20140501, cuizhenfu@gmail.com, frame type public static final int T_AUDIO16 = 101; public static final int T_AUDIO8 = 100; public static final int T_UYVY = 1; public static final int T_YV12 = 3; public static final int T_RGB32 = 7; boolean PlayM4_GetPort(NativeLongByReference nPort); boolean PlayM4_OpenStream(NativeLong nPort, ByteByReference pFileHeadBuf, int nSize, int nBufPoolSize); boolean PlayM4_InputData(NativeLong nPort, ByteByReference pBuf, int nSize); boolean PlayM4_CloseStream(NativeLong nPort); boolean PlayM4_SetStreamOpenMode(NativeLong nPort, int nMode); boolean PlayM4_Play(NativeLong nPort, HWND hWnd); boolean PlayM4_Stop(NativeLong nPort); boolean PlayM4_SetSecretKey(NativeLong nPort, NativeLong lKeyType, String pSecretKey, NativeLong lKeyLen); // 20140501, cuizhenfu@gmail.com boolean PlayM4_SetDecCallBack(NativeLong nPort, DecCallBack decCallBack); boolean PlayM4_SetDecCallBackEx(NativeLong nPort, DecCallBack decCallBack, String pDest, NativeLong nDestSize); public static interface DecCallBack extends StdCallCallback { public void invoke(NativeLong nPort, ByteByReference pBuffer, NativeLong nSize, FRAME_INFO frameInfo, NativeLong nReserved1, NativeLong nReserved2); } public static class FRAME_INFO extends Structure { public NativeLong nWidth; /* 畫面寬,單位像素。如果是音頻數據,則為音頻聲道數 */ public NativeLong nHeight; /* 畫面高,單位像素。如果是音頻數據,則為樣位率 */ public NativeLong nStamp; /* 時標信息,單位毫秒 */ public NativeLong nType; /* 數據類型,T_AUDIO16, T_RGB32, T_YV12 */ public NativeLong nFrameRate; /* 編碼時產生的圖像幀率,如果是音頻數據則為采樣率 */ public int dwFrameNum; /* 幀號 */ } }
解碼顯示和解碼不顯示可在下面段代碼切換
// //設置解碼回調函數 只解碼不顯示 // if (!playControl.PlayM4_SetDecCallBack(m_lPort.getValue(), decCallBack)) // { // break; // } // 設置解碼回調函數 解碼且顯示 if (!playControl.PlayM4_SetDecCallBackEx(m_lPort.getValue(), decCallBack, null, null)) { break; }
如果不顯示的話,則不需要窗口句柄,這句可以去掉
W32API.HWND hwnd = new W32API.HWND(Native.getComponentPointer(panelRealplay));
然后再播放的時候第二個參數傳null
if (!playControl.PlayM4_Play(m_lPort.getValue(), null)) //播放開始 { break; }
這樣就可以做到只解碼,不顯示。
——————————————————————————————————————————————————
這樣在回調函數DecCallBack 中可以得到視音頻數據,其中視頻數據是YV12格式的,音頻數據是PCM格式的。
將YV12視頻數據保存到本地磁盤
DataOutputStream d; try { d = new DataOutputStream(new FileOutputStream("c:/yv12", true)); d.write(yv12); d.flush(); d.close(); } catch (FileNotFoundException ex) { Logger.getLogger(ClientDemo.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(ClientDemo.class.getName()).log(Level.SEVERE, null, ex); }
可用yuviwer程序查看c:/yv12文件數據。
參考了海康SDK——》Demo示例——》MFC分功能示例——》2- 實時流回調解碼獲取YUV,主要是DecCallBack_DemoDlg.cpp文件。
——————————————————————————————————————————————————
調用JavaCV對海康h.264視頻流解碼還沒有成功。
大概忘說了如何設置取子碼流
m_strClientInfo = new HCNetSDK.NET_DVR_CLIENTINFO(); m_strClientInfo.lChannel = new NativeLong(iChannelNum); m_strClientInfo.lLinkMode = new NativeLong(0x80000000); // 子碼流TCP連接
- lLinkMode
-
最高位(31)為0表示主碼流,為1表示子碼流;0~30位表示連接方式:0-TCP方式,1-UDP方式,2-多播方式
例如子碼流TCP連接,則lLinkMode=0x80000000
