linux帧缓冲设备,Linux下V4L2捕捉画面+H264压缩视频+帧缓冲显示视频————帧缓冲显示视频...

本文介绍了如何在嵌入式设备上初始化帧缓冲设备并创建显示线程,通过`DisplayInit`函数操作屏幕分辨率和内存映射,以及`DisplayThread`负责处理图像数据转换和显示。关键步骤包括打开设备、设置屏幕参数和内存映射,展示了在嵌入式开发中处理显示输出的流程。
摘要由CSDN通过智能技术生成

/* display.c */

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "config.h"

#include "queue.h"

#include "display.h"

typedef enum {

DISPLAY_STATE_STOP,

DISPLAY_STATE_START

} eDisplayState;

static struct {

int DevFd;

int ScreenSize;

uint8_t* pMmap;

eDisplayState State;

pthread_t DisplayThreadId;

sQueue QueuePrivateData;

uint32_t ScreenWidth;

uint32_t ScreenHeight;

} sDisplayPrivateData;

static const int BufferSize = CONFIG_CAPTURE_WIDTH * CONFIG_CAPTURE_HEIGHT * 4;

extern int Yuyv2Rgb32(uint8_t* pYuv, uint8_t* pRgb, uint32_t Width, uint32_t Height);

int DisplayInit(const char* pDevName)

{

QueueInit(&sDisplayPrivateData.QueuePrivateData);

struct fb_fix_screeninfo FbFix;

struct fb_var_screeninfo FbVar;

if((sDisplayPrivateData.DevFd = open(pDevName, O_RDWR)) < 0){

perror("Open Framebuffer Device");

return -1;

}

printf("Open Framebuffer Device:%s successful!\n", pDevName);

if(ioctl(sDisplayPrivateData.DevFd, FBIOGET_FSCREENINFO, &FbFix)){

perror("Get Fb_fix_info error!");

return -1;

}

printf("Get Fb_fix_info successful!\n");

if(ioctl(sDisplayPrivateData.DevFd, FBIOGET_VSCREENINFO, &FbVar)){

printf("Get Fb_var_info error!\n");

return -1;

}

printf("Get Fb_var_info successful!\n");

printf("Screen origin param: physics resultion %dx%d, line length: %d\n", FbVar.xres, FbVar.yres, FbFix.line_length);

printf("Screen origin param: virtual resultion %dx%d\n", FbVar.xres_virtual, FbVar.yres_virtual);

// FbVar.xres = CONFIG_CAPTURE_WIDTH;

// FbVar.yres = CONFIG_CAPTURE_HEIGHT;

FbVar.xres_virtual = CONFIG_CAPTURE_WIDTH;

FbVar.yres_virtual = CONFIG_CAPTURE_WIDTH;

if(ioctl(sDisplayPrivateData.DevFd, FBIOPUT_VSCREENINFO, &FbVar)) {

printf("Set Fb_var_info error!\n");

// return -1;

}

printf("Set Fb_var_info successful!\n");

if(ioctl(sDisplayPrivateData.DevFd, FBIOGET_VSCREENINFO, &FbVar)) {

printf("Get Fb_var_info error!\n");

return -1;

}

printf("Get Fb_var_info successful!\n");

printf("Screen after param: physics resultion %dx%d, line length: %d\n", FbVar.xres, FbVar.yres, FbFix.line_length);

printf("Screen after param: virtual resultion %dx%d\n", FbVar.xres_virtual, FbVar.yres_virtual);

sDisplayPrivateData.ScreenWidth = FbVar.xres;

sDisplayPrivateData.ScreenHeight = FbVar.yres;

sDisplayPrivateData.ScreenSize = FbVar.xres * FbVar.yres * (FbVar.bits_per_pixel / 8);

printf("Screen size: %d\n", sDisplayPrivateData.ScreenSize);

sDisplayPrivateData.pMmap = mmap(NULL, sDisplayPrivateData.ScreenSize, PROT_READ | PROT_WRITE, MAP_SHARED, sDisplayPrivateData.DevFd, 0);

if(!sDisplayPrivateData.pMmap){

perror("Memory Mmap error");

return -1;

}

printf("Memory Mmap successful!\n");

return 0;

}

static void* DisplayThread(void* pParam)

{

int Ret = -1;

sDisplayPrivateData.State = DISPLAY_STATE_START;

uint8_t* pRgbBuffer = malloc(BufferSize);

if(!pRgbBuffer) {

perror("Malloc failed");

return NULL;

}

while(sDisplayPrivateData.State == DISPLAY_STATE_START) {

sQueueData QueueData;

Ret = QueuePopData(&sDisplayPrivateData.QueuePrivateData, &QueueData);

if(Ret) {

continue;

}

Yuyv2Rgb32(QueueData.pData, pRgbBuffer, CONFIG_CAPTURE_WIDTH, CONFIG_CAPTURE_HEIGHT);

// printf("Copy length: %d\n", BufferSize);

// memcpy(sDisplayPrivateData.pMmap, pRgbBuffer, BufferSize);

uint32_t CopyWidthLength = sDisplayPrivateData.ScreenWidth > CONFIG_CAPTURE_WIDTH ?

CONFIG_CAPTURE_WIDTH : sDisplayPrivateData.ScreenWidth;

for(int i = 0; i < CONFIG_CAPTURE_HEIGHT; i++) {

memcpy(sDisplayPrivateData.pMmap + sDisplayPrivateData.ScreenWidth * 4 * i,

&pRgbBuffer[CONFIG_CAPTURE_WIDTH * 4 * i],

CopyWidthLength * 4);

}

QueueCallback(&QueueData);

}

free(pRgbBuffer);

DisplayStop();

return NULL;

}

int DisplayStart(void)

{

if(sDisplayPrivateData.State == DISPLAY_STATE_START) {

return -1;

}

pthread_create(&sDisplayPrivateData.DisplayThreadId, NULL, DisplayThread, (void *)NULL);

return 0;

}

int DisplayStop(void)

{

if(sDisplayPrivateData.State == DISPLAY_STATE_STOP) {

return 0;

}

sDisplayPrivateData.State = DISPLAY_STATE_STOP;

pthread_join(sDisplayPrivateData.DisplayThreadId, NULL);

munmap(sDisplayPrivateData.pMmap, sDisplayPrivateData.ScreenSize);

close(sDisplayPrivateData.DevFd);

printf("Display thread stop\n");

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值