SDL2.0在mfc窗口中显示yuv的一种方法

DWORD ThreadFun()
{
       //用mfc窗口句柄创建一个sdl window
       SDL_Window * pWindow = SDL_CreateWindowFrom( (void *)( GetDlgItem(IDC_STATIC1)->GetSafeHwnd() ) );

       SDL_Rect sdlRT;
       sdlRT.h = 288;
       sdlRT.w = 352;
       sdlRT.x = 0;
       sdlRT.y = 0;

       SDL_Rect dstRT;
       dstRT.h = 288;
       dstRT.w = 352;
       dstRT.x = 0;
       dstRT.y = 0;

       int iW = 352;
       int iH = 288;
       char szData[352*288*2] = {0};

       char szPrint[256] = {0};
     
       //计算yuv一行数据占的字节数
       int iPitch = iW*SDL_BYTESPERPIXEL(SDL_PIXELFORMAT_YV12);     

       int iWidth = 0;
       int iHeight = 0;
       SDL_GetWindowSize( pWindow, &iWidth, &iHeight );
       dstRT.h = iHeight;
       dstRT.w = iWidth;

       //获取当前可用画图驱动 window中有3个,第一个为d3d,第二个为opengl,第三个为software
       int iii = SDL_GetNumRenderDrivers();
       //创建渲染器,第二个参数为选用的画图驱动,0代表d3d
       SDL_Renderer * pRender = SDL_CreateRenderer( pWindow, 0, SDL_RENDERER_ACCELERATED );
       sprintf( szPrint, "%s", SDL_GetError());

       SDL_RendererInfo info;
       SDL_GetRendererInfo(pRender, &info);

       SDL_GetRenderDriverInfo(0, &info);       //d3d
       SDL_GetRenderDriverInfo(1, &info);       //opgl
       SDL_GetRenderDriverInfo(2, &info);       //software

       char szInfo[256] = {0};
       sprintf(szInfo, "%s", info.name);
       sprintf( szPrint, "%s", SDL_GetError());

       //创建纹理
       SDL_Texture * pTexture = SDL_CreateTexture( pRender,SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, iW, iH );


       FILE * pFile = fopen( "d:\\cap1.yuv", "rb" );

       if ( pFile == NULL )
       {
              int u = 0;
       }


       //读yuv文件,该文件中存放的数据尺寸为 352*288的yv12数据
       while ( fread( szData, 1, iW*iH*3/2, pFile ) != NULL )
       {
              int i = SDL_UpdateTexture( pTexture, &sdlRT, szData, iPitch );
              SDL_RenderClear( pRender );
              SDL_RenderCopy( pRender, pTexture, &sdlRT, &dstRT );
              SDL_RenderPresent( pRender );

              Sleep(40);
       }

       fclose(pFile);


       if ( pTexture != NULL )
       {
              SDL_DestroyTexture( pTexture );
              pTexture = NULL       ;
       }

       if ( pRender != NULL )
       {
              SDL_DestroyRenderer( pRender );
              pRender = NULL;
       }


       if ( NULL != pWindow )
       {
              SDL_DestroyWindow( pWindow );
              pWindow = NULL;
       }

}
注意在SDL_CreateWindowFrom中sdl将窗口的消息处理函数地址给改写成sdl的函数了(在sdl源文件中SetupWindowData()此函数内修改),
SDL2.0在mfc窗口中显示yuv的一种方法 - airmanisvip - 我的博客

同时在SDL_Destroy函数中会恢复hwnd默认消息处理函数,如果不希望sdl参与消息处理,可将SetWindowLongPtr注销掉

对SDL的使用还在摸索中,不能保证上述知识全部正确,如哪位仁兄发现问题,请留言更正,再次谢过了!
SDL (Simple DirectMedia Layer) 是一个跨平台的多媒体库,用于处理音频、视频输入输出等,而 Qt 则是一个强大的 C++ 应用程序框架。要将 PJSUA 接收的视频流通过 SDL 显示到 Qt 窗口,你需要结合两者以及一些底层编程知识。以下是一个简化的代码示例,它假设你已经有了一个基本的 PJSUA 实例并且接收到视频数据: ```cpp #include <QApplication> #include <QQuickView> #include <QQmlEngine> #include "pjmedia.h" #include "sdl.h" // 假设 pjmedia_video_data_t 是从 PJSUA 获取到的视频数据结构 class VideoRenderer : public QRunnable { public: void run() { // 获取PJSUA提供的视频数据 pjmedia_video_data_t video_data = ...; // 初始化SDL if (! SDL_Init(SDL_INIT_VIDEO)) { qDebug() << "SDL initialization failed: " << SDL_GetError(); return; } // 创建渲染窗口 SDL_Window* sdl_window = SDL_CreateWindow( "Video Display", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, video_data.width, video_data.height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE ); if (!sdl_window) { qDebug() << "Failed to create SDL window: " << SDL_GetError(); SDL_Quit(); return; } // 获取窗口的渲染上下文 SDL_Renderer* renderer = SDL_CreateRenderer(sdl_window, -1, 0); if (!renderer) { qDebug() << "Failed to create SDL renderer: " << SDL_GetError(); SDL_DestroyWindow(sdl_window); SDL_Quit(); return; } // 渲染视频帧到窗口 while (true) { Uint8* pixels = static_cast<Uint8*>(video_data.buf); SDL_UpdateTexture(renderer, NULL, pixels, video_data.size); SDL_RenderClear(renderer); SDL_RenderCopy(renderer, video_data.texture, NULL, NULL); SDL_RenderPresent(renderer); // 更新循环直到有新的视频帧可用或者PJSUA关闭 pj_status_t status = pjsua_vid_get_next_frame(video_data); if (status != PJ_SUCCESS) { break; } } // 清理资源并退出SDL SDL_DestroyRenderer(renderer); SDL_DestroyWindow(sdl_window); SDL_Quit(); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); // 初始化PJSUA和视频处理 PJSua pj_sua; VideoRenderer* video_task = new VideoRenderer(); // 运行视频渲染任务 QObject::connect(&pj_sua, &PJSua::onIncomingCall, video_task, &VideoRenderer::run); pj_sua.start(); QQmlEngine engine; QQmlContext *context = engine.rootContext(); context->setContextProperty("window", qobject_cast<QObject*>(app.mainWindow())); QQmlApplicationEngine engine_qt; engine_qt.load(QUrl(QStringLiteral("qrc:/main.qml"))); if (!engine_qt.waitForInitialization(5000)) { qDebug() << "Failed to load QML file"; return -1; } return app.exec(); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值