急求RGB565转YUV420的算法

ayiyi0910 2011-08-18 10:30:31
急求RGB565转YUV420的算法, 有代码就最好了, 谢谢!

我在directshow采集视频时取出来的是RGB565, 现在想转换成YUV42O, 我在网上找到了一下只有YUV420转RGB565的
...全文
476 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
AudioAEC 2011-08-19
  • 打赏
  • 举报
回复
可以用ffmpeg转换。
ffmpeg的效率很高。
LiuYinChina 2011-08-19
  • 打赏
  • 举报
回复
晕,有现成的你不要,再怎么,xvid 比你的效率高啊,就几个参数,看看就明白的,
偶闪。....---->>>
ayiyi0910 2011-08-19
  • 打赏
  • 举报
回复
#define RGB565_MASK_RED 0xF800
#define RGB565_MASK_GREEN 0x07E0
#define RGB565_MASK_BLUE 0x001F
void RGB5652YV12(LPBYTE pYVUData, LPBYTE pRGB565, int width, int height)
{
int y1=0,y2=0,u=0,v=0;
LPBYTE py1,py2;
LPBYTE src1, src2;
int i,j;
SHORT * d1, *d2;

py1=pYVUData;
src1 = py1+(width*height);
src2 = src1 + (width * height/4);
py2=py1+width;

d1=(SHORT *)pRGB565;
d2=d1+width;

BYTE r,g,b;

for (j = 0; j < height; j += 2)
{
d1 = (SHORT *)pRGB565 + (height-j-1)*width;
d2 = d1-width;
for (i = 0; i < width; i += 2)
{

r = ((*d1) & RGB565_MASK_RED ) >> 8;
g = ((*d1) & RGB565_MASK_GREEN) >> 3;
b =((*d1) & RGB565_MASK_BLUE) << 3;

*py1++ = 0.299 * r + 0.587 * g + 0.114 *b;
*src1++ = 0.500 * r-0.4187 *g - 0.0813 * b + 128;
*src2++= -0.1687 * r - 0.3313 * g + 0.500 * b + 128;
d1++;

r = ((*d2) & RGB565_MASK_RED) >> 8;
g = ((*d2) & RGB565_MASK_GREEN) >> 3;
b =((*d2) & RGB565_MASK_BLUE) << 3;
*py2++ = 0.299 * r + 0.587 * g + 0.114 *b;


d2++;

r = ((*d1) & RGB565_MASK_RED) >> 8;
g = ((*d1) & RGB565_MASK_GREEN) >> 3;
b =((*d1) & RGB565_MASK_BLUE) << 3;

d1++;
*py1++ = 0.299 * r + 0.587 * g + 0.114 *b;

r = ((*d2) & RGB565_MASK_RED) >> 8;
g = ((*d2) & RGB565_MASK_GREEN) >> 3;
b =((*d2) & RGB565_MASK_BLUE) << 3;
d2++;
*py2++ = 0.299 * r + 0.587 * g + 0.114 *b;

}
//d1 += width;
//d2 += width;
py1+= width;
py2+= width;
}
}

请大家帮我看一下这个算法是不是正确的, 为什么我转出来的都是绿色的.
还有一个就是他们的大小问题比如我已经知道RGB565的大小为lSize, 那我建立的存放YUV420的大小是不是也是lSize呀, 我现在是unsigned char *pYuv = new unsigned char[lSize + 1];
ArcRain 2011-08-19
  • 打赏
  • 举报
回复
YUV与RGB格式的互转资料,可以参考http://www.fourcc.org/fccyvrgb.php
LiuYinChina 2011-08-19
  • 打赏
  • 举报
回复
23:30:41 还在回帖!!!
建议你先了解一下 yuv 的格式,不然很多事情不好搞的。
ayiyi0910 2011-08-19
  • 打赏
  • 举报
回复
谢谢大家了, 问题弄好了, hopewzy1982的方法是没有问题的.

RobertBaker大大的方法等我做好项目后要好好的学习一下, 做好项目后要仔细的去了解一下directshow
南安风语者 2011-08-19
  • 打赏
  • 举报
回复
我一开始以为是我取的数据有问题, 就设了一个设数器, 取完一次后, 本桢后面的第4桢再取, 不过出来的图像是一样的,
南安风语者 2011-08-19
  • 打赏
  • 举报
回复
#ifndef GET565RValue
#define GET565RValue(rgb) ((BYTE) (((((WORD)(rgb))&0xF800))>>8) )
#endif
#ifndef GET565GValue
#define GET565GValue(rgb) ((BYTE) (((((WORD)(rgb))&0x07E0))>>3) )
#endif
#ifndef GET565BValue
#define GET565BValue(rgb) ((BYTE) (((((WORD)(rgb))&0x001F)) << 3) )
#endif

#define CLIP(v) ( (v)<0? 0 : (v>255?255:v) )

#define GETY(r,g,b) ( ( 66 * (r) + 129 * (g) + 25 * (b) + 128) >> 8) + 16
#define GETU(r,g,b) ( ( -38 * (r) - 74 * (g) + 112 * (b) + 128) >> 8) + 128
#define GETV(r,g,b) ( ( 112 * (r) - 94 * (g) - 18 * (b) + 128) >> 8) + 128


void RgbToYuv(unsigned char *pRgbData, int w, int h, unsigned char *pYuv, int iLen)
{
unsigned char *pY, *pU, *pV, y, u, v;
WORD word, r, g, b;
WORD *pRgb = (WORD *)pRgbData;
int iVideSize = w * h;
pY = pYuv;
pU = (pY + iVideSize);
pV = (pU + iVideSize/4);
int off = 0, iChromaOff = 0;
for(int row=0; row<h; row++)
{
off = row * w;
iChromaOff = row/2 * w/2;
for(int col=0; col<w; col++)
{
word = *(pRgb + off + col);
r = GET565RValue(word);
g = GET565GValue(word);
b = GET565BValue(word);

y = CLIP(GETY(r,g,b));
pY[off + col] = y;
if( !(row%2) && !(col%2) )
{
u = CLIP(GETU(r,g,b));
v = CLIP(GETV(r,g,b));
pU[iChromaOff + col/2] = u;
pV[iChromaOff + col/2] = v;
}
}
}
}

我这里也有一个, 不过用的时候有个奇怪的问题,第1桢是正常的, 第2,3,4桢是花的, 第5桢又是正常的, 这样中间有三个桢是花的, 是不是算法那里还有问题呀

LiuYinChina 2011-08-19
  • 打赏
  • 举报
回复
你要还觉得慢就用 Intel IPP, 那个快,不过比 colorspace 要麻烦一点,要安装 IPP。
LiuYinChina 2011-08-19
  • 打赏
  • 举报
回复
你编译完 colorspace 以后,有个 colorspace.lib 的静态库 和 colorspace.h
colorspace.h 里是 colorspace 支持的转换,如

packedFunc rgb555_to_yv12_c;
packedFunc rgb565_to_yv12_c;
packedFunc rgb_to_yv12_c;
packedFunc bgr_to_yv12_c;
packedFunc bgra_to_yv12_c;


packedFunc rgb565_to_yv12_c 就是你要用的,可惜只有 c 转换的,注意后面有个 _c,

函数定义都有了

typedef void (packedFunc) (uint8_t * x_ptr,
int x_stride,
uint8_t * y_src,
uint8_t * v_src,
uint8_t * u_src,
int y_stride,
int uv_stride,
int width,
int height,
int vflip);


调用函数定义为 C 的静态库,不用我说了吧,
大小问题,yv12size=rgb565size*3/4,
ayiyi0910 2011-08-19
  • 打赏
  • 举报
回复
还有一个就是他们的大小问题比如我已经知道RGB565的大小为lSize, 那我建立的存放YUV420的大小是不是也是lSize呀, 我现在是unsigned char *pYuv = new unsigned char[lSize + 1];
ayiyi0910 2011-08-19
  • 打赏
  • 举报
回复
HRESULT hr;

hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGraph);

// Create the Capture Graph Builder.
hr = CoCreateInstance(CLSID_CaptureGraphBuilder, NULL,
CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
(void **)&m_pBuilder);

hr = m_pGraph->AddFilter(m_pCap, L"Video Capture Source");

m_pBuilder->SetFiltergraph(m_pGraph);

hr = CoCreateInstance(CLSID_VideoRenderer, NULL,
CLSCTX_INPROC_SERVER, IID_IBaseFilter,
(void **)&m_pRenderP);

hr = m_pGraph->AddFilter(m_pRenderP, L"Video Render");
hr = m_pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pCap, NULL, m_pRenderP);

IAMStreamConfig *pConfig = NULL;
hr = m_pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
m_pRenderP, IID_IAMStreamConfig, (void**)&pConfig);
if (SUCCEEDED(hr))
{
int iCount=0,iSize=0;
hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);


AM_MEDIA_TYPE *pmt = NULL;
hr = pConfig->GetFormat(&pmt);
if (SUCCEEDED(hr))
{

pConfig-> SetFormat(pmt);
}

DeleteMediaType(pmt);
pConfig-> Release();
}
另外再求教一下, 我想修改一个分辩率, 但FindInterface的时候返回的是E_NOINTERFACE, 也请大家帮我看看我这个代码是不是有问题
ayiyi0910 2011-08-19
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 robertbaker 的回复:]
晕,有现成的你不要,再怎么,xvid 比你的效率高啊,就几个参数,看看就明白的,
偶闪。....---->>>
[/Quote]

唉, 这方面我是个新手, 你的这个看的有点糊涂了, 不知道能不能麻烦你说详细一点
ayiyi0910 2011-08-18
  • 打赏
  • 举报
回复
不好意思, 我是接触这些东西不久, 边学边用, 看的有点糊涂, 能不能麻烦你说的详细一点
ayiyi0910 2011-08-18
  • 打赏
  • 举报
回复
谢谢, 我看看
LiuYinChina 2011-08-18
  • 打赏
  • 举报
回复
http://download.csdn.net/source/3348196
尝试怎么用,我不写 demo 了,
LiuYinChina 2011-08-18
  • 打赏
  • 举报
回复
别让哥削你,xvid。

2,553

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧