使用drm的over_plane显示YUV420像素格式的示例C语言代码
时间: 2023-12-10 21:38:07 浏览: 382
以下是使用 DRM 和 Over Plane 显示 YUV420 像素格式的示例 C 代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#define WIDTH 640
#define HEIGHT 480
int main(int argc, char *argv[])
{
int fd;
drmModeCrtcPtr crtc;
drmModePlaneResPtr plane_resources;
drmModePlanePtr plane;
drmModeObjectPropertiesPtr props;
uint32_t crtc_id, plane_id, blob_id;
uint32_t format = DRM_FORMAT_YUV420;
uint32_t handles[3], pitches[3], offsets[3];
uint32_t fb_id, bo_handles[4], flags = 0;
uint8_t *buf;
int ret, i, j;
/* Open the DRM device */
fd = open("/dev/dri/card0", O_RDWR);
if (fd < 0) {
fprintf(stderr, "Failed to open DRM device: %s\n", strerror(errno));
return -1;
}
/* Get the CRTC information */
crtc = drmModeGetCrtc(fd, 0);
if (!crtc) {
fprintf(stderr, "Failed to get CRTC information: %s\n", strerror(errno));
close(fd);
return -1;
}
crtc_id = crtc->crtc_id;
/* Get the plane resources */
plane_resources = drmModeGetPlaneResources(fd);
if (!plane_resources) {
fprintf(stderr, "Failed to get plane resources: %s\n", strerror(errno));
drmModeFreeCrtc(crtc);
close(fd);
return -1;
}
/* Find the primary plane */
for (i = 0; i < plane_resources->count_planes; i++) {
plane = drmModeGetPlane(fd, plane_resources->planes[i]);
if (!plane) {
fprintf(stderr, "Failed to get plane information: %s\n", strerror(errno));
continue;
}
props = drmModeObjectGetProperties(fd, plane->plane_id, DRM_MODE_OBJECT_PLANE);
for (j = 0; j < props->count_props; j++) {
drmModePropertyPtr prop = drmModeGetProperty(fd, props->props[j]);
if (!strcmp(prop->name, "type") && props->prop_values[j] == DRM_PLANE_TYPE_PRIMARY) {
plane_id = plane->plane_id;
drmModeFreeProperty(prop);
break;
}
drmModeFreeProperty(prop);
}
drmModeFreeObjectProperties(props);
drmModeFreePlane(plane);
}
/* Create the buffer object */
buf = malloc(WIDTH * HEIGHT * 3 / 2);
if (!buf) {
fprintf(stderr, "Failed to allocate buffer: %s\n", strerror(errno));
drmModeFreePlaneResources(plane_resources);
drmModeFreeCrtc(crtc);
close(fd);
return -1;
}
memset(buf, 0x80, WIDTH * HEIGHT * 3 / 2);
ret = drmPrimeFDToHandle(fd, STDIN_FILENO, &handles[0]);
if (ret < 0) {
fprintf(stderr, "Failed to get handle for file descriptor: %s\n", strerror(errno));
free(buf);
drmModeFreePlaneResources(plane_resources);
drmModeFreeCrtc(crtc);
close(fd);
return -1;
}
/* Configure the buffer object */
pitches[0] = WIDTH;
pitches[1] = pitches[2] = WIDTH / 2;
offsets[0] = 0;
offsets[1] = WIDTH * HEIGHT;
offsets[2] = offsets[1] + WIDTH * HEIGHT / 4;
bo_handles[0] = handles[0];
bo_handles[1] = bo_handles[2] = bo_handles[3] = 0;
ret = drmModeAddFB2(fd, WIDTH, HEIGHT, format, bo_handles, pitches, offsets, &fb_id, flags);
if (ret < 0) {
fprintf(stderr, "Failed to add frame buffer: %s\n", strerror(errno));
free(buf);
drmModeFreePlaneResources(plane_resources);
drmModeFreeCrtc(crtc);
close(fd);
return -1;
}
/* Set the plane mode */
ret = drmModeSetPlane(fd, plane_id, crtc_id, fb_id, 0, 0, 0, WIDTH, HEIGHT, 0, 0, WIDTH << 16, HEIGHT << 16);
if (ret < 0) {
fprintf(stderr, "Failed to set plane mode: %s\n", strerror(errno));
drmModeRmFB(fd, fb_id);
free(buf);
drmModeFreePlaneResources(plane_resources);
drmModeFreeCrtc(crtc);
close(fd);
return -1;
}
/* Wait for input */
printf("Press any key to exit...\n");
getchar();
/* Clean up */
drmModeRmFB(fd, fb_id);
free(buf);
drmModeFreePlaneResources(plane_resources);
drmModeFreeCrtc(crtc);
close(fd);
return 0;
}
```
这是一个简单的示例代码,它打开 DRM 设备,获取 CRTC 信息,找到主平面,创建 YUV420 帧缓冲区对象,将帧缓冲区对象传递给主平面,然后等待输入并在退出时清除资源。请注意,此示例仅涵盖了 DRM 和 Over Plane 基础知识,实际应用需要更多的代码来实现更复杂的功能。
阅读全文