You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
backend/src/main/java/com/netsdk/lib/callback/impl/DefaultVideoStatHeatMapCall...

167 lines
6.0 KiB
Java

package com.netsdk.lib.callback.impl;
import com.netsdk.lib.NetSDKLib;
import com.netsdk.lib.callback.BasicVideoStatHeatMapCallBack;
import com.netsdk.lib.callback.fVideoStatHeatMapCallBack;
import com.netsdk.lib.enumeration.EM_HEATMAP_TYPE;
import com.netsdk.module.HeatMapModule;
import com.netsdk.module.entity.HeatMapData;
import com.netsdk.module.entity.HeatMapGrayData;
import com.sun.jna.Pointer;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author 47081
* @version 1.0
* @description , , sdk
* @date 2020/9/24
*/
public class DefaultVideoStatHeatMapCallBack extends BasicVideoStatHeatMapCallBack {
private HeatMapModule module;
/** 由于热度图数据是分多次发送,需要判断数据接收完整再处理 */
private ConcurrentHashMap<Integer, HeatMapData> binDatas;
/** 用于外部获取灰度图数据 */
public static ConcurrentHashMap<Integer, HeatMapGrayData> grayDatas =
new ConcurrentHashMap<Integer, HeatMapGrayData>();
private static DefaultVideoStatHeatMapCallBack instance;
private DefaultVideoStatHeatMapCallBack() {
this.module = new HeatMapModule();
this.binDatas = new ConcurrentHashMap<Integer, HeatMapData>();
}
public static fVideoStatHeatMapCallBack getInstance() {
if (instance == null) {
instance = new DefaultVideoStatHeatMapCallBack();
}
return instance;
}
/**
*
*
* @param attachHandle
* @param nToken ,{@link
* com.netsdk.lib.NetSDKLib#CLIENT_GetVideoStatHeatMap(NetSDKLib.LLong, Pointer, Pointer,
* int)} nToken{@link com.netsdk.lib.structure.NET_OUT_GET_VIDEOSTAT_HEATMAP#nToken}
* @param type
* @param binData
*/
@Override
public void parseData(long attachHandle, int nToken, EM_HEATMAP_TYPE type, byte[] binData) {
System.out.println(
"receive heatmap data. attachHandle:"
+ attachHandle
+ ",nToken:"
+ nToken
+ ",type:"
+ type.getType()
+ ","
+ type.getDesc()
+ " data length:"
+ binData.length);
// 协议描述:每个getHeatMap请求的结果分多个包来发送每个包的大小在 “4~7此次数据总长度”中描述每个包的 “8~11
// 总行数总轨迹条数”相同每个包的“12~15本次行数本次轨迹条数”表示本包的数据数量最后一个包的“12~15本次行数本次轨迹条数”值为0表示数据发送完毕。
// 当总行数或者总轨迹条数和本次行数或者本次轨迹条数都为0时表示没有数据。
// 当总行数或者总轨迹条数不为0而本次行数或者本次轨迹条数为0时表示数据已经传完
// 对binData进行过滤
byte[] temp = new byte[4];
System.arraycopy(binData, 7, temp, 0, 4);
// 总行数
int totalLine = byte2Int(temp);
System.arraycopy(binData, 11, temp, 0, 4);
// 本次行数
int currentLine = byte2Int(temp);
if (totalLine == 0 && currentLine == 0) {
System.out.println("token:" + nToken + ",本次没有数据");
return;
}
// 总行数和本次行数都不为0时,说明数据有效
if (totalLine != 0 && currentLine != 0) {
HeatMapData heatMapData = binDatas.get(nToken);
// 获取宽高,宽16-17位,高18-19位
int width = ((binData[16] & 0xFF)) | ((binData[17] & 0xFF) << 8);
int height = ((binData[18] & 0xFF)) | ((binData[19] & 0xFF) << 8);
if (heatMapData == null) {
heatMapData = new HeatMapData(width, height, binData);
} else {
/** 目前设备端处理是一个完整数据包和一个结束包,以下代码基本不会被执行到, 先按协议进行多包数据拼接处理 */
// 获取已保存数据的数据行数
System.arraycopy(heatMapData.getData(), 11, temp, 0, 4);
int savedLine = byte2Int(temp);
// 合并后的本次行数
int currentTotal = savedLine + currentLine;
byte[] bytes = int2ByteArr(currentTotal);
System.arraycopy(bytes, 0, heatMapData.getData(), 11, bytes.length);
// 去掉数据头,数据头为32位
byte[] data = new byte[binData.length - 32];
System.arraycopy(binData, 32, data, 0, data.length);
// 追加到完整数据包中
heatMapData.addData(data);
}
// 将数据存到map中
binDatas.put(nToken, heatMapData);
}
// 数据接收完成
if (totalLine != 0 && currentLine == 0) {
// 将数据取出
HeatMapData heatMapData = binDatas.get(nToken);
if (heatMapData != null) {
System.out.println(
"width:"
+ heatMapData.getWidth()
+ ",height:"
+ heatMapData.getHeight()
+ ",data length:"
+ heatMapData.getData().length);
// 热度图数据转灰度图
byte[] grayData =
module.transferGray(
heatMapData.getData(), heatMapData.getWidth(), heatMapData.getHeight());
// 销毁binData数据
binDatas.remove(nToken);
// 保存灰度图数据
grayDatas.put(
nToken, new HeatMapGrayData(heatMapData.getWidth(), heatMapData.getHeight(), grayData));
}
}
}
/**
* byte[4]int
*
* @param src
* @return
*/
private int byte2Int(byte[] src) {
int value;
value =
(int)
((src[0] & 0xFF)
| ((src[1] & 0xFF) << 8)
| ((src[2] & 0xFF) << 16)
| ((src[3] & 0xFF) << 24));
return value;
}
/**
* intbyte[],4
*
* @param value
* @return
*/
private byte[] int2ByteArr(int value) {
byte[] bytes = new byte[4];
bytes[3] = (byte) (value >> 24);
bytes[2] = (byte) (value >> 16);
bytes[1] = (byte) (value >> 8);
bytes[0] = (byte) (value);
return bytes;
}
}