2025年2月25日 星期二 甲辰(龙)年 腊月廿五 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > VC/VC++

ffmpeg H264转码为RGB24,并使用GDI进行播放

时间:03-13来源:作者:点击数:46

最近在优化视频播放,原先使用.net+ocx(DirectX)进行接收视频流并展示到前端界面,在使用的过程中发现视频窗口多的话,容易分配内存失败并占用内存、GPU、CPU过高,不能满足客户的需要;

后来在优化的过程中,发现是使用DirextX导致的,在使用下面语句创建设备时经常创建失败,并且发现内存增长跟使用DirextX有关 。

  • d3d9->CreateDevice(D3DADAPTER_DEFAULT,deviceType,hwnd,vp,&d3dpp,device);

采取了第二种方案进行优化,就想到了使用GDI进行播放,并且操作也比使用DirectX更加简单。

  • if (m_pSwsContext == NULL)
  • {
  • m_pSwsContext = sws_getContext(w,h,m_pCodecContext->pix_fmt,w, h,AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR,NULL, NULL, NULL);
  • av_image_alloc(m_pFrameRGB->data, m_pFrameRGB->linesize,w, h, AV_PIX_FMT_BGR24,1);
  • }
  • sws_scale(m_pSwsContext,(uint8_t const * const *)m_pSrcFrame->data,
  • m_pSrcFrame->linesize, 0, h, m_pFrameRGB->data,m_pFrameRGB->linesize);
  • GetClientRect(m_hWnd, &recWindow);//获取窗口大小
  • int width = recWindow.right - recWindow.left; //窗口的宽度
  • int height = recWindow.bottom - recWindow.top; //窗口的高度
  • HDC hdc = GetDC(m_hWnd);
  • //转换成RGB24
  • BITMAPINFO m_bmphdr = { 0 };
  • DWORD dwBmpHdr = sizeof(BITMAPINFO);
  • //24bit
  • m_bmphdr.bmiHeader.biBitCount = 24;
  • m_bmphdr.bmiHeader.biClrImportant = 0;
  • m_bmphdr.bmiHeader.biSize = dwBmpHdr;
  • m_bmphdr.bmiHeader.biSizeImage = 0;
  • m_bmphdr.bmiHeader.biWidth = w;
  • //Notice: BMP storage pixel data in opposite direction of Y-axis (from bottom to top).
  • //So we must set reverse biHeight to show image correctly.m_bmphdr.bmiHeader.biHeight = -h;
  • m_bmphdr.bmiHeader.biXPelsPerMeter = 0;
  • m_bmphdr.bmiHeader.biYPelsPerMeter = 0;
  • m_bmphdr.bmiHeader.biClrUsed = 0;
  • m_bmphdr.bmiHeader.biPlanes = 1;
  • m_bmphdr.bmiHeader.biCompression = BI_RGB;
  • //Draw data
  • //YUV420P data convert to another buffer
  • SetStretchBltMode(hdc, STRETCH_HALFTONE);
  • int nResult = StretchDIBits(hdc,
  • 0, 0,
  • width, height,
  • 0, 0,
  • w, h,
  • m_pFrameRGB->data[0],
  • &m_bmphdr,
  • DIB_RGB_COLORS,
  • SRCCOPY);
  • //DeleteDC(hdc);
  • ReleaseDC(m_hWnd, hdc);
  • av_frame_unref(m_pSrcFrame);
  • sws_freeContext(m_pSwsContext);

使用上述代码展示视频后,内存占用没有原来的的多了,并且使用到的GPU很少(一般客户那里的电脑没有GPU),视频十分流畅;上述代码中 SetStretchBltMode(hdc, STRETCH_HALFTONE);这一句非常重要,在测试阶段发现视频失真非常严重,导致画面十分难看,加上了这段代码后,视频质量提升了不少,播放效果大大提升。在使用ffmpeg的过程中,一定要小心内存泄漏,该释放的一定要释放。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门