Linux设备驱动之LCD显示摄像图像之三进行转换
来源:互联网 发布:linux防火墙策略 编辑:程序博客网 时间:2024/05/22 13:47
因为LCD为RGB模式,所以我们所要做的工作就是将我们其他像素模式转换为RGB模式
大部分函数参照/* luvcview */这个应用函数
Convert_manager.c:
#include <config.h>#include <convert_manager.h>#include <string.h>static PT_VideoConvert g_ptVideoConvertHead = NULL;int RegisterVideoConvert(PT_VideoConvert ptVideoConvert){ PT_VideoConvert ptTmp; if (!g_ptVideoConvertHead) { g_ptVideoConvertHead = ptVideoConvert; ptVideoConvert->ptNext = NULL; } else { ptTmp = g_ptVideoConvertHead; while (ptTmp->ptNext) { ptTmp = ptTmp->ptNext; } ptTmp->ptNext = ptVideoConvert; ptVideoConvert->ptNext = NULL; } return 0;}void ShowVideoConvert(void){ int i = 0; PT_VideoConvert ptTmp = g_ptVideoConvertHead; while (ptTmp) { printf("%02d %s\n", i++, ptTmp->name); ptTmp = ptTmp->ptNext; }}PT_VideoConvert GetVideoConvert(char *pcName){ PT_VideoConvert ptTmp = g_ptVideoConvertHead; while (ptTmp) { if (strcmp(ptTmp->name, pcName) == 0) { return ptTmp; } ptTmp = ptTmp->ptNext; } return NULL;}PT_VideoConvert GetVideoConvertForFormats(int iPixelFormatIn, int iPixelFormatOut){ PT_VideoConvert ptTmp = g_ptVideoConvertHead; while (ptTmp) { if (ptTmp->isSupport(iPixelFormatIn, iPixelFormatOut)) { return ptTmp; } ptTmp = ptTmp->ptNext; } return NULL;}int VideoConvertInit(void){ int iError; iError = Yuv2RgbInit(); iError |= Mjpeg2RgbInit(); iError |= Rgb2RgbInit(); return iError;}
mjpeg2rgb:
/* MJPEG : 实质上每一帧数据都是一个完整的JPEG文件 */#include <convert_manager.h>#include <stdlib.h>#include <string.h>#include <setjmp.h>#include <jpeglib.h>typedef struct MyErrorMgr{ struct jpeg_error_mgr pub; jmp_buf setjmp_buffer;}T_MyErrorMgr, *PT_MyErrorMgr;extern void jpeg_mem_src_tj(j_decompress_ptr, unsigned char *, unsigned long);static int isSupportMjpeg2Rgb(int iPixelFormatIn, int iPixelFormatOut){ if (iPixelFormatIn != V4L2_PIX_FMT_MJPEG) return 0; if ((iPixelFormatOut != V4L2_PIX_FMT_RGB565) && (iPixelFormatOut != V4L2_PIX_FMT_RGB32)) { return 0; } return 1;}static void MyErrorExit(j_common_ptr ptCInfo){ static char errStr[JMSG_LENGTH_MAX]; PT_MyErrorMgr ptMyErr = (PT_MyErrorMgr)ptCInfo->err; /* Create the message */ (*ptCInfo->err->format_message) (ptCInfo, errStr); DBG_PRINTF("%s\n", errStr); longjmp(ptMyErr->setjmp_buffer, 1);}//Garmen:转换一行static int CovertOneLine(int iWidth, int iSrcBpp, int iDstBpp, unsigned char *pudSrcDatas, unsigned char *pudDstDatas){ unsigned int dwRed; unsigned int dwGreen; unsigned int dwBlue; unsigned int dwColor; unsigned short *pwDstDatas16bpp = (unsigned short *)pudDstDatas; unsigned int *pwDstDatas32bpp = (unsigned int *)pudDstDatas; int i; int pos = 0; if (iSrcBpp != 24) { return -1; } if (iDstBpp == 24) { memcpy(pudDstDatas, pudSrcDatas, iWidth*3); } else { for (i = 0; i < iWidth; i++) { dwRed = pudSrcDatas[pos++]; dwGreen = pudSrcDatas[pos++]; dwBlue = pudSrcDatas[pos++]; if (iDstBpp == 32) { dwColor = (dwRed << 16) | (dwGreen << 8) | dwBlue; *pwDstDatas32bpp = dwColor; pwDstDatas32bpp++; } else if (iDstBpp == 16) { /* 565 */ dwRed = dwRed >> 3; dwGreen = dwGreen >> 2; dwBlue = dwBlue >> 3; dwColor = (dwRed << 11) | (dwGreen << 5) | (dwBlue); *pwDstDatas16bpp = dwColor; pwDstDatas16bpp++; } } } return 0;}//static int GetPixelDatasFrmJPG(PT_FileMap ptFileMap, PT_PixelDatas ptPixelDatas)/* 把内存里的JPEG图像转换为RGB图像 */static int Mjpeg2RgbConvert(PT_VideoBuf ptVideoBufIn, PT_VideoBuf ptVideoBufOut){ struct jpeg_decompress_struct tDInfo; //struct jpeg_error_mgr tJErr; int iRet; int iRowStride; unsigned char *aucLineBuffer = NULL; unsigned char *pucDest; T_MyErrorMgr tJerr; //Garmen:定义一个PT_PixelDatas类型结构体,等于&ptVideoBufOut->tPixelDatas PT_PixelDatas ptPixelDatas = &ptVideoBufOut->tPixelDatas; // 分配和初始化一个decompression结构体 //tDInfo.err = jpeg_std_error(&tJErr); tDInfo.err = jpeg_std_error(&tJerr.pub); tJerr.pub.error_exit = MyErrorExit; if(setjmp(tJerr.setjmp_buffer)) { /* 如果程序能运行到这里, 表示JPEG解码出错 */ jpeg_destroy_decompress(&tDInfo); if (aucLineBuffer) { free(aucLineBuffer); } if (ptPixelDatas->aucPixelDatas) { free(ptPixelDatas->aucPixelDatas); } return -1; } jpeg_create_decompress(&tDInfo); // 用jpeg_read_header获得jpg信息 //jpeg_stdio_src(&tDInfo, ptFileMap->tFp); /* 把数据设为内存中的数据 */ jpeg_mem_src_tj (&tDInfo, ptVideoBufIn->tPixelDatas.aucPixelDatas, ptVideoBufIn->tPixelDatas.iTotalBytes); iRet = jpeg_read_header(&tDInfo, TRUE); // 设置解压参数,比如放大、缩小 tDInfo.scale_num = tDInfo.scale_denom = 1; // 启动解压:jpeg_start_decompress jpeg_start_decompress(&tDInfo); // 一行的数据长度 iRowStride = tDInfo.output_width * tDInfo.output_components; aucLineBuffer = malloc(iRowStride); if (NULL == aucLineBuffer) { return -1; } ptPixelDatas->iWidth = tDInfo.output_width; ptPixelDatas->iHeight = tDInfo.output_height; //ptPixelDatas->iBpp = iBpp; ptPixelDatas->iLineBytes = ptPixelDatas->iWidth * ptPixelDatas->iBpp / 8; ptPixelDatas->iTotalBytes = ptPixelDatas->iHeight * ptPixelDatas->iLineBytes; if (NULL == ptPixelDatas->aucPixelDatas) { ptPixelDatas->aucPixelDatas = malloc(ptPixelDatas->iTotalBytes); } pucDest = ptPixelDatas->aucPixelDatas; // 循环调用jpeg_read_scanlines来一行一行地获得解压的数据 while (tDInfo.output_scanline < tDInfo.output_height) { /* 得到一行数据,里面的颜色格式为0xRR, 0xGG, 0xBB */ (void) jpeg_read_scanlines(&tDInfo, &aucLineBuffer, 1); // 转到ptPixelDatas去 CovertOneLine(ptPixelDatas->iWidth, 24, ptPixelDatas->iBpp, aucLineBuffer, pucDest); pucDest += ptPixelDatas->iLineBytes; } free(aucLineBuffer); jpeg_finish_decompress(&tDInfo); jpeg_destroy_decompress(&tDInfo); return 0;}static int Mjpeg2RgbConvertExit(PT_VideoBuf ptVideoBufOut){ if (ptVideoBufOut->tPixelDatas.aucPixelDatas) { free(ptVideoBufOut->tPixelDatas.aucPixelDatas); ptVideoBufOut->tPixelDatas.aucPixelDatas = NULL; } return 0;}/* 构造 */static T_VideoConvert g_tMjpeg2RgbConvert = { .name = "mjpeg2rgb", .isSupport = isSupportMjpeg2Rgb, .Convert = Mjpeg2RgbConvert, .ConvertExit = Mjpeg2RgbConvertExit,};/* 注册 */int Mjpeg2RgbInit(void){ return RegisterVideoConvert(&g_tMjpeg2RgbConvert);}
rgb2rgb:
#include <convert_manager.h>#include <stdlib.h>#include <string.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 = (unsigned short *)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 = { .name = "rgb2rgb", .isSupport = isSupportRgb2Rgb, .Convert = Rgb2RgbConvert, .ConvertExit = Rgb2RgbConvertExit,};/* 注册 */int Rgb2RgbInit(void){ return RegisterVideoConvert(&g_tRgb2RgbConvert);}
yuv2rgb:
#include <convert_manager.h>#include <stdlib.h>#include "color.h"static int isSupportYuv2Rgb(int iPixelFormatIn, int iPixelFormatOut){ if (iPixelFormatIn != V4L2_PIX_FMT_YUYV) return 0; if ((iPixelFormatOut != V4L2_PIX_FMT_RGB565) && (iPixelFormatOut != V4L2_PIX_FMT_RGB32)) { return 0; } return 1;}/* translate YUV422Packed to rgb24 */static unsigned intPyuv422torgb565(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;}/* translate YUV422Packed to rgb24 */static unsigned intPyuv422torgb32(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 = (unsigned int *)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;}/* 参考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); return 0; } 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; } return -1;}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 = { .name = "yuv2rgb", .isSupport = isSupportYuv2Rgb, .Convert = Yuv2RgbConvert, .ConvertExit = Yuv2RgbConvertExit,};extern void initLut(void);/* 注册 */int Yuv2RgbInit(void){ initLut(); return RegisterVideoConvert(&g_tYuv2RgbConvert);}
阅读全文
0 0
- Linux设备驱动之LCD显示摄像图像之三进行转换
- Linux设备驱动之LCD显示摄像图像之二编写V4l2程序
- Linux设备驱动之LCD显示摄像图像之一框架与准备工作
- Linux设备驱动之CRT显示摄像图像之一准备工作
- Linux字符设备驱动之LCD驱动
- 65 linux spi设备驱动之spi LCD屏驱动
- 68 linux framebuffer设备驱动之spi lcd屏驱动
- Linux设备驱动之s3c2440添加LCD驱动
- itop4412 LCD设备驱动详解(三)之PROBE
- LINUX之LCD驱动
- linux驱动之LCD
- linux驱动之--lcd
- Linux 设备驱动之字符设备(三)
- Linux 设备驱动之字符设备(三)
- Linux驱动之mipi接口的LCD设备添加过程
- linux lcd设备驱动剖析三
- linux lcd设备驱动剖析三
- linux lcd设备驱动剖析三
- 12、消息提示框与模态弹窗
- HTTP中的GET和POST
- 扁平化立体字教程
- java中set集合的使用方法
- 学习前端之路(一)
- Linux设备驱动之LCD显示摄像图像之三进行转换
- 程序员面试金典——输出单层结点
- Array Nesting
- spring cloud 搭建高可用的注册中心
- 函数的执行过程-栈帧的创建与销毁
- 【英语】很抱歉,我一天的86400秒却没有你
- 将ffmpeg编译
- Linux设备驱动之CRT显示摄像图像之一准备工作
- 源码包安装软件