最近在做视频监控的时候,遇到了不少的问题。
由于第一次接触,像大家一样度娘上狂搜。度娘基本都是csdn,bitblt.
视频监控,当然要不断的截图,当时的想法比较简单,把图片保存后,用ffmpeg,进行压缩,遇到的问题是,图片非常的多。这个不符合要求。组长给我说,用x264,264是个什么东东,第一次听。脑子一阵乱,然后又一阵的乱搜,基本都是雷先生的demo, yuv格式的文件用x264编码,这里面不支持其它格式,坑啊,接下来的工作又是找rgb to yuv格式的转化。全是一头露水什么是yuv。整个流程基本就是 截图 ==>转化成bmp ==>转成yuv格式==> x264编码。这个过程是挺痛苦的,有很多细节要处理(bmp转yuv出现失真)。
在截图IDE窗口时,发现失真还挺严重的。所以决定找找是否x264支持对rgb的编码,让我高兴的是,宏中rgb的支持,感觉找到救星了。经度娘上确让,有2篇文章确认x264是对rgb编码的支持。剩下的就是动手一试,终于解决了rgbToYuv的缺陷。但是遇到一个问题,图像是倒置的。又一个坑。俗话说,万事开头难,第一个想法还是去度娘,这是我们开发一惯的思维,也是因为我懒的原因吧。
现在的度娘挺让我失望的。擦找不到。自己动手写吧。rgb的原理,存储结构。其实半天工作就ok了,主要的工作是在调试上。
这里贴上colorSpaceConver的代码。
DWORD ColorSpaceConver(LPBYTE byRGBdata, size_t RGBdatalen, DWORD dwWidth,DWORD dwHeight,DWORD dwBitCount)
{
DWORD lLineBytes = (dwWidth * dwBitCount + 31) / 32 * 4;//字节对齐
PTRGB rgbIn = NULL;
PTRGB rgbOut = NULL;
/*
BITMAPFILEHEADER *bmpHeader =(BITMAPFILEHEADER*)byRGBdata;
if (bmpHeader->bfType != 'MB')
{
return -1;
}
//BITMAPINFOHEADER *bmpinfo = (BITMAPINFOHEADER*)(byRGBdata + sizeof(BITMAPFILEHEADER));
*/
//图像数据首地址lpData
size_t dwImageSize = dwWidth * dwHeight * 3;
BYTE *pData =(BYTE *) new BYTE[dwImageSize];
if (pData == nullptr)
{
return -1;
}
memset(pData, 0, dwImageSize);
memcpy_s(pData, dwImageSize, byRGBdata, dwImageSize);
rgbIn = (PTRGB)pData;
rgbOut = (PTRGB)byRGBdata;
DWORD dwLoopHeight = dwHeight - 1;
DWORD dwOffset = 0;
for (int i = 0; i < dwLoopHeight; ++i) {
for (int j = 0; j < dwWidth; ++j)
{
TRGB rgbByte;
rgbByte = rgbIn[(dwLoopHeight - i)*dwWidth + j]; //取得垂直方向上镜像的位置即可解决倒立问题
dwOffset = i * lLineBytes + 3 * j;
//memcpy_s(byRGBdata + dwOffset, dwImageSize, &rgbByte, sizeof(TRGB));
rgbOut = (PTRGB)(byRGBdata + dwOffset);
rgbOut->r = rgbByte.r;
rgbOut->b = rgbByte.b;
rgbOut->g = rgbByte.g;
}
}
if (pData != NULL){
delete[] pData;
pData = nullptr;
}
return S_OK;
}