qt中用SDL 1.3实现播放视频双窗口

 

思路:
1。跳过由sdl直接创建弹出窗口,那么它的窗口应该是QT指定的窗口。
2。给SDL传递窗口Handle,由SDL_getenv("SDL_WINDOWID")来实现
3。在SDL调用系统函数CreateWindow前把它Filter下来,否则会生成一个独立的窗口。
4。更改当前窗口的消息循环.

  印象中当时是参考1.26版本源代码来实现的,由于1.26与1.3相差比较大,因此走了一些弯路。
当时花了很多时间在处理消息循环上, 最终才形成下面的代码。

下面是SDL中需要更改的地方:
sdl1.3/src/video/win32/SDL_win32window.h:
extern void WIN_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window * window,
                                    struct SDL_SysWMinfo *info);
+ HWND SDL_WindowId;
#endif /* _SDL_win32window_h */

sdl1.3/src/video/win32/SDL_win32window.c:
 //在int WIN_CreateWindow(_THIS, SDL_Window * window)函数中

if ((window->flags & SDL_WINDOW_FULLSCREEN)
    || window->y == SDL_WINDOWPOS_CENTERED) {
    y = bounds.y + (bounds.h - h) / 2;
} else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
    if (bounds.x == 0) {
        y = CW_USEDEFAULT;
    } else {
        y = bounds.y;
    }
} else {
    y = bounds.y + window->y + rect.top;
}
+// for inter window
+             
+ {
+  BOOL SDL_windowid;
+  char *windowid;
+  LONG rtv;
+  windowid = SDL_getenv("SDL_WINDOWID");
+  SDL_windowid = (windowid != NULL);
+  if ( SDL_windowid ) {
+   SDL_WindowId = (HWND)SDL_strtoull(windowid, NULL, 0);
+   if ( SDL_WindowId == NULL ) {
+    SDL_SetError("Couldn't get user specified window");
+    return(-1);
+   }
+
+   /* DJM: we want all event's for the user specified
+   window to be handled by SDL.
+   */
+   //userWindowProc = (WNDPROCTYPE)GetWindowLongPtr(SDL_Window, GWLP_WNDPROC);
+   //rtv = SetWindowLongPtr(SDL_WindowId, GWLP_WNDPROC, (LONG_PTR)DefWindowProc);
+   //SDL_SetError("return = %d", rtv);
+  }
+ }
+
+ if (SDL_WindowId)
+ {
+  hwnd = SDL_WindowId;
+  SetWindowPos(hwnd, NULL, x, y, 0, 0, (SWP_NOCOPYBITS | SWP_NOSIZE));
+ }
+ else
+ {
+    hwnd =
+        CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL,
+                     SDL_Instance, NULL);
+ }

由于1.3版本的改变,只需要设置hwnd,不再象1.26那样还要处理消息循环相关的,具体可跟踪代码,在这后面有个函数:SetupWindowData里面的实现

QT中调用方法:
char windowid[32];
memset(windowid, 0, 32);
sprintf(windowid, "SDL_WINDOWID=0x%lx",  state->window_ids[i]); //window_ids[i]是QT中窗口的Wid
SDL_putenv(windowid);
//sprintf(windowid, "SDL_WINDOW_PARENTID=0x%lx",  state->window_ids[i+1]);
//SDL_putenv(windowid);

由于自己也没有深入地应用,在此只作入门介绍,具体应用还要需要进一步SDL熟悉。
在window下,开发者最好对win32及directshow比较了解,否则对后面的sdl_window,sdl_texture,sdl_overlay,render等会比较困惑. 至于双窗口之间如何通信等,个人没有去应用,感觉它不如QT实现便捷。
SDL (Simple DirectMedia Layer) 是一个跨平台的多媒体库,用于游戏和多媒体应用程序的开发。要在 Qt 中使用 SDL 2.0 播放视频,你需要将 SDL 库集成到 Qt 项目中,并实现视频渲染的功能。 以下是大致步骤: 1. **安装依赖**: - 安装 SDL 2.0 和相关开发包(如 SDL_image、SDL_ttf 等,取决于你的应用需要显示图片或文本)。 - 安装Qt 开发环境,确保已经配置了包含SDL支持的构建系统。 2. **在 Qt 项目中设置**: - 在`.pro`文件中添加对SDL和相关模块的支持: ```pro DEFINES += QT_NO_GRAPHICSVIEW LIBS += -lSDL2 -lSDL2_image -lSDL2_ttf # 或其他所需模块 INCLUDEPATH += /path/to/sdl/include # 将路径替换为实际的SDL头文件位置 ``` 3. **创建视频播放类**: 创建一个QObject派生的类,比如`SdldVideoPlayer`,并初始化SDL窗口视频渲染上下文。 ```cpp class SdlVideoPlayer : public QObject { Q_OBJECT private: SDL_Window* window; SDL_Renderer* renderer; // 添加其他必要的变量 public: SdlVideoPlayer(QWidget* parent = nullptr); ~SdlVideoPlayer(); void playVideo(const QString& filePath); }; ``` 4. **实现关键函数**: - 初始化窗口和渲染器: ```cpp SdlVideoPlayer::SdlVideoPlayer(QWidget* parent) : QWidget(parent), window(nullptr), renderer(nullptr) { // ... 初始化 SDL } // 销毁资源 SdlVideoPlayer::~SdlVideoPlayer() { stopVideo(); // 清理 SDL 资源 } void SdlVideoPlayer::playVideo(const QString& filePath) { // 加载视频,创建SDL_Texture等 // ... 使用 SDL_LoadBMP 或其他 API 加载视频 // ... 更新窗口内容 } ``` 5. **在Qt界面中使用**: - 在Qt UI中创建`SdlVideoPlayer`实例,并连接信号槽处理播放暂停、停止等操作。 注意,在实际项目中,可能会涉及到更多细节和错误处理。使用Qt的`QMovie`或者`QGraphicsVideoItem`结合SDL可以简化一些工作。此外,确保你在Qt主线程之外进行耗时的操作,因为Qt的核心事件循环会在主线程中阻塞。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值