请教海康威视DS-4004HC视频卡视频录像问题
我只知道可通过回调函数来实现录像RegisterStreamDirectReadCallback
但我不知道 回调函数里面 对文件的操作如何处理
在使用回调函数前 先创建.264文件,回调函数里面如何写这个.264文件呢?
请大侠 指点一下
[解决办法]
海康官方网站上有DS-40xxHC、DS-40xxHC+、DS-40xxMD SDK的文档和示例程序包下载的,楼主可去下载一个看看。
RegisterStreamDirectReadCallback函数所设置的回调函数有四个参数:
STREAM_DIRECT_READ_CALLBACK(ULONG channelNumber, void* DataBuf, DWORD Length, int FrameType, void* context)
要根据FrameType进行相应的处理的,以下是摘录自官方示例的代码:
- C/C++ code
int __cdecl StreamDirectReadCallback(ULONG channelNum,void *DataBuf,DWORD Length,int frameType,void *context){ BOOL breakable; int nframetype =0; CHKVisionDlg *hkdlg = (CHKVisionDlg *)context; if(frameType >0) { if (frameType == PktSysHeader) { memcpy(FileHeader[channelNum],DataBuf,Length); FileHeaderLen = Length; } else if (frameType == PktSubSysHeader) { memcpy(FileHeaderQcif[channelNum],DataBuf,Length); FileHeaderLen = Length; } if (frameType == PktMotionDetection) { int result[4]; if(bOverlayMode) { hkdlg->m_VideoWin.DrawVectEx(channelNum, (char *)DataBuf); } else { hkdlg->m_bMoving[channelNum] = TRUE; memcpy(motionData[channelNum],(char*)DataBuf,Length); } MotionAnalyzer(ChannelHandle[channelNum],(char*)DataBuf,15,result); if((result[0] + result[1] + result[2] + result[3])) { if (channelNum ==0) TRACE("!!!!!!!!!!!!!!!!CH=%d motion detect result is %d %d %d %d\n",channelNum,result[0],\ result[1],result[2],result[3]); // Triggerº¯ÊýµÄ×÷ÓÃÊǰѱ¨¾¯Ç°µÄÊý¾Ý°´setupÀïÃæµÄÉèÖ㬰ÑÏàÓ¦µÄ¾¯Ç°Ö¡Ð´ÈëÎļþ if(!hkdlg->baftermotion[channelNum]) alarmFile[channelNum].Trigger(gFileHandle[channelNum]); //ÿ´ÎÓÐÒÆ¶¯Õì²âÖ¡ÉÏÀ´£¬×Ô¶¯°Ñualreadywriteframes[channelNum]ÇåΪ0 £¬ÎªÐ´È뾯ºóÖ¡×÷×¼±¸ hkdlg->ualreadywriteframes[channelNum]=0; hkdlg->baftermotion[channelNum]=TRUE; } return 0; } if (frameType == PktIFrames || frameType ==PktSubIFrames) breakable = TRUE; else breakable = FALSE; } gChannelTotalLength[channelNum].QuadPart +=Length; gCurrentFileLen[channelNum] +=Length; if ((gCurrentFileLen[channelNum] > gFileSize*1000*1000) && (breakable) ) { char fileName[256]; CTime m_StartTime1=CTime::GetCurrentTime(); CString csStartTime=m_StartTime1.Format("%Y%m%d%H%M%S"); if (gFileHandle[channelNum]) { _close(gFileHandle[channelNum]); sprintf(fileName, "ch%02d_%s.264", channelNum,csStartTime); gFileHandle[channelNum] = _open(fileName,_O_CREAT|_O_BINARY|_O_WRONLY|_O_TRUNC,_S_IREAD|_S_IWRITE); _write(gFileHandle[channelNum],FileHeader[channelNum],FileHeaderLen); } if (gFileHandleQcif[channelNum]) { _close(gFileHandleQcif[channelNum]); sprintf(fileName, "ch%02d_%s_sub.264", channelNum,csStartTime); gFileHandleQcif[channelNum] = _open(fileName,_O_CREAT|_O_BINARY|_O_WRONLY|_O_TRUNC,_S_IREAD|_S_IWRITE); _write(gFileHandleQcif[channelNum],FileHeaderQcif[channelNum],FileHeaderLen); } gCurrentFileLen[channelNum] -=gFileSize*1000*1000; } if(bAlarmFileSave) { if(frameType == PktSysHeader) _write(gFileHandle[channelNum],DataBuf,Length); else { //ͳ¼ÆÒƶ¯Õì²âÖ¡ÉÏÀ´Ö®ºóµÄÒôÊÓÆµÊý¾Ý£¬Í³¼ÆËüÃÇ £¬²¢°ÑËüÃÇдÈëÎļþ£¬Ã¿Ò»´ÎÓРеÄÒÆ¶¯Õì²âÊý¾ÝÉÏÀ´£¬ //ualreadywriteframes¶¼»áÏÈÇå0£¬È»ºóͳ¼ÆÐ´ÈëÎļþµÄÒôÊÓÆµÊý¾Ý hkdlg->ualreadywriteframes[channelNum] += hkdlg->TypeToFrames((FrameType_t)frameType); if (hkdlg->ualreadywriteframes[channelNum] <6*(25+25)) //Â¼ÖÆÒÆ¶¯Õì²âÖ¡ÉÏÀ´Ö®ºó 6ÃëÖÓµÄÒôÊÓÆµÊý¾Ý£¬Ò²¾ÍÊǾ¯ºóÊý¾Ý _write(gFileHandle[channelNum],DataBuf,Length); else { // Èç¹ûÒÆ¶¯Õì²âÉÏÀ´Ö®ºó£¬Ð´ÈëÎļþµÄÒôÊÓÆµÊý¾ÝÒѾ­×ã¹»£¬ÄÇô°Ñ½ÓÏÂÀ´ÉÏÀ´µÄÒôÊÓÆµÊý¾Ýѹ»º³å£¬ // ѹÈ뻺³åµÄÊý¾ÝÓÐÁ½ÖÖ´¦Àí·½Ê½£º£±¡¡Èç¹û»º³åÂúÁË£¬×Ô¶¯±»É¾³ý£»£²¡¡×÷ΪÏ´α¨¾¯ÉÏÀ´µÄ¾¯Ç°Ö¡Ð´ÈëÎļþ£»¡¡ alarmFile[channelNum].FramePush(gFileHandle[channelNum],(unsigned char *)DataBuf,Length,(FrameType_t)frameType,breakable); hkdlg->baftermotion[channelNum] = FALSE; } } } else { if(frameType ==PktAudioFrames) { _write(gFileHandle[channelNum],DataBuf,Length); _write(gFileHandleQcif[channelNum],DataBuf,Length); }else if (frameType ==PktSubIFrames || frameType ==PktSubPFrames || frameType == PktSubBBPFrames || frameType == PktSubSysHeader) { _write(gFileHandleQcif[channelNum],DataBuf,Length); }else { _write(gFileHandle[channelNum],DataBuf,Length); } } return 0;}
[解决办法]
实际上把DataBuf传过来的数据流直接保存起来就可以了。但是注意一下,海康视频文件有个文件头,每个文件前面的40个字节用来描述这个视频文件的格式,所以一定不能漏下,剩下的直接写就是了。当frameType == PktSubSysHeader时,DataBuf里的数据就是文件头。