两个回调函数:
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
——————————————————————————————————
傲轩游戏网
傲轩游戏网