convert_manager.h文件:
#ifndef _CONVERT_MANAGER_H
#define _CONVERT_MANAGER_H
#include <config.h>
#include <video_manager.h>
typedef struct VideoConvert {
int (*isSupport)(int iPixelFormatIn, int iPixelFormatOut);
int (*Convert)(PT_VideoBuf ptVideoBufIn, PT_VideoBuf ptVideoBufOut);
int (*ConvertExit)(PT_VideoBuf ptVideoBufOut);
}T_VideoConvert, *PT_VideoConvert;
#endif /* _CONVERT_MANAGER_H */
定义一个VideoConvert结构体,包含三个函数,support;convert; convertexit函数;
并且命名为T_VideoConvert, *PT_VideoConvert。
还有三个文件:rgb2rgb.c; yuv2rgb.c; mjpeg2rgb.c
rgb2rgb.c; yuv2rgb.c;比较好理解,先来rgb2rgb(rgb565转rgb565或者rgb565转rgb32)
#include <convert_manager.h>
static int isSupportRgb2Rgb(int iPixelFormatIn, int iPixelFormatOut)
{
if (iPixelFormatIn != V4L2_PIX_FMT_RGB565)
return 0;
if ((iPixelFormatOut != V4L2_PIX_FMT_RGB565) && (iPixelFormatOut != V4L2_PIX_FMT_RGB32))
{
return 0;
}
return 1;
}
static int Rgb2RgbConvert(PT_VideoBuf ptVideoBufIn, PT_VideoBuf ptVideoBufOut)
{
PT_PixelDatas ptPixelDatasIn = &ptVideoBufIn->tPixelDatas;
PT_PixelDatas ptPixelDatasOut = &ptVideoBufOut->tPixelDatas;
int x, y;
int r, g, b;
int color;
unsigned short *pwSrc = ptPixelDatasIn->aucPixelDatas;
unsigned int *pdwDest;
if (ptVideoBufIn->iPixelFormat != V4L2_PIX_FMT_RGB565)
{
return -1;
}
if (ptVideoBufOut->iPixelFormat == V4L2_PIX_FMT_RGB565)
{
ptPixelDatasOut->iWidth = ptPixelDatasIn->iWidth;
ptPixelDatasOut->iHeight = ptPixelDatasIn->iHeight;
ptPixelDatasOut->iBpp = 16;
ptPixelDatasOut->iLineBytes = ptPixelDatasOut->iWidth * ptPixelDatasOut->iBpp / 8;
ptPixelDatasOut->iTotalBytes = ptPixelDatasOut->iLineBytes * ptPixelDatasOut->iHeight;
if (!ptPixelDatasOut->aucPixelDatas)
{
ptPixelDatasOut->aucPixelDatas = malloc(ptPixelDatasOut->iTotalBytes);
}
memcpy(ptPixelDatasOut->aucPixelDatas, ptPixelDatasIn->aucPixelDatas, ptPixelDatasOut->iTotalBytes);
return 0;
}
else if (ptVideoBufOut->iPixelFormat == V4L2_PIX_FMT_RGB32)
{
ptPixelDatasOut->iWidth = ptPixelDatasIn->iWidth;
ptPixelDatasOut->iHeight = ptPixelDatasIn->iHeight;
ptPixelDatasOut->iBpp = 32;
ptPixelDatasOut->iLineBytes = ptPixelDatasOut->iWidth * ptPixelDatasOut->iBpp / 8;
ptPixelDatasOut->iTotalBytes = ptPixelDatasOut->iLineBytes * ptPixelDatasOut->iHeight;
if (!ptPixelDatasOut->aucPixelDatas)
{
ptPixelDatasOut->aucPixelDatas = malloc(ptPixelDatasOut->iTotalBytes);
}
pdwDest = (unsigned int *)ptPixelDatasOut->aucPixelDatas;
for (y = 0; y < ptPixelDatasOut->iHeight; y++)
{
for (x = 0; x < ptPixelDatasOut->iWidth; x++)
{
color = *pwSrc++;
/* 从RGB565格式的数据中提取出R,G,B */
r = color >> 11;
g = (color >> 5) & (0x3f);
b = color & 0x1f;
/* 把r,g,b转为0x00RRGGBB的32位数据 */
color = ((r << 3) << 16) | ((g << 2) << 8) | (b << 3);
*pdwDest = color;
pdwDest++;
}
}
return 0;
}
return -1;
}
static int Rgb2RgbConvertExit(PT_VideoBuf ptVideoBufOut)
{
if (ptVideoBufOut->tPixelDatas.aucPixelDatas)
{
free(ptVideoBufOut->tPixelDatas.aucPixelDatas);
ptVideoBufOut->tPixelDatas.aucPixelDatas = NULL;
}
return 0;
}
/* 构造 */
static T_VideoConvert g_tRgb2RgbConvert = {
.isSupport = isSupportRgb2Rgb,
.Convert = Rgb2RgbConvert,
.ConvertExit = Rgb2RgbConvertExit,
};
/* 注册 */
int Rgb2RgbInit(void)
{
return RegisterVideoConvert(&g_tRgb2RgbConvert);
}
rgb565转rgb565就直接memcpy
rgb565转rgb32,对于宽度*高度,每一个像素,都进行rgb convert
565:0xff = rrrrr gggggg bbbbb;(16位)R5,G6,B5
32 :0xffff =0x00rrggbb(32位) 每个占8位
/* 参考luvcview */
static int Yuv2RgbConvert(PT_VideoBuf ptVideoBufIn, PT_VideoBuf ptVideoBufOut)
{
PT_PixelDatas ptPixelDatasIn = &ptVideoBufIn->tPixelDatas;
PT_PixelDatas ptPixelDatasOut = &ptVideoBufOut->tPixelDatas;
ptPixelDatasOut->iWidth = ptPixelDatasIn->iWidth;
ptPixelDatasOut->iHeight = ptPixelDatasIn->iHeight;
if (ptVideoBufOut->iPixelFormat == V4L2_PIX_FMT_RGB565)
{
ptPixelDatasOut->iBpp = 16;
ptPixelDatasOut->iLineBytes = ptPixelDatasOut->iWidth * ptPixelDatasOut->iBpp / 8;
ptPixelDatasOut->iTotalBytes = ptPixelDatasOut->iLineBytes * ptPixelDatasOut->iHeight;
if (!ptPixelDatasOut->aucPixelDatas)
{
ptPixelDatasOut->aucPixelDatas = malloc(ptPixelDatasOut->iTotalBytes);
}
Pyuv422torgb565(ptPixelDatasIn->aucPixelDatas, ptPixelDatasOut->aucPixelDatas, ptPixelDatasOut->iWidth, ptPixelDatasOut->iHeight);
}
else if (ptVideoBufOut->iPixelFormat == V4L2_PIX_FMT_RGB32)
{
ptPixelDatasOut->iBpp = 32;
ptPixelDatasOut->iLineBytes = ptPixelDatasOut->iWidth * ptPixelDatasOut->iBpp / 8;
ptPixelDatasOut->iTotalBytes = ptPixelDatasOut->iLineBytes * ptPixelDatasOut->iHeight;
if (!ptPixelDatasOut->aucPixelDatas)
{
ptPixelDatasOut->aucPixelDatas = malloc(ptPixelDatasOut->iTotalBytes);
}
Pyuv422torgb32(ptPixelDatasIn->aucPixelDatas, ptPixelDatasOut->aucPixelDatas, ptPixelDatasOut->iWidth, ptPixelDatasOut->iHeight);
}
return 0;
}
判断输出是RGB565还是RGB32,调用对应的转换函数。
/* translate YUV422Packed to rgb24 */
static unsigned int
Pyuv422torgb565(unsigned char * input_ptr, unsigned char * output_ptr, unsigned int image_width, unsigned int image_height)
{
unsigned int i, size;
unsigned char Y, Y1, U, V;
unsigned char *buff = input_ptr;
unsigned char *output_pt = output_ptr;
unsigned int r, g, b;
unsigned int color;
size = image_width * image_height /2;
for (i = size; i > 0; i--) {
/* bgr instead rgb ?? */
Y = buff[0] ;
U = buff[1] ;
Y1 = buff[2];
V = buff[3];
buff += 4;
r = R_FROMYV(Y,V);
g = G_FROMYUV(Y,U,V); //b
b = B_FROMYU(Y,U); //v
/* 把r,g,b三色构造为rgb565的16位值 */
r = r >> 3;
g = g >> 2;
b = b >> 3;
color = (r << 11) | (g << 5) | b;
*output_pt++ = color & 0xff;
*output_pt++ = (color >> 8) & 0xff;
r = R_FROMYV(Y1,V);
g = G_FROMYUV(Y1,U,V); //b
b = B_FROMYU(Y1,U); //v
/* 把r,g,b三色构造为rgb565的16位值 */
r = r >> 3;
g = g >> 2;
b = b >> 3;
color = (r << 11) | (g << 5) | b;
*output_pt++ = color & 0xff;
*output_pt++ = (color >> 8) & 0xff;
}
return 0;
}
output_Pt是char类型,所以要++2次
/* translate YUV422Packed to rgb24 */
static unsigned int
Pyuv422torgb32(unsigned char * input_ptr, unsigned char * output_ptr, unsigned int image_width, unsigned int image_height)
{
unsigned int i, size;
unsigned char Y, Y1, U, V;
unsigned char *buff = input_ptr;
unsigned int *output_pt = output_ptr;
unsigned int r, g, b;
unsigned int color;
size = image_width * image_height /2;
for (i = size; i > 0; i--) {
/* bgr instead rgb ?? */
Y = buff[0] ;
U = buff[1] ;
Y1 = buff[2];
V = buff[3];
buff += 4;
r = R_FROMYV(Y,V);
g = G_FROMYUV(Y,U,V); //b
b = B_FROMYU(Y,U); //v
/* rgb888 */
color = (r << 16) | (g << 8) | b;
*output_pt++ = color;
r = R_FROMYV(Y1,V);
g = G_FROMYUV(Y1,U,V); //b
b = B_FROMYU(Y1,U); //v
color = (r << 16) | (g << 8) | b;
*output_pt++ = color;
}
return 0;
}
output_Pt是int类型,所以++一次就够
其中的一些宏定义函数如R_FROMYV来源于LUVCview中的color.c。
static int Yuv2RgbConvertExit(PT_VideoBuf ptVideoBufOut)
{
if (ptVideoBufOut->tPixelDatas.aucPixelDatas)
{
free(ptVideoBufOut->tPixelDatas.aucPixelDatas);
ptVideoBufOut->tPixelDatas.aucPixelDatas = NULL;
}
return 0;
}
当函数结束后,要对操作空间进行释放。
/* 构造 */
static T_VideoConvert g_tYuv2RgbConvert = {
.isSupport = isSupportYuv2Rgb,
.Convert = Yuv2RgbConvert,
.ConvertExit = Yuv2RgbConvertExit,
};
extern void initLut(void);
/* 注册 */
int Yuv2RgbInit(void)
{
initLut();
return RegisterVideoConvert(&g_tYuv2RgbConvert);
}
构造操作函数结构体,以及注册结构体