GB28181 AI视频数据库以及SDP协议
Posted qianbo_insist
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GB28181 AI视频数据库以及SDP协议相关的知识,希望对你有一定的参考价值。
目的
搜索监控视频中的目标对象。为了快速搜索,打造数据库,记录预搜索目标,快速搜索。目前还在制作过程中,还不成熟,随时设计修改,望关注之人一同打造视频数据库。
SDP协议
SDP 协议里面有关于如何建立连接通道,采用何种编码格式,使用哪些RTP扩展,SDP(Session Description Protocol)就是这样一种会话描述协议。IETF RFC2327中定义了SDP标准,并随后在2006年7月出版的新的修订规范RFC4566作为RFC2327的更新。当前SDP被广泛用于SAP, RTSP, SIP等多媒体通讯协议中,包括webrtc也是以RFC4566(SDP)为基本蓝本,然后配合RFC3264关于offer/answer交互模式来进行媒体协商。我们在制作数据库的过程中,将会使用SDP协议存储AI信息,有人问sdp协议可以用来存储AI标注信息?当然可以。
制作视频数据库
目的是为了存储视频的备份,从gb28181 那里读取回放数据后备份并且做标识。
//前缀8字节
// 4 字节总索引个数
// 4 字节已存储索引个数
//索引内容
// 4字节sequence num 或者timestamp 4字节偏移量
//文件内容
// 4字节内容长度, 内容不定长,包含2 字节预先识别内容,2字节预先识别内容SDP会话,内容不定长
由于视频内容一般不需要删除,并且顺序读写,先写后读,极大加快了视频数据库的制作。数据库主要是为了写存储视频的基本数据,其基本流程为读取文件预识别人脸和车,车牌以及基本物体。
1 读取视频直播或者回放
使用gb28181 来直接获取标准直播视频和回放视频,sip协议本身包含ssrc 音视频等标准协议内容,对于rtp协议里比较重要的是记录时间戳。
读取方式:
对于已经存储到数据库中的文件内容,我们使用文件映射读取,易于并发,对于需要需要存储到数据库中的内容,我们使用普通的FILE API 函数写入,当然也有FILE API的读取。以下是文件映射的示例,在windows下和linux下用宏分开。
#include <stdio.h>
#include <stdint.h>
#ifdef _WIN32
#include <Windows.h>
class cmem_map
HANDLE hFile = NULL;
OFSTRUCT opBuf;
HANDLE hMapfile = NULL;
HANDLE hMapview = NULL;
long offset = 0;
public:
cmem_map()
~cmem_map()
bool IsOpen()
return (hMapview != NULL);
bool IsClosed()
return (hMapfile == NULL);
int Open(const wchar_t * memfile_add, int fsize)
hFile = ::CreateFile(memfile_add, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == 0)
printf("open file failed!\\n");
return -1;
//2.为指定文件创建一个有名的文件映象
hMapfile = CreateFileMapping((HANDLE)hFile, NULL, PAGE_READWRITE, 0, fsize, L"MapTest");
if (hMapfile == NULL)
printf("mapping file failed!\\n");
return -1;
//关闭文件句柄
CloseHandle((HANDLE)hFile);
hFile = 0;
hMapview = MapViewOfFile(hMapfile, FILE_MAP_WRITE, 0, 0, 0);
if (hMapview == NULL)
printf("mapping view failed!\\n");
return -1;
return 0;
void Close()
UnmapViewOfFile(hMapview);
//关闭文件映象句柄
CloseHandle(hMapfile);
hMapfile = 0;
long GetSize()
return offset;
int Write(uint8_t * data, int size)
char *recv = (char *)hMapview;
recv += offset;
memcpy(recv, data, size);
offset += size;
//把文件映射视图中的修改的内容或全部写回到磁盘文件中
FlushViewOfFile(recv, size);
return offset;
//return 0;
;
#endif
#ifndef _WIN32
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
cmem_map::cmem_map() : m_pData(0), m_uSize(0), m_nFile(0)
cmem_map::~cmem_map()
UnMap();
bool cmem_map::Map(const char* szFileName)
UnMap();
m_nFile = open(szFileName, O_RDONLY);
if (m_nFile < 0)
m_nFile = 0;
return false;
struct stat status;
fstat(m_nFile, &status);
m_uSize = status.st_size;
m_pData = mmap(0, m_uSize, PROT_READ, MAP_SHARED, m_nFile, 0);
if (MAP_FAILED != m_pData) return true;
close(m_nFile);
m_pData = NULL;
m_nFile = 0;
m_uSize = 0;
return false;
void cmem_map::UnMap()
if (m_pData)
munmap(m_pData, m_uSize);
m_pData = NULL;
if (m_nFile)
close(m_nFile);
m_nFile = 0;
m_uSize = 0;
#endif // !WIN32
#endif
2 识别人脸位置和车位置
数据量巨大设计并发和并行,多个处理器一起执行,这里强调一下GPU,GPU支持多个执行引擎,这里要多利用GPU的并发,对于回放和实时播放,既然是预先处理,就不能做太过重的工作,对于人脸,只做人脸的探测,对于车辆,只识别车牌的位置,等等。除此之外,预先处理还可以识别文件全局性相关特征并且分割,记录。
3 记录
记录在sdp协议里面记录。
4 用户输入需要识别的具体内容
包含图像识别,语义分割,人脸和车牌识别。记录在sdp协议里面,其他视频的sdp本身存在,不过扩展标注是增加出来的,语义为:
AI:
数据结构和文件系统api函数
这里是第一层文件系统api,并非我们的外层AI 识别api
typedef struct sdata
uint32_t index;
char vardata[128];
sdata;
typedef struct sdata_index
uint32_t index;
uint32_t offset;
sdata_index* next;
sdata_index;
typedef struct db_context
uint32_t v_tindex = 0;
uint32_t v_nindex = 0;
uint32_t v_timestart = 0;
uint32_t v_timeend = 0;
//file bytes index total 总索引加头部字节
uint32_t v_index_bytes = 0;
char v_tablename[256];
FILE* fp = NULL;
sdata_index* v_index = NULL;
int v_exists = 0;
uint8_t* v_data = NULL;
int v_datalen = 0;
//user 自定义context
void* v_user_context = NULL;
~db_context()
if (v_data != NULL)
free(v_data);
if (fp != NULL)
fclose(fp);
//index map table
std::map<uint32_t, uint32_t> v_index_maps;
//index vector table
std::vector<uint32_t> v_index_vector;
db_context;
int Insert(void *data,db_context *v_context);
int Delete(void *key, db_context *v_context);
int Update(void *key, void *data, db_context *v_context);
void *Select(void *key, db_context *v_context);
API 初始化
int Initialize(const char *tname, db_context *context)
if (context == NULL)
return -1;
strcpy(context->v_tablename,tname);
if (context->v_index == NULL)
context->v_index = bfile_read_index(
tname, /*filename*/
context->v_tindex,
context->v_nindex
);
if (context->v_index == NULL)
return -1;
return 0;
如果文件已经存在,我们必须在内存中构建一个hash 搜索
增加记录,数据是h264或者h265 等等,我们将会给该数据增加AB协议
int Insert(void *data, db_context *context)
if (context->v_nindex < context->v_tindex)
FILE * fp = fopen(context->v_tablename, "wb");
if (fp == NULL)
return -1;
fpos_t pos = (fpos_t)(4 + 4 + (context->v_nindex) * (8));
fsetpos(fp, &pos);
//int last_index = context->v_nindex - 1;
uint32_t indexlast = context->v_index[context->v_nindex - 1].index ;
uint32_t indexinsert = indexlast + 1;
size_t n = fwrite(&indexinsert, sizeof(uint32_t), 1, fp);
if (n != sizeof(uint32_t))
fclose(fp);
return -1;
sdata *pdata = (sdata*)data;
size_t vsize = sizeof(pdata->vardata);
size_t datasize = vsize * indexlast;
fpos_t offset = 4 + 4 + INDEX_BYTES + datasize;
n = fwrite(&offset, sizeof(uint32_t), 1, fp);
if (n != sizeof(uint32_t))
fclose(fp);
return -1;
fsetpos(fp, &offset);
n = fwrite(data, vsize, 1, fp);
if (n != vsize)
fclose(fp);
return -1;
fpos_t index = sizeof(uint32_t);
fsetpos(fp, &index);
uint32_t newnindex = context->v_nindex + 1;
n = fwrite(&newnindex, sizeof(uint32_t), 1, fp);
if (n != sizeof(int))
fclose(fp);
return -1;
fclose(fp);
return 0;
return -1;
函数示例
AI api函数
用户将输入比如一副图片,或者描述的一段话,语句必须被语义分割,或者使用者手动分割关键词,如颜色信息,灾难信息。描述举例
1 1只红色的狗
2 一辆黑色的suv
3 一个扎辫子的5岁左右的小姑娘,身高在1米左右。
4 昨天我丢了一个褐色的皮包。
这个api函数最好是输入词以后进行自动语义分割,否则用户会感到困惑。搜索过程必须多重分布式进程分析。
投屏
DLNA协议DLNA协议是索尼、英特尔、微软等发起的一套 PC、移动设备、消费电器之间互联互通的协议。DLNA与苹果的AirPlay比较相似。我们的视频搜索过程可视化,是可以被投屏的,搜索到目标以后将前后1分钟的视频投屏出去,期间要用到ssdp协议,或者指定到某个显示设备上进行投放,支持的协议可以是DLNA和苹果的airplay以及华为的Cast+协议等,流程为:
1 预先搜索所有设备ssdp协议
2 搜索完后列表
3 启动媒体服务
4 启动投屏
媒体服务必须支持常见的rtsp扩展协议以支持扩展投屏。
未完待续…
以上是关于GB28181 AI视频数据库以及SDP协议的主要内容,如果未能解决你的问题,请参考以下文章
GB/T28181-2016 SDP定义和音视频传输模式解读