D3D11
+ -

OBS-D3D9获取GPU渲染的最终图像数据

2024-05-16 31 0
  1. void output_frame(struct obs_core_video_mix *video)
  2. {
  3. struct video_data frame;
  4. bool frame_ready = 0;
  5. memset(&frame, 0, sizeof(struct video_data));
  6. ...
  7. profile_start(output_frame_render_video_name);
  8. GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_RENDER_VIDEO, output_frame_render_video_name);
  9. //渲染视频到纹理
  10. render_video(video, raw_active, gpu_active, cur_texture);
  11. GS_DEBUG_MARKER_END();
  12. profile_end(output_frame_render_video_name);
  13. if (raw_active) {
  14. profile_start(output_frame_download_frame_name);
  15. //使用frame保存视频数据的指针和linesize
  16. frame_ready = download_frame(video, prev_texture, &frame);
  17. profile_end(output_frame_download_frame_name);
  18. }
  19. }
  20. //从显卡的textuure中将数据map到video_data *frame中
  21. static inline bool download_frame(struct obs_core_video_mix *video,
  22. int prev_texture, struct video_data *frame)
  23. {
  24. if (!video->textures_copied[prev_texture])
  25. return false;
  26. for (int channel = 0; channel < NUM_CHANNELS; ++channel)
  27. {
  28. //每个gs_stagesurf_t *surface其实是一个通道的数据内容
  29. gs_stagesurf_t *surface =video->active_copy_surfaces[prev_texture][channel];
  30. if (surface)
  31. {
  32. if (!gs_stagesurface_map(surface, &frame->data[channel],&frame->linesize[channel]))
  33. return false;
  34. // 用于unmap_last_surface
  35. video->mapped_surfaces[channel] = surface;
  36. }
  37. }
  38. return true;
  39. }
  40. //通用函数回调指针,根据Directx或者OPENGL调用
  41. bool gs_stagesurface_map(gs_stagesurf_t *stagesurf, uint8_t **data,
  42. uint32_t *linesize)
  43. {
  44. graphics_t *graphics = thread_graphics;
  45. if (!gs_valid_p3("gs_stagesurface_map", stagesurf, data, linesize))
  46. return 0;
  47. return graphics->exports.gs_stagesurface_map(stagesurf, data, linesize);
  48. }
  49. //D3D11
  50. bool gs_stagesurface_map(gs_stagesurf_t *stagesurf, uint8_t **data,
  51. uint32_t *linesize)
  52. {
  53. D3D11_MAPPED_SUBRESOURCE map;
  54. if (FAILED(stagesurf->device->context->Map(stagesurf->texture, 0, D3D11_MAP_READ, 0, &map)))
  55. return false;
  56. *data = (uint8_t *)map.pData;
  57. *linesize = map.RowPitch;
  58. return true;
  59. }

对于obs->video.mixes每个obs_core_video_mix类型的成员
有NUM_TEXTURES个纹理,进行循环
有NUM_CHANNELS个通道,进行

  1. #define NUM_CHANNELS 8
  2. #define NUM_TEXTURES 2

从以上8x2个成员中取其中一个有效的用于保存umap.另外就是把数据保存在frame的data和linesize中。

  1. static inline void unmap_last_surface(struct obs_core_video_mix *video)
  2. {
  3. for (int c = 0; c < NUM_CHANNELS; ++c) {
  4. if (video->mapped_surfaces[c]) {
  5. gs_stagesurface_unmap(video->mapped_surfaces[c]);
  6. video->mapped_surfaces[c] = NULL;
  7. }
  8. }
  9. }

0 篇笔记 写笔记

作者信息
站长漫谈
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!