海康sdk部署Linux环境下无法播放子码流的问题

海康sdk部署Linux环境下无法播放子码流的问题

    • 问题描述
    • 解决方法

码云(Gitee)地址:https://gitee.com/banmajio/HCSDKtoRTMP
github地址:https://github.com/banmajio/HCSDKtoRTMP
个人博客:banmajio’s blog

海康sdk二次开发系列文章
海康sdk捕获码流数据通过JavaCV推成rtmp流的实现思路(PS流转封装RTMP)
海康sdk进行历史回放时,码流数据回调过快问题的解决方法
海康sdk项目(java)部署Linux环境相关问题总结
海康sdk部署Linux环境下无法播放子码流的问题
海康sdk项目部署Linux系统时出现java.lang.UnstisfiedLinkError:jnidispatch(xxx)not found in resource path错误

问题描述

windows环境下开发的Java程序打包部署到Linux环境下,发现通过NET_DVR_RealPlay_V40接口的第二个结构NET_DVR_PREVIEWINFO(预览参数结构体的)的dwStreamType字段控制码流类型时,无论传入的值为0(主码流)还是1(子码流),在Linux环境下,播放出来的视频都是主码流的。而在windows环境下dwStreamType为0,播放的是主码流,为1播放子码流。

通过参考海康技术发来的demo发现,demo里的HCNetSDK.java文件中的NET_DVR_PREVIEWINFO这个结构体的lChannel字段使用的是 int类型的,而从海康官网获取到的各个版本的sdk中HCNetSDK.java文件中的lChannel字段都是 “NativeLong” 类型的。

尝试将lChannel字段的类型改为 “int” 后编译打成jar包部署到Linux后,发现终于可以播放出子码流了。询问海康技术支持造成这个问题的原因得知:

SDK结构体传参,每个字段顺序、所占字节大小是严格规定的,需要和动态库匹配。
C++中该字段定义为DWORD类型,占4个字节,在windows下,NativeLong和int类型都占用4个字节,所以没有关系。
而linux64环境下,NativeLong占8个字节,而int类型占4个字节,如果定义成NativeLong的话,就会导致结构体偏移,原本您设置码流主次类型的位置,传递到别的参数中了,所以一直获取的主码流。所以建议您这边,Linux64下对接的话,所有NativeLong定义修改成int类型。

淦!!! 这TM普通人哪里会想到这边会出问题,最离谱的是官网下载的sdk所有版本的HCNetSDK.java文件中都用的 “NativeLong” 类型,给我发的demo中才使用的是 “int” ,文档中也没有说明,官网sdk也没有严谨的更新,属实坑人。

解决方法

将HCNetSDK.java文件的lChannel字段类型由NativeLong改为int。

public static class NET_DVR_PREVIEWINFO extends Structure {
		public int lChannel;
		public int dwStreamType;
		public int dwLinkMode;
		public HWND hPlayWnd;
		public boolean bBlocked;
		public boolean bPassbackRecord;
		public byte byPreviewMode;
		public byte[] byStreamID = new byte[STREAM_ID_LEN];
		public byte byProtoType;
		public byte[] byRes1 = new byte[2];
		public int dwDisplayBufNum;
		public byte[] byRes = new byte[216];
	}

根据海康技术支持的说法,在与Linux对接时将最好将NativeLong都改为int,但是项目中目前其他的功能没有影响就保持原样没有改,遇到相关问题的朋友们可以尝试改一下看看会不会解决问题。

你可能感兴趣的:(海康sdk二次开发,流媒体技术)