|
Tange Cloud for Device
Rev.362 |
反馈问题时描述清楚操作条件、现象,并提供level为6的设备日志
日志的默认等级是3。要调整日志等级,在程序开始时调用 TciSetLogLevel():
在Linux系统下,也可以在启动应用前设置环境变量:
默认会生成的SDK日志文件位于 /tmp/icam365.log,大小为512K。日志文件是滚动覆写,应该放到 tmpfs文件系统里。
可以调用 TciSetLogOption() 修改日志文件位置和大小。
建议固件实现成从TF卡上读取标志,根据标志对调试配置、日志文件位置等做修改。
每一款固件程序都要有一个全平台唯一标识firmware_id(不同型号设备可以有相同固件)。该固件标识用于设备**ota升级**和**厂测工具**对设备分类。
固件标识通过 TciCB::get_info() 回调在 TCIDEVICEINFO::firmware_id 中返回。
firmware_id按 "厂家-产品类型-硬件平台-设计者内部定义描述" 的规则定义,以避免不同厂家的间命名冲突。
固件版本firmware_ver 是一个8个数字组成的字符串。ota前会用于判断平台端的版本是否更新。
移步 配网和绑定设备
事件截图用于app端的事件列表展示,和AI服务器端的对象识别,取标清分辨率。
设备和客户端播放和回放时都使用时间戳来对音视频作同步。这个值一定要保证正确。时间戳不匹配会造成实时或回放的音视频不对上,音频时间戳不正确则可能会造成播放时被插入空白,听起来有噪声。
时间戳用 uint32_t 表示,单位是 ms。硬件平台底层输出时间戳一般需要转换。
有的平台输出的时间戳在音视频间并不匹配,或者在重启流后二者会失配,固件必须对此作处理。
除了视频中的叠加的OSD 时间,APP可能还会在界面其它地方显示当前正在播放的画面所对应的时间(例如滚动时间轴)。这个时间需要额外的方式去同步。参见 a40_TimeSyncWhenPlayback,和 TciSendPbSyncFrame() 的说明。
在实时和录像回放中,系统只支持g711a编码格式。采样格式为 8000/16位/mono
底层输出的音频包格式大小要合理。太大意味着在设备端就引入声音延迟(大包分多次发送没意义),太小则效率降低。
推荐每个音频包大小为 40ms ,亦即编码后的包大小为 320字节。App端做回声消除可能对包大小有为80倍数的要求。
因为音频包大小是固定的,只要硬件不停止采样,相邻包的**时间戳的差是一个固定值**。固件要确保这一点。
设备需要同时输出两个视频流,分别以0和1作为第二个参数(stream)调用 TciSendFrameEx()。
App端选择高清和标清时分别访问的是stream0和1。如果固件没有传递相应流,app看不到图像
同时支持的最大连接数为5。如果系统内存紧张,可以在 TciStart()前调用 TciSetMaxP2pClientsNum() 将这最大连接数设小一点。
因为底层实现上的差异,实际能节省的内存占用以系统运行起来后用 free 命令观察到的结果为准
用户扩展指令范围在 0x9000 ~ 0xfffe。因为指令的最低位用作应答标志,所以指令本身应是一个偶数(设备端调用 TciSendCmdResp()/TciSendCmdRespStatus() 时会对指令的最低位自动置1)
在 set_timezone() 回调里收到的时区是形如 "GMT+08:00" 的字符串。GMT后面的带符号数值表示 在标准时间上加上这个值得到当地时间。“GMT+08:00”表示东八区,"GMT-08:00"则表示西八区。
在Linux下,TZ 环境变量的这个符号的意义刚好与上相反:带符号的数值表示本地时间加上这个值得到 可得到标准时间。"GMT-08:00"表示东八区,"GMT+08:00"表示西八区。也就是说设置到Linux下时,+/- 要反一下。
非(类)Linux的设备例如RTOS系统,要按前述解释计算一个偏移,手动在UTC时间和本地时间之间作转换。
如果系统内存紧张,可以从以下方面配置SDK减少内存使用。
设置较小的云存预录缓冲
TciStart(is_registered, uCloudBuffSize) 第二个参数为事件云存预录缓冲大小。发生事件录像时,SDK从缓冲区向后查找3 ~ 5s 前的I帧(如果没有的话取最近的I帧)作为录像起始点。要预录这个缓存至少要能保存两个I帧之间的所有音视频数据。
如果内存实在紧张,可以取消预录功能,把这个值设得很小(比最大的I帧大一点)
强制限制云存文件大小
TciSetSysOption()`"TciSetSysOption(TCOPT_MAX_DATAFILE_SIZE, ...)"`。 这会在文件过大时丢包
设置较小的上传队列
调用 TciSetBackStore(NULL, BUFFERHINT_SMALL), 可以将待上传的云存文件队列设为1,减少因网络不好占用的缓存
减少支持的p2p连接数
调用 TciSetMaxP2pClientsNum(), 减少支持的最大连接数。最大连接数默认为5。节省的内存以实测为准。
SD卡录像与云存共享缓存
参看文档与 TgCloudApi_mufb.h 头文件里的说明
4G+有线 设备,要通过 TciReport4GInfo() 上报当前连网方式是4G还是有线。
TciGetWakeupServers() 返回心跳服务器的 IPv4 地址数组。注意这个地址和端口都是网络字节序的,直接赋值给 struct sockaddr_in 的 sin_addr.s_addr 和 sin_port,不要再转序了。STATUS_IDLE来下电。云录像上传、查看实时、SD卡回放、停在修改设备配置界面,这些都不应断电。设备端可以设一个最大上电工作时长,以在异常的时候下电事件云录像的初始时长T由平台配置。如果有预录(TciStart()配置的云存缓冲足够大), 录像从前5"内的第一个I帧开始,从那之后的T秒结束。如果事件在录像结束前再次触发, 录像在事件触发时间之后T秒结束。
同一种事件上报到平台的间隔最小30"。间隔小于30"的事件,如果当前没有云录像被会完全忽略; 如果正在云录像,会延长事件录像的时间,但不会出现在事件回看列表,也不会通知到App。
云录像文件默认在内存里缓存,网络不好的时候,云上传会丢文件。可以开启sdk内置的后备存储功能(TciSetBackStore()), 传不动的文件会写到后备存储空间(通常是TF卡)在网络恢复的时候自动上传
TciStart() 和 TciConfigWifi(GWM_AP)。STATUS_LOGON 前没有收到 set_wifi()回调,表示有了有线添加方式,固件调用 TciStopConfigWifi(GWM_AP) 停止配网。set_wifi() 回调,表示走wifi添加。切换到wifi后,调用 TcnIpChanged() 通知sdk IP配置改变。TciStart()返回后,调用 TciReport4GInfoEx() 上报当前连网方式。如果用wifi联网,调用 TciReport4GInfoEx(NULL, -1)如果要支持云存功能,就需要一直发。 呼叫类应用(门口机/室内机)如果不支持云存,需要
request_iframe_ex()回调时启动编码发送。固件可以在 TciCB::on_status() 回调里处理 STATUS_TRANSFER_MONITOR 状态。该回调实时反馈发送缓冲区占比(Linux/Adroind系统的发送缓冲大小为512KB)。固件可以监视这个值的变化调整对应流的 bitrate。
如果要切换码流(例如从高分辨率切到低辨率或相反),需要在用户知情的情况下做切换。实现的前提:
auto然后固件在 STATUS_TRANSFER_MONITOR 状态回调里返回不同值来指示SDK切换流:
丢帧时才切换可能会有很大滞后,因为在网络不畅的情况下排空发送缓冲区中的高清数据可能就要花不少时间, 然后才轮到发送新的标清视频
另外一种可能的在App端实现的码流调整方式是: 监控帧到达的速度。如果连续数秒内的帧实际到达的时间大于帧的时间戳之差,则App主动切换码流。