海康威视实时预览回调PS流用EasyRTMP向RTMP服务器推流中视频数据处理的代码
在上一篇方案《EasyRTMP结合海康HCNetSDK获取海康摄像机H.264实时流并转化成为RTMP直播推流(附源码)》我们介绍了将海康安防摄像机进行互联网直播的整体方案流程,其中有一个流程“数据处理与分析”我们当时没有展开详述,今天我们将海康HCNetSDK实时预览回调接口数据处理的过程,尤其是在RealDataCallback中对AVData的处理过程:
case NET_DVR_STREAMDATA:{BOOL inData=PlayM4_InputData(nPort,pBuffer,dwBufSize);while (!inData){Sleep(10);inData=PlayM4_InputData(nPort,pBuffer,dwBufSize);OutputDebugString("PlayM4_InputData failed \n"); } //PS流数据解析处理 {int nI = 0;int nCacheSize = 0;nI = m_mFrameCacheLenth[lRealHandle];//直接--提取H264数据BOOL bVideo = FALSE;BOOL bPatialData = FALSE;bPatialData = GetH246FromPS(pBuffer,dwBufSize, &m_pFrameCache[lRealHandle][nI].pCacheBuffer, m_pFrameCache[lRealHandle][nI].nCacheBufLenth, bVideo);if (bVideo){if (bPatialData)//部分包数据{//缓存数据m_pFrameCache[lRealHandle][nI].lTimeStamp = clock();m_mFrameCacheLenth[lRealHandle]++;} else//包头{int i = 0;if(m_mFrameCacheLenth[lRealHandle]>0){long lH264DataLenth = m_mFrameCacheLenth[lRealHandle]*MAX_PACK_SIZE;BYTE* pH264Nal = NULL;pH264Nal = new BYTE[lH264DataLenth];memset(pH264Nal, 0x00, lH264DataLenth);BYTE* pTempBuffer = pH264Nal;int nTempBufLenth = 0;//TRACE("m_mFrameCacheLenth==%d\r\n", pDemoDlg->m_mFrameCacheLenth);// 最大缓存数据个数设为pDemoDlg->m_mFrameCacheLenth,程序会过程中报错,Why? [5/6/2014-13:19:51 Dingshuai]for (i=0; i</*MAX_FRAME_LENTH*/m_mFrameCacheLenth[lRealHandle]; i++){if(m_pFrameCache[lRealHandle][i].pCacheBuffer!=NULL&&m_pFrameCache[lRealHandle][i].nCacheBufLenth>0){// memcpy(pTempBuffer, m_pFrameCache[i].pCacheBuffer, m_pFrameCache[i].nCacheBufLenth);// pTempBuffer = pTempBuffer + m_pFrameCache[i].nCacheBufLenth;memcpy(pH264Nal+nTempBufLenth, m_pFrameCache[lRealHandle][i].pCacheBuffer, m_pFrameCache[lRealHandle][i].nCacheBufLenth);nTempBufLenth += m_pFrameCache[lRealHandle][i].nCacheBufLenth;}if (m_pFrameCache[lRealHandle][i].pCacheBuffer){delete [](m_pFrameCache[lRealHandle][i].pCacheBuffer);m_pFrameCache[lRealHandle][i].pCacheBuffer = NULL;} m_pFrameCache[lRealHandle][i].nCacheBufLenth = 0; }if (m_bRtmpRunning && pH264Nal && nTempBufLenth>0){BOOL bIsKeyFrame = FALSE;//查找是否为关键帧if(pH264Nal[4]==0x67){bIsKeyFrame = TRUE;}long lTimeStamp = clock();WriteH264DataToChace(lRealHandle, pH264Nal, nTempBufLenth, bIsKeyFrame, lTimeStamp);}if (pH264Nal){delete []pH264Nal;pH264Nal = NULL;}// 缓存数据个数 清0m_mFrameCacheLenth[lRealHandle] = 0;}}}}}
通过对上述代码的分析,整个视频流回调过程还是比较简单的:判断回调数据类型(NET_DVR_STREAMDATA)–》海康PS数据Demux成音视频ES数据(GetH246FromPS)–》对关键帧数据做缓存和处理(bIsKeyFrame )–》进入转推RTMP缓存队列(WriteH264DataToChace)
海康PS流解析:
BOOL CDecCallBack_DemoDlg::GetH246FromPS(IN BYTE* pBuffer, IN int nBufLenth, BYTE** pH264, int& nH264Lenth, BOOL& bVideo)
{if (!pBuffer || nBufLenth<=0){return FALSE;}BYTE* pH264Buffer = NULL;int nHerderLen = 0;if( pBuffer&& pBuffer[0]==0x00&& pBuffer[1]==0x00 && pBuffer[2]==0x01&& pBuffer[3]==0xE0)//E==视频数据(此处E0标识为视频){bVideo = TRUE;nHerderLen = 9 + (int)pBuffer[8];//9个为固定的数据包头长度,pBuffer[8]为填充头部分的长度pH264Buffer = pBuffer+nHerderLen;if (*pH264 == NULL){*pH264 = new BYTE[nBufLenth];}if (*pH264&&pH264Buffer&&(nBufLenth-nHerderLen)>0){ memcpy(*pH264, pH264Buffer, (nBufLenth-nHerderLen));} nH264Lenth = nBufLenth-nHerderLen;return TRUE;} else if(pBuffer && pBuffer[0]==0x00&& pBuffer[1]==0x00&& pBuffer[2]==0x01&& pBuffer[3]==0xC0) //C==音频数据{*pH264 = NULL;nH264Lenth = 0;bVideo = FALSE;}else if(pBuffer && pBuffer[0]==0x00&& pBuffer[1]==0x00&& pBuffer[2]==0x01&& pBuffer[3]==0xBA)//视频流数据包 包头{bVideo = TRUE;*pH264 = NULL;nH264Lenth = 0;return FALSE;}return FALSE;
}
海康音视频数据进行RTMP推流:
int CDecCallBack_DemoDlg::WriteH264DataToChace(int nDevId, BYTE* pBuffer, int nBufSize, BOOL bIsKeyFrame, long lTimeStamp)
{if (!pBuffer || nBufSize<=0 || lTimeStamp<0){return -1;}BOOL bKeyFrame = bIsKeyFrame;int nDeviceType = nDevId+1;if (m_RtmpHandle && m_bRtmpRunning){//H264推送RTMPEASY_AV_Frame avFrame;memset(&avFrame, 0x00, sizeof(EASY_AV_Frame));avFrame.pBuffer = (unsigned char*)pBuffer;avFrame.u32AVFrameLen = nBufSize;avFrame.u32VFrameType = (bKeyFrame)?EASY_SDK_VIDEO_FRAME_I:EASY_SDK_VIDEO_FRAME_P;avFrame.u32AVFrameFlag = EASY_SDK_VIDEO_FRAME_FLAG;avFrame.u32TimestampSec = lTimeStamp/1000000;avFrame.u32TimestampUsec = (lTimeStamp%1000000);//EnterCriticalSection(&m_cs);EasyRTMP_SendPacket(m_RtmpHandle, &avFrame); }return 1;
}
经过上述步骤,基本完成了对一路SDK数据回调的处理,如果需要一个完整的、系统的、中间件级别的流转服务,那还需要一套完整的控制机制和配套接口以及前端界面,就类似于EasyNVR一样。
本文中所述详细代码见:https://github.com/EasyDSS/EasyRTMP/tree/master/EasyRTMP_HIK
海康威视实时预览回调PS流用EasyRTMP向RTMP服务器推流中视频数据处理的代码相关推荐
- EasyRTMP:RTMP推流海康威视实时预览回调PS流用EasyRTMP向RTMP服务器推流中视频数据处理的代码
在上一篇方案<EasyRTMP结合海康HCNetSDK获取海康摄像机H.264实时流并转化成为RTMP直播推流(附源码)>中我们介绍了将海康安防摄像机进行互联网直播的整体方案流程,其中有一 ...
- Ant Design Form组件表单实时预览
本篇文章主要是关于如何采用Form useWatch Hooks实现表单实时预览效果 文章目录 一.应用场景 二.useWatch 三.关键代码 一.应用场景 使用的场景主要来源于工作或者我们具体的项 ...
- 海康威视摄像机Java SDK拉流(二)开启关闭实时预览
上一篇:海康威视Java SDK拉流(一)初始化SDK 本篇介绍海康威视摄像机通过SDK开启关闭实时预览接口 下篇介绍实时预览的回调函数及解码库 测试环境: 系统:Centos 7 SDK:设备网络S ...
- 海康威视摄像机SDK二次开发--实时预览视频流保存到指定文件中
开发海康威视sdk ,IPC设备,视频回调用的是官方提供的Demo中的(fRealDataCallBack ) 在最下面代码可以设置Thread.sleep()设置拍摄时长 文件结构 CameraIn ...
- vue2实现海康威视根据海康插件进行监控实时预览和回放功能,全套代码,开箱即用。
这是一套拿到手就能直接用的根据海康提供的摄像机节点实时预览和回放的全步骤代码,开箱即用. 前言 我的是基于vue2写的,vue3可以看我下一篇文章. 点击跳转至vue3关于海康视频开发文章. 很多人 ...
- 网络监控摄像头流媒体视频管理平台实时预览零延迟支持海康威视浙江大华宇视等解决方案分析
方案简介 网络摄像头监控视频低延迟一直是一个比较难以解决的问题,很多非音视频开发专业的技术人员,花费了大量精力开发出来的各种集成网络监控摄像头在浏览器Web网页实时播放的程序,要么延迟非常高,要么及其 ...
- Java海康威视摄像头实时预览视频流保存到指定文件中
海康威视摄像头实时预览视频流保存到文件中 目前在开发海康威视sdk ,IPC设备,视频回调用的是官方提供的Demo中的(fRealDataCallBack ) 在最下面代码可以设置Thread.sle ...
- 掌握PS制作,实时预览你的精彩作品
在PS的不断学习中,总结了些许经验,现在的工具栏的使用,各项技能也掌握的七七八八. PS是一项上手快,但也忘得快的软件,最好是带着任务去学习PS,比如你今天一定要学会图形工具的使用,那你可以找些对应的 ...
- 腾讯ui测试机实时预览软件,腾讯ISUX终端设备实时预览Photoshop的设计稿的神器Ps Play...
Ps Play是一个通过Wi-Fi网络,实时在终端设备上预览电脑上Photoshop的设计稿,可同步调试及截图保存到移动终端,并可以通过Email.微信等工具即时分享的跨终端应用.这就是这个工具的功能 ...
最新文章
- Win7部署基础知识(7):使用Imagex捕获和安装映像
- 1342. 断开的项链【难度: 一般 / 破环成链】
- C++版二叉树非递归遍历
- JMS 2.0的新增功能
- 前端学习(3258):js高级教程(2)
- centos7下编译openjdk11
- Eclipse创建SpringMVC,Spring, Hibernate项目
- 长沙试水数字人民币:线下支持数字人民币支付的商家已达3404个
- ssas_通过SSAS透视图提高可读性
- Apache PDFBox 1.8.1 发布
- 搭建 LimeSurvey投票调查问卷系统
- java常用工具下载
- PS、PR、AE、AI、AU区别
- PifPaf: Composite Fields for Human Pose Estimation
- 2023服装零售erp有哪些,5款主流服装零售erp软件真实测评!
- [Minecraft]基于Forge的1.8.9MOD开发教程——第二讲:创建一个空Mod
- 干货 | 95后运维小哥20天+通过Elastic认证考试经验分享
- GaussDB ETCD 服务异常实例分析处理的5种方法
- AntD Button 图标集成 iconfont
- To Be Better |这个冬天,与CDA一起游学北卡罗莱纳州立大学(NCSU)
热门文章
- 新版Microsoft Edge下载时,提示验证失败的问题处理
- mysql IP address 'xxx' could not be resolved
- 1860-zbj的电梯间
- 20230221 git设置upstream
- python异步的发展历程_深入了解Python的异步IO:概念和历史
- 不知道自己不知道 知道自己不知道 不知道自己知道 知道自己知道
- 仓库管理员怎样做台账_福利好企业SKF招聘测量检查员和仓库管理员,还在等什么快来报名吧...
- 自学java面向实习从零开始路线
- 如何顺利通过 PMP 考试?
- 豆瓣fm android,豆瓣FM - 遇见音乐 - Android 应用 - 【最美应用】