做了一个ffmpeg+SDL的播放器,现在移植到QT中,暂时又不想直接用QT+ffmpeg的方式。
但是原来的SDL做播放器的话,每次运行就直接弹出独立的SDL播放窗口。
所以就把SDL嵌入到QT的子窗口中,记录一下遇到的问题。
百度了网上的方式,都是3年前的了,有点老,踩了不少坑,

下面开始说明一下:
一开始是这种写法,如下:

        if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
          fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
          exit(1);
        }
        
        char winID[32] = {0};
        /* 获取窗口的大小 */
        QSize size = ui->label->baseSize();

        sprintf(winID, "SDL_WINDOWID=0x%lx", ui->label->winId());

        SDL_putenv(winID);
        //putenv("SDL_WINDOWID=XXX");

        screen = SDL_SetVideoMode(640, 480, 0, 0);

然后还是弹出SDL独立窗口,并没有嵌入QT的控件中。
如下,左边是QT的窗口,右边是SDL的播放窗口,并且关闭右边的窗口后,左边的也退出了。
在这里插入图片描述
我去官网文档看了下,相关说明如下:
在这里插入图片描述
可以看到第一行的说明:
This makes SDL use an existing window instead of creating a new one. This works under X11 and Win32. Basically you putenv(“SDL_WINDOWID=XXX”) where XXX is an existing window’s ID. You can only use it on one existing window (not several).
简单说下就是:让SDL使用现有的窗口,不要创建新的窗口。这适用于X11和Win32。你可以使用putenv(“SDL_WINDOWID=XXX”)方式,其中XXX是一个现有窗口的ID。只能在一个现有窗口上使用它。

这么看来上面的方法没错,那么是那里出了问题?
又试了很多方法,结果发现是SDL的初始化问题:

       char winID[32] = {0};

        sprintf(winID, "SDL_WINDOWID=0x%lx", ui->label->winId());
        
        SDL_putenv(winID);			//最核心的绑定窗口功能

        if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
          fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
          exit(1);
        }

        screen = SDL_SetVideoMode(640, 480, 0, 0);

上面的代码顺序,播放就正常了,如下!
但是为什么之前别人的初始化都是放在前面,可能是SDL的函数经过调整了,比较ffmpeg和SDL一直都在不断di更新。
在这里插入图片描述
说明一下:我的QT控件使用的是Qlabel,上面那个资料的网站,有兴趣可以自己去看下:http://sdl.beuc.net/sdl.wiki/FAQ_GUI

将SDL嵌入到qt后出现了一个问题需要注意:SDL的窗口嵌入label之后,那么显示窗口就是交给label了,即label变成了父窗口,那么原来SDL窗口就响应不了按键的输入了
后续再解决吧,至少显示的问题OK了!

GitHub 加速计划 / sd / SDL
8.9 K
1.68 K
下载
Simple Directmedia Layer
最近提交(Master分支:2 个月前 )
a57c5669 - 3 个月前
20a6193e - 3 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐