Dus*_*rea 6 c python linux kernel hdmi
如何在不允许操作系统自动配置显示输出的情况下,从应用程序专门驱动HDMI输出怎么可能?
例如,使用标准DVI/VGA作为主显示器,但使用设备文件将Mplayer视频输出发送到HDMI.
这是一个很难通过谷歌回答的问题.几乎所有结果都与通过HDMI进行音频工作有关.
(在这里编辑)
下面的评论提到使用单独的Xorg服务器.虽然这是一个有用的想法,但它没有回答我提出的一个问题,而且我暗示了一个问题:
1)如何让Linux不希望将控制台放在该显示器上,如果它在另一个显示器之前加载,或者它是唯一的显示器(当只使用SSH登录时)?2)如果没有X怎么办?我想直接将图形驱动到适配器.我可以使用标准功能从代码执行此操作,而无需直接与驱动程序交互(可能过时,但使用SVGALib或其他非X图形层)?
(在这里编辑)
我看了SVGALib(旧的)和SDL.后者在X内外工作,甚至可以访问OpenGL.我通过某个论坛链接找到了1.3版,但网站和FTP似乎只有1.2.一般来说,SDL是一个很好的解决方案,但它有以下两个特定的缺点:
1)常规create-device调用接受设备索引,但完全忽略它:
(src/video/bwindow/SDL_bvideo.cc)
BE_CreateDevice(int devindex)
Run Code Online (Sandbox Code Playgroud)
特定于驱动程序的调用似乎具有相同的缺陷.例如,DirectFB(我假设,它在控制台下提供图形):
(src/video/directfb/SDL_DirectFB_video.c)
DirectFB_CreateDevice(int devindex)
Run Code Online (Sandbox Code Playgroud)
这些函数的主体似乎都没有设置设备索引的位置......毫无疑问,由于缺乏对它们构建的标准接口的支持.
2)无论选择何种适配器,SDL似乎都会自动将所有显示器连接在一起.示例"testsprite2.c"(随附库)接受"--display"参数,该参数在"common.c"中处理(所有示例的通用功能).您可以看到它使用"--display"参数执行的操作是在一个大的组合画布中计算该屏幕的X/Y坐标:
if (SDL_strcasecmp(argv[index], "--display") == 0) {
++index;
if (!argv[index]) {
return -1;
}
state->display = SDL_atoi(argv[index]);
if (SDL_WINDOWPOS_ISUNDEFINED(state->window_x)) {
state->window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);
state->window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display);
}
if (SDL_WINDOWPOS_ISCENTERED(state->window_x)) {
state->window_x = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);
state->window_y = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display);
}
return 2;
}
Run Code Online (Sandbox Code Playgroud)
因此,如果它们位于同一个适配器上,则无法将一个显示器与另一个显示器隔离.SDL不起作用.
除非有一个与SDL类似的解决方案,否则将特定设备(devindex)设置在适当的位置(这可能不是这种情况,因此,可能是它未被实现的原因)变得微不足道,似乎是专用和完全专用屏幕的最佳选择是在分配给第二个设备的单独Xorg实例下编写自己的窗口管理器.
您可以直接写入帧缓冲设备/dev/fb(假设您的控制台默认使用一个)。要防止控制台显示在其上,只需禁用所有虚拟终端(然后您将只能远程登录)。如果您有多个适配器,您应该获得多个帧缓冲设备(这一点需要确认)。
在帧缓冲区上绘制矩形的 AC 示例如下:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
int main()
{
int fbfd = 0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long int screensize = 0;
char *fbp = 0;
int x = 0, y = 0;
long int location = 0;
// Open the file for reading and writing
fbfd = open("/dev/fb0", O_RDWR);
if (fbfd == -1) {
perror("Error: cannot open framebuffer device");
exit(1);
}
printf("The framebuffer device was opened successfully.\n");
// Get fixed screen information
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {
perror("Error reading fixed information");
exit(2);
}
// Get variable screen information
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
perror("Error reading variable information");
exit(3);
}
printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
// Figure out the size of the screen in bytes
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
// Map the device to memory
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
if ((int)fbp == -1) {
perror("Error: failed to map framebuffer device to memory");
exit(4);
}
printf("The framebuffer device was mapped to memory successfully.\n");
x = 100; y = 100; // Where we are going to put the pixel
// Figure out where in memory to put the pixel
for (y = 100; y < 300; y++)
for (x = 100; x < 300; x++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
if (vinfo.bits_per_pixel == 32) {
*(fbp + location) = 100; // Some blue
*(fbp + location + 1) = 15+(x-100)/2; // A little green
*(fbp + location + 2) = 200-(y-100)/5; // A lot of red
*(fbp + location + 3) = 0; // No transparency
//location += 4;
} else { //assume 16bpp
int b = 10;
int g = (x-100)/6; // A little green
int r = 31-(y-100)/16; // A lot of red
unsigned short int t = r<<11 | g << 5 | b;
*((unsigned short int*)(fbp + location)) = t;
}
}
munmap(fbp, screensize);
close(fbfd);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
只要您有可用的构建工具以及系统的标头,它就应该可以编译。如果想要刺激一下,可以从 SSH 运行它,然后观看它在您尚未登录的物理屏幕上绘制。
应该注意的是,除了 X11 之外,还有很多针对帧缓冲区的工具,但它们不会直接访问帧缓冲区。相反,它们通过称为 DirectFB 的附加抽象层进行工作。DirectFB 将允许相同的应用程序在 X11 内部和外部运行...包括 MPlayer、GStreamer、任何包含 SDL(称为 DirectFB)的应用程序,以及一个名为 XDirectFB 的轻量级、流行的假 X11 容器(我相信它应该运行 X11 应用程序,但不会像典型的窗口管理器那样负担过重)。
| 归档时间: |
|
| 查看次数: |
6365 次 |
| 最近记录: |