使用drm库drmModeAddFB2函数创建NV12显示
时间: 2023-12-03 20:01:57 浏览: 527
要使用drmModeAddFB2函数创建NV12显示,需要先准备好NV12数据,并设置好显示的宽度和高度。下面是一个简单的例子:
```c
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/drm.h>
// 设置显示宽度和高度
#define WIDTH 800
#define HEIGHT 600
int main()
{
// 打开 DRM 设备
int fd = open("/dev/dri/card0", O_RDWR);
if (fd < 0) {
printf("Failed to open DRM device: %s\n", strerror(errno));
return -1;
}
// 准备 NV12 数据
uint8_t *data = (uint8_t *)calloc(WIDTH * HEIGHT * 3 / 2, sizeof(uint8_t));
if (!data) {
printf("Failed to allocate memory\n");
close(fd);
return -1;
}
// 创建 NV12 帧缓冲
struct drm_mode_create_dumb create = {0};
create.width = WIDTH;
create.height = HEIGHT;
create.bpp = 8;
create.flags = DRM_MODE_CREATE_DUMB_MODE_HORIZONTALLY_TILED;
int ret = ioctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create);
if (ret < 0) {
printf("Failed to create dumb buffer: %s\n", strerror(errno));
free(data);
close(fd);
return -1;
}
// 映射帧缓冲到用户空间
struct drm_mode_map_dumb map = {0};
map.handle = create.handle;
ret = ioctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map);
if (ret < 0) {
printf("Failed to map dumb buffer: %s\n", strerror(errno));
ioctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &create);
free(data);
close(fd);
return -1;
}
// 将 NV12 数据写入帧缓冲
uint8_t *ptr = (uint8_t *)mmap(0, create.size, PROT_WRITE, MAP_SHARED, fd, map.offset);
if (ptr == MAP_FAILED) {
printf("Failed to mmap dumb buffer: %s\n", strerror(errno));
ioctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &create);
free(data);
close(fd);
return -1;
}
memcpy(ptr, data, WIDTH * HEIGHT * 3 / 2);
munmap(ptr, create.size);
// 创建 NV12 显示
struct drm_mode_create_fb2 create_fb = {0};
create_fb.width = WIDTH;
create_fb.height = HEIGHT;
create_fb.pixel_format = DRM_FORMAT_NV12;
create_fb.pitches[0] = WIDTH;
create_fb.pitches[1] = WIDTH;
create_fb.offsets[0] = 0;
create_fb.offsets[1] = WIDTH * HEIGHT;
create_fb.handles[0] = create.handle;
create_fb.modifier[0] = DRM_FORMAT_MOD_NONE;
ret = ioctl(fd, DRM_IOCTL_MODE_ADDFB2, &create_fb);
if (ret < 0) {
printf("Failed to create FB: %s\n", strerror(errno));
ioctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &create);
free(data);
close(fd);
return -1;
}
// 显示 NV12 帧缓冲
struct drm_mode_set_plane set_plane = {0};
set_plane.fb_id = create_fb.fb_id;
set_plane.crtc_id = 0;
set_plane.plane_id = 0;
set_plane.src_x = 0 << 16;
set_plane.src_y = 0 << 16;
set_plane.src_w = WIDTH << 16;
set_plane.src_h = HEIGHT << 16;
set_plane.crtc_x = 0;
set_plane.crtc_y = 0;
set_plane.crtc_w = WIDTH;
set_plane.crtc_h = HEIGHT;
ret = ioctl(fd, DRM_IOCTL_MODE_SET_PLANES, &set_plane);
if (ret < 0) {
printf("Failed to set plane: %s\n", strerror(errno));
ioctl(fd, DRM_IOCTL_MODE_RMFB, &create_fb.fb_id);
ioctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &create);
free(data);
close(fd);
return -1;
}
// 等待 5 秒钟后关闭显示
sleep(5);
ioctl(fd, DRM_IOCTL_MODE_RMFB, &create_fb.fb_id);
ioctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &create);
free(data);
close(fd);
return 0;
}
```
上面的代码将创建一个宽度为 800,高度为 600 的 NV12 显示,并将其显示在屏幕上。你可以将NV12数据替换成自己的数据,然后运行上面的代码,查看效果。
阅读全文
相关推荐
![gz](https://img-home.csdnimg.cn/images/20210720083447.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)