// libvideoqueue.cpp : 定义 DLL 应用程序的导出函数。 // #include "libvideoqueue.h" #include "../libsharememory/libsharememory.h" #include "videoutil.h" #ifdef _WIN32 #include "stdafx.h" #include "ipp.h" #else #include #include #include #endif // _WIN32 typedef struct Qnode { unsigned int videoframeindex; unsigned int nextqnodeindex; }Qnode, *queueptr; typedef struct linkqueue { unsigned int frontindex; unsigned int rearindex; unsigned int queuelens; }linkqueue; class libvideoqueue_impl { private: Clibsharememory m_ShareMem; void* m_lpMem; linkqueue*m_pQueue; int m_nTimeSignLens; int m_nQueueAddrLens; int m_nQnodeAddrLens; int m_nFrameAddrLens; int m_nDataAddrlens; char* szShareMemName; unsigned long aQnodeAddr[MAX_VIDEOQUEUE_LENS]; unsigned long aVideoFrameAddr[MAX_VIDEOQUEUE_LENS]; unsigned long aImgDataAddr[MAX_VIDEOQUEUE_LENS]; unsigned long nTimeSignAddr; public: libvideoqueue_impl(const char* videoqueuename,int framesize=MAX_VIDEOQNODE_SIZE) { m_lpMem = NULL; m_pQueue = NULL; szShareMemName = NULL; m_nQueueAddrLens = 0; m_nQnodeAddrLens = 0; m_nTimeSignLens = 0; m_nFrameAddrLens = 0; m_nDataAddrlens = 0; for(int i=0;ifrontindex = m_pQueue->rearindex = 0; m_pQueue->queuelens = 0; m_ShareMem.Unlock(); bret = true; } } else if(m_ShareMem.Open(szName)) { m_ShareMem.GetBytes(); m_lpMem = m_ShareMem.Lock(1000); if(m_lpMem != NULL) { m_pQueue = (linkqueue*)m_lpMem; for(int i =0;iqueuelens; m_ShareMem.Unlock(); return num; } else { return 0; } } else { return 0; } } //往视频循环队列尾部插节点 bool InsertVideo(videoq_frame* Video, int flags, unsigned int nowtime) { if(m_ShareMem.IsValid()) { m_lpMem = m_ShareMem.Lock(1000); if(m_lpMem != NULL) { unsigned int nRearNextIndex = 0; //保存当前对位指针的序列号 queueptr rearptrfront = (queueptr)aQnodeAddr[m_pQueue->rearindex]; //如果队列已满 if(m_pQueue->queuelens == MAX_VIDEOQUEUE_LENS) { m_pQueue->rearindex = (m_pQueue->rearindex+1)%MAX_VIDEOQUEUE_LENS; m_pQueue->frontindex = (m_pQueue->frontindex+1)%MAX_VIDEOQUEUE_LENS; m_pQueue->queuelens = MAX_VIDEOQUEUE_LENS; } else if (m_pQueue->queuelens == 0) { m_pQueue->rearindex = 0; m_pQueue->frontindex = 0; m_pQueue->queuelens++; } else { m_pQueue->rearindex = (m_pQueue->rearindex+1)%MAX_VIDEOQUEUE_LENS; m_pQueue->frontindex = m_pQueue->frontindex; m_pQueue->queuelens++; } if (Video != NULL) { queueptr rearqnodetmp = (queueptr)aQnodeAddr[m_pQueue->rearindex]; rearqnodetmp->videoframeindex = m_pQueue->rearindex; rearqnodetmp->nextqnodeindex = 0; videoq_frame*videotmp = (videoq_frame*)aVideoFrameAddr[m_pQueue->rearindex]; videotmp->data = (unsigned char*)aImgDataAddr[m_pQueue->rearindex ]; videotmp->format = Video->format; if (VIDEOQ_FORMAT_I420 == Video->format){ videotmp->framesize = Video->height * Video->width * 3/2; } else { videotmp->framesize = Video->height * Video->width * 3; } videotmp->height = Video->height; videotmp->width = Video->width; videotmp->iframeid = Video->iframeid; unsigned int*Ptr = (unsigned int*)nTimeSignAddr; *Ptr = nowtime; #ifdef _WIN32 if (flags) { IppiAxis flip; if (flags == VIDEOQUEUE_FLAG_VERTICAL_FLIP) { // 上下翻转 flip = ippAxsHorizontal; // x轴 } else if (flags == VIDEOQUEUE_FLAG_HORIZONTAL_FLIP) { // 左右翻转 flip = ippAxsVertical; // y轴 } else { flip = ippAxsBoth; } IppiSize roiSize; roiSize.width = videotmp->width; roiSize.height = videotmp->height; ippiMirror_8u_C3R(Video->data, Video->framesize/Video->height, videotmp->data, videotmp->width*3, roiSize, flip); } else { IppiSize roiSize; roiSize.width = videotmp->width; roiSize.height = videotmp->height; ippiCopy_8u_C3R(Video->data, Video->framesize/Video->height, videotmp->data, videotmp->width*3, roiSize); } #else memcpy(videotmp->data, Video->data, Video->framesize); #endif // _WIN32 rearptrfront->nextqnodeindex = m_pQueue->rearindex; } m_ShareMem.Unlock(); return true; } else { return false; } } else { return false; } } //读视频队列头部节点 bool GetVideo(videoq_frame* Video, int flags) { if(m_ShareMem.IsValid()) { m_lpMem = m_ShareMem.Lock(1000); if(m_lpMem != NULL) { if (m_pQueue->queuelens == 0) { m_ShareMem.Unlock(); return false; } else { videoq_frame*videotemp = (videoq_frame*)aVideoFrameAddr[m_pQueue->frontindex]; Video->format = videotemp->format; Video->framesize = videotemp->framesize; Video->height = videotemp->height; Video->width = videotemp->width; Video->iframeid = videotemp->iframeid; #ifdef _WIN32 if (flags) { IppiAxis flip; if (flags == VIDEOQUEUE_FLAG_VERTICAL_FLIP) { // 上下翻转 flip = ippAxsHorizontal; // x轴 } else if (flags == VIDEOQUEUE_FLAG_HORIZONTAL_FLIP) { // 左右翻转 flip = ippAxsVertical; // y轴 } else { flip = ippAxsBoth; } IppiSize roiSize; roiSize.width = videotemp->width; roiSize.height = videotemp->height; try { ippiMirror_8u_C3R((unsigned char*)aImgDataAddr[m_pQueue->frontindex], videotemp->width * 3, Video->data, videotemp->width * 3, roiSize, flip); } catch (...) { m_ShareMem.Unlock(); return false; } } else { IppiSize roiSize; roiSize.width = videotemp->width; roiSize.height = videotemp->height; try { ippiCopy_8u_C3R((unsigned char*)aImgDataAddr[m_pQueue->frontindex], videotemp->width * 3, Video->data, videotemp->width * 3, roiSize); //memcpy(Video->data,(unsigned char*)aImgDataAddr[m_pQueue->frontindex],videotemp->framesize); } catch (...) { m_ShareMem.Unlock(); return false; } } #else try { memcpy(Video->data,(unsigned char*)aImgDataAddr[m_pQueue->frontindex],videotemp->framesize); } catch (...) { m_ShareMem.Unlock(); return false; } #endif // _WIN32 m_ShareMem.Unlock(); return true; } } else { return false; } } else { return false; } } bool GetVideo2(video_frame* Video, int flags) { if(m_ShareMem.IsValid()) { m_lpMem = m_ShareMem.Lock(1000); if(m_lpMem != NULL) { if (m_pQueue->queuelens == 0) { m_ShareMem.Unlock(); return false; } else { videoq_frame*videotemp = (videoq_frame*)aVideoFrameAddr[m_pQueue->frontindex]; assert(Video->height == videotemp->height); assert(Video->width == videotemp->width); #ifdef _WIN32 Video->iframeid = videotemp->iframeid; //Video->format = videotemp->format; //Video->framesize = videotemp->framesize; //Video->height = videotemp->height; //Video->width = videotemp->width; if (flags) { IppiAxis flip; if (flags == VIDEOQUEUE_FLAG_VERTICAL_FLIP) { // 上下翻转 flip = ippAxsHorizontal; // x轴 } else if (flags == VIDEOQUEUE_FLAG_HORIZONTAL_FLIP) { // 左右翻转 flip = ippAxsVertical; // y轴 } else { flip = ippAxsBoth; } IppiSize roiSize; roiSize.width = videotemp->width; roiSize.height = videotemp->height; ippiMirror_8u_C3R((unsigned char*)aImgDataAddr[m_pQueue->frontindex], videotemp->width*3, Video->data[0], Video->linesize[0], roiSize, flip); } else { IppiSize roiSize; roiSize.width = videotemp->width; roiSize.height = videotemp->height; ippiCopy_8u_C3R((unsigned char*)aImgDataAddr[m_pQueue->frontindex], videotemp->width*3, Video->data[0], Video->linesize[0], roiSize); } #else Video->iframeid = videotemp->iframeid; for (int i = 0; i < videotemp->height; i++) { memcpy(Video->data[0] + i*Video->linesize[0], (unsigned char*)aImgDataAddr[m_pQueue->frontindex] + i * Video->width*3, Video->width*3); } #endif // _WIN32 m_ShareMem.Unlock(); return true; } } else { return false; } } else { return false; } } bool GetVideo3(videoq_frame* Video, int flags) { if(m_ShareMem.IsValid()) { m_lpMem = m_ShareMem.Lock(1000); if(m_lpMem != NULL) { if (m_pQueue->queuelens == 0) { m_ShareMem.Unlock(); return false; } else { videoq_frame*videotemp = (videoq_frame*)aVideoFrameAddr[m_pQueue->frontindex]; Video->format = videotemp->format; Video->framesize = videotemp->framesize; Video->height = videotemp->height; Video->width = videotemp->width; Video->iframeid = videotemp->iframeid; #ifdef _WIN32 if (flags) { IppiAxis flip; if (flags == VIDEOQUEUE_FLAG_VERTICAL_FLIP) { // 上下翻转 flip = ippAxsHorizontal; // x轴 } else if (flags == VIDEOQUEUE_FLAG_HORIZONTAL_FLIP) { // 左右翻转 flip = ippAxsVertical; // y轴 } else { flip = ippAxsBoth; } IppiSize roiSize; roiSize.width = videotemp->width; roiSize.height = videotemp->height; try { ippiMirror_8u_C3R((unsigned char*)aImgDataAddr[m_pQueue->frontindex], videotemp->width*3, Video->data, videotemp->height*3, roiSize, flip); } catch (...) { m_ShareMem.Unlock(); return false; } } else { IppiSize roiSize; roiSize.width = videotemp->width; roiSize.height = videotemp->height; try { ippiCopy_8u_C3R((unsigned char*)aImgDataAddr[m_pQueue->frontindex], videotemp->width*3, Video->data, videotemp->height*3, roiSize); } catch (...) { m_ShareMem.Unlock(); return false; } } #else //memcpy(Video->data, (unsigned char*)aImgDataAddr[m_pQueue->frontindex], videotemp->framesize); for (int i = 0; i < videotemp->height; i++) { memcpy((unsigned char*)Video->data + i * videotemp->height * 3, (unsigned char*)aImgDataAddr[m_pQueue->frontindex] + i * videotemp->width * 3, videotemp->width * 3); } #endif // _WIN32 m_ShareMem.Unlock(); return true; } } else { return false; } } else { return false; } } //读视频队列头部节点,并删除头部节点 bool GetVideoAndDel(videoq_frame* Video, int flags) { if(m_ShareMem.IsValid()) { m_lpMem = m_ShareMem.Lock(1000); if(m_lpMem != NULL) { if (m_pQueue->queuelens == 0) { m_ShareMem.Unlock(); return false; } else { videoq_frame*videotemp = (videoq_frame*)aVideoFrameAddr[m_pQueue->frontindex]; Video->format = videotemp->format; Video->framesize = videotemp->framesize; Video->height = videotemp->height; Video->width = videotemp->width; Video->iframeid = videotemp->iframeid; #ifdef _WIN32 if (flags) { IppiAxis flip; if (flags == VIDEOQUEUE_FLAG_VERTICAL_FLIP) { // 上下翻转 flip = ippAxsHorizontal; // x轴 } else if (flags == VIDEOQUEUE_FLAG_HORIZONTAL_FLIP) { // 左右翻转 flip = ippAxsVertical; // y轴 } else { flip = ippAxsBoth; } IppiSize roiSize; roiSize.width = videotemp->width; roiSize.height = videotemp->height; ippiMirror_8u_C3R((unsigned char*)aImgDataAddr[m_pQueue->frontindex], videotemp->width*3, Video->data, videotemp->width*3, roiSize, flip); } else { memcpy(Video->data,(unsigned char*)aImgDataAddr[m_pQueue->frontindex],videotemp->framesize); } #else memcpy(Video->data, (unsigned char*)aImgDataAddr[m_pQueue->frontindex], videotemp->framesize); #endif // _WIN32 unsigned char*data = (unsigned char*)aImgDataAddr[m_pQueue->frontindex]; memset(data,0,videotemp->framesize); memset(videotemp,0,sizeof(videoq_frame)); queueptr qnodetmp = (queueptr)aQnodeAddr[m_pQueue->frontindex]; m_pQueue->frontindex = qnodetmp->nextqnodeindex; qnodetmp = (queueptr)aQnodeAddr[m_pQueue->rearindex]; qnodetmp->nextqnodeindex = 0; m_pQueue->queuelens--; m_ShareMem.Unlock(); return true; } } else { return false; } } else { return false; } } //清除队列 bool ClearVideoQueue() { if(m_ShareMem.IsValid()) { m_lpMem = m_ShareMem.Lock(1000); if(m_lpMem != NULL) { if (m_pQueue->queuelens != 0) { while(m_pQueue->queuelens != 0) { videoq_frame*videotemp = (videoq_frame*)aVideoFrameAddr[m_pQueue->frontindex]; unsigned char*data = (unsigned char*)aImgDataAddr[m_pQueue->frontindex]; memset(data,0,videotemp->framesize); memset(videotemp,0,sizeof(videoq_frame)); queueptr qnodetmp = (queueptr)aQnodeAddr[m_pQueue->frontindex]; m_pQueue->frontindex = qnodetmp->nextqnodeindex; qnodetmp = (queueptr)aQnodeAddr[m_pQueue->rearindex]; qnodetmp->nextqnodeindex = 0; m_pQueue->queuelens--; } } m_ShareMem.Unlock(); return true; } else { return false; } } else { return false; } } //删除队头的数据 bool DeleteHeadVideo() { if(m_ShareMem.IsValid()) { m_lpMem = m_ShareMem.Lock(1000); if(m_lpMem != NULL) { if (m_pQueue->queuelens != 0) { videoq_frame*videotemp = (videoq_frame*)aVideoFrameAddr[m_pQueue->frontindex]; unsigned char*data = (unsigned char*)aImgDataAddr[m_pQueue->frontindex]; memset(data,0,videotemp->framesize); memset(videotemp,0,sizeof(videoq_frame)); queueptr qnodetmp = (queueptr)aQnodeAddr[m_pQueue->frontindex]; m_pQueue->frontindex = qnodetmp->nextqnodeindex; qnodetmp = (queueptr)aQnodeAddr[m_pQueue->rearindex]; qnodetmp->nextqnodeindex = 0; m_pQueue->queuelens--; } m_ShareMem.Unlock(); return true; } else { return false; } } else { return false; } } //获取图像的大小 int GetFrameSize(int&width,int&height) { if(m_ShareMem.IsValid()) { m_lpMem = m_ShareMem.Lock(1000); if(m_lpMem != NULL) { int nFrameSize = 0; if (m_pQueue->queuelens != 0) { videoq_frame*videotmp = (videoq_frame*)aVideoFrameAddr[m_pQueue->frontindex]; nFrameSize = videotmp->framesize; width = videotmp->width; height = videotmp->height; } m_ShareMem.Unlock(); return nFrameSize; } else { return 0; } } else { return 0; } } unsigned int GetLastFrameTime() { if(m_ShareMem.IsValid()) { m_lpMem = m_ShareMem.Lock(1000); if(m_lpMem != NULL) { unsigned int nLastFrameTime = 0; nLastFrameTime = *(unsigned int *)nTimeSignAddr; m_ShareMem.Unlock(); return nLastFrameTime; } else { return 0; } } else { return 0; } } }; // 这是已导出类的构造函数。 // 有关类定义的信息,请参阅 libvideoqueue.h Clibvideoqueue::Clibvideoqueue(const char* videoqueuename,int framesize) { m_pImpl = new libvideoqueue_impl(videoqueuename,framesize); return; } Clibvideoqueue::~Clibvideoqueue() { ClearVideoQueue(); delete m_pImpl; return; } bool Clibvideoqueue::InsertVideo(videoq_frame* Video, int flags, unsigned int nowtime) { bool bRst = m_pImpl->InsertVideo(Video, flags, nowtime); return bRst; } bool Clibvideoqueue::GetVideo(videoq_frame* Video, int flags) { bool bRst = m_pImpl->GetVideo(Video, flags); return bRst; } bool Clibvideoqueue::GetVideo2(video_frame* Video, int flags) { bool bRst = m_pImpl->GetVideo2(Video, flags); return bRst; } bool Clibvideoqueue::GetVideo3(videoq_frame* Video, int flags) { bool bRst = m_pImpl->GetVideo3(Video, flags); return bRst; } bool Clibvideoqueue::GetVideoAndDel(videoq_frame* Video, int flags) { bool bRst = m_pImpl->GetVideoAndDel(Video, flags); return bRst; } int Clibvideoqueue::GetVideoLens(void) { int i = m_pImpl->GetVideoLens(); return i; } void Clibvideoqueue::ClearVideoQueue() { m_pImpl->ClearVideoQueue(); return; } int Clibvideoqueue::GetFrameSize(int&width,int&height) { int i = m_pImpl->GetFrameSize(width, height); return i; } void Clibvideoqueue::DeleteHeadVideo() { m_pImpl->DeleteHeadVideo(); return; } unsigned int Clibvideoqueue::GetLastFrameTime() { return m_pImpl->GetLastFrameTime(); }