void SSRecord::Dump (std::ostream& os) const { os << "Offset: " << GetOffset (); os << " Type: " << GetRecordType (); os << " Len: " << GetLen(); std::string validity = IsValid() ? "valid" : "invalid"; os << " crc: " << m_Header.checksum << " -> " << validity << std::endl; }
int FiRecIsHandLeRecording(int channel) { uint recType = GetRecordType(channel); int ctlFlag = GetRecordCtlFlag(channel); SVPrint("recType(0x%X) ,ctlFlag(%d)\r\n", recType, ctlFlag); if( REC_SLEEP != ctlFlag && (RECORD_TYPE_HAND & recType) ) return FI_TRUE; else return FI_FALSE; }
/* * 停止录像 * recType:录像类型,支持所有录像的中的其中一种 */ static void StopOneKindRecord(int channel,uint recType) { uint recordType; if(FI_FAIL == CheckRecordStartUpType(recType)) { SVPrint("failed ch(%d) FI_FAIL == CheckRecordStartUpType(recType)!\r\n",channel); return; } recordType = GetRecordType(channel); if(recordType & recType) //原来有那种录像 { recordType &= (~recType); SetRecordType(channel,recordType); } }
/************************************************************ * 从缓冲池中拿到一帧以后取出我们需要的数据 * pRecPcp:从缓冲池中取出的帧 * utc:out,时间戳 * recordType:out,录像类型(定时录像、报警录像等等) * writeSize:out,要写进硬盘的数据大小 * frameType:out,帧类型(I、P、智能等等) ******************************************************************/ static int AnalysisFrameData( int channel, PCP_NODE_T *pRecPcp, time_t *utc, uint *recordType, uint *writeSize, uchar *frameType ) { uint curRecordType = *recordType; if( NULL==pRecPcp || NULL==utc || NULL==recordType || NULL==writeSize || NULL==frameType ) { SVPrint("error:NULL==pRecPcp || NULL==utc || NULL==recordType || NULL==writeSize || NULL==frameType!\r\n"); return FI_FAIL; } *frameType = pRecPcp->pcpHead.type; *writeSize = pRecPcp->pcpHead.len; *utc = time(NULL); curRecordType = GetRecordType(channel); *recordType |= curRecordType; return FI_SUCCESS; }
/* * 启动录像 * recType:录像类型,支持所有录像的中的其中一种 */ static void StartOneKindRecord(int channel,uint recType) { uint recordType; if(FI_FAIL == CheckRecordStartUpType(recType)) { SVPrint("failed ch(%d) FI_FAIL == CheckRecordStartUpType(recType)!\r\n",channel); return; } recordType = GetRecordType(channel); if(!(recordType & recType)) //原来没有那种录像 { recordType |= recType; SetRecordType(channel,recordType); } //刷新时间游标 if(recType & RECORD_TYPE_ALARM_ALL) { RefrechAlarmBaseTimeCursor(channel); } //Usleep(1); //just for test 有必要添加吗? }
/********************************************************* 录像监视线程,该线程与系统时间有关, 请在启动应用线程后再启动该线程 并在启动此次线程再启动录像线程 ***********************************************************/ static void *ManageRecordThread(void *arg) { int chNum = REAL_CHANNEL_NUM; int i,j; int real_time[chNum]; int base_time[REAL_CHANNEL_NUM] = {-1}; int real_year[chNum],real_month[chNum],real_day[chNum]; int base_year[chNum],base_month[chNum],base_day[chNum]; uint base_rec_type[REAL_CHANNEL_NUM]; uint real_rec_type[REAL_CHANNEL_NUM]; int alarm_real_time[REAL_CHANNEL_NUM]; int alarm_base_time[REAL_CHANNEL_NUM]; char real_parh[RECORD_FILENAME_LEN] = {0}; char base_path[RECORD_FILENAME_LEN] = {0}; SVPrint("start ManageRecordThread:%d!\r\n",ThreadSelf()); while(rec_manage.recordManageRunFlag) { FiRecStartAutoDelOldFile(); /*录像分区改变切换文件,优先级最高*/ if(FI_FAIL == FiHddGetUsingPartition(real_parh)) { for(i=0;i<chNum;i++) { if(REC_SLEEP != GetRecordCtlFlag(i)) SetRecordCtlFlag(i,REC_STOP); } sleep(1); continue; } else { if(0 != strcmp(base_path,real_parh)) { strcpy(base_path,real_parh); for(i=0;i<chNum;i++) { if(REC_WRITE == GetRecordCtlFlag(i)) { SVPrint("record switch partition.\r\n"); RefrechAlarmBaseTimeCursor(i); RefrechTimerBaseTimeCursor(&real_time[i],&real_year[i],&real_month[i],&real_day[i], &base_time[i],&base_year[i],&base_month[i],&base_day[i]); SetRecordCtlFlag(i,REC_SWITCH); //仅仅录像分区,不做任何时间检测 } } } } if(-1 == manage_init_flag) { for(j=0;j<chNum;j++) { /*初始化定时录像监测*/ real_time[j] = time(NULL); base_time[j] = real_time[j]; FiTimeUtcToHuman(base_time[j],&base_year[j],&base_month[j],&base_day[j],NULL,NULL,NULL); /*初始化录像类型切换监测*/ real_rec_type[j] = GetRecordType(j); base_rec_type[j] = real_rec_type[j]; RefrechAlarmBaseTimeCursor(j); alarm_real_time[j] = SysRunTimeGet(); } manage_init_flag = 0; } /*监测手动和定时录像*/ for(i=0;i<chNum;i++) { ManageHandRecord(i); ManageTimerRecordTime(i); } /*定时录像切文件*/ for(i=0;i<chNum;i++) { real_time[i] = time(NULL); FiTimeUtcToHuman(real_time[i],&real_year[i],&real_month[i],&real_day[i],NULL,NULL,NULL); if(( real_time[i] - base_time[i] >= FiRecGetRecFileSwitchTime() ) || (real_time[i] - base_time[i] < 0 && base_time[i] - real_time[i] > RECORD_TIME_ERROR_RANGE) || (real_year[i] != base_year[i]) || (real_month[i] != base_month[i]) || (real_day[i] != base_day[i])) { SVPrint("ch(%d),%d-%d=%d\r\n",i,real_time[i],base_time[i],real_time[i]-base_time[i]); RefrechAlarmBaseTimeCursor(i); RefrechTimerBaseTimeCursor(&real_time[i],&real_year[i],&real_month[i],&real_day[i], &base_time[i],&base_year[i],&base_month[i],&base_day[i]); if(REC_WRITE == GetRecordCtlFlag(i)) { SetRecordCtlFlag(i,REC_SWITCH); } } } /*报警录像情况的录像类型改变从而切换文件*/ for(i=0;i<chNum;i++) { real_rec_type[i] = GetRecordType(i); if(real_rec_type[i] & RECORD_TYPE_ALARM_ALL) { alarm_base_time[i] = getAlarmBaseTimeCursor(i); alarm_real_time[i] = SysRunTimeGet(); if( alarm_real_time[i] - alarm_base_time[i] >= FiRecGetRecFileSwitchTimeAlarm() ) { SVPrint("%d-%d=%d\r\n",alarm_real_time[i] , alarm_base_time[i],alarm_real_time[i] - alarm_base_time[i]); FiRecStopRecord(i,RECORD_TYPE_ALARM_ALL); RefrechAlarmBaseTimeCursor(i); RefrechTimerBaseTimeCursor(&real_time[i],&real_year[i],&real_month[i],&real_day[i], &base_time[i],&base_year[i],&base_month[i],&base_day[i]); if(real_rec_type[i] & (RECORD_TYPE_ALL&(~RECORD_TYPE_ALARM_ALL))) { SetRecordCtlFlag(i,REC_SWITCH); } } } } /* 控制录像线程启动录像 ,是否启动录像*/ for(i=0;i<chNum;i++) { real_rec_type[i] = GetRecordType(i); if(real_rec_type[i] & RECORD_TYPE_ALL) { if(FI_TRUE == ControlRecordThreadStartRecord(i)) { RefrechAlarmBaseTimeCursor(i); RefrechTimerBaseTimeCursor(&real_time[i],&real_year[i],&real_month[i],&real_day[i], &base_time[i],&base_year[i],&base_month[i],&base_day[i]); } } else { ControlRecordThreadStopRecord(i); } } Usleep(500000); //500ms } //while(rec_manage.recordManageRunFlag) SVPrint("quit ManageRecordThread!\r\n"); return NULL; }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Operand* ConstantFolder::LoadFromAddress(Operand* op, const Type* loadType, __int64 offset) { // If the operand has a defining instruction then we try to compute // the offset from which we should load. If it's a variable reference // we try to load from the offset that was already computed. if(op->HasDefiningInstruction() == false) { return LoadFromGlobal(op, loadType, offset); } auto instr = op->DefiningInstruction(); switch(instr->GetOpcode()) { case Instr_Index: { // If the index operand is not a constant give up. auto indexInstr = instr->As<IndexInstr>(); auto indexConst = indexInstr->IndexOp()->As<IntConstant>(); if(indexConst == nullptr) { return nullptr; } // The type of the base is 'pointer-to-array', so we need to strip the pointer. auto elementType = indexInstr->GetElementType(); __int64 index = indexConst->Value(); __int64 elemSize = TypeInfo::GetSize(elementType, target_); // The offset is incremented by the index multiplied with the element size. __int64 newOffset = offset + (index * elemSize); return LoadFromAddress(indexInstr->BaseOp(), loadType, newOffset); } case Instr_Element: { auto elemInstr = instr->As<ElementInstr>(); __int64 index = elemInstr->GetFieldIndex(); // The type of the base is 'pointer-to-record', // so we need to strip the pointer. auto recordType = elemInstr->GetRecordType(); // Obtain the offset of the selected field. // The new offset is the old one added with the field offset. __int64 fieldOffset = recordType->Fields()[index].FieldOffset; __int64 newOffset = offset + fieldOffset; return LoadFromAddress(elemInstr->BaseOp(), loadType, newOffset); } case Instr_Address: { // If the index operand is not a constant give up. auto addrInstr = instr->As<AddressInstr>(); auto indexConst = addrInstr->IndexOp()->As<IntConstant>(); if(indexConst == nullptr) { return nullptr; } // The type of the base is 'pointer-to-object', // so we need to strip the pointer. auto objectType = addrInstr->GetPointeeType(); __int64 index = indexConst->Value(); __int64 elemSize = TypeInfo::GetSize(objectType, target_); // The offset is incremented by the index multiplied with the object size. __int64 newOffset = offset + (index * elemSize); return LoadFromAddress(addrInstr->BaseOp(), loadType, newOffset); } case Instr_Ptop: { // This instruction is ignored (the previous recursion step // has already taken care about its effects). auto ptopInstr = instr->As<PtopInstr>(); auto targetInstr = ptopInstr->TargetOp()->DefiningInstruction(); return LoadFromAddress(ptopInstr->TargetOp(), loadType, offset); } case Instr_Load: { // This happens when the variable is a pointer. auto loadInstr = instr->As<LoadInstr>(); return LoadFromAddress(loadInstr->SourceOp(), loadType, offset); } default: { // All other cases don't lead to a constant operand. return nullptr; } } }