RGB24转成YV12,其后进行x264编码,图像失真
发布时间:2011-06-27 19:15:13 文章来源:www.iduyao.cn 采编人员:星星草
RGB24转成YV12,然后进行x264编码,图像失真
将采集到的RGB24转成YV12,然后进行x264编码,图像失真,图像为相册内的"失真"。
void HotRGB24_2_YV12(unsigned char* yv12,unsigned char* rgb24,int w,int h)
{
int iBufLen = w * h;
int i,j,vay,vau,vav;
unsigned char* cv; // 当前坐标的v(current v);
unsigned char* nv; // 在cv下一行的对应位置的 v;
unsigned char* cu; // 当前坐标的u(current u);
unsigned char* nu; // 在cu下一行的对应位置的 u;
unsigned char v01,v02,v11,v12,u01,u02,u11,u12; // 需要整合的相邻的4个象素 如下
unsigned char* vv = new unsigned char[iBufLen]; // 每个RGB单位对应的V!
unsigned char* uu = new unsigned char[iBufLen]; // 每个RGB单位对应的U!
// 按标准算法从RGB24计算出所有YUV
RGB24 * pRGB = (RGB24*)rgb24;
unsigned char* y = yv12; // 这里直接用 yuv 缓冲。。省了copy了。
unsigned char* v = vv;
unsigned char* u = uu;
for(i = 0; i < h; i++)
{
for(j = 0; j < w; j++)
{
//Y = 0.299R + 0.587G + 0.114B
//U = -0.147R - 0.289G + 0.436B
//V = 0.615R - 0.515G - 0.100B
//Y = round( 0.256788 * R + 0.504129 * G + 0.097906 * B) + 16
//U = round(-0.148223 * R - 0.290993 * G + 0.439216 * B) + 128
//V = round( 0.439216 * R - 0.367788 * G - 0.071427 * B) + 128
// 好象这个算法颜色正,而且是MSDN中列出的算法
vay = int(0.256788 * pRGB->r + 0.504129 * pRGB->g + 0.097906 * pRGB->b) + 16;
vau = int(-0.148223 * pRGB->r - 0.290993 * pRGB->g + 0.439216 * pRGB->b) + 128;
vav = int(0.439216 * pRGB->r - 0.367788 * pRGB->g - 0.071427 * pRGB->b) + 128;
*y = vay < 0 ? 0 : (vay > 255 ? 255: vay); // 如果Y小于0置换成0,如果Y大于255就置换成255
*v = vav < 0 ? 0 : (vav > 255 ? 255: vav); // 如果V小于0置换成0,如果V大于255就置换成255
*u = vau < 0 ? 0 : (vau > 255 ? 255: vau); // 如果U小于0置换成0,如果U大于255就置换成255
y++; // 移动到下一位!
v++;
u++;
pRGB++;
}
}
v = yv12 + iBufLen; // 记录成品YV12的V的位置
u = v + (iBufLen >> 2); // 记录成品YV12的U的位置
for(i = 0; i < h; i+=2) // 由于 V 和 U 只记录隔行的,所以 += 2;
{
cv = vv + i * w; // 取得第i 行的v;
nv = vv + (i + 1) * w; // 取得第i + 1 行的v
cu = uu + i * w; // 取得第i 行的u;
nu = uu + (i + 1) * w; // 取得第i + 1 行的u
for(j = 0; j < w; j+=2) // 由于 一躺循环 我们访问 两个 uu 或 vv 所以 += 2;
{
v01 = *(cv + j); // 取得第i 行的第j 个v的具体的值
v02 = *(cv + j + 1); // 取得第i 行的第j + 1 个v的具体的值
v11 = *(nv + j); // 取得第i + 1 行的第j 个v的具体的值
v12 = *(nv + j + 1); // 取得第i + 1 行的第j + 1 个v的具体的值
*v = (v01 + v02 + v11 + v12) / 4; // 取v01,v02,v11,v12的平均值给v
u01 = *(cu + j); // 取得第i 行的第j 个u的具体的值
u02 = *(cu + j + 1); // 取得第i 行的第j + 1 个u的具体的值
u11 = *(nu + j); // 取得第i + 1 行的第j 个u的具体的值
u12 = *(nu + j + 1); // 取得第i + 1 行的第j + 1 个u的具体的值
友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。
其他相似内容:
-
DSHOW push
推模式,ConnectDirect 的,为什么我一直反回错误
下级级用的是HAALI的一个东西,用CMemStream拉模式的时候是可以连接的
...
-
ffmpeg编码后视频速度不正确,质量也不好,求助,求助,求助,求助啊
对采集到得摄像头图像进行编码保存,发现得到的视频质量不好,而且速度不...
-
请问怎么在live555中接收jpeg
请问,我现在想接收一个服务器发送的jpeg 不知道怎么用live555做一个客户端, 接收它并显示。
请问应...
-
XP SP3 YUV420 的fiter依赖 在线等答案……
链接时媒体类型为WMMEDIASUBTYPE_I420
有的XP可以播放出来
有的就不行,请问不能播放...
-
如何获取通过麦克风来获取当前说话的音量?
使用Wave系统API采集音频输入的数据,当数据缓存区满了后,收到消息取得数据后,如何根据这里...
-
RFC3984 有没有完整的中文版本呢?
搜了几个 都是一半英文一半中文的。哎 郁闷!
------解决方案--------------------
英文的凑合...
-
介绍一个学习directshow和com、atl技术的网站
有一个学习directshow和com、atl技术的网站,还可以下视频教程,共享给大家: http://www...
-
攻击帖:jrtplib、live555是个垃圾,刚开始搞流媒体就用这玩意就是找s
不解释~
来丢我砖头吧~~
我分太多了用不完~ 支持的散分~~~
...
-
50分,寻找《Visual C++音频/视频处理技术及工程实践》的随书光盘?
急于使用其中的几个例程。若哪位好心人能够提供,非常感谢!!我的QQ:52...
-
h264的高宽比怎么获取?
我看标准里面只有样点的高宽比啊。
还有,bit rate可以读出来吗?
------解决方案--------------------
是要...