qt 、VC++ 共享内存的实现及应用
做下笔记,最近有个项目,针对RTSP解码网页播放的,由于网页播放器大都不支持RTSP视频流;有三个方案:
1、C解码RTSP视频流,然后推流到RTMP服务器;
2、使用VLC网页视频播放RTSP流;
3、C解码RTSP视频流,然后通过进程间内存共享实现一帧图像数据的共享,后台服务器获取到一帧数据之后通过webSocket推送到网页刷新;
前面两个不在本章讨论,现在主要讨论最后一种,使用FFMPEG库解码RTSP,格式可以是24位RGB888或YUV,
再通过内存共享一帧图像数据;
qt 共享内存的实现
//如果第一次则创建共享内存,内存大小nSize
bool createShareMemory(int nSize){
m_ShareMemory.setKey("shareMemoryTest");
return m_ShareMemory.create(nSize);
}
//关联内存共享
bool connectShareMemory(){
m_ShareMemory.setKey("shareMemoryTest");
return m_ShareMemory.attach();
}
//解除共享内存
bool disconnectShareMemory(){
return m_ShareMemory.detach();
}
void writeFrame(int nWidth,int nHeight,char* pFrame,int nLen){
if(!m_ShareMemory.isAttached())return;
m_ShareMemory.lock();
char *testdata = static_cast<char*>( m_ShareMemory.data() );
memset(testdata,0,m_ShareMemory.size());
const char *from = buffer.data().constData();
//共享内存段就是一段普通内存,用C语言标准函数memcpy()复制内存段。
memcpy(testdata,&nWidth,4);
memcpy(testdata+4,&nHeight,4);
memcpy(testdata+8,&nLen,4);
memcpy(testdata+12,pFrame,nLen);
m_ShareMemory.unlock();
}
void readFrame(int& nWidth,int& nHeight,char* pFrame,int &nLen){
nWidth = 0;
nHeight = 0;
nLen = 0;
m_ShareMemory.lock();
char * data = (char*)(m_ShareMemory.constData());
if(data == NULL || pFrame == NULL)
{
m_ShareMemory.unlock();
return ;
}
memcpy(&nWidth, data, 4);
memcpy(&nHeight, data + 4, 4);
memcpy(&nLen, data + 8, 4);
memcpy(pFrame, data + 12, nLen);
m_ShareMemory.unlock();
return;
}
VC++共享内存的实现
如果qt创建的共享内存,Key值必须一致而且需要转换成WIN API能关联的pfName
//return qipc_sharedmemory_shareMemoryTestca21e4e29fe487344b6ed8a8d0480bc13907f9b4
QString makePlatformSafeKey(const QString &key)
{
const QString prefix = QLatin1String("qipc_sharedmemory_");
QString result = prefix;
QString part1 = key;
part1.replace(QRegExp(QLatin1String("[^A-Za-z]")), QString());
result.append(part1);
QByteArray hex = QCryptographicHash::hash(key.toUtf8(),
QCryptographicHash::Sha1).toHex();
result.append(QLatin1String(hex));
#ifdef Q_OS_WIN
return result;
#else
return QDir::tempPath() + QLatin1Char('/') + result;
#endif
}
VC++实现共享内存读操作(有兴趣的可以在百度了解一下吧)
void readFreme(int nWidth,int nHeight,char* pFrame,int nLen){
nWidth = 0;
nHeight = 0;
nLen = 0;
HANDLE m_hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, _T("qipc_sharedmemory_shareMemoryTestca21e4e29fe487344b6ed8a8d0480bc13907f9b4"));
if (m_hMapFile)
{
LPVOID pBuffer;
pBuffer = (LPVOID)MapViewOfFile(m_hMapFile,FILE_MAP_WRITE|FILE_MAP_READ, 0,0,0);
memcpy(&nWidth, pBuffer, 4);
memcpy(&nHeight, pBuffer + 4, 4);
memcpy(&nLen, pBuffer + 8, 4);
memcpy(pFrame, pBuffer + 12, nLen);
}
return;
}
下班了,走了,有时间再补充!