From db5292897540903c21e042063662b4dc6a8928ca Mon Sep 17 00:00:00 2001 From: tqcq <99722391+tqcq@users.noreply.github.com> Date: Thu, 22 Aug 2024 14:55:41 +0800 Subject: [PATCH 1/7] feat parse h264 --- CMakeLists.txt | 12 +- PcapSender/main.cpp | 288 +++--- src/HuaWei/HWsign.cpp | 942 ++++++++++---------- src/HuaWei/HWsign.h | 61 +- src/base/event.h | 47 + src/base/frame.cpp | 28 + src/base/frame.h | 53 ++ src/base/frame_manager.cpp | 48 + src/base/frame_manager.h | 39 + src/base/rtp_decoder.cpp | 102 +++ src/base/rtp_decoder.h | 53 ++ src/base/rtp_manager.cpp | 129 +++ src/base/rtp_manager.h | 65 ++ src/base/rtp_packet.cpp | 134 +++ src/base/rtp_packet.h | 67 ++ src/base/signer.cpp | 1 + src/base/signer.h | 15 + src/base/util.cpp | 110 +++ src/base/util.h | 30 + src/sigslot.h | 1682 ++++++++++++++++++++++++++++++++++++ 20 files changed, 3288 insertions(+), 618 deletions(-) create mode 100644 src/base/event.h create mode 100644 src/base/frame.cpp create mode 100644 src/base/frame.h create mode 100644 src/base/frame_manager.cpp create mode 100644 src/base/frame_manager.h create mode 100644 src/base/rtp_decoder.cpp create mode 100644 src/base/rtp_decoder.h create mode 100644 src/base/rtp_manager.cpp create mode 100644 src/base/rtp_manager.h create mode 100644 src/base/rtp_packet.cpp create mode 100644 src/base/rtp_packet.h create mode 100644 src/base/signer.cpp create mode 100644 src/base/signer.h create mode 100644 src/base/util.cpp create mode 100644 src/base/util.h create mode 100644 src/sigslot.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 27ea99c..8756047 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.9) project( SecMedia + LANGUAGES C CXX VERSION 0.0.1 DESCRIPTION "Security Media Package") set(CMAKE_CXX_STANDARD 11) @@ -83,13 +84,20 @@ file( ${SecMedia_Root}/*/*.c ${SecMedia_Root}/*/*/*.cpp ${SecMedia_Root}/*/*/*.h - ${SecMedia_Root}/*/*/*.c) + ${SecMedia_Root}/*/*/*.c +) file(GLOB SecMedia_api_list ${CMAKE_CURRENT_SOURCE_DIR}/include/common.h) # # target_compile_options(${PROJECT_NAME} PRIVATE -fvisibility=hidden) # list(APPEND LINK_LIB_LIST ${LINK_LIB_SVAC_LIST}) -add_library(${PROJECT_NAME} SHARED ${SecMedia_src_list}) +add_library(${PROJECT_NAME} SHARED +"src/base/util.cpp" +"src/base/rtp_packet.cpp" +"src/SVAC/src/sm2sm3/sm3.c" +"src/SVAC/src/sm2sm3/sm2.c" +${SecMedia_src_list} +) # add_library(${PROJECT_NAME} STATIC ${SecMedia_src_list}) target_link_libraries(${PROJECT_NAME} ${LINK_LIB_SVAC_LIST} rtp) target_include_directories(${PROJECT_NAME} PRIVATE ${SecMedia_Root}/.) diff --git a/PcapSender/main.cpp b/PcapSender/main.cpp index 2849c54..1358b0a 100644 --- a/PcapSender/main.cpp +++ b/PcapSender/main.cpp @@ -1,44 +1,46 @@ -#include +#include "HuaWei/HWsec.h" +#include "HuaWei/HWsign.h" #include #include #include +#include +#include +#include +#include #include -#include -#include -#include #include -#include "HuaWei/HWsign.h" -#include "HuaWei/HWsec.h" +#include using namespace std; using namespace pcpp; -sec_set_info sign_info={ - 2, - "34020000001320000003", - "2021-07-06T17:27:19.000", - 32, - 64, - { - 0x24,0x88,0xc8,0xdc,0x7f,0xd7,0xe0,0x91,0x30,0x1b,0x5c,0x58,0x2f,0xe7,0x44,0x7d, - 0x2f,0x43,0xe4,0xee,0xc8,0x7d,0xc0,0xfb,0xa4,0xb8,0x7d,0x4b,0x8a,0x69,0x7c,0x4e - }, - { - 0xaa,0xb1,0x3f,0xd7,0x66,0xe2,0x75,0x97,0xc0,0x03,0xe6,0xe4,0x1d,0x77,0x54,0x78, - 0xc8,0x29,0xb2,0x0b,0x9e,0xd1,0xff,0xa3,0x6a,0x6f,0xd2,0x7f,0xd6,0x2d,0xaa,0x3f, - 0xc9,0x24,0xec,0x6c,0x96,0x0a,0x7b,0x73,0xf6,0xe6,0xfc,0xda,0x3a,0x08,0xfd,0x92, - 0xfc,0x00,0x08,0x97,0x78,0x2c,0x71,0x6b,0xe1,0x26,0xf5,0x1e,0xba,0x31,0xf5,0xb2, - } - }; -void * EncrypInit(){ +sec_set_info sign_info = { + 2, + "34020000001320000003", + "2021-07-06T17:27:19.000", + 32, + 64, + {0x24, 0x88, 0xc8, 0xdc, 0x7f, 0xd7, 0xe0, 0x91, 0x30, 0x1b, 0x5c, 0x58, 0x2f, 0xe7, 0x44, 0x7d, + 0x2f, 0x43, 0xe4, 0xee, 0xc8, 0x7d, 0xc0, 0xfb, 0xa4, 0xb8, 0x7d, 0x4b, 0x8a, 0x69, 0x7c, 0x4e}, + { + 0xaa, 0xb1, 0x3f, 0xd7, 0x66, 0xe2, 0x75, 0x97, 0xc0, 0x03, 0xe6, 0xe4, 0x1d, 0x77, 0x54, 0x78, + 0xc8, 0x29, 0xb2, 0x0b, 0x9e, 0xd1, 0xff, 0xa3, 0x6a, 0x6f, 0xd2, 0x7f, 0xd6, 0x2d, 0xaa, 0x3f, + 0xc9, 0x24, 0xec, 0x6c, 0x96, 0x0a, 0x7b, 0x73, 0xf6, 0xe6, 0xfc, 0xda, 0x3a, 0x08, 0xfd, 0x92, + 0xfc, 0x00, 0x08, 0x97, 0x78, 0x2c, 0x71, 0x6b, 0xe1, 0x26, 0xf5, 0x1e, 0xba, 0x31, 0xf5, 0xb2, + }}; + +void * +EncrypInit() +{ // auto Verify_handle=HWVerify_init(); - auto sign_handle=GB28181_stream_init(&sign_info); //HWSign_init(&sign_info); + auto sign_handle = GB28181_stream_init(&sign_info);//HWSign_init(&sign_info); return sign_handle; } -std::string getProtocolTypeAsString(pcpp::ProtocolType protocolType) + +std::string +getProtocolTypeAsString(pcpp::ProtocolType protocolType) { - switch (protocolType) - { + switch (protocolType) { case pcpp::Ethernet: return "Ethernet"; case pcpp::IPv4: @@ -53,116 +55,132 @@ std::string getProtocolTypeAsString(pcpp::ProtocolType protocolType) default: return "Unknown"; } - } -inline void sleep(timeval & delta){ +inline void +sleep(timeval &delta) +{ // delta.tv_sec - select(0,NULL,NULL,NULL,&delta); + select(0, NULL, NULL, NULL, &delta); } -template -timespec TimeDiff(T && minu,U && sub){ + +template +timespec +TimeDiff(T &&minu, U &&sub) +{ timespec deltatime; - deltatime.tv_nsec=minu.tv_nsec-sub.tv_nsec; - deltatime.tv_sec=minu.tv_sec-sub.tv_sec; - if(deltatime.tv_nsec<0 && deltatime.tv_sec>0){ - deltatime.tv_nsec+=1000000000; + deltatime.tv_nsec = minu.tv_nsec - sub.tv_nsec; + deltatime.tv_sec = minu.tv_sec - sub.tv_sec; + if (deltatime.tv_nsec < 0 && deltatime.tv_sec > 0) { + deltatime.tv_nsec += 1000000000; deltatime.tv_sec--; } return move(deltatime); } -int ReadPcapAndSend(int socket,sockaddr_in & addr,const string & filename,const string & filter,void * sign_handle){ +int +ReadPcapAndSend(int socket, sockaddr_in &addr, const string &filename, const string &filter, void *sign_handle) +{ // auto sign_h2=EncrypInit(); - auto reader=pcpp::IFileReaderDevice::getReader(filename); + auto reader = pcpp::IFileReaderDevice::getReader(filename); // verify that a reader interface was indeed created - if (reader == NULL) - { + if (reader == NULL) { std::cerr << "Cannot determine reader for file type" << std::endl; return 1; } // open the reader for reading - if (!reader->open()) - { + if (!reader->open()) { std::cerr << "Cannot open input.pcap for reading" << std::endl; return 1; } - if (!reader->setFilter(filter)) - { + if (!reader->setFilter(filter)) { std::cerr << "Cannot set filter for file reader" << std::endl; return 1; } - uint8_t * payload; + uint8_t *payload; size_t payload_len; pcpp::RawPacket rawPacket; - bool first_flag=true; - timespec nowtime,gaptime; + bool first_flag = true; + timespec nowtime, gaptime; timespec real_now; - timespec inital_time,current_time; - static char sign_out_buf[3096]; + timespec inital_time, current_time; + static char sign_out_buf[3096]; unsigned int sign_out_len; - void *param=nullptr; - uint16_t offset_len,append_len; - while (reader->getNextPacket(rawPacket)) - { - pcpp::Packet parsedPacket(&rawPacket,OsiModelTransportLayer); - auto layer = parsedPacket.getLayerOfType(false); - - if(layer){ - payload=layer->getLayerPayload(); - payload_len=layer->getLayerPayloadSize(); - // cout<<" payload_len:" << payload_len<=0 && gaptime.tv_sec>=0) - { - nanosleep(&gaptime,NULL); - }else{ - // cout<<" s:" << gaptime.tv_sec<<" ns:" << gaptime.tv_nsec < output_thread; + std::atomic processing{true}; + std::atomic processing_cnt{0}; + if (sign_handle) { + output_thread = std::shared_ptr(new std::thread([&] { + while (processing.load(std::memory_order_relaxed)) { + int ret = + GB28181_stream_out(sign_handle, sign_out_buf, &sign_out_len, &offset_len, &append_len, ¶m); + if (ret != 1) { continue; } + processing_cnt.fetch_sub(1); + if (append_len == 0) { + sendto(socket, sign_out_buf, sign_out_len, 0, (const sockaddr *) &addr, sizeof(addr)); + } else { + sendto(socket, sign_out_buf, offset_len, 0, (const sockaddr *) &addr, sizeof(addr)); + sendto(socket, sign_out_buf + offset_len, sign_out_len - offset_len, 0, (const sockaddr *) &addr, + sizeof(addr)); } // GB28181_stream_in(sign_h2,(char*)payload,payload_len,nullptr); // GB28181_stream_out(sign_h2,sign_out_buf,&sign_out_len,&offset_len,&append_len, ¶m); - - - - }else{ - if(sendto(socket,payload,payload_len,0,(const sockaddr*)&addr,sizeof(addr))==-1){ + } + })); + } + + while (reader->getNextPacket(rawPacket)) { + pcpp::Packet parsedPacket(&rawPacket, OsiModelTransportLayer); + auto layer = parsedPacket.getLayerOfType(false); + + if (layer) { + payload = layer->getLayerPayload(); + payload_len = layer->getLayerPayloadSize(); + // cout<<" payload_len:" << payload_len<= 0 && gaptime.tv_sec >= 0) { + nanosleep(&gaptime, NULL); + } else { + // cout<<" s:" << gaptime.tv_sec<<" ns:" << gaptime.tv_nsec < 0) { + timeval delta = {0, 100000}; + sleep(delta); + } + processing.store(false); + output_thread->join(); + } // reader->getNextPacket(rawPacket); - + // for (pcpp::Layer* curLayer = parsedPacket.getFirstLayer(); curLayer != NULL; curLayer = curLayer->getNextLayer()) // { // std::cout @@ -175,44 +193,43 @@ int ReadPcapAndSend(int socket,sockaddr_in & addr,const string & filename,const // create the stats object pcpp::IPcapDevice::PcapStats stats; reader->getStatistics(stats); - std::cout << "Read " << stats.packetsRecv << " packets successfully and " << stats.packetsDrop << " packets could not be read" << std::flush; + std::cout << "Read " << stats.packetsRecv << " packets successfully and " << stats.packetsDrop + << " packets could not be read" << std::flush; return 0; } -int main(int argc, char *argv[]){ - - char ip[16] = {0}; - int sockfd, port; - if (argc>4) - { - string filename(argv[1]); - strcpy(ip, argv[2]); - port = atoi(argv[3]); - string filter(argv[4]); - printf("filename:%s\nip:%s\nport:%d\nfilter:%s\n", filename.data(), ip,port,filter.data()); - sockfd = socket(AF_INET, SOCK_DGRAM , IPPROTO_UDP);//SOCK_STREAM +int +main(int argc, char *argv[]) +{ + + char ip[16] = {0}; + int sockfd, port; + if (argc > 4) { + string filename(argv[1]); + strcpy(ip, argv[2]); + port = atoi(argv[3]); + string filter(argv[4]); + printf("filename:%s\nip:%s\nport:%d\nfilter:%s\n", filename.data(), ip, port, filter.data()); + + sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);//SOCK_STREAM if (sockfd == -1) { printf("create socket failed : %s\n", strerror(errno)); return -1; - } + } int rcvBufSize = 2097152; int rcvlen = sizeof(rcvBufSize); - setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char*)&rcvBufSize, sizeof(rcvBufSize)); - if (getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char*)&rcvBufSize, (socklen_t *)&rcvlen) >= 0) - { + setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *) &rcvBufSize, sizeof(rcvBufSize)); + if (getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *) &rcvBufSize, (socklen_t *) &rcvlen) >= 0) { printf("set udp socket send buff size to : %d\n", rcvBufSize); - if (rcvBufSize < 4194304) - { - printf("socket send buff too small, please set up to 2097152(2M)"); - } - }else { - printf("socket failed : %s\n", strerror(errno)); + if (rcvBufSize < 4194304) { printf("socket send buff too small, please set up to 2097152(2M)"); } + } else { + printf("socket failed : %s\n", strerror(errno)); return -1; - } + } struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); - addr.sin_addr.s_addr =inet_addr(ip); + addr.sin_addr.s_addr = inet_addr(ip); // if(connect(sockfd, (struct sockaddr*)&addr, sizeof(addr))==-1){ // printf("connection error : %s\n", strerror(errno)); // return -1; @@ -220,19 +237,16 @@ int main(int argc, char *argv[]){ // bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)); // while (1) // { - cout.flush(); - auto sign_h=EncrypInit(); - - ReadPcapAndSend(sockfd,addr,filename,filter,sign_h); + cout.flush(); + auto sign_h = EncrypInit(); + + ReadPcapAndSend(sockfd, addr, filename, filter, sign_h); // } - - } - else - { - printf("CMD as: filename.pcap ip port\n"); - system("pause"); - return 0; - } + + } else { + printf("CMD as: filename.pcap ip port\n"); + system("pause"); + return 0; + } return 0; - -} \ No newline at end of file +} diff --git a/src/HuaWei/HWsign.cpp b/src/HuaWei/HWsign.cpp index 543146f..6606f5b 100644 --- a/src/HuaWei/HWsign.cpp +++ b/src/HuaWei/HWsign.cpp @@ -1,137 +1,140 @@ +#include "HuaWei/HWsign.h" +#include "HWcommon.h" +#include "common.h" +#include #include #include #include #include -#include -#include -#include "common.h" -#include "HWcommon.h" -#include "HuaWei/HWsign.h" +#include #include "DecEnc/NALUdecode.h" #include "DecEnc/base64.h" #include "HuaWei/HWsec.h" #ifdef ENABLE_HARDWARE_SIGN - #include "sm/sm.h" +#include "sm/sm.h" #endif +void send_rtp(HWsign *Handle, const char *buf, const uint32_t len, int tcp, void *param); -void send_rtp(HWsign* Handle,const char * buf, const uint32_t len ,int tcp,void * param); - -void print_data2(const char * buf, uint32_t len,uint8_t offest){ - printf("\n --%d-- \n",len); - for (int num = 0; num < offest; num++) - { - printf("%02X ", (uint8_t)buf[num]); - } +void +print_data2(const char *buf, uint32_t len, uint8_t offest) +{ + printf("\n --%d-- \n", len); + for (int num = 0; num < offest; num++) { printf("%02X ", (uint8_t) buf[num]); } printf(", "); - for (int num = offest; num < 20; num++) - { - printf("%02X ", (uint8_t)buf[num]); - } + for (int num = offest; num < 20; num++) { printf("%02X ", (uint8_t) buf[num]); } printf("\n ---- \n"); } -void print_rtp2(const char * buf, uint32_t len,uint8_t offest){ - uint8_t mask=0; - uint16_t seq=0; - uint32_t stamp=0; - mask=(uint8_t)*(buf+1)>>7; +void +print_rtp2(const char *buf, uint32_t len, uint8_t offest) +{ + uint8_t mask = 0; + uint16_t seq = 0; + uint32_t stamp = 0; + mask = (uint8_t) * (buf + 1) >> 7; memcpy(&seq, buf + 2, 2); - seq= ntohs(seq); + seq = ntohs(seq); memcpy(&stamp, buf + 4, 4); - stamp= ntohl(stamp); - DEBUGL("seq %d stamp %d mask %d",seq,stamp,mask); - print_data2(buf,len,offest); + stamp = ntohl(stamp); + DEBUGL("seq %d stamp %d mask %d", seq, stamp, mask); + print_data2(buf, len, offest); } #ifdef ENABLE_HARDWARE_SIGN -int hardware_sign_l(SM2Config * config,const unsigned char * data_in,const size_t in_len, unsigned char * sign_out, uint16_t * sign_len){ +int +hardware_sign_l(SM2Config *config, + const unsigned char *data_in, + const size_t in_len, + unsigned char *sign_out, + uint16_t *sign_len) +{ int rv = 0; rv = Device_Init(); - printf("Device_Init rv = 0x%02x\n", rv); - if(rv != 0) - { - printf("Device_Init Fail\n"); - return -1; - } + printf("Device_Init rv = 0x%02x\n", rv); + if (rv != 0) { + printf("Device_Init Fail\n"); + return -1; + } unsigned char Hash_Data[35]; - unsigned int Hash_Data_len = 32; - rv = Generate_Hash(data_in, (const unsigned int)in_len, Hash_Data, &Hash_Data_len, NULL, SGD_SM3); - if(rv != 0) - { - printf("Generate_Hash FAIL\n\n"); - return -1; - } - else printf("Generate_Hash SUCCESS\n\n"); + unsigned int Hash_Data_len = 32; + rv = Generate_Hash(data_in, (const unsigned int) in_len, Hash_Data, &Hash_Data_len, NULL, SGD_SM3); + if (rv != 0) { + printf("Generate_Hash FAIL\n\n"); + return -1; + } else + printf("Generate_Hash SUCCESS\n\n"); - unsigned int Sign_Data_len = 65; - *sign_len=Sign_Data_len; - rv = Generate_SignData_ExtPrikey(config->prikey, Hash_Data, Hash_Data_len, sign_out, &Sign_Data_len); - if(rv != 0) - { - printf("Generate_SignData_ExtPrikey Fail\n"); - return 0; - } - else printf("Generate_SignData_ExtPrikey SUCCESS\n"); + unsigned int Sign_Data_len = 65; + *sign_len = Sign_Data_len; + rv = Generate_SignData_ExtPrikey(config->prikey, Hash_Data, Hash_Data_len, sign_out, &Sign_Data_len); + if (rv != 0) { + printf("Generate_SignData_ExtPrikey Fail\n"); + return 0; + } else + printf("Generate_SignData_ExtPrikey SUCCESS\n"); return 1; } -int Hardware_sign(SM2Config * config,const unsigned char * data_in,const size_t in_len, unsigned char * sign_out, uint16_t * sign_len){ +int +Hardware_sign(SM2Config *config, + const unsigned char *data_in, + const size_t in_len, + unsigned char *sign_out, + uint16_t *sign_len) +{ int ret; - ret=hardware_sign_l(config,data_in,in_len,sign_out,sign_len); + ret = hardware_sign_l(config, data_in, in_len, sign_out, sign_len); Close_Device(); return ret; } #endif - -void ThreadSign(HWsign * HW_ptr){ +void +ThreadSign(HWsign *HW_ptr) +{ uint8_t sha[128]; cpu_set_t mask; CPU_ZERO(&mask); - CPU_SET(HW_ptr->cpu_core,&mask); - if(pthread_setaffinity_np(pthread_self(),sizeof(mask),&mask)<0){ - ERROL("Sign Thread start fail"); - } - while (1) - { + CPU_SET(HW_ptr->cpu_core, &mask); + if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) { ERROL("Sign Thread start fail"); } + while (1) { std::unique_lock lock(HW_ptr->sign_mtx); - while (HW_ptr->I_seq!=-2) - { - if(HW_ptr->thread_exit){ + while (HW_ptr->I_seq != -2) { + if (HW_ptr->thread_exit) { NOTICEL("sign thread release\n"); sleep(0); return; } HW_ptr->sign_start.wait(lock); } - if(HW_ptr->thread_exit){ - NOTICEL("sign thread release\n"); - sleep(0); - return; + if (HW_ptr->thread_exit) { + NOTICEL("sign thread release\n"); + sleep(0); + return; } SUCSL("Start sign\n"); - NOTICEL("sign cpu:%d\n",sched_getcpu()); - sm3_update(HW_ptr->sm3_hd,(uint8_t*)HW_ptr->buff->data(),HW_ptr->buff->size()); - sm3_final(HW_ptr->sm3_hd,sha); - do_sm2_sign((char*)HW_ptr->sm2_hd->prikey,(char*)HW_ptr->sm2_hd->pubkey,(char *) sha, 32, (char *)HW_ptr->sign); + NOTICEL("sign cpu:%d\n", sched_getcpu()); + sm3_update(HW_ptr->sm3_hd, (uint8_t *) HW_ptr->buff->data(), HW_ptr->buff->size()); + sm3_final(HW_ptr->sm3_hd, sha); + do_sm2_sign((char *) HW_ptr->sm2_hd->prikey, (char *) HW_ptr->sm2_hd->pubkey, (char *) sha, 32, + (char *) HW_ptr->sign); // Hardware_sign(Handle->sm2_hd,(const unsigned char *)(buf+offset),len-offset,sign,&sign_len); - HW_ptr->ver_set.sign_len=64; - memcpy(HW_ptr->ver_set.sign,HW_ptr->sign,64); - HW_ptr->I_seq=-5; - + HW_ptr->ver_set.sign_len = 64; + memcpy(HW_ptr->ver_set.sign, HW_ptr->sign, 64); + HW_ptr->I_seq = -5; + DEBUGL("\n&&&&&&&& sign: hash &&&&&&&&&&&&&&&&&&&&&&&&"); - print_data2((char*)sha,32,32); + print_data2((char *) sha, 32, 32); DEBUGL("\n&&&&&&&& sign: sign &&&&&&&&&&&&&&&&&&&&&&&&"); - print_data2((char*)HW_ptr->sign,64,64); - + print_data2((char *) HW_ptr->sign, 64, 64); // HW_ptr->sign_finish.notify_all(); } @@ -155,130 +158,131 @@ void ThreadSign(HWsign * HW_ptr){ // SUCSL("success sign!!!!!!!!!! sei package\n"); // // send_rtp(HW_ptr,(char *) sei_head,sei_len,0,param); // send_rtp(HW_ptr,(char *) sei,rtp_len,0,param); - + // } -void GenSEI(HWsign * HW_ptr,const char * sei_head, const uint16_t sei_len,void * param){ - uint8_t sei[2048],sei_race[1024]; - uint16_t sign_len=64; - uint8_t * set_ptr=sei; +void +GenSEI(HWsign *HW_ptr, const char *sei_head, const uint16_t sei_len, void *param) +{ + uint8_t sei[2048], sei_race[1024]; + uint16_t sign_len = 64; + uint8_t *set_ptr = sei; uint32_t rtp_len; - memcpy(set_ptr,sei_head,sei_len); - set_ptr+=sei_len; - set_ptr=SecMedia::appendSEIframe(set_ptr,SEC_SET_PT,(uint8_t*)SecMedia::Sec_set_UUID,(uint8_t*)&HW_ptr->sec_set,sizeof(HW_ptr->sec_set)); - set_ptr=SecMedia::appendSEIframe(set_ptr,VER_SET_PT,(uint8_t*)SecMedia::Ver_set_UUID,(uint8_t*)&HW_ptr->ver_set,sizeof(HW_ptr->ver_set)); - HW_ptr->sei_param=nullptr; - rtp_len=set_ptr-sei; + memcpy(set_ptr, sei_head, sei_len); + set_ptr += sei_len; + set_ptr = SecMedia::appendSEIframe( + set_ptr, SEC_SET_PT, (uint8_t *) SecMedia::Sec_set_UUID, (uint8_t *) &HW_ptr->sec_set, sizeof(HW_ptr->sec_set)); + set_ptr = SecMedia::appendSEIframe( + set_ptr, VER_SET_PT, (uint8_t *) SecMedia::Ver_set_UUID, (uint8_t *) &HW_ptr->ver_set, sizeof(HW_ptr->ver_set)); + HW_ptr->sei_param = nullptr; + rtp_len = set_ptr - sei; SUCSL("success sign!!!!!!!!!! sei package\n"); // send_rtp(HW_ptr,(char *) sei_head,sei_len,0,param); - send_rtp(HW_ptr,(char *) sei,rtp_len,0,param); - + send_rtp(HW_ptr, (char *) sei, rtp_len, 0, param); } - -bool MakeFU(uint8_t in, FU &fu) { +bool +MakeFU(uint8_t in, FU &fu) +{ fu.S = in >> 7; fu.E = (in >> 6) & 0x01; fu.R = (in >> 5) & 0x01; fu.type = in & 0x1f; - if (fu.R != 0) { - return false; - } + if (fu.R != 0) { return false; } return true; } -void Make265FU(uint8_t in, FU &fu) { +void +Make265FU(uint8_t in, FU &fu) +{ fu.S = in >> 7; fu.E = (in >> 6) & 0x01; fu.type = in & 0x3f; } - -uint32_t add_racing_code(uint8_t *dst,uint8_t *src, uint32_t src_len,uint16_t jump_bytes) +uint32_t +add_racing_code(uint8_t *dst, uint8_t *src, uint32_t src_len, uint16_t jump_bytes) { - const uint8_t d_zero[]={0x00,0x00}; - uint8_t *ptr_zero=src+jump_bytes,*dst_head=dst,*src_tail=src+src_len, *noncpy_src_head=src; - uint32_t data_len=0,remain_data_len=src_len-jump_bytes; - while(remain_data_len>2) - { - ptr_zero=(uint8_t*) memmem(ptr_zero,remain_data_len-2,&d_zero,sizeof(d_zero)); - if(ptr_zero ){ //0x00 1 2 3 - ptr_zero+=2; - - if(!(*(ptr_zero)&0xFC)){ - data_len=ptr_zero-noncpy_src_head; - memcpy(dst_head,noncpy_src_head,data_len); - dst_head+=data_len; - *(dst_head++)=0x03; - noncpy_src_head=ptr_zero; //更新未复制的源数据头 + const uint8_t d_zero[] = {0x00, 0x00}; + uint8_t *ptr_zero = src + jump_bytes, *dst_head = dst, *src_tail = src + src_len, *noncpy_src_head = src; + uint32_t data_len = 0, remain_data_len = src_len - jump_bytes; + while (remain_data_len > 2) { + ptr_zero = (uint8_t *) memmem(ptr_zero, remain_data_len - 2, &d_zero, sizeof(d_zero)); + if (ptr_zero) {//0x00 1 2 3 + ptr_zero += 2; + + if (!(*(ptr_zero) & 0xFC)) { + data_len = ptr_zero - noncpy_src_head; + memcpy(dst_head, noncpy_src_head, data_len); + dst_head += data_len; + *(dst_head++) = 0x03; + noncpy_src_head = ptr_zero;//更新未复制的源数据头 } - remain_data_len=(src_tail-ptr_zero); - }else - { + remain_data_len = (src_tail - ptr_zero); + } else { break; } } - data_len=src_tail-noncpy_src_head; - memcpy(dst_head,noncpy_src_head,data_len); + data_len = src_tail - noncpy_src_head; + memcpy(dst_head, noncpy_src_head, data_len); //int finnum=(int)(dst_head-dst)+(int)data_len; - return (uint32_t)(dst_head-dst)+data_len;; + return (uint32_t) (dst_head - dst) + data_len; + ; } -uint32_t del_racing_code(uint8_t *dst,uint8_t *src, uint32_t src_len) +uint32_t +del_racing_code(uint8_t *dst, uint8_t *src, uint32_t src_len) { - const uint8_t d_zero[]={0x00,0x00,0x03}; - uint8_t *ptr_zero=src,*dst_head=dst,*src_tail=src+src_len, *noncpy_src_head=src; - uint32_t data_len=0,remain_data_len=src_len; - while(remain_data_len>2) - { - ptr_zero=(uint8_t*) memmem(ptr_zero,remain_data_len-2,&d_zero,sizeof(d_zero)); - if(ptr_zero ){ //0x00 1 2 3 - ptr_zero+=3; - + const uint8_t d_zero[] = {0x00, 0x00, 0x03}; + uint8_t *ptr_zero = src, *dst_head = dst, *src_tail = src + src_len, *noncpy_src_head = src; + uint32_t data_len = 0, remain_data_len = src_len; + while (remain_data_len > 2) { + ptr_zero = (uint8_t *) memmem(ptr_zero, remain_data_len - 2, &d_zero, sizeof(d_zero)); + if (ptr_zero) {//0x00 1 2 3 + ptr_zero += 3; - data_len=ptr_zero-noncpy_src_head-1;//末尾0x03 不要 - memcpy(dst_head,noncpy_src_head,data_len); - dst_head+=data_len; + data_len = ptr_zero - noncpy_src_head - 1;//末尾0x03 不要 + memcpy(dst_head, noncpy_src_head, data_len); + dst_head += data_len; - noncpy_src_head=ptr_zero; //更新未复制的源数据头 + noncpy_src_head = ptr_zero;//更新未复制的源数据头 - remain_data_len=(src_tail-ptr_zero); - }else - { + remain_data_len = (src_tail - ptr_zero); + } else { break; } } - data_len=src_tail-noncpy_src_head; - memcpy(dst_head,noncpy_src_head,data_len); + data_len = src_tail - noncpy_src_head; + memcpy(dst_head, noncpy_src_head, data_len); //int finnum=(int)(dst_head-dst)+(int)data_len; - return (uint32_t)(dst_head-dst)+data_len;; + return (uint32_t) (dst_head - dst) + data_len; + ; } - // void * HWSign_init(const function rtp_callback){ -void * HWSign_init(struct sec_set_info * sign_info){ - if(!sign_info) return nullptr; - HWsign* HWSign_hd= new HWsign(); - HWSign_hd->I_seq=-1; - HWSign_hd->in=0; - HWSign_hd->out=0; - HWSign_hd->seq_accu=0; - HWSign_hd->stamp=0; - HWSign_hd->buff_offest=0; - HWSign_hd->track_type=CodecInvalid; - HWSign_hd->sm3_hd=new sm3_ctx(); - HWSign_hd->sm2_hd=new SM2Config(); - HWSign_hd->buff=new string(); - HWSign_hd->rtp_buff = new list,void *>>(); - HWSign_hd->buff_que =new ThreadsafeQueue,void *>>(); +void * +HWSign_init(struct sec_set_info *sign_info) +{ + if (!sign_info) return nullptr; + HWsign *HWSign_hd = new HWsign(); + HWSign_hd->I_seq = -1; + HWSign_hd->in = 0; + HWSign_hd->out = 0; + HWSign_hd->seq_accu = 0; + HWSign_hd->stamp = 0; + HWSign_hd->buff_offest = 0; + HWSign_hd->track_type = CodecInvalid; + HWSign_hd->sm3_hd = new sm3_ctx(); + HWSign_hd->sm2_hd = new SM2Config(); + HWSign_hd->buff = new string(); + HWSign_hd->rtp_buff = new list, void *>>(); + HWSign_hd->buff_que = new ThreadsafeQueue, void *>>(); // HWSign_hd->rtp_cb=rtp_callback; - HWSign_hd->rtp_cb=[HWSign_hd](const char * rtp_ptr, const uint32_t rtp_len,void * param){ - + HWSign_hd->rtp_cb = [HWSign_hd](const char *rtp_ptr, const uint32_t rtp_len, void *param) { DEBUGL("\n========================= output ====== "); // print_rtp2(rtp_ptr,rtp_len,12); - auto str_ptr=make_shared(rtp_ptr,rtp_len); - HWSign_hd->buff_que->push(make_pair(str_ptr,param)); - + auto str_ptr = make_shared(rtp_ptr, rtp_len); + HWSign_hd->buff_que->push(make_pair(str_ptr, param)); }; sm3_init(HWSign_hd->sm3_hd); // SM2Config sm2fig={ @@ -295,90 +299,106 @@ void * HWSign_init(struct sec_set_info * sign_info){ // 0xfc,0x00,0x08,0x97,0x78,0x2c,0x71,0x6b,0xe1,0x26,0xf5,0x1e,0xba,0x31,0xf5,0xb2, // } // }; - HWSign_hd->sm2_hd->prikey_size=sign_info->prikey_size; - HWSign_hd->sm2_hd->pubkey_size=sign_info->pubkey_size; - memcpy(HWSign_hd->sm2_hd->prikey,sign_info->prikey,sign_info->prikey_size); - memcpy(HWSign_hd->sm2_hd->pubkey,sign_info->pubkey,sign_info->pubkey_size); - genSECset(HWSign_hd,sign_info); - HWSign_hd->cpu_core=sign_info->cpu_core; - HWSign_hd->thread_exit=0; - HWSign_hd->sign_thread=new std::thread(ThreadSign,HWSign_hd); + HWSign_hd->sm2_hd->prikey_size = sign_info->prikey_size; + HWSign_hd->sm2_hd->pubkey_size = sign_info->pubkey_size; + memcpy(HWSign_hd->sm2_hd->prikey, sign_info->prikey, sign_info->prikey_size); + memcpy(HWSign_hd->sm2_hd->pubkey, sign_info->pubkey, sign_info->pubkey_size); + genSECset(HWSign_hd, sign_info); + HWSign_hd->cpu_core = sign_info->cpu_core; + HWSign_hd->thread_exit = 0; + HWSign_hd->sign_thread = new std::thread(ThreadSign, HWSign_hd); HWSign_hd->sign_thread->detach(); - return (void*)HWSign_hd; + return (void *) HWSign_hd; } -void HWSign_release(void* Handle){ - HWsign* HWSign_hd=(HWsign*) Handle; +void +HWSign_release(void *Handle) +{ + HWsign *HWSign_hd = (HWsign *) Handle; delete HWSign_hd->sm3_hd; delete HWSign_hd->sm2_hd; delete HWSign_hd->buff; delete HWSign_hd->rtp_buff; - HWSign_hd->thread_exit=1; + HWSign_hd->thread_exit = 1; HWSign_hd->sign_start.notify_all(); delete HWSign_hd->sign_thread; - HWSign_hd->rtp_cb=nullptr; + HWSign_hd->rtp_cb = nullptr; } -uint16_t get_sequence(const char * rtp ,int tcp){ +uint16_t +get_sequence(const char *rtp, int tcp) +{ uint16_t seq; - if(tcp){ + if (tcp) { memcpy(&seq, rtp + 2 + 4, 2); - }else{ + } else { memcpy(&seq, rtp + 2 + 0, 2); } return htons(seq); } -void send_rtp(HWsign* Handle,const char * buf, const uint32_t len ,int tcp,void * param){ - char * send_buff=(char *)malloc(len); - uint8_t offset,offset2; +void +send_rtp(HWsign *Handle, const char *buf, const uint32_t len, int tcp, void *param) +{ + char *send_buff = (char *) malloc(len); + uint8_t offset, offset2; uint16_t seq; - memcpy(send_buff,buf,len); - if (tcp) - { - offset2=16; - offset=4; - send_buff[2] = (len-4) >> 8; - send_buff[3] = (len-4) & 0x00FF; - }else - { - offset2=12; - offset=0; + memcpy(send_buff, buf, len); + if (tcp) { + offset2 = 16; + offset = 4; + send_buff[2] = (len - 4) >> 8; + send_buff[3] = (len - 4) & 0x00FF; + } else { + offset2 = 12; + offset = 0; } memcpy(&seq, buf + 2 + offset, 2); - seq=ntohs(seq)+Handle->seq_accu; - seq=htons(seq); - memcpy(send_buff+offset+2, &seq, 2); + seq = ntohs(seq) + Handle->seq_accu; + seq = htons(seq); + memcpy(send_buff + offset + 2, &seq, 2); // DEBUGL("\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ modify @@@@@@@@@ id %d ",id); // print_rtp2(send_buff,len,offset2); - Handle->rtp_cb(send_buff,len,param); + Handle->rtp_cb(send_buff, len, param); free(send_buff); } -void sign_data(HWsign* Handle,const char * buf, const uint32_t len,uint8_t offset,int tcp,void * param,const char * sei_head, const uint16_t sei_len){ - uint8_t sha[128],sign[128],sei[2048],sei_race[1024]; - uint16_t sign_len=64; - sm3_update(Handle->sm3_hd,(uint8_t*)buf+offset,len-offset); - sm3_final(Handle->sm3_hd,sha); - do_sm2_sign((char*)Handle->sm2_hd->prikey,(char*)Handle->sm2_hd->pubkey,(char *) sha, 32, (char *)sign); + +void +sign_data(HWsign *Handle, + const char *buf, + const uint32_t len, + uint8_t offset, + int tcp, + void *param, + const char *sei_head, + const uint16_t sei_len) +{ + uint8_t sha[128], sign[128], sei[2048], sei_race[1024]; + uint16_t sign_len = 64; + sm3_update(Handle->sm3_hd, (uint8_t *) buf + offset, len - offset); + sm3_final(Handle->sm3_hd, sha); + do_sm2_sign((char *) Handle->sm2_hd->prikey, (char *) Handle->sm2_hd->pubkey, (char *) sha, 32, (char *) sign); // Hardware_sign(Handle->sm2_hd,(const unsigned char *)(buf+offset),len-offset,sign,&sign_len); DEBUGL("\n&&&&&&&& sign: hash &&&&&&&&&&&&&&&&&&&&&&&&"); - print_data2((char*)sha,32,32); + print_data2((char *) sha, 32, 32); DEBUGL("\n&&&&&&&& sign: sign &&&&&&&&&&&&&&&&&&&&&&&&"); - print_data2((char*)sign,64,64); + print_data2((char *) sign, 64, 64); - Handle->sei_param=nullptr; - auto rtp_len=SecMedia::GeneHWSecritySEI(sei,Handle->track_type,1,len-offset,sign_len,sign,(char *)sei_head,sei_len); - rtp_len=add_racing_code(sei_race,sei+sei_len,rtp_len-sei_len); - memcpy(sei+sei_len,sei_race,rtp_len); - rtp_len+=sei_len; + Handle->sei_param = nullptr; + auto rtp_len = SecMedia::GeneHWSecritySEI( + sei, Handle->track_type, 1, len - offset, sign_len, sign, (char *) sei_head, sei_len); + rtp_len = add_racing_code(sei_race, sei + sei_len, rtp_len - sei_len); + memcpy(sei + sei_len, sei_race, rtp_len); + rtp_len += sei_len; SUCSL("success sign!!!!!!!!!! sei package\n"); - send_rtp(Handle,(char *) sei,rtp_len,tcp,param); + send_rtp(Handle, (char *) sei, rtp_len, tcp, param); // Handle->seq_accu++; } + // void none_sign_data(HWsign* Handle,uint8_t offset,int tcp,void * param,const char * sei_head){ // uint8_t sei[1024]; // auto rtp_len=SecMedia::GeneHWSecritySEI(sei,Handle->track_type,0,0,64,nullptr,(char *)sei_head, Handle->sei_len); @@ -386,25 +406,29 @@ void sign_data(HWsign* Handle,const char * buf, const uint32_t len,uint8_t offse // WRNGL("Warning!!!!!!!!!! none sei package\n"); // send_rtp(Handle,(char *) sei,rtp_len,tcp,param); // } -int HWSign_rtp_out(void* Handle, char * buf, uint32_t * len, void ** param){ - HWsign* HWSign_hd=(HWsign*) Handle; - if(!HWSign_hd) return -1; +int +HWSign_rtp_out(void *Handle, char *buf, uint32_t *len, void **param) +{ + HWsign *HWSign_hd = (HWsign *) Handle; + if (!HWSign_hd) return -1; // if (HWSign_hd->buff_que->empty()) return -1; - auto element= HWSign_hd->buff_que->pop(); + auto element = HWSign_hd->buff_que->pop(); if (!element.first || element.first->empty()) return -1; - *len=(uint32_t) element.first->size(); - memcpy(buf,element.first->data(),*len); - *param=element.second; + *len = (uint32_t) element.first->size(); + memcpy(buf, element.first->data(), *len); + *param = element.second; HWSign_hd->out++; - DEBUGL("\nHWSign: in %d out %d \n",HWSign_hd->in,HWSign_hd->out); + DEBUGL("\nHWSign: in %d out %d \n", HWSign_hd->in, HWSign_hd->out); return 1; } -void flush_all(HWsign* HWSign_hd){ - auto rtp_list=*(HWSign_hd->rtp_buff); - for(auto& rtp_sig : rtp_list){ - HWSign_hd->rtp_cb(rtp_sig.first->data(),rtp_sig.first->size(),rtp_sig.second); +void +flush_all(HWsign *HWSign_hd) +{ + auto rtp_list = *(HWSign_hd->rtp_buff); + for (auto &rtp_sig : rtp_list) { + HWSign_hd->rtp_cb(rtp_sig.first->data(), rtp_sig.first->size(), rtp_sig.second); // send_rtp(HWSign_hd,rtp_sig.first->data(),rtp_sig.first->size(),HWSign_hd->tcp,rtp_sig.second); } HWSign_hd->buff->clear(); @@ -412,126 +436,126 @@ void flush_all(HWsign* HWSign_hd){ DEBUGL("flush all!!!!!!!!!! \n"); } -int HWSign_rtp_264(HWsign* HWSign_hd, const char * buf, const uint32_t len,int tcp, void * param){ +int +HWSign_rtp_264(HWsign *HWSign_hd, const char *buf, const uint32_t len, int tcp, void *param) +{ uint8_t offset; - if (tcp) offset=16; - else offset=12; + if (tcp) + offset = 16; + else + offset = 12; - const char * rtp=buf+offset; - int length = len- offset; + const char *rtp = buf + offset; + int length = len - offset; int nal_type = *rtp & 0x1F; int nal_suffix = *rtp & (~0x1F); - - uint16_t now_seq= get_sequence(buf,tcp); + + uint16_t now_seq = get_sequence(buf, tcp); DEBUGL("\n###### input ##########################"); // print_rtp2(buf,len,offset); // send_rtp(HWSign_hd,buf,len,tcp,id); // return 1; // HWSign_hd->rtp_cb(buf,len,id); // return 1; - TRACEL("nal_type:%d\n",nal_type); - if (nal_type == 5 || nal_type == 7 || nal_type == 8 ) { + TRACEL("nal_type:%d\n", nal_type); + if (nal_type == 5 || nal_type == 7 || nal_type == 8) { //a full frame // send_rtp(HWSign_hd,buf,len,tcp,id); - HWSign_hd->rtp_cb(buf,len,param); + HWSign_hd->rtp_cb(buf, len, param); return 1; } - switch (nal_type){ - case 6:{ - NOTICEL("SEI!!!!!!!!!! package\n"); - NOTICEL("main cpu:%d\n",sched_getcpu()); - if(len<1300){ - - std::unique_lock lock(HWSign_hd->sign_mtx); - if (!HWSign_hd->buff->empty()) - { - if(HWSign_hd->I_seq==-5) - GenSEI(HWSign_hd,buf,len,param); - else - WRNGL("Sign not complete\n"); + switch (nal_type) { + case 6: { + NOTICEL("SEI!!!!!!!!!! package\n"); + NOTICEL("main cpu:%d\n", sched_getcpu()); + if (len < 1300) { - HWSign_hd->I_seq=-1; - HWSign_hd->buff->clear(); - return -1; - }else - { - WRNGL("Without Sign data\n"); - - } - + std::unique_lock lock(HWSign_hd->sign_mtx); + if (!HWSign_hd->buff->empty()) { + if (HWSign_hd->I_seq == -5) + GenSEI(HWSign_hd, buf, len, param); + else + WRNGL("Sign not complete\n"); + + HWSign_hd->I_seq = -1; + HWSign_hd->buff->clear(); + return -1; + } else { + WRNGL("Without Sign data\n"); } - HWSign_hd->I_seq=-1; - HWSign_hd->rtp_cb(buf,len,param); + } + HWSign_hd->I_seq = -1; + HWSign_hd->rtp_cb(buf, len, param); + return 1; + } + case 28: { + FU fu; + MakeFU((uint8_t) rtp[1], fu); + + if (fu.type != 5) { + HWSign_hd->rtp_cb(buf, len, param); + // send_rtp(HWSign_hd,buf,len,tcp,param); return 1; } - case 28:{ - FU fu; - MakeFU((uint8_t)rtp[1], fu); - if (fu.type!=5) - { - HWSign_hd->rtp_cb(buf,len,param); - // send_rtp(HWSign_hd,buf,len,tcp,param); - return 1; + // HWSign_hd->rtp_cb(buf,len,param); + // return 1; + // TRACEL("%u,%u",fu.type,fu.S); + if (fu.S) {//第一个rtp包 + std::unique_lock lock(HWSign_hd->sign_mtx); + if (!HWSign_hd->buff->empty()) { + WRNGL("Warning!!!!!!!!!! missing sei package\n"); + HWSign_hd->buff->clear(); } - - // HWSign_hd->rtp_cb(buf,len,param); - // return 1; - // TRACEL("%u,%u",fu.type,fu.S); - if (fu.S) { //第一个rtp包 - std::unique_lock lock(HWSign_hd->sign_mtx); - if(!HWSign_hd->buff->empty()){ - WRNGL("Warning!!!!!!!!!! missing sei package\n"); - HWSign_hd->buff->clear(); - } - INFOL("!!!!!!!!!! I head\n"); - HWSign_hd->I_seq=now_seq; - HWSign_hd->buff->assign(rtp+2,length-2); - HWSign_hd->rtp_cb(buf,len,param); - return 1; - } - - if(HWSign_hd->I_seq+1==now_seq){ - HWSign_hd->I_seq=now_seq; - - HWSign_hd->buff->append(rtp+2,length-2); - HWSign_hd->rtp_cb(buf,len,param); - if (!fu.E) { //中间rtp包 - return 1; - } - INFOL("!!!!!!!!!! I END\n"); - // flush_all(HWSign_hd); - HWSign_hd->I_seq=-2; //complete - - HWSign_hd->sign_start.notify_all(); - return 1; - }else{ - HWSign_hd->rtp_cb(buf,len,param); - return 1; - } - - + INFOL("!!!!!!!!!! I head\n"); + HWSign_hd->I_seq = now_seq; + HWSign_hd->buff->assign(rtp + 2, length - 2); + HWSign_hd->rtp_cb(buf, len, param); + return 1; } - default:{ - HWSign_hd->rtp_cb(buf,len,param); + + if (HWSign_hd->I_seq + 1 == now_seq) { + HWSign_hd->I_seq = now_seq; + + HWSign_hd->buff->append(rtp + 2, length - 2); + HWSign_hd->rtp_cb(buf, len, param); + if (!fu.E) {//中间rtp包 + return 1; + } + INFOL("!!!!!!!!!! I END\n"); + // flush_all(HWSign_hd); + HWSign_hd->I_seq = -2;//complete + + HWSign_hd->sign_start.notify_all(); + return 1; + } else { + HWSign_hd->rtp_cb(buf, len, param); return 1; } } + default: { + HWSign_hd->rtp_cb(buf, len, param); + return 1; + } + } } - -int HWSign_rtp_265(HWsign* HWSign_hd, const char * buf, const uint32_t len,int tcp, void * param){ +int +HWSign_rtp_265(HWsign *HWSign_hd, const char *buf, const uint32_t len, int tcp, void *param) +{ uint8_t offset; - if (tcp) offset=16; - else offset=12; + if (tcp) + offset = 16; + else + offset = 12; - const char * rtp=buf+offset; - int length = len- offset; + const char *rtp = buf + offset; + int length = len - offset; int nal_type = H265_TYPE(*rtp); // int nal_suffix = *rtp & (~0x1F); - - uint16_t now_seq= get_sequence(buf,tcp); + + uint16_t now_seq = get_sequence(buf, tcp); DEBUGL("\n###### input ########################## nal: %d ", nal_type); // print_rtp2(buf,len,offset); // send_rtp(HWSign_hd,buf,len,tcp,id); @@ -539,206 +563,210 @@ int HWSign_rtp_265(HWsign* HWSign_hd, const char * buf, const uint32_t len,int t // HWSign_hd->rtp_cb(buf,len,id); // return 1; - switch (nal_type){ - case H265Nal::NAL_SEI_PREFIX:{ - NOTICEL("SEI!!!!!!!!!! package\n"); - NOTICEL("main cpu:%d\n",sched_getcpu()); - if(len<1300){ - - std::unique_lock lock(HWSign_hd->sign_mtx); - if (!HWSign_hd->buff->empty()) - { - if(HWSign_hd->I_seq==-5) - GenSEI(HWSign_hd,buf,len,param); - else - if(HWSign_hd->I_seq==-2) - WRNGL("Sign not complete\n"); - else - WRNGL("non Sign\n"); + switch (nal_type) { + case H265Nal::NAL_SEI_PREFIX: { + NOTICEL("SEI!!!!!!!!!! package\n"); + NOTICEL("main cpu:%d\n", sched_getcpu()); + if (len < 1300) { - HWSign_hd->I_seq=-1; - HWSign_hd->buff->clear(); - return -1; - }else - { - WRNGL("Without Sign data\n"); - - } - + std::unique_lock lock(HWSign_hd->sign_mtx); + if (!HWSign_hd->buff->empty()) { + if (HWSign_hd->I_seq == -5) + GenSEI(HWSign_hd, buf, len, param); + else if (HWSign_hd->I_seq == -2) + WRNGL("Sign not complete\n"); + else + WRNGL("non Sign\n"); + + HWSign_hd->I_seq = -1; + HWSign_hd->buff->clear(); + return -1; + } else { + WRNGL("Without Sign data\n"); } - HWSign_hd->I_seq=-1; - HWSign_hd->rtp_cb(buf,len,param); + } + HWSign_hd->I_seq = -1; + HWSign_hd->rtp_cb(buf, len, param); + return 1; + } + case 49: { + FU fu; + Make265FU((uint8_t) rtp[2], fu); + + if (!(fu.type >= H265Nal::NAL_IDR_W_RADL && fu.type <= H265Nal::NAL_IDR_N_LP)) { + HWSign_hd->rtp_cb(buf, len, param); + // send_rtp(HWSign_hd,buf,len,tcp,param); return 1; } - case 49:{ - FU fu; - Make265FU((uint8_t)rtp[2], fu); + // HWSign_hd->rtp_cb(buf,len,param); + // return 1; - if (!(fu.type>=H265Nal::NAL_IDR_W_RADL && fu.type<=H265Nal::NAL_IDR_N_LP)) - { - HWSign_hd->rtp_cb(buf,len,param); - // send_rtp(HWSign_hd,buf,len,tcp,param); - return 1; + if (fu.S) {//第一个rtp包 + std::unique_lock lock(HWSign_hd->sign_mtx); + if (!HWSign_hd->buff->empty()) { + WRNGL("Warning!!!!!!!!!! missing package\n"); + HWSign_hd->buff->clear(); } - // HWSign_hd->rtp_cb(buf,len,param); - // return 1; - - if (fu.S) { //第一个rtp包 - std::unique_lock lock(HWSign_hd->sign_mtx); - if(!HWSign_hd->buff->empty()){ - WRNGL("Warning!!!!!!!!!! missing package\n"); - HWSign_hd->buff->clear(); - } - DEBUGL("!!!!!!!!!! I head\n"); - HWSign_hd->I_seq=now_seq; - HWSign_hd->buff->assign(rtp+3,length-3); - HWSign_hd->rtp_cb(buf,len,param); - return 1; - } - - if(HWSign_hd->I_seq+1==now_seq){ - HWSign_hd->I_seq=now_seq; - HWSign_hd->buff->append(rtp+3,length-3); - HWSign_hd->rtp_cb(buf,len,param); - if (!fu.E) { //中间rtp包 - return 1; - } - - HWSign_hd->I_seq=-2; //complete - - HWSign_hd->sign_start.notify_all(); - // SUCSL("Notify sign\n"); - return 1; - }else{ - HWSign_hd->rtp_cb(buf,len,param); - return 1; - } - - + DEBUGL("!!!!!!!!!! I head\n"); + HWSign_hd->I_seq = now_seq; + HWSign_hd->buff->assign(rtp + 3, length - 3); + HWSign_hd->rtp_cb(buf, len, param); + return 1; } - default:{ - HWSign_hd->rtp_cb(buf,len,param); + + if (HWSign_hd->I_seq + 1 == now_seq) { + HWSign_hd->I_seq = now_seq; + HWSign_hd->buff->append(rtp + 3, length - 3); + HWSign_hd->rtp_cb(buf, len, param); + if (!fu.E) {//中间rtp包 + return 1; + } + + HWSign_hd->I_seq = -2;//complete + + HWSign_hd->sign_start.notify_all(); + // SUCSL("Notify sign\n"); + return 1; + } else { + HWSign_hd->rtp_cb(buf, len, param); return 1; } } + default: { + HWSign_hd->rtp_cb(buf, len, param); + return 1; + } + } } -int HWSign_rtp_input(void* Handle, const char * buf, const uint32_t len, void * param){ - int ret=-1; - HWsign* HWSign_hd=(HWsign*) Handle; - if(!HWSign_hd || !HWSign_hd->rtp_cb || !HWSign_hd->sm3_hd || !HWSign_hd->sm2_hd || !HWSign_hd->buff || !HWSign_hd->buff_que) { +int +HWSign_rtp_input(void *Handle, const char *buf, const uint32_t len, void *param) +{ + int ret = -1; + HWsign *HWSign_hd = (HWsign *) Handle; + if (!HWSign_hd || !HWSign_hd->rtp_cb || !HWSign_hd->sm3_hd || !HWSign_hd->sm2_hd || !HWSign_hd->buff + || !HWSign_hd->buff_que) { throw runtime_error("HWSign_rtp initial error"); return -1; } HWSign_hd->in++; - DEBUGL("input: in %d que %ld out %d \n",HWSign_hd->in,HWSign_hd->buff_que->size(),HWSign_hd->out); + DEBUGL("input: in %d que %ld out %d \n", HWSign_hd->in, HWSign_hd->buff_que->size(), HWSign_hd->out); - HWSign_hd->tcp=0; - uint8_t offset=12; + HWSign_hd->tcp = 0; + uint8_t offset = 12; - if (len<=offset) { - HWSign_hd->rtp_cb(buf,len,param); + if (len <= offset) { + HWSign_hd->rtp_cb(buf, len, param); return 1; } - if((uint8_t)buf[0]!=0x80){ + if ((uint8_t) buf[0] != 0x80) { WRNGL("Not RTP Package\n"); - HWSign_hd->rtp_cb(buf,len,param); + HWSign_hd->rtp_cb(buf, len, param); return 1; } + uint8_t payload_type = buf[1] & 0x7f; - uint8_t payload_type=buf[1]& 0x7f; - - switch (payload_type) - { - case 99: //h264 - if (HWSign_hd->track_type!=CodecId::CodecH264) - { - HWSign_hd->track_type=CodecId::CodecH264; + switch (payload_type) { + case 99://h264 + if (HWSign_hd->track_type != CodecId::CodecH264) { + HWSign_hd->track_type = CodecId::CodecH264; DEBUGL("Track type is changed to H.264"); } - ret=HWSign_rtp_264(HWSign_hd,buf,len,0,param); + ret = HWSign_rtp_264(HWSign_hd, buf, len, 0, param); break; - case 103 ... 108: //h265 - if (HWSign_hd->track_type!=CodecId::CodecH265) - { - HWSign_hd->track_type=CodecId::CodecH265; + case 103 ... 108://h265 + if (HWSign_hd->track_type != CodecId::CodecH265) { + HWSign_hd->track_type = CodecId::CodecH265; DEBUGL("Track type is changed to H.265"); } - ret=HWSign_rtp_265(HWSign_hd,buf,len,0,param); + ret = HWSign_rtp_265(HWSign_hd, buf, len, 0, param); break; - case 0 ... 95: // standard type - HWSign_hd->rtp_cb(buf,len,param); + case 0 ... 95:// standard type + HWSign_hd->rtp_cb(buf, len, param); break; default: - HWSign_hd->rtp_cb(buf,len,param); - WRNGL("Error !!!!!!!!!! Unsupport track type: %u \n",payload_type); + HWSign_hd->rtp_cb(buf, len, param); + WRNGL("Error !!!!!!!!!! Unsupport track type: %u \n", payload_type); break; } - return 1; } -int genSECset(HWsign * HWptr,struct sec_set_info * sign_info){ +int +genSECset(HWsign *HWptr, struct sec_set_info *sign_info) +{ + uint8_t security_set_version[19] = "Ver 0.0.2"; + memset(&HWptr->sec_set, 0, sizeof(HWptr->sec_set)); + HWptr->sec_set.Flag.encryption_flag = 0; + HWptr->sec_set.Flag.authnetication_flag = 1; + HWptr->sec_set.Flag.vek_flag = 0; + HWptr->sec_set.Flag.iv_flag = 0; + HWptr->sec_set.Flag.hash_discard_p_picture = 1; + HWptr->sec_set.Flag.reserved_flag = 0b001; - uint8_t security_set_version[19] = "Ver 0.0.2"; - memset(&HWptr->sec_set,0,sizeof(HWptr->sec_set)); - HWptr->sec_set.Flag.encryption_flag = 0; - HWptr->sec_set.Flag.authnetication_flag = 1; - HWptr->sec_set.Flag.vek_flag = 0; - HWptr->sec_set.Flag.iv_flag = 0; - HWptr->sec_set.Flag.hash_discard_p_picture = 1; - HWptr->sec_set.Flag.reserved_flag = 0b001; + HWptr->sec_set.Type.signature_type = (uint8_t) SecMedia::DecryptType::SM2_auth; + HWptr->sec_set.Type.hash_type = (uint8_t) SecMedia::DecryptType::SM3; + HWptr->sec_set.Type.encryption_type = (uint8_t) SecMedia::DecryptType::NONE; + HWptr->sec_set.Type.vek_encryption_type = (uint8_t) SecMedia::DecryptType::NONE; - HWptr->sec_set.Type.signature_type = (uint8_t) SecMedia::DecryptType::SM2_auth; - HWptr->sec_set.Type.hash_type =(uint8_t) SecMedia::DecryptType::SM3; - HWptr->sec_set.Type.encryption_type =(uint8_t) SecMedia::DecryptType::NONE; - HWptr->sec_set.Type.vek_encryption_type = (uint8_t) SecMedia::DecryptType::NONE; + memcpy(HWptr->sec_set.camera_id, sign_info->camera_id, 20); - memcpy(HWptr->sec_set.camera_id, sign_info->camera_id, 20); + HWptr->sec_set.vkek_version_length_minus1 = 31;//@@在加密复用中:为视频密钥长度 + //////////////////////////////////////////// + memcpy(HWptr->sec_set.vkek_version, sign_info->vkek_version, 32); + HWptr->sec_set.end_flag = 0x80; - HWptr->sec_set.vkek_version_length_minus1 = 31; //@@在加密复用中:为视频密钥长度 - //////////////////////////////////////////// - memcpy(HWptr->sec_set.vkek_version, sign_info->vkek_version, 32); - HWptr->sec_set.end_flag=0x80; - - /////////////////////ver set - - memset(&HWptr->ver_set,0,sizeof(HWptr->ver_set)); - HWptr->ver_set.end_flag=0x80; - return 1; + /////////////////////ver set + memset(&HWptr->ver_set, 0, sizeof(HWptr->ver_set)); + HWptr->ver_set.end_flag = 0x80; + return 1; } - -void * HWSign_tcp_init(struct sec_set_info * sign_info){ - HWsec * HWsec_ptr= new HWsec(sign_info); - return (void*) HWsec_ptr; +void * +HWSign_tcp_init(struct sec_set_info *sign_info) +{ + HWsec *HWsec_ptr = new HWsec(sign_info); + return (void *) HWsec_ptr; } -void HWSign_tcp_release(void* Handle){ - delete (HWsec *)Handle; -} -int HWSign_tcp_rtp_input(void* Handle, const char * buf, const uint32_t len, void * param){ - HWsec * HWsec_ptr=(HWsec * )Handle; - if(!HWsec_ptr || !HWsec_ptr->check_class()) { - if(!HWsec_ptr) ERROL("HWSign_tcp_rtp_input NULL Handle"); - if(!HWsec_ptr->check_class()) ERROL("HWSign_tcp_rtp Wrong Type Handle"); +void +HWSign_tcp_release(void *Handle) +{ + delete (HWsec *) Handle; +} + +int +HWSign_tcp_rtp_input(void *Handle, const char *buf, const uint32_t len, void *param) +{ + + HWsec *HWsec_ptr = (HWsec *) Handle; + if (!HWsec_ptr || !HWsec_ptr->check_class()) { + if (!HWsec_ptr) ERROL("HWSign_tcp_rtp_input NULL Handle"); + if (!HWsec_ptr->check_class()) ERROL("HWSign_tcp_rtp Wrong Type Handle"); throw runtime_error("HWSign_tcp_rtp initial error"); } - HWsec_ptr->HWsec_input((uint8_t*)buf,len,param); + HWsec_ptr->HWsec_input((uint8_t *) buf, len, param); return 1; } -int HWSign_tcp_rtp_out(void* Handle, char * buf, uint32_t * len,uint16_t* sei_end_offset,uint16_t* append_length, void ** param){ - HWsec * HWsec_ptr=(HWsec * )Handle; - if(!HWsec_ptr || !HWsec_ptr->check_class()) { - if(!HWsec_ptr) ERROL("HWSign_tcp_rtp_out NULL Handle"); - if(!HWsec_ptr->check_class()) ERROL("HWSign_tcp_rtp_out Wrong Type Handle"); + +int +HWSign_tcp_rtp_out(void *Handle, + char *buf, + uint32_t *len, + uint16_t *sei_end_offset, + uint16_t *append_length, + void **param) +{ + HWsec *HWsec_ptr = (HWsec *) Handle; + if (!HWsec_ptr || !HWsec_ptr->check_class()) { + if (!HWsec_ptr) ERROL("HWSign_tcp_rtp_out NULL Handle"); + if (!HWsec_ptr->check_class()) ERROL("HWSign_tcp_rtp_out Wrong Type Handle"); throw runtime_error("HWSign_tcp_rtp_out initial error"); } - return HWsec_ptr->HWsec_output(buf,len,sei_end_offset,append_length, param); + return HWsec_ptr->HWsec_output(buf, len, sei_end_offset, append_length, param); } - diff --git a/src/HuaWei/HWsign.h b/src/HuaWei/HWsign.h index fb55274..912e5aa 100644 --- a/src/HuaWei/HWsign.h +++ b/src/HuaWei/HWsign.h @@ -2,41 +2,58 @@ #ifndef _HWSIGN_H #define _HWSIGN_H -#include -#include +#include +#include +#include //#include #define API_EXPORT __attribute__((visibility("default"))) -struct sec_set_info{ +struct sec_set_info { uint8_t cpu_core; - uint8_t camera_id[21]; - uint8_t vkek_version[32]; // 秘钥的加密秘钥的版本号 + uint8_t camera_id[21]; + uint8_t vkek_version[32];// 秘钥的加密秘钥的版本号 uint8_t prikey_size; uint8_t pubkey_size; - uint8_t prikey[64]; - uint8_t pubkey[128]; + uint8_t prikey[64]; + uint8_t pubkey[128]; }; + // void * HWSign_init(const std::function rtp_callback); API_EXPORT int SDF_Device_open(); API_EXPORT int SDF_Device_close(); -API_EXPORT void * GB28181_stream_init(struct sec_set_info * sign_info); -API_EXPORT int GB28181_stream_in(void* Handle, const char * buf, const uint32_t len, void * param); -API_EXPORT void GB28181_stream_release(void* Handle); -API_EXPORT int GB28181_stream_out(void* Handle, char * buf, uint32_t * len, uint16_t* sei_end_offset,uint16_t* append_length,void ** param); +API_EXPORT void *HK_stream_init(struct sec_set_info *sign_info); +API_EXPORT int HK_stream_in(void *Handle, const char *buf, const uint32_t len, void *param); +API_EXPORT void HK_stream_release(void *Handle); +API_EXPORT int +KH_stream_out(void *Handle, char *buf, uint32_t *len, uint16_t *sei_end_offset, uint16_t *append_length, void **param); -API_EXPORT void * HWSign_init(struct sec_set_info * sign_info); -API_EXPORT void HWSign_release(void* Handle); -API_EXPORT int HWSign_rtp_input(void* Handle, const char * buf, const uint32_t len, void * param); -API_EXPORT int HWSign_rtp_out(void* Handle, char * buf, uint32_t * len, void ** param); +API_EXPORT void *GB28181_stream_init(struct sec_set_info *sign_info); +API_EXPORT int GB28181_stream_in(void *Handle, const char *buf, const uint32_t len, void *param); +API_EXPORT void GB28181_stream_release(void *Handle); +API_EXPORT int GB28181_stream_out(void *Handle, + char *buf, + uint32_t *len, + uint16_t *sei_end_offset, + uint16_t *append_length, + void **param); -API_EXPORT void * HWSign_tcp_init(struct sec_set_info * sign_info); -API_EXPORT void HWSign_tcp_release(void* Handle); -API_EXPORT int HWSign_tcp_rtp_input(void* Handle, const char * buf, const uint32_t len, void * param); -API_EXPORT int HWSign_tcp_rtp_out(void* Handle, char * buf, uint32_t * len, uint16_t* sei_end_offset,uint16_t* append_length,void ** param); +API_EXPORT void *HWSign_init(struct sec_set_info *sign_info); +API_EXPORT void HWSign_release(void *Handle); +API_EXPORT int HWSign_rtp_input(void *Handle, const char *buf, const uint32_t len, void *param); +API_EXPORT int HWSign_rtp_out(void *Handle, char *buf, uint32_t *len, void **param); +API_EXPORT void *HWSign_tcp_init(struct sec_set_info *sign_info); +API_EXPORT void HWSign_tcp_release(void *Handle); +API_EXPORT int HWSign_tcp_rtp_input(void *Handle, const char *buf, const uint32_t len, void *param); +API_EXPORT int HWSign_tcp_rtp_out(void *Handle, + char *buf, + uint32_t *len, + uint16_t *sei_end_offset, + uint16_t *append_length, + void **param); -API_EXPORT void * HWVerify_init(); -API_EXPORT void HWVerify_release(void* Handle); -API_EXPORT int HWVerify_rtp_input(void* Handle, const char * buf, const uint32_t len,int tcp, void * param); +API_EXPORT void *HWVerify_init(); +API_EXPORT void HWVerify_release(void *Handle); +API_EXPORT int HWVerify_rtp_input(void *Handle, const char *buf, const uint32_t len, int tcp, void *param); #endif /* _DECRYPT_H */ diff --git a/src/base/event.h b/src/base/event.h new file mode 100644 index 0000000..90bd785 --- /dev/null +++ b/src/base/event.h @@ -0,0 +1,47 @@ +#ifndef AW_SECURITY_MEDIA_LIB_BASE_EVENT_H +#define AW_SECURITY_MEDIA_LIB_BASE_EVENT_H + +#pragma once +#include +#include +#include + +namespace sign { +class Event { +public: + Event(bool signaled = false) { Reset(signaled); } + + bool Signaled() const + { + std::lock_guard _(_lock); + return _signaled; + } + + void Wait() + { + std::unique_lock _(_lock); + _cv.wait(_, [this] { return _signaled; }); + } + + void Reset(bool signaled = false) + { + std::lock_guard _(_lock); + _signaled = signaled; + if (_signaled) { _cv.notify_all(); } + } + + void Signal() + { + std::lock_guard _(_lock); + _signaled = true; + _cv.notify_all(); + } + +private: + mutable std::mutex _lock; + bool _signaled{false}; + std::condition_variable _cv; +}; +}// namespace sign + +#endif// AW_SECURITY_MEDIA_LIB_BASE_EVENT_H diff --git a/src/base/frame.cpp b/src/base/frame.cpp new file mode 100644 index 0000000..1b71a7c --- /dev/null +++ b/src/base/frame.cpp @@ -0,0 +1,28 @@ +#include "frame.h" +#include "HuaWei/HWcommon.h" +#include + +namespace sign { + +static std::atomic g_frame_cnt{0}; + +Frame::~Frame() { g_frame_cnt.fetch_sub(1); } + +Frame::Ptr +Frame::CreateUDPFrame(const uint8_t *data, size_t len) +{ + return std::shared_ptr(new Frame(kUDP, data, len)); +} + +Frame::Ptr +Frame::CreateTCPFrame(const uint8_t *data, size_t len) +{ + return std::shared_ptr(new Frame(kTCP, data, len)); +} + +Frame::Frame(Type type, const uint8_t *data, size_t len) : _type(type), _data(data, data + len) +{ + auto cur = g_frame_cnt.fetch_add(1); + // INFOL("frame count: %d\n", cur); +} +}// namespace sign diff --git a/src/base/frame.h b/src/base/frame.h new file mode 100644 index 0000000..1d3e6ae --- /dev/null +++ b/src/base/frame.h @@ -0,0 +1,53 @@ +#ifndef AW_SECURITY_MEDIA_LIB_BASE_FRAME_H +#define AW_SECURITY_MEDIA_LIB_BASE_FRAME_H + +#pragma once +#include "base/event.h" +#include +#include + +namespace sign { +class Frame : std::enable_shared_from_this { +public: + using Ptr = std::shared_ptr; + + enum Type { kTCP, kUDP }; + + static Ptr CreateUDPFrame(const uint8_t *data, size_t len); + static Ptr CreateTCPFrame(const uint8_t *data, size_t len); + +public: + ~Frame(); + + Type type() const { return _type; } + + const uint8_t *data() const { return _data.data(); } + + uint8_t *data() { return _data.data(); } + + size_t size() const { return _data.size(); } + + // 用户附加的参数 + void set_user_data(void *param) { _user_data = param; } + + void *user_data() const { return _user_data; } + + bool paused() const { return !_event.Signaled(); } + + // signaled -> unpaused + void set_paused(bool paused) { _event.Reset(!paused); } + + void Wait() { _event.Wait(); } + +private: + Frame(Type type, const uint8_t *data, size_t len); + +private: + Event _event{true}; + Type _type; + std::vector _data; + void *_user_data; +}; +}// namespace sign + +#endif// AW_SECURITY_MEDIA_LIB_BASE_FRAME_H diff --git a/src/base/frame_manager.cpp b/src/base/frame_manager.cpp new file mode 100644 index 0000000..2b4126d --- /dev/null +++ b/src/base/frame_manager.cpp @@ -0,0 +1,48 @@ +#include "frame_manager.h" +#include "HuaWei/HWcommon.h" + +namespace sign { + +FrameManager::FrameManager() { Init(); } + +FrameManager::~FrameManager() {} + +bool +FrameManager::Enqueue(Frame::Ptr frame) +{ + + std::lock_guard _(_frame_queue_lock); + OnFrameEnqueue(frame); + _frame_queue.push(frame); + return true; +} + +Frame::Ptr +FrameManager::Dequeue() +{ + Frame::Ptr frame{nullptr}; + { + std::lock_guard _(_frame_queue_lock); + if (_frame_queue.empty()) { return nullptr; } + frame = _frame_queue.front(); + _frame_queue.pop(); + OnFrameDequeue(frame); + } + + frame->Wait(); + return frame; +} + +void +FrameManager::SetSecSetInfo(sec_set_info *info) +{ + _rtp_manager.SetSecSetInfo(info); +} + +void +FrameManager::Init() +{ + OnFrameEnqueue.connect(&_rtp_manager, &RTPManager::OnFrameEnqueue); +} + +}// namespace sign diff --git a/src/base/frame_manager.h b/src/base/frame_manager.h new file mode 100644 index 0000000..8131022 --- /dev/null +++ b/src/base/frame_manager.h @@ -0,0 +1,39 @@ +#ifndef AW_SECURITY_MEDIA_LIB_BASE_FRAME_MANAGER_H +#define AW_SECURITY_MEDIA_LIB_BASE_FRAME_MANAGER_H + +#pragma once + +#include "HuaWei/HWsign.h" +#include "base/frame.h" +#include "base/rtp_manager.h" +#include "sigslot.h" +#include +#include + +namespace sign { +class FrameManager { +public: + sigslot::signal1 OnFrameEnqueue; + sigslot::signal1 OnFrameDequeue; + + FrameManager(); + ~FrameManager(); + + bool Enqueue(Frame::Ptr frame); + Frame::Ptr Dequeue(); + + // HACK: 透传参数 + void SetSecSetInfo(sec_set_info *info); + +private: + void Init(); + +private: + RTPManager _rtp_manager; + + std::mutex _frame_queue_lock; + std::queue _frame_queue; +}; +}// namespace sign + +#endif// AW_SECURITY_MEDIA_LIB_BASE_FRAME_MANAGER_H diff --git a/src/base/rtp_decoder.cpp b/src/base/rtp_decoder.cpp new file mode 100644 index 0000000..6354049 --- /dev/null +++ b/src/base/rtp_decoder.cpp @@ -0,0 +1,102 @@ +#include "rtp_decoder.h" +#include "HuaWei/HWcommon.h" +#include "util.h" + +namespace sign { + +RTPDecoder::Ptr +RTPDecoder::Create(int payload_type, const char *encoding) +{ + auto decoder = std::shared_ptr(new RTPDecoder(payload_type, encoding)); + if (decoder->Initialize()) { + return decoder; + } else { + ERROL("RTPDecoder initialize failed. payload_type=%d, encoding=%s\n", payload_type, encoding); + return nullptr; + } +} + +RTPDecoder::~RTPDecoder() {} + +bool +RTPDecoder::Initialize() +{ + _handler = CreateHandler(); + _decoder = CreateDecoder(_handler); + return _handler && _decoder; +} + +void +RTPDecoder::Input(RTPPacket::Ptr packet) +{ + if (packet->packet_size() < 12) { + WRNGL("RTP packet length is too short. len=%lu\n", packet->packet_size()); + return; + } + + const uint8_t pt = GetRTPPayloadType(packet->packet_data()); + if (pt != _payload_type) { + // WRNGL("RTP packet payload type is mismatch. discard it. pt=%d, _payload_type=%d\n", pt, _payload_type); + return; + } + + const uint16_t seq = GetRTPSequenceNumber(packet->packet_data()); + if (_prev_seq == -1) { + _prev_seq = seq; + } else if (seq != ((_prev_seq + 1) & 0xFFFF)) { + _ref_rtp_packets.clear(); + _prev_seq = -1; + return; + } else { + _prev_seq = seq; + } + + _ref_rtp_packets.push_back(packet); + auto ret = rtp_payload_decode_input(_decoder.get(), packet->packet_data(), packet->packet_size()); + if (ret < 1) { _ref_rtp_packets.pop_back(); } +} + +RTPDecoder::RTPDecoder(int payload_type, const char *encoding) : _payload_type(payload_type), _encoding(encoding) {} + +std::shared_ptr +RTPDecoder::CreateHandler() +{ + auto handler = std::make_shared(); + + handler->alloc = [](void *clazz, int bytes) -> void * { + auto self = (RTPDecoder *) clazz; + auto &buf = self->_buffer; + if (buf.size() < bytes) { + buf.resize(bytes); + } else if (buf.capacity() > 2 * bytes && bytes > 2048) { + buf.shrink_to_fit(); + } + + return buf.data(); + }; + + handler->free = [](void *clazz, void *packet) {}; + + handler->packet = [](void *clazz, const void *packet, int bytes, uint32_t timestamp, int flags) { + auto self = (RTPDecoder *) clazz; + int type = 0x1F & ((uint8_t *) packet)[0]; + // INFOL("RTPDecoder::CreateHandler packet timestamp=%u, bytes=%d, flags=%d type=%d\n", timestamp, bytes, flags, + // type); + // std::string hex = ToHex((const uint8_t *) packet, bytes); + // INFOL("Data: %s\n", hex.c_str()); + DecodedPacket dp{packet, bytes, timestamp, flags}; + dp.ref_rtp_packets.swap(self->_ref_rtp_packets); + + self->OnDecoded(dp); + }; + return handler; +} + +std::shared_ptr +RTPDecoder::CreateDecoder(std::shared_ptr handler) +{ + auto rtp_decoder = rtp_payload_decode_create(_payload_type, _encoding.c_str(), handler.get(), this); + return std::shared_ptr(rtp_decoder, rtp_payload_decode_destroy); +} + +}// namespace sign diff --git a/src/base/rtp_decoder.h b/src/base/rtp_decoder.h new file mode 100644 index 0000000..eab719b --- /dev/null +++ b/src/base/rtp_decoder.h @@ -0,0 +1,53 @@ +#ifndef AW_SECURITY_MEDIA_LIB_BASE_RTP_DECODER_H +#define AW_SECURITY_MEDIA_LIB_BASE_RTP_DECODER_H + +#pragma once +#include "rtp-payload.h" +#include "rtp_packet.h" +#include "sigslot.h" +#include +#include +#include + +namespace sign { +class RTPDecoder { +public: + using Ptr = std::shared_ptr; + + // void (*packet)(void* param, const void *packet, int bytes, uint32_t timestamp, int flags); + struct DecodedPacket { + const void *packet; + int bytes; + uint32_t timestamp; + int flags; + std::vector ref_rtp_packets; + }; + + sigslot::signal1 OnDecoded; + + static Ptr Create(int payload_type, const char *encoding = nullptr); + +public: + ~RTPDecoder(); + bool Initialize(); + void Input(RTPPacket::Ptr packet); + +private: + RTPDecoder(int payload_type, const char *encoding); + std::shared_ptr CreateHandler(); + std::shared_ptr CreateDecoder(std::shared_ptr handler); + +private: + int _payload_type; + std::string _encoding; + int32_t _prev_seq{-1}; + + std::shared_ptr _decoder; + std::shared_ptr _handler; + std::vector _buffer; + + std::vector _ref_rtp_packets; +}; +}// namespace sign + +#endif// AW_SECURITY_MEDIA_LIB_BASE_RTP_DECODER_H diff --git a/src/base/rtp_manager.cpp b/src/base/rtp_manager.cpp new file mode 100644 index 0000000..ce0a327 --- /dev/null +++ b/src/base/rtp_manager.cpp @@ -0,0 +1,129 @@ +#include "rtp_manager.h" +#include "HuaWei/HWcommon.h" +#include "base/util.h" +#include + +namespace sign { +RTPManager::RTPManager() {} + +RTPManager::~RTPManager() {} + +void +RTPManager::OnFrameEnqueue(Frame::Ptr frame) +{ + if (frame->type() == Frame::kTCP) { + ProcessTCPFrame(frame); + } else if (frame->type() == Frame::kUDP) { + ProcessUDPFrame(frame); + } else { + // unknown + } +} + +void +RTPManager::SetSecSetInfo(sec_set_info *info) +{} + +void +RTPManager::ProcessUDPFrame(Frame::Ptr frame) +{ + if (!IsRTPHeader(frame->data(), frame->size())) { return; } + auto packet = RTPPacket::CreateCompleteRTPPacket(this, frame); + ProcessPacket(packet); +} + +void +RTPManager::ProcessTCPFrame(Frame::Ptr) +{} + +void +RTPManager::ProcessPacket(RTPPacket::Ptr packet) +{ + if (!packet->IsComplete()) { + // ERROL("RTP packet is not complete, discard it.\n"); + return; + } + + MaybeSetSSRC(packet->ssrc()); + if (packet->ssrc() != _cur_rtp_ssrc) { + WRNGL("RTP packet ssrc is mismatch. discard it. cur_ssrc=%ld, packet->ssrc=%d\n", _cur_rtp_ssrc, + packet->ssrc()); + return; + } + + MaybeSetSeq(packet->seq()); + if (packet->seq() != _cur_rtp_seq) { + // WRNGL("RTP packet seq is not continuous. cur_seq=%ld, packet->seq=%d\n", _cur_rtp_seq, packet->seq()); + SetCurSeq(packet->seq()); + } + IncCurSeq(); + + if (!_decoder) { + _decoder = RTPDecoder::Create(packet->payload_type(), "H264"); + if (_decoder) { _decoder->OnDecoded.connect(this, &RTPManager::OnRTPDecoded); } + } + if (_decoder) { _decoder->Input(packet); } + + MaybeReplaceSeq(packet); +} + +void +RTPManager::SetCurSeq(uint16_t seq) +{ + _cur_rtp_seq = seq; +} + +void +RTPManager::MaybeSetSSRC(uint32_t ssrc) +{ + if (_cur_rtp_ssrc == -1) { SetCurSSRC(ssrc); } +} + +void +RTPManager::MaybeSetSeq(uint16_t seq) +{ + if (_cur_rtp_seq == -1) { SetCurSeq(seq); } +} + +void +RTPManager::MaybeReplaceSeq(RTPPacket::Ptr packet) +{ + auto new_seq = (packet->seq() + _insert_packet_num); + packet->set_seq(new_seq); +} + +void +RTPManager::SetCurSSRC(uint32_t ssrc) +{ + _cur_rtp_ssrc = ssrc; +} + +void +RTPManager::IncCurSeq() +{ + _cur_rtp_seq = GetNextSeq(); +} + +uint16_t +RTPManager::GetNextSeq() +{ + return (_cur_rtp_seq + 1) & 0xFFFF; +} + +void +RTPManager::OnRTPDecoded(RTPDecoder::DecodedPacket packet) +{ + uint8_t h264_type = ((uint8_t *) packet.packet)[0] & 0x1F; + + // if (h264_type == 1) { return; } + std::stringstream ss; + for (auto &p : packet.ref_rtp_packets) { + ss << p->seq() << " "; + p->set_paused(false); + } + auto str = ss.str(); + if (!str.empty()) str.pop_back(); + INFOL("RTP decoded. type=%2d, size=%5u seq=[%s]\n", h264_type, packet.bytes, str.c_str()); +} + +}// namespace sign diff --git a/src/base/rtp_manager.h b/src/base/rtp_manager.h new file mode 100644 index 0000000..398d3e5 --- /dev/null +++ b/src/base/rtp_manager.h @@ -0,0 +1,65 @@ +#ifndef AW_SECURITY_MEDIA_LIB_BASE_RTP_MANAGER_H +#define AW_SECURITY_MEDIA_LIB_BASE_RTP_MANAGER_H + +#pragma once + +#include "HuaWei/HWsign.h" +#include "rtp_decoder.h" +#include "rtp_packet.h" +#include "sigslot.h" + +namespace sign { +class RTPManager : public sigslot::has_slots<> { +public: + sigslot::signal1 OnRTPPacket; + +public: + RTPManager(); + ~RTPManager(); + + void OnFrameEnqueue(Frame::Ptr frame); + + // HACK: + void SetSecSetInfo(sec_set_info *info); + +private: + void ProcessUDPFrame(Frame::Ptr); + void ProcessTCPFrame(Frame::Ptr); + + void ProcessPacket(RTPPacket::Ptr packet); + + void SetCurSeq(uint16_t seq); + void MaybeSetSSRC(uint32_t ssrc); + void MaybeSetSeq(uint16_t seq); + void MaybeReplaceSeq(RTPPacket::Ptr packet); + + void SetCurSSRC(uint32_t ssrc); + void IncCurSeq(); + uint16_t GetNextSeq(); + +private: + // FOR TEST + void OnRTPDecoded(RTPDecoder::DecodedPacket packet); + +private: + /** + * Partical RTP packet -> Complete RTP packet -> Decoder -> Signer + * + * Signer -> RTPManager: + * 1. Modify SEI + * 2. Insert SEI + **/ + + // 当前不完整的RTP包 + RTPPacket::Ptr _cur_rtp_packet{nullptr}; + int64_t _cur_rtp_seq{-1}; + int64_t _cur_rtp_ssrc{-1}; + + // 插入的包对seq有影响,需要记录插入包的数量 + uint16_t _insert_packet_num{0}; + + RTPDecoder::Ptr _decoder; +}; +}// namespace sign + +#endif// AW_SECURITY_MEDIA_LIB_BASE_RTP_MANAGER_H diff --git a/src/base/rtp_packet.cpp b/src/base/rtp_packet.cpp new file mode 100644 index 0000000..2f278b9 --- /dev/null +++ b/src/base/rtp_packet.cpp @@ -0,0 +1,134 @@ +#include "rtp_packet.h" +#include "HuaWei/HWcommon.h" +#include "util.h" +#include +#include +#include + +namespace sign { +static std::atomic g_rtp_packet_cnt{0}; + +void +IncRTPPacketCnt() +{ + auto cnt = g_rtp_packet_cnt.fetch_add(1); + // INFOL("rtp packet count: %d\n", cnt); +} + +void +DecRTPPacketCnt() +{ + g_rtp_packet_cnt.fetch_sub(1); +} + +RTPPacket::Ptr +RTPPacket::CreateParticalRTPPacket(RTPManager *owner) +{ + return std::shared_ptr(new RTPPacket(owner)); +} + +RTPPacket::Ptr +RTPPacket::CreateCompleteRTPPacket(RTPManager *owner, Frame::Ptr udp_frame) +{ + return std::shared_ptr(new RTPPacket(owner, udp_frame)); +} + +RTPPacket::~RTPPacket() +{ + set_paused(false); + DecRTPPacketCnt(); +} + +size_t +RTPPacket::packet_size() +{ + assert(_frame_type == Frame::kUDP || state() > kMissTCPHeader); + if (_frame_type == Frame::kUDP) { + return _ref_frames.front()->size(); + } else { + assert(false); + return 0; + } +} + +const uint8_t * +RTPPacket::packet_data() const +{ + return _rtp_ptr; +} + +uint8_t +RTPPacket::payload_type() const +{ + assert(state() > kMissRTPHeader); + return GetRTPPayloadType(_rtp_ptr); +} + +uint16_t +RTPPacket::seq() const +{ + assert(state() > kMissRTPHeader); + return GetRTPSequenceNumber(_rtp_ptr); +} + +uint32_t +RTPPacket::ssrc() const +{ + assert(state() > kMissRTPHeader); + return GetRTPSSRC(_rtp_ptr); +} + +uint32_t +RTPPacket::timestamp() const +{ + assert(state() > kMissRTPHeader); + return GetRTPTimestamp(_rtp_ptr); +} + +void +RTPPacket::set_seq(uint16_t seq) +{ + if (_frame_type == Frame::kUDP) { + SetRTPSequenceNumber(_rtp_ptr, seq); + } else { + assert(false); + } +} + +void +RTPPacket::AddRefFrame(Frame::Ptr frame) +{ + assert(false); +} + +bool +RTPPacket::paused() const +{ + for (auto &frame : _ref_frames) { + if (frame->paused()) { return true; } + } + return false; +} + +void +RTPPacket::set_paused(bool paused) +{ + std::for_each(_ref_frames.begin(), _ref_frames.end(), [paused](Frame::Ptr &frame) { frame->set_paused(paused); }); +} + +RTPPacket::RTPPacket(RTPManager *owner, Frame::Ptr udp_frame) + +{ + IncRTPPacketCnt(); + _owner = owner; + _ref_frames.push_back(udp_frame); + _frame_type = Frame::kUDP; + _rtp_ptr = udp_frame->data(); + _state = IsRTPHeader(udp_frame->data(), udp_frame->size()) ? kComplete : kError; + + udp_frame->set_paused(true); +} + +RTPPacket::RTPPacket(RTPManager *owner) : _owner(owner), _frame_type(Frame::kTCP) { IncRTPPacketCnt(); } + +}// namespace sign diff --git a/src/base/rtp_packet.h b/src/base/rtp_packet.h new file mode 100644 index 0000000..2eb8076 --- /dev/null +++ b/src/base/rtp_packet.h @@ -0,0 +1,67 @@ +#ifndef AW_SECURITY_MEDIA_LIB_BASE_RTP_H +#define AW_SECURITY_MEDIA_LIB_BASE_RTP_H + +#pragma once + +#include "base/frame.h" + +namespace sign { +class RTPManager; + +class RTPPacket : std::enable_shared_from_this { +public: + enum State { + kError = -1, + kMissTCPHeader = 0, + kMissRTPHeader = 1, + kMissPayload = 2, + kComplete = 3, + }; + + using Ptr = std::shared_ptr; + + static Ptr CreateParticalRTPPacket(RTPManager *owner); + static Ptr CreateCompleteRTPPacket(RTPManager *owner, Frame::Ptr udp_frame); + +public: + ~RTPPacket(); + + State state() const { return _state; } + + bool IsComplete() const { return state() == kComplete; } + + // available on kMissRTPHeader,kMissPayload,kComplete + size_t packet_size(); + const uint8_t *packet_data() const; + size_t rtp_payload_size(); + + // rtp header, kMissPayload or kComplete + uint8_t payload_type() const; + uint16_t seq() const; + uint32_t ssrc() const; + uint32_t timestamp() const; + + void set_seq(uint16_t seq); + + void AddRefFrame(Frame::Ptr frame); + + RTPManager *owner() const { return _owner; } + + bool paused() const; + void set_paused(bool paused); + +private: + RTPPacket(RTPManager *owner, Frame::Ptr udp_frame); + RTPPacket(RTPManager *owner); + +private: + RTPManager *_owner{nullptr}; + uint8_t *_rtp_ptr{nullptr}; + + Frame::Type _frame_type; + State _state; + std::vector _ref_frames; +}; +}// namespace sign + +#endif// AW_SECURITY_MEDIA_LIB_BASE_RTP_H diff --git a/src/base/signer.cpp b/src/base/signer.cpp new file mode 100644 index 0000000..7d277ae --- /dev/null +++ b/src/base/signer.cpp @@ -0,0 +1 @@ +#include "signer.h" diff --git a/src/base/signer.h b/src/base/signer.h new file mode 100644 index 0000000..b99ca71 --- /dev/null +++ b/src/base/signer.h @@ -0,0 +1,15 @@ +#ifndef AW_SECURITY_MEDIA_LIB_BASE_SIGNER_H +#define AW_SECURITY_MEDIA_LIB_BASE_SIGNER_H + +#pragma once + +#include +#include + +namespace sign { +class Signer { +public: +}; +}// namespace sign + +#endif// AW_SECURITY_MEDIA_LIB_BASE_SIGNER_H diff --git a/src/base/util.cpp b/src/base/util.cpp new file mode 100644 index 0000000..44fb903 --- /dev/null +++ b/src/base/util.cpp @@ -0,0 +1,110 @@ +#include "util.h" +extern "C" { +#include "SVAC/src/sm2sm3/sm2.h" +#include "SVAC/src/sm2sm3/sm3.h" +} + +namespace sign { +uint8_t +GetRTPVersion(const uint8_t *data) +{ + return (data[0] & 0xC0) >> 6; +} + +uint8_t +GetRTPPayloadType(const uint8_t *data) +{ + return data[1] & 0x7F; +} + +uint16_t +GetRTPSequenceNumber(const uint8_t *data) +{ + return (data[2] << 8) | data[3]; +} + +uint32_t +GetRTPTimestamp(const uint8_t *data) +{ + return (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7]; +} + +uint32_t +GetRTPSSRC(const uint8_t *header) +{ + return (header[8] << 24) | (header[9] << 16) | (header[10] << 8) | header[11]; +} + +void +SetRTPSequenceNumber(uint8_t *header, uint16_t seq) +{ + header[2] = seq >> 8; + header[3] = seq & 0xFF; +} + +bool +FindRTPOverTCPHeader(const uint8_t *data, size_t len, size_t *header_pos) +{ + if (len <= 0) { + return false; + } else if (len == 1) { + if (data[0] == '$') { + *header_pos = 0; + return true; + } else { + return false; + } + } else { + // len >= 2 + static const uint8_t kRTPOverTCPHeader[] = {'$', 0}; + uint8_t *ptr = (uint8_t *) memmem(data, len, kRTPOverTCPHeader, sizeof(kRTPOverTCPHeader)); + if (!ptr) { return false; } + *header_pos = ptr - data; + return true; + } +} + +bool +IsRTPHeader(const uint8_t *data, size_t len) +{ + if (len < 12) { return false; } + if (GetRTPVersion(data) != 2) { return false; } + return true; +} + +bool +IsParticalRTPHeader(const uint8_t *data, size_t len) +{ + if (len == 0) { + return true; + } else { + return GetRTPVersion(data) == 2; + } +} + +std::string +ToHex(const void *data, size_t len) +{ + static const char hex[] = "0123456789ABCDEF"; + std::string hex_str; + hex_str.resize(len * 2); + const uint8_t *ptr = (const uint8_t *) data; + for (size_t i = 0; i < len; i++) { + hex_str[2 * i] = hex[ptr[i] >> 4]; + hex_str[2 * i + 1] = hex[ptr[i] & 0x0F]; + } + return hex_str; +} + +std::vector +SM3Hash(const void *data, size_t len) +{ + uint8_t digest[128]; + sm3_ctx ctx; + sm3_init(&ctx); + sm3_update(&ctx, (const uint8_t *) data, len); + sm3_final(&ctx, digest); + return std::vector(digest, digest + 32); +} + +}// namespace sign diff --git a/src/base/util.h b/src/base/util.h new file mode 100644 index 0000000..28abbe4 --- /dev/null +++ b/src/base/util.h @@ -0,0 +1,30 @@ +#ifndef AW_SECURITY_MEDIA_LIB_BASE_UTIL_H +#define AW_SECURITY_MEDIA_LIB_BASE_UTIL_H + +#pragma once + +#include +#include +#include +#include + +namespace sign { +uint8_t GetRTPVersion(const uint8_t *header); +uint8_t GetRTPPayloadType(const uint8_t *header); +uint16_t GetRTPSequenceNumber(const uint8_t *header); +uint32_t GetRTPTimestamp(const uint8_t *header); +uint32_t GetRTPSSRC(const uint8_t *header); + +void SetRTPSequenceNumber(uint8_t *header, uint16_t seq); + +bool FindRTPOverTCPHeader(const uint8_t *data, size_t len, size_t *header_pos = nullptr); +bool IsRTPHeader(const uint8_t *data, size_t len); +bool IsParticalRTPHeader(const uint8_t *data, size_t len); + +std::string ToHex(const void *data, size_t len); + +std::vector SM3Hash(const void *data, size_t len); + +}// namespace sign + +#endif// AW_SECURITY_MEDIA_LIB_BASE_UTIL_H diff --git a/src/sigslot.h b/src/sigslot.h new file mode 100644 index 0000000..912b235 --- /dev/null +++ b/src/sigslot.h @@ -0,0 +1,1682 @@ +// sigslot.h: Signal/Slot classes +// +// Written by Sarah Thompson (sarah@telergy.com) 2002. +// +// License: Public domain. You are free to use this code however you like, with the proviso that +// the author takes on no responsibility or liability for any use. +// +// QUICK DOCUMENTATION +// +// (see also the full documentation at http://sigslot.sourceforge.net/) +// +// #define switches +// SIGSLOT_PURE_ISO - Define this to force ISO C++ compliance. This also disables +// all of the thread safety support on platforms where it is +// available. +// +// SIGSLOT_USE_POSIX_THREADS - Force use of Posix threads when using a C++ compiler other than +// gcc on a platform that supports Posix threads. (When using gcc, +// this is the default - use SIGSLOT_PURE_ISO to disable this if +// necessary) +// +// SIGSLOT_DEFAULT_MT_POLICY - Where thread support is enabled, this defaults to multi_threaded_global. +// Otherwise, the default is single_threaded. #define this yourself to +// override the default. In pure ISO mode, anything other than +// single_threaded will cause a compiler error. +// +// PLATFORM NOTES +// +// Win32 - On Win32, the WIN32 symbol must be #defined. Most mainstream +// compilers do this by default, but you may need to define it +// yourself if your build environment is less standard. This causes +// the Win32 thread support to be compiled in and used automatically. +// +// Unix/Linux/BSD, etc. - If you're using gcc, it is assumed that you have Posix threads +// available, so they are used automatically. You can override this +// (as under Windows) with the SIGSLOT_PURE_ISO switch. If you're using +// something other than gcc but still want to use Posix threads, you +// need to #define SIGSLOT_USE_POSIX_THREADS. +// +// ISO C++ - If none of the supported platforms are detected, or if +// SIGSLOT_PURE_ISO is defined, all multithreading support is turned off, +// along with any code that might cause a pure ISO C++ environment to +// complain. Before you ask, gcc -ansi -pedantic won't compile this +// library, but gcc -ansi is fine. Pedantic mode seems to throw a lot of +// errors that aren't really there. If you feel like investigating this, +// please contact the author. +// +// +// THREADING MODES +// +// single_threaded - Your program is assumed to be single threaded from the point of view +// of signal/slot usage (i.e. all objects using signals and slots are +// created and destroyed from a single thread). Behaviour if objects are +// destroyed concurrently is undefined (i.e. you'll get the occasional +// segmentation fault/memory exception). +// +// multi_threaded_global - Your program is assumed to be multi threaded. Objects using signals and +// slots can be safely created and destroyed from any thread, even when +// connections exist. In multi_threaded_global mode, this is achieved by a +// single global mutex (actually a critical section on Windows because they +// are faster). This option uses less OS resources, but results in more +// opportunities for contention, possibly resulting in more context switches +// than are strictly necessary. +// +// multi_threaded_local - Behaviour in this mode is essentially the same as multi_threaded_global, +// except that each signal, and each object that inherits has_slots, all +// have their own mutex/critical section. In practice, this means that +// mutex collisions (and hence context switches) only happen if they are +// absolutely essential. However, on some platforms, creating a lot of +// mutexes can slow down the whole OS, so use this option with care. +// +// USING THE LIBRARY +// +// See the full documentation at http://sigslot.sourceforge.net/ +// +// + +#ifndef __SIGSLOT_H__ +#define __SIGSLOT_H__ + +#include +#include + +#if defined(SIGSLOT_PURE_ISO) || (!defined(WIN32) && !defined(__GNUG__) && !defined(SIGSLOT_USE_POSIX_THREADS)) +# define _SIGSLOT_SINGLE_THREADED +#elif defined(WIN32) +# define _SIGSLOT_HAS_WIN32_THREADS +# include +#elif defined(__GNUG__) || defined(SIGSLOT_USE_POSIX_THREADS) +# define _SIGSLOT_HAS_POSIX_THREADS +# include +#else +# define _SIGSLOT_SINGLE_THREADED +#endif + +#ifndef SIGSLOT_DEFAULT_MT_POLICY +# ifdef _SIGSLOT_SINGLE_THREADED +# define SIGSLOT_DEFAULT_MT_POLICY single_threaded +# else +# define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_local +# endif +#endif + +#ifndef SIGSLOT_EMIT +# ifdef QT_VERSION +# define SIGSLOT_EMIT broadcast +# else +# define SIGSLOT_EMIT emit +# endif +#endif + +namespace sigslot { + +class single_threaded +{ +public: + single_threaded() {} + virtual ~single_threaded() {} + virtual void lock() {} + virtual void unlock() {} +}; + +#ifdef _SIGSLOT_HAS_WIN32_THREADS +// The multi threading policies only get compiled in if they are enabled. +class multi_threaded_global +{ +public: + multi_threaded_global() + { + static bool isinitialised = false; + + if(!isinitialised) + { + InitializeCriticalSection(get_critsec()); + isinitialised = true; + } + } + + multi_threaded_global(const multi_threaded_global&) + {} + + virtual ~multi_threaded_global() + {} + + virtual void lock() + { + EnterCriticalSection(get_critsec()); + } + + virtual void unlock() + { + LeaveCriticalSection(get_critsec()); + } + +private: + CRITICAL_SECTION* get_critsec() + { + static CRITICAL_SECTION g_critsec; + return &g_critsec; + } +}; + +class multi_threaded_local +{ +public: + multi_threaded_local() + { + InitializeCriticalSection(&m_critsec); + } + + multi_threaded_local(const multi_threaded_local&) + { + InitializeCriticalSection(&m_critsec); + } + + virtual ~multi_threaded_local() + { + DeleteCriticalSection(&m_critsec); + } + + virtual void lock() + { + EnterCriticalSection(&m_critsec); + } + + virtual void unlock() + { + LeaveCriticalSection(&m_critsec); + } + +private: + CRITICAL_SECTION m_critsec; +}; +#endif // _SIGSLOT_HAS_WIN32_THREADS + +#ifdef _SIGSLOT_HAS_POSIX_THREADS +// The multi threading policies only get compiled in if they are enabled. +class multi_threaded_global +{ +public: + multi_threaded_global() + { + pthread_mutex_init(get_mutex(), NULL); + } + + multi_threaded_global(const multi_threaded_global&) + {} + + virtual ~multi_threaded_global() + {} + + virtual void lock() + { + pthread_mutex_lock(get_mutex()); + } + + virtual void unlock() + { + pthread_mutex_unlock(get_mutex()); + } + +private: + pthread_mutex_t* get_mutex() + { + static pthread_mutex_t g_mutex; + return &g_mutex; + } +}; + +class multi_threaded_local +{ +public: + multi_threaded_local() + { + pthread_mutex_init(&m_mutex, NULL); + } + + multi_threaded_local(const multi_threaded_local&) + { + pthread_mutex_init(&m_mutex, NULL); + } + + virtual ~multi_threaded_local() + { + pthread_mutex_destroy(&m_mutex); + } + + virtual void lock() + { + pthread_mutex_lock(&m_mutex); + } + + virtual void unlock() + { + pthread_mutex_unlock(&m_mutex); + } + +private: + pthread_mutex_t m_mutex; +}; +#endif // _SIGSLOT_HAS_POSIX_THREADS + +template +class lock_block +{ +public: + mt_policy *m_mutex; + + lock_block(mt_policy *mtx) + : m_mutex(mtx) + { + m_mutex->lock(); + } + + ~lock_block() + { + m_mutex->unlock(); + } +}; + +template +class has_slots; + +template +class _connection_base0 +{ +public: + virtual ~_connection_base0() {} + virtual has_slots* getdest() const = 0; + virtual void SIGSLOT_EMIT() = 0; + virtual _connection_base0* clone() = 0; + virtual _connection_base0* duplicate(has_slots* pnewdest) = 0; +}; + +template +class _connection_base1 +{ +public: + virtual ~_connection_base1() {} + virtual has_slots* getdest() const = 0; + virtual void SIGSLOT_EMIT(arg1_type) = 0; + virtual _connection_base1* clone() = 0; + virtual _connection_base1* duplicate(has_slots* pnewdest) = 0; +}; + +template +class _connection_base2 +{ +public: + virtual ~_connection_base2() {} + virtual has_slots* getdest() const = 0; + virtual void SIGSLOT_EMIT(arg1_type, arg2_type) = 0; + virtual _connection_base2* clone() = 0; + virtual _connection_base2* duplicate(has_slots* pnewdest) = 0; +}; + +template +class _connection_base3 +{ +public: + virtual ~_connection_base3() {} + virtual has_slots* getdest() const = 0; + virtual void SIGSLOT_EMIT(arg1_type, arg2_type, arg3_type) = 0; + virtual _connection_base3* clone() = 0; + virtual _connection_base3* duplicate(has_slots* pnewdest) = 0; +}; + +template +class _connection_base4 +{ +public: + virtual ~_connection_base4() {} + virtual has_slots* getdest() const = 0; + virtual void SIGSLOT_EMIT(arg1_type, arg2_type, arg3_type, arg4_type) = 0; + virtual _connection_base4* clone() = 0; + virtual _connection_base4* duplicate(has_slots* pnewdest) = 0; +}; + +template +class _connection_base5 +{ +public: + virtual ~_connection_base5() {} + virtual has_slots* getdest() const = 0; + virtual void SIGSLOT_EMIT(arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type) = 0; + virtual _connection_base5* clone() = 0; + virtual _connection_base5* duplicate(has_slots* pnewdest) = 0; +}; + +template +class _connection_base6 +{ +public: + virtual ~_connection_base6() {} + virtual has_slots* getdest() const = 0; + virtual void SIGSLOT_EMIT(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, + arg6_type) = 0; + virtual _connection_base6* clone() = 0; + virtual _connection_base6* duplicate(has_slots* pnewdest) = 0; +}; + +template +class _connection_base7 +{ +public: + virtual ~_connection_base7() {} + virtual has_slots* getdest() const = 0; + virtual void SIGSLOT_EMIT(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, + arg6_type, arg7_type) = 0; + virtual _connection_base7* clone() = 0; + virtual _connection_base7* duplicate(has_slots* pnewdest) = 0; +}; + +template +class _connection_base8 +{ +public: + virtual ~_connection_base8() {} + virtual has_slots* getdest() const = 0; + virtual void SIGSLOT_EMIT(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, + arg6_type, arg7_type, arg8_type) = 0; + virtual _connection_base8* clone() = 0; + virtual _connection_base8* duplicate(has_slots* pnewdest) = 0; +}; + +template +class _signal_base : public mt_policy +{ +public: + virtual void slot_disconnect(has_slots* pslot) = 0; + virtual void slot_duplicate(const has_slots* poldslot, has_slots* pnewslot) = 0; +}; + +// Implements common functionality of signalN classes. signalN classes +// derive from this class. +template +class _signal_base_middle: public _signal_base +{ +public: + + typedef T connections_list; + typedef typename connections_list::iterator iterator; + typedef typename connections_list::const_iterator const_iterator; + + _signal_base_middle() {} + + _signal_base_middle(const _signal_base_middle &s) + : _signal_base(s) + { + lock_block lock(this); + + const_iterator it = s.m_connected_slots.begin(); + const_iterator itEnd = s.m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_connect(this); + m_connected_slots.push_back((*it)->clone()); + ++it; + } + } + + virtual ~_signal_base_middle() {} + + void disconnect_all() + { + lock_block lock(this); + + const_iterator it = m_connected_slots.begin(); + const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_disconnect(this); + delete *it; + + ++it; + } + + m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); + } + + bool is_empty() + { + lock_block lock(this); + + const_iterator it = m_connected_slots.begin(); + const_iterator itEnd = m_connected_slots.end(); + + return it == itEnd; + } + +#ifdef _DEBUG + bool connected(has_slots* pclass) + { + lock_block lock(this); + + const_iterator itNext, it = m_connected_slots.begin(); + const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + if ((*it)->getdest() == pclass) + return true; + it = itNext; + } + return false; + } +#endif + + void disconnect(has_slots* pclass) + { + lock_block lock(this); + + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == pclass) + { + delete *it; + m_connected_slots.erase(it); + pclass->signal_disconnect(this); + return; + } + + ++it; + } + } + + void slot_disconnect(has_slots* pslot) + { + lock_block lock(this); + + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + iterator itNext = it; + ++itNext; + + if((*it)->getdest() == pslot) + { + delete *it; + m_connected_slots.erase(it); + } + + it = itNext; + } + } + + void slot_duplicate(const has_slots* oldtarget, has_slots* newtarget) + { + lock_block lock(this); + + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == oldtarget) + { + m_connected_slots.push_back((*it)->duplicate(newtarget)); + } + + ++it; + } + } + +protected: + + connections_list m_connected_slots; + +}; + +template +class has_slots : public mt_policy +{ +private: + typedef typename std::set<_signal_base *> sender_set; + typedef typename sender_set::const_iterator const_iterator; + +public: + has_slots() + {} + + has_slots(const has_slots& hs) + : mt_policy(hs) + { + lock_block lock(this); + const_iterator it = hs.m_senders.begin(); + const_iterator itEnd = hs.m_senders.end(); + + while(it != itEnd) + { + (*it)->slot_duplicate(&hs, this); + m_senders.insert(*it); + ++it; + } + } + + void signal_connect(_signal_base* sender) + { + lock_block lock(this); + m_senders.insert(sender); + } + + void signal_disconnect(_signal_base* sender) + { + lock_block lock(this); + m_senders.erase(sender); + } + + virtual ~has_slots() + { + disconnect_all(); + } + + void disconnect_all() + { + lock_block lock(this); + const_iterator it = m_senders.begin(); + const_iterator itEnd = m_senders.end(); + + while(it != itEnd) + { + (*it)->slot_disconnect(this); + ++it; + } + + m_senders.erase(m_senders.begin(), m_senders.end()); + } + +private: + sender_set m_senders; +}; + + + +template +class _connection0 : public _connection_base0 +{ +public: + _connection0() + { + m_pobject = NULL; + m_pmemfun = NULL; + } + + _connection0(dest_type* pobject, void (dest_type::*pmemfun)()) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection0() + {} + + virtual _connection_base0* clone() + { + return new _connection0(*this); + } + + virtual _connection_base0* duplicate(has_slots* pnewdest) + { + return new _connection0((dest_type *)pnewdest, m_pmemfun); + } + + virtual void SIGSLOT_EMIT() + { + (m_pobject->*m_pmemfun)(); + } + + virtual has_slots* getdest() const + { + return m_pobject; + } + +private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(); +}; + +template +class _connection1 : public _connection_base1 +{ +public: + _connection1() + { + m_pobject = NULL; + m_pmemfun = NULL; + } + + _connection1(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection1() + {} + + virtual _connection_base1* clone() + { + return new _connection1(*this); + } + + virtual _connection_base1* duplicate(has_slots* pnewdest) + { + return new _connection1((dest_type *)pnewdest, m_pmemfun); + } + + virtual void SIGSLOT_EMIT(arg1_type a1) + { + (m_pobject->*m_pmemfun)(a1); + } + + virtual has_slots* getdest() const + { + return m_pobject; + } + +private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type); +}; + +template +class _connection2 : public _connection_base2 +{ +public: + _connection2() + { + m_pobject = NULL; + m_pmemfun = NULL; + } + + _connection2(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, + arg2_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection2() + {} + + virtual _connection_base2* clone() + { + return new _connection2(*this); + } + + virtual _connection_base2* duplicate(has_slots* pnewdest) + { + return new _connection2((dest_type *)pnewdest, m_pmemfun); + } + + virtual void SIGSLOT_EMIT(arg1_type a1, arg2_type a2) + { + (m_pobject->*m_pmemfun)(a1, a2); + } + + virtual has_slots* getdest() const + { + return m_pobject; + } + +private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type, arg2_type); +}; + +template +class _connection3 : public _connection_base3 +{ +public: + _connection3() + { + m_pobject = NULL; + m_pmemfun = NULL; + } + + _connection3(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, + arg2_type, arg3_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection3() + {} + + virtual _connection_base3* clone() + { + return new _connection3(*this); + } + + virtual _connection_base3* duplicate(has_slots* pnewdest) + { + return new _connection3((dest_type *)pnewdest, m_pmemfun); + } + + virtual void SIGSLOT_EMIT(arg1_type a1, arg2_type a2, arg3_type a3) + { + (m_pobject->*m_pmemfun)(a1, a2, a3); + } + + virtual has_slots* getdest() const + { + return m_pobject; + } + +private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type); +}; + +template +class _connection4 : public _connection_base4 +{ +public: + _connection4() + { + m_pobject = NULL; + m_pmemfun = NULL; + } + + _connection4(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection4() + {} + + virtual _connection_base4* clone() + { + return new _connection4(*this); + } + + virtual _connection_base4* duplicate(has_slots* pnewdest) + { + return new _connection4((dest_type *)pnewdest, m_pmemfun); + } + + virtual void SIGSLOT_EMIT(arg1_type a1, arg2_type a2, arg3_type a3, + arg4_type a4) + { + (m_pobject->*m_pmemfun)(a1, a2, a3, a4); + } + + virtual has_slots* getdest() const + { + return m_pobject; + } + +private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, + arg4_type); +}; + +template +class _connection5 : public _connection_base5 +{ +public: + _connection5() + { + m_pobject = NULL; + m_pmemfun = NULL; + } + + _connection5(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection5() + {} + + virtual _connection_base5* clone() + { + return new _connection5(*this); + } + + virtual _connection_base5* duplicate(has_slots* pnewdest) + { + return new _connection5((dest_type *)pnewdest, m_pmemfun); + } + + virtual void SIGSLOT_EMIT(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5) + { + (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5); + } + + virtual has_slots* getdest() const + { + return m_pobject; + } + +private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type); +}; + +template +class _connection6 : public _connection_base6 +{ +public: + _connection6() + { + m_pobject = NULL; + m_pmemfun = NULL; + } + + _connection6(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type, arg6_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection6() + {} + + virtual _connection_base6* clone() + { + return new _connection6(*this); + } + + virtual _connection_base6* duplicate(has_slots* pnewdest) + { + return new _connection6((dest_type *)pnewdest, m_pmemfun); + } + + virtual void SIGSLOT_EMIT(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6) + { + (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6); + } + + virtual has_slots* getdest() const + { + return m_pobject; + } + +private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type); +}; + +template +class _connection7 : public _connection_base7 +{ +public: + _connection7() + { + m_pobject = NULL; + m_pmemfun = NULL; + } + + _connection7(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection7() + {} + + virtual _connection_base7* clone() + { + return new _connection7(*this); + } + + virtual _connection_base7* duplicate(has_slots* pnewdest) + { + return new _connection7((dest_type *)pnewdest, m_pmemfun); + } + + virtual void SIGSLOT_EMIT(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6, arg7_type a7) + { + (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7); + } + + virtual has_slots* getdest() const + { + return m_pobject; + } + +private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type); +}; + +template +class _connection8 : public _connection_base8 +{ +public: + _connection8() + { + m_pobject = NULL; + m_pmemfun = NULL; + } + + _connection8(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, + arg7_type, arg8_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection8() + {} + + virtual _connection_base8* clone() + { + return new _connection8(*this); + } + + virtual _connection_base8* duplicate(has_slots* pnewdest) + { + return new _connection8((dest_type *)pnewdest, m_pmemfun); + } + + virtual void SIGSLOT_EMIT(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8) + { + (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7, a8); + } + + virtual has_slots* getdest() const + { + return m_pobject; + } + +private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, arg8_type); +}; + +template +class signal0 : public _signal_base_middle*>, mt_policy> +{ +public: + + typedef signal0 this_type; + typedef std::list<_connection_base0*> connections_list; + typedef _signal_base_middle base_type; + + using base_type::m_connected_slots; + + signal0() + {} + + signal0(const this_type& s) + : base_type(s) + {} + + ~signal0() + { + base_type::disconnect_all(); + } + + template + void connect(desttype* pclass, void (desttype::*pmemfun)()) + { + lock_block lock(this); + + _connection0* conn = + new _connection0(pclass, pmemfun); + + m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void SIGSLOT_EMIT() + { + lock_block lock(this); + + typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); + typename connections_list::const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->SIGSLOT_EMIT(); + + it = itNext; + } + } + + void operator()() + { + SIGSLOT_EMIT(); + } +}; + +template +class signal1 : public _signal_base_middle*>, mt_policy> +{ +public: + + typedef signal1 this_type; + typedef std::list<_connection_base1*> connections_list; + typedef _signal_base_middle base_type; + + using base_type::m_connected_slots; + + signal1() + {} + + signal1(const this_type& s) + : base_type(s) + {} + + ~signal1() + { + base_type::disconnect_all(); + } + + template + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type)) + { + lock_block lock(this); + _connection1* conn = + new _connection1(pclass, pmemfun); + m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void SIGSLOT_EMIT(arg1_type a1) + { + lock_block lock(this); + typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); + typename connections_list::const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->SIGSLOT_EMIT(a1); + + it = itNext; + } + } + + void operator()(arg1_type a1) + { + SIGSLOT_EMIT(a1); + } +}; + +template +class signal2 : public _signal_base_middle*>, mt_policy> +{ +public: + + typedef signal2 this_type; + typedef std::list<_connection_base2*> connections_list; + typedef _signal_base_middle base_type; + + using base_type::m_connected_slots; + + signal2() + {} + + signal2(const this_type& s) + : base_type(s) + {} + + ~signal2() + { + base_type::disconnect_all(); + } + + template + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, + arg2_type)) + { + lock_block lock(this); + _connection2* conn = new + _connection2(pclass, pmemfun); + m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void SIGSLOT_EMIT(arg1_type a1, arg2_type a2) + { + lock_block lock(this); + typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); + typename connections_list::const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->SIGSLOT_EMIT(a1, a2); + + it = itNext; + } + } + + void operator()(arg1_type a1, arg2_type a2) + { + SIGSLOT_EMIT(a1, a2); + } +}; + +template +class signal3 : public _signal_base_middle*>, mt_policy> +{ +public: + + typedef signal3 this_type; + typedef std::list<_connection_base3*> connections_list; + typedef _signal_base_middle base_type; + + using base_type::m_connected_slots; + + signal3() + {} + + signal3(const this_type& s) + : base_type(s) + {} + + ~signal3() + { + base_type::disconnect_all(); + } + + template + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, + arg2_type, arg3_type)) + { + lock_block lock(this); + _connection3* conn = + new _connection3(pclass, + pmemfun); + m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void SIGSLOT_EMIT(arg1_type a1, arg2_type a2, arg3_type a3) + { + lock_block lock(this); + typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); + typename connections_list::const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->SIGSLOT_EMIT(a1, a2, a3); + + it = itNext; + } + } + + void operator()(arg1_type a1, arg2_type a2, arg3_type a3) + { + SIGSLOT_EMIT(a1, a2, a3); + } +}; + +template +class signal4 : public _signal_base_middle*>, mt_policy> +{ +public: + + typedef signal4 this_type; + typedef std::list<_connection_base4*> connections_list; + typedef _signal_base_middle base_type; + + using base_type::m_connected_slots; + + signal4() + {} + + signal4(const this_type& s) + : base_type(s) + {} + + ~signal4() + { + base_type::disconnect_all(); + } + + template + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type)) + { + lock_block lock(this); + _connection4* + conn = new _connection4(pclass, pmemfun); + m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void SIGSLOT_EMIT(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4) + { + lock_block lock(this); + typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); + typename connections_list::const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->SIGSLOT_EMIT(a1, a2, a3, a4); + + it = itNext; + } + } + + void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4) + { + SIGSLOT_EMIT(a1, a2, a3, a4); + } +}; + +template +class signal5 : public _signal_base_middle*>, mt_policy> +{ +public: + + typedef signal5 this_type; + typedef std::list<_connection_base5*> connections_list; + typedef _signal_base_middle base_type; + + using base_type::m_connected_slots; + + signal5() + {} + + signal5(const this_type& s) + : base_type(s) + {} + + ~signal5() + { + base_type::disconnect_all(); + } + + template + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type)) + { + lock_block lock(this); + _connection5* conn = new _connection5(pclass, pmemfun); + m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void SIGSLOT_EMIT(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5) + { + lock_block lock(this); + typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); + typename connections_list::const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->SIGSLOT_EMIT(a1, a2, a3, a4, a5); + + it = itNext; + } + } + + void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5) + { + SIGSLOT_EMIT(a1, a2, a3, a4, a5); + } +}; + + +template +class signal6 : public _signal_base_middle*>, mt_policy> +{ +public: + + typedef signal6 this_type; + typedef std::list<_connection_base6*> connections_list; + typedef _signal_base_middle base_type; + + using base_type::m_connected_slots; + + signal6() + {} + + signal6(const this_type& s) + : base_type(s) + {} + + ~signal6() + { + base_type::disconnect_all(); + } + + template + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type, arg6_type)) + { + lock_block lock(this); + _connection6* conn = + new _connection6(pclass, pmemfun); + m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void SIGSLOT_EMIT(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6) + { + lock_block lock(this); + typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); + typename connections_list::const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->SIGSLOT_EMIT(a1, a2, a3, a4, a5, a6); + + it = itNext; + } + } + + void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6) + { + SIGSLOT_EMIT(a1, a2, a3, a4, a5, a6); + } +}; + +template +class signal7 : public _signal_base_middle*>, mt_policy> +{ +public: + + typedef signal7 this_type; + typedef std::list<_connection_base7*> connections_list; + typedef _signal_base_middle base_type; + + using base_type::m_connected_slots; + + signal7() + {} + + signal7(const this_type& s) + : base_type(s) + {} + + ~signal7() + { + base_type::disconnect_all(); + } + + template + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, + arg7_type)) + { + lock_block lock(this); + _connection7* conn = + new _connection7(pclass, pmemfun); + m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void SIGSLOT_EMIT(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6, arg7_type a7) + { + lock_block lock(this); + typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); + typename connections_list::const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->SIGSLOT_EMIT(a1, a2, a3, a4, a5, a6, a7); + + it = itNext; + } + } + + void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6, arg7_type a7) + { + SIGSLOT_EMIT(a1, a2, a3, a4, a5, a6, a7); + } +}; + +template +class signal8 : public _signal_base_middle*>, mt_policy> +{ +public: + + typedef signal8 this_type; + typedef std::list<_connection_base8*> connections_list; + typedef _signal_base_middle base_type; + + using base_type::m_connected_slots; + + signal8() + {} + + signal8(const this_type& s) + : base_type(s) + {} + + ~signal8() + { + base_type::disconnect_all(); + } + + template + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, + arg7_type, arg8_type)) + { + lock_block lock(this); + _connection8* conn = + new _connection8(pclass, pmemfun); + m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void SIGSLOT_EMIT(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8) + { + lock_block lock(this); + typename connections_list::const_iterator itNext, it = m_connected_slots.begin(); + typename connections_list::const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->SIGSLOT_EMIT(a1, a2, a3, a4, a5, a6, a7, a8); + + it = itNext; + } + } + + void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8) + { + SIGSLOT_EMIT(a1, a2, a3, a4, a5, a6, a7, a8); + } +}; + +namespace impl +{ + +struct empty {}; + +} // namespace impl + +// signal can be used instead of the numbered signalN classes. +// For example: +// +// sigslot::signal signal; +// +// instead of +// +// sigslot::signal2 signal; +template +struct signal; + +template<> +struct signal<>: public signal0<> +{}; + +template +struct signal: public signal1 +{}; + +template +struct signal: public signal2 +{}; + +template +struct signal: public signal3 +{}; + +template +struct signal: public signal4 +{}; + +template +struct signal: public signal5 +{}; + +template +struct signal: public signal6 +{}; + +template +struct signal: + public signal7 +{}; + +template +struct signal: public signal8 +{}; + +// Some convenience methods for signal handling. +template +struct has_signals +{ + virtual ~has_signals() {} + + // Connect a signal to a slot on the specified destination object. + template + static inline void connect(Signal &signal, Dst *dst, Sig memfun) + { + signal.connect(dst, memfun); + } + + // Connect a signal to a slot on 'this'. + template + inline void connect(Signal &signal, Sig memfun) + { + Derived* dst = static_cast(this); + connect(signal, dst, memfun); + } +}; + +}; // namespace sigslot + +#endif // __SIGSLOT_H__ \ No newline at end of file -- 2.45.2 From a445cdfbec8baaae702eae4793dfc06ae8003eee Mon Sep 17 00:00:00 2001 From: tqcq <99722391+tqcq@users.noreply.github.com> Date: Sat, 24 Aug 2024 17:51:41 +0800 Subject: [PATCH 2/7] feat generate sign data --- CMakeLists.txt | 76 +++++++++++++------- PcapSender/main.cpp | 23 +++++-- src/HuaWei/HWsign.h | 2 +- src/base/frame.cpp | 6 +- src/base/frame.h | 6 +- src/base/frame_manager.cpp | 9 +++ src/base/frame_manager.h | 1 + src/base/hk_sign.cpp | 44 ++++++++++++ src/base/rtp_decoder.cpp | 6 ++ src/base/rtp_decoder.h | 1 + src/base/rtp_manager.cpp | 137 ++++++++++++++++++++++++++++++++++++- src/base/rtp_manager.h | 28 +++++++- src/base/rtp_packet.cpp | 16 ++++- src/base/rtp_packet.h | 2 + src/base/signer.cpp | 116 +++++++++++++++++++++++++++++++ src/base/signer.h | 61 +++++++++++++++++ src/base/util.cpp | 6 ++ src/base/util.h | 1 + 18 files changed, 500 insertions(+), 41 deletions(-) create mode 100644 src/base/hk_sign.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8756047..44e5af0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,23 +41,29 @@ include(GenerateExportHeader) # media-server ps dec enc set(MediaServer_Root ${SecMedia_Root}/3rdpart/media-server) -include_directories(${MediaServer_Root}/librtp/include) -include_directories(${MediaServer_Root}/libmpeg/include) -include_directories(${MediaServer_Root}/libmpeg/source) +add_library(rtp STATIC "") aux_source_directory(${MediaServer_Root}/libmpeg/include src_rtp) aux_source_directory(${MediaServer_Root}/libmpeg/source src_rtp) aux_source_directory(${MediaServer_Root}/librtp/include src_rtp) aux_source_directory(${MediaServer_Root}/librtp/source src_rtp) aux_source_directory(${MediaServer_Root}/librtp/payload src_rtp) -add_library(rtp STATIC ${src_rtp}) +target_sources(rtp PRIVATE ${src_rtp}) +foreach(src ${src_rtp}) + message(STATUS "rtp src: ${src}") +endforeach() + +target_include_directories(rtp PUBLIC + ${MediaServer_Root}/librtp/include + ${MediaServer_Root}/libmpeg/include + ${MediaServer_Root}/libmpeg/source) include_directories(${SecMedia_Root}/SVAC/src/svac_src) # 添加svac解密 aux_source_directory(${SecMedia_Root}/SVAC/src/sm2sm3 src_DEC) aux_source_directory(${SecMedia_Root}/SVAC/src/svac_src src_DEC) add_library(SVAC_DEC STATIC ${src_DEC}) -# 添加svac加密 include_directories(${DEC_ENC_Algorithm}/SVAC/svac_enc) file(GLOB +# 添加svac加密 include_directories(${DEC_ENC_Algoruithm}/SVAC/svac_enc) file(GLOB # src_DEC_ENC ${DEC_ENC_Algorithm}/SVAC/svac_enc/*/*.c # ${DEC_ENC_Algorithm}/SVAC/svac_enc/*/*.h) aux_source_directory(${SecMedia_Root}/SVAC/src/sm2sm3_enc src_ENC) @@ -76,31 +82,53 @@ include_directories(include src) # file(GLOB SecMedia_src_list ${SecMedia_Root}/SVAC/./*.c # ${SecMedia_Root}/SVAC/./*.h) -file( - GLOB - SecMedia_src_list - ${SecMedia_Root}/*/*.cpp - ${SecMedia_Root}/*/*.h - ${SecMedia_Root}/*/*.c - ${SecMedia_Root}/*/*/*.cpp - ${SecMedia_Root}/*/*/*.h - ${SecMedia_Root}/*/*/*.c -) + +macro(append_srcs out_var root_dir) + file(GLOB_RECURSE srcs ${root_dir}/*.c ${root_dir}/*.cpp) + list(APPEND ${out_var} ${srcs}) +endmacro(append_srcs) + +append_srcs(SecMedia_src_list ${SecMedia_Root}/DecEnc) +append_srcs(SecMedia_src_list ${SecMedia_Root}/Decrypt) +append_srcs(SecMedia_src_list ${SecMedia_Root}/Encrypt) +append_srcs(SecMedia_src_list ${SecMedia_Root}/GB28181) +append_srcs(SecMedia_src_list ${SecMedia_Root}/HuaWei) +# append_srcs(SecMedia_src_list ${SecMedia_Root}/SVAC) +append_srcs(SecMedia_src_list ${SecMedia_Root}/base) + +# message(STATUS "SRCS: ${SecMedia_src_list}") + +# file( +# GLOB +# SecMedia_src_list +# ${SecMedia_Root}/*/*.cpp +# ${SecMedia_Root}/*/*.h +# ${SecMedia_Root}/*/*.c +# ${SecMedia_Root}/*/*/*.cpp +# ${SecMedia_Root}/*/*/*.h +# ${SecMedia_Root}/*/*/*.c +# ) file(GLOB SecMedia_api_list ${CMAKE_CURRENT_SOURCE_DIR}/include/common.h) # # target_compile_options(${PROJECT_NAME} PRIVATE -fvisibility=hidden) # list(APPEND LINK_LIB_LIST ${LINK_LIB_SVAC_LIST}) -add_library(${PROJECT_NAME} SHARED -"src/base/util.cpp" -"src/base/rtp_packet.cpp" -"src/SVAC/src/sm2sm3/sm3.c" -"src/SVAC/src/sm2sm3/sm2.c" -${SecMedia_src_list} -) +add_library(${PROJECT_NAME} SHARED ${SecMedia_src_list}) # add_library(${PROJECT_NAME} STATIC ${SecMedia_src_list}) -target_link_libraries(${PROJECT_NAME} ${LINK_LIB_SVAC_LIST} rtp) -target_include_directories(${PROJECT_NAME} PRIVATE ${SecMedia_Root}/.) +target_link_libraries(${PROJECT_NAME} PUBLIC ${LINK_LIB_SVAC_LIST} rtp) +target_include_directories(${PROJECT_NAME} PRIVATE +${SecMedia_Root} +${SecMedia_Root}/3rdpart/media-server/libdash/include +${SecMedia_Root}/3rdpart/media-server/libflv/include +${SecMedia_Root}/3rdpart/media-server/libhls/include +${SecMedia_Root}/3rdpart/media-server/libmov/include +${SecMedia_Root}/3rdpart/media-server/libmpeg/include +${SecMedia_Root}/3rdpart/media-server/librtmp/include +${SecMedia_Root}/3rdpart/media-server/librtp/include +${SecMedia_Root}/3rdpart/media-server/librtsp/include +${SecMedia_Root}/3rdpart/media-server/libsip/include + +) # set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} # SOVERSION 1 PUBLIC_HEADER ${SecMedia_api_list} ) diff --git a/PcapSender/main.cpp b/PcapSender/main.cpp index 1358b0a..5af8a17 100644 --- a/PcapSender/main.cpp +++ b/PcapSender/main.cpp @@ -33,7 +33,7 @@ EncrypInit() { // auto Verify_handle=HWVerify_init(); - auto sign_handle = GB28181_stream_init(&sign_info);//HWSign_init(&sign_info); + auto sign_handle = HK_stream_init(&sign_info);//HWSign_init(&sign_info); return sign_handle; } @@ -68,6 +68,12 @@ template timespec TimeDiff(T &&minu, U &&sub) { + if (minu.tv_sec < sub.tv_sec) { + return {0, 0}; + } else if (minu.tv_sec == sub.tv_sec && minu.tv_nsec < sub.tv_nsec) { + return {0, 0}; + } + timespec deltatime; deltatime.tv_nsec = minu.tv_nsec - sub.tv_nsec; deltatime.tv_sec = minu.tv_sec - sub.tv_sec; @@ -75,7 +81,7 @@ TimeDiff(T &&minu, U &&sub) deltatime.tv_nsec += 1000000000; deltatime.tv_sec--; } - return move(deltatime); + return deltatime; } int @@ -116,9 +122,12 @@ ReadPcapAndSend(int socket, sockaddr_in &addr, const string &filename, const str if (sign_handle) { output_thread = std::shared_ptr(new std::thread([&] { while (processing.load(std::memory_order_relaxed)) { - int ret = - GB28181_stream_out(sign_handle, sign_out_buf, &sign_out_len, &offset_len, &append_len, ¶m); + auto now = std::chrono::steady_clock::now(); + int ret = HK_stream_out(sign_handle, sign_out_buf, &sign_out_len, &offset_len, &append_len, ¶m); + auto end = std::chrono::steady_clock::now(); if (ret != 1) { continue; } + // WRNGL("HK_stream_out time: %lu ms\n", + // std::chrono::duration_cast(end - now).count()); processing_cnt.fetch_sub(1); if (append_len == 0) { sendto(socket, sign_out_buf, sign_out_len, 0, (const sockaddr *) &addr, sizeof(addr)); @@ -127,8 +136,8 @@ ReadPcapAndSend(int socket, sockaddr_in &addr, const string &filename, const str sendto(socket, sign_out_buf + offset_len, sign_out_len - offset_len, 0, (const sockaddr *) &addr, sizeof(addr)); } - // GB28181_stream_in(sign_h2,(char*)payload,payload_len,nullptr); - // GB28181_stream_out(sign_h2,sign_out_buf,&sign_out_len,&offset_len,&append_len, ¶m); + // HK_stream_in(sign_h2,(char*)payload,payload_len,nullptr); + // HK_stream_out(sign_h2,sign_out_buf,&sign_out_len,&offset_len,&append_len, ¶m); } })); } @@ -159,7 +168,7 @@ ReadPcapAndSend(int socket, sockaddr_in &addr, const string &filename, const str if (sign_handle) { auto cnt = processing_cnt.fetch_add(1); // printf("frame processing cnt:%d\n", cnt); - GB28181_stream_in(sign_handle, (char *) payload, payload_len, nullptr); + HK_stream_in(sign_handle, (char *) payload, payload_len, nullptr); } else { if (sendto(socket, payload, payload_len, 0, (const sockaddr *) &addr, sizeof(addr)) == -1) { printf("send failed : %s\n", strerror(errno)); diff --git a/src/HuaWei/HWsign.h b/src/HuaWei/HWsign.h index 912e5aa..9fb199b 100644 --- a/src/HuaWei/HWsign.h +++ b/src/HuaWei/HWsign.h @@ -26,7 +26,7 @@ API_EXPORT void *HK_stream_init(struct sec_set_info *sign_info); API_EXPORT int HK_stream_in(void *Handle, const char *buf, const uint32_t len, void *param); API_EXPORT void HK_stream_release(void *Handle); API_EXPORT int -KH_stream_out(void *Handle, char *buf, uint32_t *len, uint16_t *sei_end_offset, uint16_t *append_length, void **param); +HK_stream_out(void *Handle, char *buf, uint32_t *len, uint16_t *sei_end_offset, uint16_t *append_length, void **param); API_EXPORT void *GB28181_stream_init(struct sec_set_info *sign_info); API_EXPORT int GB28181_stream_in(void *Handle, const char *buf, const uint32_t len, void *param); diff --git a/src/base/frame.cpp b/src/base/frame.cpp index 1b71a7c..95b56e9 100644 --- a/src/base/frame.cpp +++ b/src/base/frame.cpp @@ -9,18 +9,18 @@ static std::atomic g_frame_cnt{0}; Frame::~Frame() { g_frame_cnt.fetch_sub(1); } Frame::Ptr -Frame::CreateUDPFrame(const uint8_t *data, size_t len) +Frame::CreateUDPFrame(const void *data, size_t len) { return std::shared_ptr(new Frame(kUDP, data, len)); } Frame::Ptr -Frame::CreateTCPFrame(const uint8_t *data, size_t len) +Frame::CreateTCPFrame(const void *data, size_t len) { return std::shared_ptr(new Frame(kTCP, data, len)); } -Frame::Frame(Type type, const uint8_t *data, size_t len) : _type(type), _data(data, data + len) +Frame::Frame(Type type, const void *data, size_t len) : _type(type), _data((uint8_t *) data, (uint8_t *) data + len) { auto cur = g_frame_cnt.fetch_add(1); // INFOL("frame count: %d\n", cur); diff --git a/src/base/frame.h b/src/base/frame.h index 1d3e6ae..b3a3190 100644 --- a/src/base/frame.h +++ b/src/base/frame.h @@ -13,8 +13,8 @@ public: enum Type { kTCP, kUDP }; - static Ptr CreateUDPFrame(const uint8_t *data, size_t len); - static Ptr CreateTCPFrame(const uint8_t *data, size_t len); + static Ptr CreateUDPFrame(const void *data, size_t len); + static Ptr CreateTCPFrame(const void *data, size_t len); public: ~Frame(); @@ -40,7 +40,7 @@ public: void Wait() { _event.Wait(); } private: - Frame(Type type, const uint8_t *data, size_t len); + Frame(Type type, const void *data, size_t len); private: Event _event{true}; diff --git a/src/base/frame_manager.cpp b/src/base/frame_manager.cpp index 2b4126d..930750f 100644 --- a/src/base/frame_manager.cpp +++ b/src/base/frame_manager.cpp @@ -7,6 +7,12 @@ FrameManager::FrameManager() { Init(); } FrameManager::~FrameManager() {} +bool +FrameManager::Initialize() +{ + return _rtp_manager.Initialize(); +} + bool FrameManager::Enqueue(Frame::Ptr frame) { @@ -21,6 +27,7 @@ Frame::Ptr FrameManager::Dequeue() { Frame::Ptr frame{nullptr}; + auto start = std::chrono::system_clock::now(); { std::lock_guard _(_frame_queue_lock); if (_frame_queue.empty()) { return nullptr; } @@ -30,6 +37,8 @@ FrameManager::Dequeue() } frame->Wait(); + auto end = std::chrono::system_clock::now(); + // WRNGL("frame wait time: %ld ms\n", std::chrono::duration_cast(end - start).count()); return frame; } diff --git a/src/base/frame_manager.h b/src/base/frame_manager.h index 8131022..2e2d71f 100644 --- a/src/base/frame_manager.h +++ b/src/base/frame_manager.h @@ -18,6 +18,7 @@ public: FrameManager(); ~FrameManager(); + bool Initialize(); bool Enqueue(Frame::Ptr frame); Frame::Ptr Dequeue(); diff --git a/src/base/hk_sign.cpp b/src/base/hk_sign.cpp new file mode 100644 index 0000000..35454ea --- /dev/null +++ b/src/base/hk_sign.cpp @@ -0,0 +1,44 @@ +#include "HuaWei/HWsign.h" +#include "base/frame_manager.h" + +void * +HK_stream_init(struct sec_set_info *sign_info) +{ + sign::FrameManager *fm = new sign::FrameManager(); + fm->SetSecSetInfo(sign_info); + if (!fm->Initialize()) { + delete fm; + return nullptr; + } + return fm; +} + +int +HK_stream_in(void *Handle, const char *buf, const uint32_t len, void *param) +{ + sign::FrameManager *fm = (sign::FrameManager *) Handle; + auto frame = sign::Frame::CreateUDPFrame(buf, len); + fm->Enqueue(frame); + return 1; +} + +void +HK_stream_release(void *Handle) +{ + if (Handle) { delete (sign::FrameManager *) Handle; } +} + +int +HK_stream_out(void *Handle, char *buf, uint32_t *len, uint16_t *sei_end_offset, uint16_t *append_length, void **param) +{ + sign::FrameManager *fm = (sign::FrameManager *) Handle; + auto frame = fm->Dequeue(); + if (!frame) { return -1; } + + *len = frame->size(); + if (buf) { std::copy(frame->data(), frame->data() + frame->size(), buf); } + *sei_end_offset = 0; + *append_length = 0; + + return 1; +} diff --git a/src/base/rtp_decoder.cpp b/src/base/rtp_decoder.cpp index 6354049..855add7 100644 --- a/src/base/rtp_decoder.cpp +++ b/src/base/rtp_decoder.cpp @@ -43,7 +43,9 @@ RTPDecoder::Input(RTPPacket::Ptr packet) const uint16_t seq = GetRTPSequenceNumber(packet->packet_data()); if (_prev_seq == -1) { _prev_seq = seq; + _start_decode_tp = std::chrono::steady_clock::now(); } else if (seq != ((_prev_seq + 1) & 0xFFFF)) { + _start_decode_tp = std::chrono::steady_clock::now(); _ref_rtp_packets.clear(); _prev_seq = -1; return; @@ -87,7 +89,11 @@ RTPDecoder::CreateHandler() DecodedPacket dp{packet, bytes, timestamp, flags}; dp.ref_rtp_packets.swap(self->_ref_rtp_packets); + auto end = std::chrono::steady_clock::now(); + // WRNGL("decode time: %lu ms\n", + // std::chrono::duration_cast(end - self->_start_decode_tp).count()); self->OnDecoded(dp); + self->_start_decode_tp = std::chrono::steady_clock::now(); }; return handler; } diff --git a/src/base/rtp_decoder.h b/src/base/rtp_decoder.h index eab719b..9f672f7 100644 --- a/src/base/rtp_decoder.h +++ b/src/base/rtp_decoder.h @@ -47,6 +47,7 @@ private: std::vector _buffer; std::vector _ref_rtp_packets; + std::chrono::steady_clock::time_point _start_decode_tp; }; }// namespace sign diff --git a/src/base/rtp_manager.cpp b/src/base/rtp_manager.cpp index ce0a327..5e758bc 100644 --- a/src/base/rtp_manager.cpp +++ b/src/base/rtp_manager.cpp @@ -8,6 +8,13 @@ RTPManager::RTPManager() {} RTPManager::~RTPManager() {} +bool +RTPManager::Initialize() +{ + _signer.OnSigned.connect(this, &RTPManager::OnSigned); + return _signer.Start(_sec_set_info); +} + void RTPManager::OnFrameEnqueue(Frame::Ptr frame) { @@ -22,7 +29,46 @@ RTPManager::OnFrameEnqueue(Frame::Ptr frame) void RTPManager::SetSecSetInfo(sec_set_info *info) -{} +{ + _sec_set_info = info; + InitSecSet(info); + InitVerifySet(info); +} + +void +RTPManager::InitSecSet(void *data) +{ + sec_set_info *info = (sec_set_info *) data; + + uint8_t security_set_version[19] = "Ver 0.0.2"; + memset(&_sec_set, 0, sizeof(_sec_set)); + memset(&_sec_set.evek, 0xFF, sizeof(_sec_set.evek)); + memset(&_sec_set.iv, 0xFF, sizeof(_sec_set.iv)); + // Set Flag + _sec_set.Flag.encryption_flag = 0; + _sec_set.Flag.authnetication_flag = 1; + _sec_set.Flag.vek_flag = 0; + _sec_set.Flag.iv_flag = 0; + _sec_set.Flag.hash_discard_p_picture = 1; + _sec_set.Flag.reserved_flag = 0b001; + // set Type + _sec_set.Type.signature_type = (uint8_t) SecMedia::DecryptType::SM2_auth; + _sec_set.Type.hash_type = (uint8_t) SecMedia::DecryptType::SM3; + _sec_set.Type.encryption_type = (uint8_t) SecMedia::DecryptType::NONE; + _sec_set.Type.vek_encryption_type = (uint8_t) SecMedia::DecryptType::NONE; + memcpy(_sec_set.camera_id, info->camera_id, sizeof(_sec_set.camera_id)); + memcpy(_sec_set.vkek_version, info->vkek_version, sizeof(_sec_set.vkek_version)); + _sec_set.vkek_version_length_minus1 = sizeof(_sec_set.vkek_version) - 1; + _sec_set.end_flag = 0x80; +} + +void +RTPManager::InitVerifySet(void *info) +{ + memset(&_verify_set, 0, sizeof(_verify_set)); + memset(&_verify_set.sign, 0xFF, sizeof(_verify_set.sign)); + _verify_set.end_flag = 0x80; +} void RTPManager::ProcessUDPFrame(Frame::Ptr frame) @@ -124,6 +170,95 @@ RTPManager::OnRTPDecoded(RTPDecoder::DecodedPacket packet) auto str = ss.str(); if (!str.empty()) str.pop_back(); INFOL("RTP decoded. type=%2d, size=%5u seq=[%s]\n", h264_type, packet.bytes, str.c_str()); + if (h264_type == H264Nal::NAL_IDR) { + // remove old sign + ResetSignData(); + + Signer::DataPacket::Ptr sign_packet = std::make_shared(); + sign_packet->param.codec_type = h264_type; + sign_packet->param.dts = packet.timestamp; + sign_packet->param.data_len = packet.bytes; + sign_packet->data = std::vector((uint8_t *) packet.packet, (uint8_t *) packet.packet + packet.bytes); + _signer.Enqueue(sign_packet); + } else if (h264_type == H264Nal::NAL_SEI) { + INFOL("origin SEI data: %s\n", ToHex((const uint8_t *) packet.packet, packet.bytes).c_str()); + uint8_t buf[4096]; + uint8_t *ptr = buf; + ptr = SecMedia::appendSEIframe( + ptr, SEC_SET_PT, (uint8_t *) SecMedia::Sec_set_UUID, (uint8_t *) (&_sec_set), sizeof(_sec_set)); + + auto signed_packet = FetchSignData(); + if (!signed_packet || signed_packet->sign_data.empty()) { + + if (_signer.state() == Signer::kSigning) { + WRNGL("Sign data is empty. still signing\n"); + _verify_set.head_frame_type = SecMedia::ERR_incomplete_Sign; + } else if (!signed_packet) { + WRNGL("Sign data is empty. no I-Frame\n"); + _verify_set.head_frame_type = SecMedia::ERR_Without_Frame_Data; + } else { + WRNGL("Sign data is empty. no sign_data\n"); + _verify_set.head_frame_type = SecMedia::ERR_Without_Sign_Data; + } + + ptr = SecMedia::appendSEIframe( + ptr, VER_SET_PT, (uint8_t *) SecMedia::Ver_set_UUID, (uint8_t *) &_verify_set, sizeof(_verify_set)); + } else { + INFOL("Sign data size=%lu\n", signed_packet->sign_data.size()); + INFOL("Sign data: %s\n", ToHex(signed_packet->sign_data).c_str()); + _verify_set.head_frame_type = signed_packet->param.codec_type; + _verify_set.head_frame_dts = signed_packet->param.dts; + _verify_set.total_hash_data_len = signed_packet->param.data_len; + _verify_set.sign_len = signed_packet->sign_data.size(); + memcpy(_verify_set.sign, signed_packet->sign_data.data(), signed_packet->sign_data.size()); + + ptr = SecMedia::appendSEIframe( + ptr, VER_SET_PT, (uint8_t *) SecMedia::Ver_set_UUID, (uint8_t *) &_verify_set, sizeof(_verify_set)); + } + ModifySEIPacket(packet, buf, ptr); + } +} + +void +RTPManager::ModifySEIPacket(RTPDecoder::DecodedPacket packet, void *sei_begin, void *sei_end) +{ + // TODO: @tqcq 增加对padding udp rtp sei包的处理 + auto last_packet = packet.ref_rtp_packets.back(); + auto last_frame = last_packet->ref_frames().back(); + INFOL("Modify SEI packet. seq=%d, size=%lu\n", last_packet->seq(), last_frame->size()); + INFOL("SEI data size=%lu\n", (uint8_t *) sei_end - (uint8_t *) sei_begin); + INFOL("SEI data: %s\n", ToHex((const uint8_t *) sei_begin, (uint8_t *) sei_end - (uint8_t *) sei_begin).c_str()); +} + +void +RTPManager::OnSigned(Signer::SignedPacket::Ptr signed_packet) +{ + INFOL("RTPManager::OnSigned sign data size=%lu\n", signed_packet->sign_data.size()); + INFOL("RTPManager::OnSigned sign data: %s\n", ToHex(signed_packet->sign_data).c_str()); + SetSignData(signed_packet); +} + +void +RTPManager::SetSignData(Signer::SignedPacket::Ptr signed_packet) +{ + std::lock_guard _(_signed_packet_lock); + _signed_packet = signed_packet; +} + +void +RTPManager::ResetSignData() +{ + std::lock_guard _(_signed_packet_lock); + _signed_packet = nullptr; +} + +Signer::SignedPacket::Ptr +RTPManager::FetchSignData() +{ + std::lock_guard _(_signed_packet_lock); + auto res = _signed_packet; + _signed_packet.reset(); + return res; } }// namespace sign diff --git a/src/base/rtp_manager.h b/src/base/rtp_manager.h index 398d3e5..dca2770 100644 --- a/src/base/rtp_manager.h +++ b/src/base/rtp_manager.h @@ -6,6 +6,7 @@ #include "HuaWei/HWsign.h" #include "rtp_decoder.h" #include "rtp_packet.h" +#include "signer.h" #include "sigslot.h" namespace sign { @@ -17,12 +18,16 @@ public: RTPManager(); ~RTPManager(); + bool Initialize(); void OnFrameEnqueue(Frame::Ptr frame); // HACK: void SetSecSetInfo(sec_set_info *info); private: + void InitSecSet(void *info); + void InitVerifySet(void *info); + void ProcessUDPFrame(Frame::Ptr); void ProcessTCPFrame(Frame::Ptr); @@ -37,10 +42,19 @@ private: void IncCurSeq(); uint16_t GetNextSeq(); + void SetSignData(Signer::SignedPacket::Ptr signed_packet); + void ResetSignData(); + Signer::SignedPacket::Ptr FetchSignData(); + + void ModifySEIPacket(RTPDecoder::DecodedPacket packet, void *sei_begin, void *sei_end); + private: - // FOR TEST + // NALU 组包回调 void OnRTPDecoded(RTPDecoder::DecodedPacket packet); + // 签名数据回调 + void OnSigned(Signer::SignedPacket::Ptr signed_packet); + private: /** * Partical RTP packet -> Complete RTP packet -> Decoder -> Signer @@ -50,6 +64,10 @@ private: * 2. Insert SEI **/ + std::mutex _signed_packet_lock; + // std::vector _sign_data; + Signer::SignedPacket::Ptr _signed_packet{nullptr}; + // 当前不完整的RTP包 RTPPacket::Ptr _cur_rtp_packet{nullptr}; int64_t _cur_rtp_seq{-1}; @@ -59,6 +77,14 @@ private: uint16_t _insert_packet_num{0}; RTPDecoder::Ptr _decoder; + + void *_sec_set_info{nullptr}; + Signer _signer; + + // 安全相关的辅助信息 + SecMedia::NALUdecodeInfo _sec_set; + // 签名验证信息集合 + SecMedia::VerificationSet _verify_set; }; }// namespace sign diff --git a/src/base/rtp_packet.cpp b/src/base/rtp_packet.cpp index 2f278b9..2371a51 100644 --- a/src/base/rtp_packet.cpp +++ b/src/base/rtp_packet.cpp @@ -5,6 +5,10 @@ #include #include +extern "C" { +#include "rtp-packet.h" +} + namespace sign { static std::atomic g_rtp_packet_cnt{0}; @@ -126,7 +130,17 @@ RTPPacket::RTPPacket(RTPManager *owner, Frame::Ptr udp_frame) _rtp_ptr = udp_frame->data(); _state = IsRTPHeader(udp_frame->data(), udp_frame->size()) ? kComplete : kError; - udp_frame->set_paused(true); + udp_frame->set_paused(false); + if (_state == kComplete) { + rtp_packet_t pkt; + if (rtp_packet_deserialize(&pkt, udp_frame->data(), udp_frame->size()) == 0) { + _state = kComplete; + uint8_t h264_type = ((uint8_t *) pkt.payload)[0] & 0x1F; + if (h264_type == H264Nal::NAL_SEI) { udp_frame->set_paused(true); } + } else { + _state = kError; + } + } } RTPPacket::RTPPacket(RTPManager *owner) : _owner(owner), _frame_type(Frame::kTCP) { IncRTPPacketCnt(); } diff --git a/src/base/rtp_packet.h b/src/base/rtp_packet.h index 2eb8076..07b677b 100644 --- a/src/base/rtp_packet.h +++ b/src/base/rtp_packet.h @@ -50,6 +50,8 @@ public: bool paused() const; void set_paused(bool paused); + std::vector ref_frames() const { return _ref_frames; } + private: RTPPacket(RTPManager *owner, Frame::Ptr udp_frame); RTPPacket(RTPManager *owner); diff --git a/src/base/signer.cpp b/src/base/signer.cpp index 7d277ae..83dd0f4 100644 --- a/src/base/signer.cpp +++ b/src/base/signer.cpp @@ -1 +1,117 @@ #include "signer.h" +#include "HuaWei/HWcommon.h" +#include "HuaWei/HWsign.h" +#include "util.h" + +#include +#include +#include + +namespace sign { +Signer::Signer() {} + +Signer::~Signer() +{ + Stop(); + Join(); +} + +bool +Signer::Start(void *param) +{ + _param = param; + if (_sign_thread) { + ERROL("sign thread already running\n"); + assert(false); + return true; + } + if (!_param) { + WRNGL("sec_set_info param is null\n"); + return false; + } + // 初始化安全相关的辅助信息 + _sign_thread = std::unique_ptr(new std::thread(&Signer::WorkProc, this)); + + return true; +} + +void +Signer::Enqueue(DataPacket::Ptr packet) +{ + std::unique_lock _(_sign_lock); + _data_queue.push(packet); + _cv.notify_one(); +} + +void +Signer::WorkProc() +{ + sec_set_info *info = reinterpret_cast(_param); + if (info) { + cpu_set_t mask; + CPU_ZERO(&mask); + CPU_SET(info->cpu_core, &mask); + if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) { + ERROL("set thread affinity failed, target_cpu = %d\n", info->cpu_core); + } + } + + DataPacket::Ptr data_packet; + while (!_stopped.load(std::memory_order_relaxed)) { + { + std::unique_lock _(_sign_lock); + _cv.wait(_, [this] { return !_data_queue.empty() || _stopped; }); + if (_stopped) { return; } + + _state = kSigning; + data_packet.swap(_data_queue.front()); + _data_queue.pop(); + } + std::vector sign; + if (!Sign(data_packet->data, &sign)) { + // do nothing + ERROL("sign failed\n"); + } else { + auto signed_packet = std::make_shared(); + signed_packet->param = data_packet->param; + signed_packet->sign_data = sign; + OnSigned(signed_packet); + } + _state = kIdle; + } +} + +bool +Signer::Sign(const std::vector &data, std::vector *sign) +{ + // 1. sm3 hash + std::vector sm3_hash = SM3Hash(data.data(), data.size()); + if (sm3_hash.empty() || sm3_hash.size() < 32) { + ERROL("sm3 hash failed\n"); + return false; + } + + sec_set_info *info = reinterpret_cast(_param); + uint8_t sm2_sign[128]; + + do_sm2_sign((char *) info->prikey, (char *) info->pubkey, (char *) sm3_hash.data(), 32, (char *) sm2_sign); + sign->assign(sm2_sign, sm2_sign + 64); + return true; +} + +void +Signer::Stop() +{ + _stopped.store(true); +} + +void +Signer::Join() +{ + if (_sign_thread && _sign_thread->joinable()) { + _sign_thread->joinable(); + _sign_thread.reset(); + } +} + +}// namespace sign diff --git a/src/base/signer.h b/src/base/signer.h index b99ca71..e078c8d 100644 --- a/src/base/signer.h +++ b/src/base/signer.h @@ -3,12 +3,73 @@ #pragma once +#include "DecEnc/NALUdecode.h" +#include "sigslot.h" +#include +#include #include +#include #include namespace sign { class Signer { public: + enum State { + kIdle, + kSigning, + }; + + struct SignParam { + uint64_t data_len; + uint32_t dts; + uint8_t codec_type; + }; + + // 待签名数据包 + struct DataPacket { + SignParam param; + std::vector data; + using Ptr = std::shared_ptr; + }; + + // 签名数据包 + struct SignedPacket { + SignParam param; + std::vector sign_data; + using Ptr = std::shared_ptr; + }; + + sigslot::signal1 OnSigned; + +public: + Signer(); + virtual ~Signer(); + + void Enqueue(DataPacket::Ptr packet); + + bool Start(void *param); + void Stop(); + void Join(); + + State state() const { return _state; } + +private: + void WorkProc(); + + bool Sign(const std::vector &data, std::vector *sign); + +private: + State _state{kIdle}; + void *_param{nullptr}; + + std::atomic _stopped{false}; + + std::unique_ptr _sign_thread{nullptr}; + + std::mutex _sign_lock; + std::condition_variable _cv; + // 存放待签名数据 + std::queue _data_queue; }; }// namespace sign diff --git a/src/base/util.cpp b/src/base/util.cpp index 44fb903..1f91b0c 100644 --- a/src/base/util.cpp +++ b/src/base/util.cpp @@ -82,6 +82,12 @@ IsParticalRTPHeader(const uint8_t *data, size_t len) } } +std::string +ToHex(std::vector data) +{ + return ToHex(data.data(), data.size()); +} + std::string ToHex(const void *data, size_t len) { diff --git a/src/base/util.h b/src/base/util.h index 28abbe4..4bfb326 100644 --- a/src/base/util.h +++ b/src/base/util.h @@ -22,6 +22,7 @@ bool IsRTPHeader(const uint8_t *data, size_t len); bool IsParticalRTPHeader(const uint8_t *data, size_t len); std::string ToHex(const void *data, size_t len); +std::string ToHex(std::vector data); std::vector SM3Hash(const void *data, size_t len); -- 2.45.2 From bb0f0a23209374074556245d73be972dde21fa6e Mon Sep 17 00:00:00 2001 From: tqcq <99722391+tqcq@users.noreply.github.com> Date: Mon, 26 Aug 2024 12:41:30 +0800 Subject: [PATCH 3/7] feat update interface --- PcapSender/main.cpp | 12 ++++++------ src/HuaWei/HWsign.h | 8 ++++---- src/base/hk_sign.cpp | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/PcapSender/main.cpp b/PcapSender/main.cpp index 5af8a17..559c74e 100644 --- a/PcapSender/main.cpp +++ b/PcapSender/main.cpp @@ -33,7 +33,7 @@ EncrypInit() { // auto Verify_handle=HWVerify_init(); - auto sign_handle = HK_stream_init(&sign_info);//HWSign_init(&sign_info); + auto sign_handle = HK_udp_init(&sign_info);//HWSign_init(&sign_info); return sign_handle; } @@ -123,10 +123,10 @@ ReadPcapAndSend(int socket, sockaddr_in &addr, const string &filename, const str output_thread = std::shared_ptr(new std::thread([&] { while (processing.load(std::memory_order_relaxed)) { auto now = std::chrono::steady_clock::now(); - int ret = HK_stream_out(sign_handle, sign_out_buf, &sign_out_len, &offset_len, &append_len, ¶m); + int ret = HK_udp_out(sign_handle, sign_out_buf, &sign_out_len, &offset_len, &append_len, ¶m); auto end = std::chrono::steady_clock::now(); if (ret != 1) { continue; } - // WRNGL("HK_stream_out time: %lu ms\n", + // WRNGL("HK_udp_out time: %lu ms\n", // std::chrono::duration_cast(end - now).count()); processing_cnt.fetch_sub(1); if (append_len == 0) { @@ -136,8 +136,8 @@ ReadPcapAndSend(int socket, sockaddr_in &addr, const string &filename, const str sendto(socket, sign_out_buf + offset_len, sign_out_len - offset_len, 0, (const sockaddr *) &addr, sizeof(addr)); } - // HK_stream_in(sign_h2,(char*)payload,payload_len,nullptr); - // HK_stream_out(sign_h2,sign_out_buf,&sign_out_len,&offset_len,&append_len, ¶m); + // HK_udp_in(sign_h2,(char*)payload,payload_len,nullptr); + // HK_udp_out(sign_h2,sign_out_buf,&sign_out_len,&offset_len,&append_len, ¶m); } })); } @@ -168,7 +168,7 @@ ReadPcapAndSend(int socket, sockaddr_in &addr, const string &filename, const str if (sign_handle) { auto cnt = processing_cnt.fetch_add(1); // printf("frame processing cnt:%d\n", cnt); - HK_stream_in(sign_handle, (char *) payload, payload_len, nullptr); + HK_udp_in(sign_handle, (char *) payload, payload_len, nullptr); } else { if (sendto(socket, payload, payload_len, 0, (const sockaddr *) &addr, sizeof(addr)) == -1) { printf("send failed : %s\n", strerror(errno)); diff --git a/src/HuaWei/HWsign.h b/src/HuaWei/HWsign.h index 9fb199b..c2f254e 100644 --- a/src/HuaWei/HWsign.h +++ b/src/HuaWei/HWsign.h @@ -22,11 +22,11 @@ struct sec_set_info { API_EXPORT int SDF_Device_open(); API_EXPORT int SDF_Device_close(); -API_EXPORT void *HK_stream_init(struct sec_set_info *sign_info); -API_EXPORT int HK_stream_in(void *Handle, const char *buf, const uint32_t len, void *param); -API_EXPORT void HK_stream_release(void *Handle); +API_EXPORT void *HK_udp_init(struct sec_set_info *sign_info); +API_EXPORT int HK_udp_in(void *Handle, const char *buf, const uint32_t len, void *param); +API_EXPORT void HK_udp_release(void *Handle); API_EXPORT int -HK_stream_out(void *Handle, char *buf, uint32_t *len, uint16_t *sei_end_offset, uint16_t *append_length, void **param); +HK_udp_out(void *Handle, char *buf, uint32_t *len, uint16_t *sei_end_offset, uint16_t *append_length, void **param); API_EXPORT void *GB28181_stream_init(struct sec_set_info *sign_info); API_EXPORT int GB28181_stream_in(void *Handle, const char *buf, const uint32_t len, void *param); diff --git a/src/base/hk_sign.cpp b/src/base/hk_sign.cpp index 35454ea..0019b8b 100644 --- a/src/base/hk_sign.cpp +++ b/src/base/hk_sign.cpp @@ -2,7 +2,7 @@ #include "base/frame_manager.h" void * -HK_stream_init(struct sec_set_info *sign_info) +HK_udp_init(struct sec_set_info *sign_info) { sign::FrameManager *fm = new sign::FrameManager(); fm->SetSecSetInfo(sign_info); @@ -14,7 +14,7 @@ HK_stream_init(struct sec_set_info *sign_info) } int -HK_stream_in(void *Handle, const char *buf, const uint32_t len, void *param) +HK_udp_in(void *Handle, const char *buf, const uint32_t len, void *param) { sign::FrameManager *fm = (sign::FrameManager *) Handle; auto frame = sign::Frame::CreateUDPFrame(buf, len); @@ -23,13 +23,13 @@ HK_stream_in(void *Handle, const char *buf, const uint32_t len, void *param) } void -HK_stream_release(void *Handle) +HK_udp_release(void *Handle) { if (Handle) { delete (sign::FrameManager *) Handle; } } int -HK_stream_out(void *Handle, char *buf, uint32_t *len, uint16_t *sei_end_offset, uint16_t *append_length, void **param) +HK_udp_out(void *Handle, char *buf, uint32_t *len, uint16_t *sei_end_offset, uint16_t *append_length, void **param) { sign::FrameManager *fm = (sign::FrameManager *) Handle; auto frame = fm->Dequeue(); -- 2.45.2 From 2a1fa19f3f56ad4bd3dfc8b468e988b58791fe51 Mon Sep 17 00:00:00 2001 From: tqcq <99722391+tqcq@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:06:11 +0800 Subject: [PATCH 4/7] fix frame --- PcapSender/main.cpp | 2 +- src/base/frame.h | 3 +++ src/base/rtp_manager.cpp | 25 ++++++++++++++++++++++++- src/base/rtp_packet.cpp | 6 ++++++ src/base/rtp_packet.h | 1 + src/base/util.cpp | 6 ++++++ src/base/util.h | 1 + 7 files changed, 42 insertions(+), 2 deletions(-) diff --git a/PcapSender/main.cpp b/PcapSender/main.cpp index 559c74e..4372c4d 100644 --- a/PcapSender/main.cpp +++ b/PcapSender/main.cpp @@ -159,7 +159,7 @@ ReadPcapAndSend(int socket, sockaddr_in &addr, const string &filename, const str current_time.tv_sec = inital_time.tv_sec + real_now.tv_sec; current_time.tv_nsec = inital_time.tv_nsec + real_now.tv_nsec; gaptime = TimeDiff(nowtime, current_time); - if (gaptime.tv_nsec >= 0 && gaptime.tv_sec >= 0) { + if (gaptime.tv_nsec > 0 || gaptime.tv_sec > 0) { nanosleep(&gaptime, NULL); } else { // cout<<" s:" << gaptime.tv_sec<<" ns:" << gaptime.tv_nsec < namespace sign { +class RTPManager; + class Frame : std::enable_shared_from_this { public: using Ptr = std::shared_ptr; @@ -41,6 +43,7 @@ public: private: Frame(Type type, const void *data, size_t len); + friend class RTPManager; private: Event _event{true}; diff --git a/src/base/rtp_manager.cpp b/src/base/rtp_manager.cpp index 5e758bc..1d3d95d 100644 --- a/src/base/rtp_manager.cpp +++ b/src/base/rtp_manager.cpp @@ -225,9 +225,32 @@ RTPManager::ModifySEIPacket(RTPDecoder::DecodedPacket packet, void *sei_begin, v // TODO: @tqcq 增加对padding udp rtp sei包的处理 auto last_packet = packet.ref_rtp_packets.back(); auto last_frame = last_packet->ref_frames().back(); + auto append_len = (const uint8_t *) sei_end - (const uint8_t *) sei_begin; INFOL("Modify SEI packet. seq=%d, size=%lu\n", last_packet->seq(), last_frame->size()); INFOL("SEI data size=%lu\n", (uint8_t *) sei_end - (uint8_t *) sei_begin); - INFOL("SEI data: %s\n", ToHex((const uint8_t *) sei_begin, (uint8_t *) sei_end - (uint8_t *) sei_begin).c_str()); + INFOL("SEI data: %s\n", ToHex((const uint8_t *) sei_begin, append_len).c_str()); + + if (last_frame->type() != Frame::kUDP) { + ERROL("Only support kUDP"); + return; + } + auto &buf = last_frame->_data; + + bool has_padding = last_packet->has_padding(); + uint8_t padding_len = 0; + if (has_padding) { + // remove padding + padding_len = buf.back(); + buf.resize(buf.size() - padding_len); + } + std::copy((uint8_t *) sei_begin, (uint8_t *) sei_end, std::back_inserter(buf)); + if (has_padding) { + // append_len align 4 need (4 - append_len & 0x3) + // new_padding_len = (old_padding + append_len_align_len) %4 + const uint8_t new_padding_len = ((4 - (append_len & 0x3)) + padding_len) % 4; + for (int i = 1; i < new_padding_len; ++i) { buf.push_back(0); } + buf.push_back(new_padding_len); + } } void diff --git a/src/base/rtp_packet.cpp b/src/base/rtp_packet.cpp index 2371a51..0e34a97 100644 --- a/src/base/rtp_packet.cpp +++ b/src/base/rtp_packet.cpp @@ -61,6 +61,12 @@ RTPPacket::packet_data() const return _rtp_ptr; } +bool +RTPPacket::has_padding() const +{ + return GetRTPPadding(_rtp_ptr); +} + uint8_t RTPPacket::payload_type() const { diff --git a/src/base/rtp_packet.h b/src/base/rtp_packet.h index 07b677b..61a314e 100644 --- a/src/base/rtp_packet.h +++ b/src/base/rtp_packet.h @@ -36,6 +36,7 @@ public: size_t rtp_payload_size(); // rtp header, kMissPayload or kComplete + bool has_padding() const; uint8_t payload_type() const; uint16_t seq() const; uint32_t ssrc() const; diff --git a/src/base/util.cpp b/src/base/util.cpp index 1f91b0c..7bf8f93 100644 --- a/src/base/util.cpp +++ b/src/base/util.cpp @@ -11,6 +11,12 @@ GetRTPVersion(const uint8_t *data) return (data[0] & 0xC0) >> 6; } +uint8_t +GetRTPPadding(const uint8_t *header) +{ + return (header[0] & 0x20); +} + uint8_t GetRTPPayloadType(const uint8_t *data) { diff --git a/src/base/util.h b/src/base/util.h index 4bfb326..8e6dccf 100644 --- a/src/base/util.h +++ b/src/base/util.h @@ -10,6 +10,7 @@ namespace sign { uint8_t GetRTPVersion(const uint8_t *header); +uint8_t GetRTPPadding(const uint8_t *header); uint8_t GetRTPPayloadType(const uint8_t *header); uint16_t GetRTPSequenceNumber(const uint8_t *header); uint32_t GetRTPTimestamp(const uint8_t *header); -- 2.45.2 From 5ad12d6257cda28e3a0798eecddb369bcc04e794 Mon Sep 17 00:00:00 2001 From: tqcq <99722391+tqcq@users.noreply.github.com> Date: Wed, 28 Aug 2024 09:57:33 +0800 Subject: [PATCH 5/7] feat build tools only BUILD_TOOLS=ON --- .gitignore | 1 + CMakeLists.txt | 61 ++++++++++++++++++++------------------------ src/base/frame.h | 8 ++++++ src/base/hk_sign.cpp | 4 +-- 4 files changed, 38 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index 27e86e5..f70a489 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ release/ .cache out/ compile_commands.json +build_* diff --git a/CMakeLists.txt b/CMakeLists.txt index 44e5af0..e6937c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,10 +53,10 @@ foreach(src ${src_rtp}) message(STATUS "rtp src: ${src}") endforeach() -target_include_directories(rtp PUBLIC - ${MediaServer_Root}/librtp/include - ${MediaServer_Root}/libmpeg/include - ${MediaServer_Root}/libmpeg/source) +target_include_directories( + rtp + PUBLIC ${MediaServer_Root}/librtp/include ${MediaServer_Root}/libmpeg/include + ${MediaServer_Root}/libmpeg/source) include_directories(${SecMedia_Root}/SVAC/src/svac_src) # 添加svac解密 @@ -98,16 +98,9 @@ append_srcs(SecMedia_src_list ${SecMedia_Root}/base) # message(STATUS "SRCS: ${SecMedia_src_list}") -# file( -# GLOB -# SecMedia_src_list -# ${SecMedia_Root}/*/*.cpp -# ${SecMedia_Root}/*/*.h -# ${SecMedia_Root}/*/*.c -# ${SecMedia_Root}/*/*/*.cpp -# ${SecMedia_Root}/*/*/*.h -# ${SecMedia_Root}/*/*/*.c -# ) +# file( GLOB SecMedia_src_list ${SecMedia_Root}/*/*.cpp ${SecMedia_Root}/*/*.h +# ${SecMedia_Root}/*/*.c ${SecMedia_Root}/*/*/*.cpp ${SecMedia_Root}/*/*/*.h +# ${SecMedia_Root}/*/*/*.c ) file(GLOB SecMedia_api_list ${CMAKE_CURRENT_SOURCE_DIR}/include/common.h) # # target_compile_options(${PROJECT_NAME} PRIVATE -fvisibility=hidden) @@ -116,23 +109,22 @@ file(GLOB SecMedia_api_list ${CMAKE_CURRENT_SOURCE_DIR}/include/common.h) add_library(${PROJECT_NAME} SHARED ${SecMedia_src_list}) # add_library(${PROJECT_NAME} STATIC ${SecMedia_src_list}) target_link_libraries(${PROJECT_NAME} PUBLIC ${LINK_LIB_SVAC_LIST} rtp) -target_include_directories(${PROJECT_NAME} PRIVATE -${SecMedia_Root} -${SecMedia_Root}/3rdpart/media-server/libdash/include -${SecMedia_Root}/3rdpart/media-server/libflv/include -${SecMedia_Root}/3rdpart/media-server/libhls/include -${SecMedia_Root}/3rdpart/media-server/libmov/include -${SecMedia_Root}/3rdpart/media-server/libmpeg/include -${SecMedia_Root}/3rdpart/media-server/librtmp/include -${SecMedia_Root}/3rdpart/media-server/librtp/include -${SecMedia_Root}/3rdpart/media-server/librtsp/include -${SecMedia_Root}/3rdpart/media-server/libsip/include - -) +target_include_directories( + ${PROJECT_NAME} + PRIVATE ${SecMedia_Root} + ${SecMedia_Root}/3rdpart/media-server/libdash/include + ${SecMedia_Root}/3rdpart/media-server/libflv/include + ${SecMedia_Root}/3rdpart/media-server/libhls/include + ${SecMedia_Root}/3rdpart/media-server/libmov/include + ${SecMedia_Root}/3rdpart/media-server/libmpeg/include + ${SecMedia_Root}/3rdpart/media-server/librtmp/include + ${SecMedia_Root}/3rdpart/media-server/librtp/include + ${SecMedia_Root}/3rdpart/media-server/librtsp/include + ${SecMedia_Root}/3rdpart/media-server/libsip/include) # set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} -# SOVERSION 1 PUBLIC_HEADER ${SecMedia_api_list} ) -# CXX_VISIBILITY_PRESET hidden CMAKE_C_FLAGS hidden) +# SOVERSION 1 PUBLIC_HEADER ${SecMedia_api_list} ) CXX_VISIBILITY_PRESET hidden +# CMAKE_C_FLAGS hidden) list(APPEND LINK_LIB_LIST ${PROJECT_NAME}) list(APPEND LINK_LIB_LIST pthread) @@ -155,8 +147,9 @@ endif() # ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION # ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig) -add_subdirectory(test) -add_subdirectory(PcapSender) -add_subdirectory(PcapRawSender) -add_subdirectory(SecSetGen) - +if(BUILD_TOOLS) + add_subdirectory(test) + add_subdirectory(PcapSender) + add_subdirectory(PcapRawSender) + add_subdirectory(SecSetGen) +endif(BUILD_TOOLS) diff --git a/src/base/frame.h b/src/base/frame.h index c7aeed1..d034f63 100644 --- a/src/base/frame.h +++ b/src/base/frame.h @@ -41,11 +41,19 @@ public: void Wait() { _event.Wait(); } + // For Interface + size_t sei_end_offset() const { return _sei_end_offset; } + + size_t append_length() const { return _append_length; } + private: Frame(Type type, const void *data, size_t len); friend class RTPManager; private: + size_t _sei_end_offset{0}; + size_t _append_length{0}; + Event _event{true}; Type _type; std::vector _data; diff --git a/src/base/hk_sign.cpp b/src/base/hk_sign.cpp index 0019b8b..9488ad8 100644 --- a/src/base/hk_sign.cpp +++ b/src/base/hk_sign.cpp @@ -37,8 +37,8 @@ HK_udp_out(void *Handle, char *buf, uint32_t *len, uint16_t *sei_end_offset, uin *len = frame->size(); if (buf) { std::copy(frame->data(), frame->data() + frame->size(), buf); } - *sei_end_offset = 0; - *append_length = 0; + *sei_end_offset = frame->sei_end_offset(); + *append_length = frame->append_length(); return 1; } -- 2.45.2 From fe7da4f6380390df641ac51eed12df414bb028af Mon Sep 17 00:00:00 2001 From: tqcq <99722391+tqcq@users.noreply.github.com> Date: Wed, 28 Aug 2024 14:54:06 +0800 Subject: [PATCH 6/7] feat add init check --- CMakeLists.txt | 7 ++++++- src/base/frame_manager.cpp | 15 +++++++++++++-- src/base/frame_manager.h | 2 ++ src/base/hk_sign.cpp | 5 +++++ src/base/rtp_manager.cpp | 37 ++++++++++++++++++++++++++++++++----- src/base/rtp_packet.cpp | 8 ++++++-- 6 files changed, 64 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e6937c5..0b314a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,8 @@ set(CMAKE_C_VISIBILITY_PRESET hidden) set(CMAKE_CXX_VISIBILITY_PRESET hidden) # set(CMAKE_C_FLAGS$ "${CMAKE_C_FLAGS} -fvisibility = hidden") # set(CMAKE_CXX_FLAGS$ "${CMAKE_CXX_FLAGS} -fvisibility = hidden") +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address +# -fno-omit-frame-pointer") set(SecMedia_Root ${CMAKE_CURRENT_SOURCE_DIR}/src) add_compile_options(-fPIC) # add_compile_options(-fvisibility=hidden) add_compile_options(-std=c++11) @@ -105,10 +107,13 @@ file(GLOB SecMedia_api_list ${CMAKE_CURRENT_SOURCE_DIR}/include/common.h) # # target_compile_options(${PROJECT_NAME} PRIVATE -fvisibility=hidden) # list(APPEND LINK_LIB_LIST ${LINK_LIB_SVAC_LIST}) +# +find_package(Threads REQUIRED) add_library(${PROJECT_NAME} SHARED ${SecMedia_src_list}) # add_library(${PROJECT_NAME} STATIC ${SecMedia_src_list}) -target_link_libraries(${PROJECT_NAME} PUBLIC ${LINK_LIB_SVAC_LIST} rtp) +target_link_libraries(${PROJECT_NAME} PUBLIC ${LINK_LIB_SVAC_LIST} rtp + Threads::Threads) target_include_directories( ${PROJECT_NAME} PRIVATE ${SecMedia_Root} diff --git a/src/base/frame_manager.cpp b/src/base/frame_manager.cpp index 930750f..eeb68c1 100644 --- a/src/base/frame_manager.cpp +++ b/src/base/frame_manager.cpp @@ -3,20 +3,21 @@ namespace sign { -FrameManager::FrameManager() { Init(); } +FrameManager::FrameManager() {} FrameManager::~FrameManager() {} bool FrameManager::Initialize() { + Init(); return _rtp_manager.Initialize(); } bool FrameManager::Enqueue(Frame::Ptr frame) { - + CheckMagicNumber(); std::lock_guard _(_frame_queue_lock); OnFrameEnqueue(frame); _frame_queue.push(frame); @@ -26,6 +27,7 @@ FrameManager::Enqueue(Frame::Ptr frame) Frame::Ptr FrameManager::Dequeue() { + CheckMagicNumber(); Frame::Ptr frame{nullptr}; auto start = std::chrono::system_clock::now(); { @@ -54,4 +56,13 @@ FrameManager::Init() OnFrameEnqueue.connect(&_rtp_manager, &RTPManager::OnFrameEnqueue); } +void +FrameManager::CheckMagicNumber() +{ + if (memcmp(magic_number, "MAGI", 4) != 0) { + ERROL("Please Init FrameManager.\n"); + exit(-1); + } +} + }// namespace sign diff --git a/src/base/frame_manager.h b/src/base/frame_manager.h index 2e2d71f..81c6bbc 100644 --- a/src/base/frame_manager.h +++ b/src/base/frame_manager.h @@ -28,8 +28,10 @@ public: private: void Init(); + void CheckMagicNumber(); private: + char magic_number[4] = {'M', 'A', 'G', 'I'}; RTPManager _rtp_manager; std::mutex _frame_queue_lock; diff --git a/src/base/hk_sign.cpp b/src/base/hk_sign.cpp index 9488ad8..8f8b88e 100644 --- a/src/base/hk_sign.cpp +++ b/src/base/hk_sign.cpp @@ -1,3 +1,4 @@ +#include "HuaWei/HWcommon.h" #include "HuaWei/HWsign.h" #include "base/frame_manager.h" @@ -18,6 +19,10 @@ HK_udp_in(void *Handle, const char *buf, const uint32_t len, void *param) { sign::FrameManager *fm = (sign::FrameManager *) Handle; auto frame = sign::Frame::CreateUDPFrame(buf, len); + if (!frame) { + ERROL("Create frame failed\n"); + return -1; + } fm->Enqueue(frame); return 1; } diff --git a/src/base/rtp_manager.cpp b/src/base/rtp_manager.cpp index 1d3d95d..cb9c6f8 100644 --- a/src/base/rtp_manager.cpp +++ b/src/base/rtp_manager.cpp @@ -73,8 +73,15 @@ RTPManager::InitVerifySet(void *info) void RTPManager::ProcessUDPFrame(Frame::Ptr frame) { - if (!IsRTPHeader(frame->data(), frame->size())) { return; } + if (!IsRTPHeader(frame->data(), frame->size())) { + INFOL("Not a RTP packet. discard it.\n"); + return; + } auto packet = RTPPacket::CreateCompleteRTPPacket(this, frame); + if (packet->payload_type() == 112) { + INFOL("RTCP packet pt=112. discard it.\n"); + return; + } ProcessPacket(packet); } @@ -86,7 +93,7 @@ void RTPManager::ProcessPacket(RTPPacket::Ptr packet) { if (!packet->IsComplete()) { - // ERROL("RTP packet is not complete, discard it.\n"); + ERROL("RTP packet is not complete, discard it.\n"); return; } @@ -99,7 +106,7 @@ RTPManager::ProcessPacket(RTPPacket::Ptr packet) MaybeSetSeq(packet->seq()); if (packet->seq() != _cur_rtp_seq) { - // WRNGL("RTP packet seq is not continuous. cur_seq=%ld, packet->seq=%d\n", _cur_rtp_seq, packet->seq()); + WRNGL("RTP packet seq is not continuous. cur_seq=%ld, packet->seq=%d\n", _cur_rtp_seq, packet->seq()); SetCurSeq(packet->seq()); } IncCurSeq(); @@ -110,7 +117,7 @@ RTPManager::ProcessPacket(RTPPacket::Ptr packet) } if (_decoder) { _decoder->Input(packet); } - MaybeReplaceSeq(packet); + // MaybeReplaceSeq(packet); } void @@ -156,6 +163,25 @@ RTPManager::GetNextSeq() return (_cur_rtp_seq + 1) & 0xFFFF; } +static const char * +ToString(H264Nal::H264Nal_t type) +{ + switch (type) { + case H264Nal::NAL_IDR: + return "IDR"; + case H264Nal::NAL_SEI: + return "SEI"; + case H264Nal::NAL_PPS: + return "PPS"; + case H264Nal::NAL_SPS: + return "SPS"; + case H264Nal::NAL_P_B: + return "P_B"; + default: + return "Unknown"; + } +} + void RTPManager::OnRTPDecoded(RTPDecoder::DecodedPacket packet) { @@ -169,7 +195,8 @@ RTPManager::OnRTPDecoded(RTPDecoder::DecodedPacket packet) } auto str = ss.str(); if (!str.empty()) str.pop_back(); - INFOL("RTP decoded. type=%2d, size=%5u seq=[%s]\n", h264_type, packet.bytes, str.c_str()); + INFOL("RTP decoded. type=%s, size=%5u seq=[%s]\n", ToString((H264Nal::H264Nal_t) h264_type), packet.bytes, + str.c_str()); if (h264_type == H264Nal::NAL_IDR) { // remove old sign ResetSignData(); diff --git a/src/base/rtp_packet.cpp b/src/base/rtp_packet.cpp index 0e34a97..748d957 100644 --- a/src/base/rtp_packet.cpp +++ b/src/base/rtp_packet.cpp @@ -141,8 +141,12 @@ RTPPacket::RTPPacket(RTPManager *owner, Frame::Ptr udp_frame) rtp_packet_t pkt; if (rtp_packet_deserialize(&pkt, udp_frame->data(), udp_frame->size()) == 0) { _state = kComplete; - uint8_t h264_type = ((uint8_t *) pkt.payload)[0] & 0x1F; - if (h264_type == H264Nal::NAL_SEI) { udp_frame->set_paused(true); } + if (pkt.payloadlen > 0 && pkt.payload) { + uint8_t h264_type = ((uint8_t *) pkt.payload)[0] & 0x1F; + if (h264_type == H264Nal::NAL_SEI) { udp_frame->set_paused(true); } + } else { + // WRNGL("rtp packet payload is empty\n"); + } } else { _state = kError; } -- 2.45.2 From f5c77704c46ff135cc68913c4c167b4c82b57511 Mon Sep 17 00:00:00 2001 From: tqcq <99722391+tqcq@users.noreply.github.com> Date: Wed, 28 Aug 2024 17:23:00 +0800 Subject: [PATCH 7/7] feat add info log --- src/base/frame_manager.cpp | 1 + src/base/hk_sign.cpp | 1 + src/base/rtp_manager.cpp | 17 ++++++++++++----- src/base/rtp_manager.h | 3 +++ src/base/util.cpp | 14 +++++++++++--- 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/base/frame_manager.cpp b/src/base/frame_manager.cpp index eeb68c1..32940b1 100644 --- a/src/base/frame_manager.cpp +++ b/src/base/frame_manager.cpp @@ -53,6 +53,7 @@ FrameManager::SetSecSetInfo(sec_set_info *info) void FrameManager::Init() { + _rtp_manager.SetHandler(this); OnFrameEnqueue.connect(&_rtp_manager, &RTPManager::OnFrameEnqueue); } diff --git a/src/base/hk_sign.cpp b/src/base/hk_sign.cpp index 8f8b88e..59a1f2b 100644 --- a/src/base/hk_sign.cpp +++ b/src/base/hk_sign.cpp @@ -18,6 +18,7 @@ int HK_udp_in(void *Handle, const char *buf, const uint32_t len, void *param) { sign::FrameManager *fm = (sign::FrameManager *) Handle; + INFOL(">>> New Frame <<< \n"); auto frame = sign::Frame::CreateUDPFrame(buf, len); if (!frame) { ERROL("Create frame failed\n"); diff --git a/src/base/rtp_manager.cpp b/src/base/rtp_manager.cpp index cb9c6f8..cff26d5 100644 --- a/src/base/rtp_manager.cpp +++ b/src/base/rtp_manager.cpp @@ -77,6 +77,9 @@ RTPManager::ProcessUDPFrame(Frame::Ptr frame) INFOL("Not a RTP packet. discard it.\n"); return; } + INFOL("RTP info version=%d, payload_type=%d, seq=%d, ssrc=%d\n", GetRTPVersion(frame->data()), + GetRTPPayloadType(frame->data()), GetRTPSequenceNumber(frame->data()), GetRTPSSRC(frame->data())); + auto packet = RTPPacket::CreateCompleteRTPPacket(this, frame); if (packet->payload_type() == 112) { INFOL("RTCP packet pt=112. discard it.\n"); @@ -99,15 +102,19 @@ RTPManager::ProcessPacket(RTPPacket::Ptr packet) MaybeSetSSRC(packet->ssrc()); if (packet->ssrc() != _cur_rtp_ssrc) { - WRNGL("RTP packet ssrc is mismatch. discard it. cur_ssrc=%ld, packet->ssrc=%d\n", _cur_rtp_ssrc, - packet->ssrc()); + WRNGL("RTP packet ssrc is mismatch. discard it. handler=%p, cur_ssrc=%ld, packet->ssrc=%d\n", _handler, + _cur_rtp_ssrc, packet->ssrc()); return; } MaybeSetSeq(packet->seq()); if (packet->seq() != _cur_rtp_seq) { - WRNGL("RTP packet seq is not continuous. cur_seq=%ld, packet->seq=%d\n", _cur_rtp_seq, packet->seq()); + WRNGL("RTP packet seq is not continuous. handler=%p, cur_seq=%ld, packet->seq=%d\n", _handler, _cur_rtp_seq, + packet->seq()); SetCurSeq(packet->seq()); + } else { + INFOL("RTP packet seq is continuous. handler=%p, cur_seq=%ld, packet->seq=%d\n", _handler, _cur_rtp_seq, + packet->seq()); } IncCurSeq(); @@ -195,8 +202,8 @@ RTPManager::OnRTPDecoded(RTPDecoder::DecodedPacket packet) } auto str = ss.str(); if (!str.empty()) str.pop_back(); - INFOL("RTP decoded. type=%s, size=%5u seq=[%s]\n", ToString((H264Nal::H264Nal_t) h264_type), packet.bytes, - str.c_str()); + INFOL("RTP decoded. handler=%p, type=%s, size=%5u seq=[%s]\n", _handler, ToString((H264Nal::H264Nal_t) h264_type), + packet.bytes, str.c_str()); if (h264_type == H264Nal::NAL_IDR) { // remove old sign ResetSignData(); diff --git a/src/base/rtp_manager.h b/src/base/rtp_manager.h index dca2770..2c8c77e 100644 --- a/src/base/rtp_manager.h +++ b/src/base/rtp_manager.h @@ -24,6 +24,8 @@ public: // HACK: void SetSecSetInfo(sec_set_info *info); + void SetHandler(void *handler) { _handler = handler; } + private: void InitSecSet(void *info); void InitVerifySet(void *info); @@ -64,6 +66,7 @@ private: * 2. Insert SEI **/ + void *_handler{nullptr}; std::mutex _signed_packet_lock; // std::vector _sign_data; Signer::SignedPacket::Ptr _signed_packet{nullptr}; diff --git a/src/base/util.cpp b/src/base/util.cpp index 7bf8f93..8249132 100644 --- a/src/base/util.cpp +++ b/src/base/util.cpp @@ -1,8 +1,8 @@ #include "util.h" extern "C" { #include "SVAC/src/sm2sm3/sm2.h" -#include "SVAC/src/sm2sm3/sm3.h" } +#include "HuaWei/HWcommon.h" namespace sign { uint8_t @@ -73,8 +73,16 @@ FindRTPOverTCPHeader(const uint8_t *data, size_t len, size_t *header_pos) bool IsRTPHeader(const uint8_t *data, size_t len) { - if (len < 12) { return false; } - if (GetRTPVersion(data) != 2) { return false; } + if (len < 12) { + WRNGL("RTP header length error len=%ld", len); + return false; + } + + if (GetRTPVersion(data) != 2) { + INFOL("RTP version error version=%d", GetRTPVersion(data)); + return false; + } + return true; } -- 2.45.2