OBS-D3D9获取GPU渲染的最终图像数据
2024-05-16
30
0
void output_frame(struct obs_core_video_mix *video)
{
struct video_data frame;
bool frame_ready = 0;
memset(&frame, 0, sizeof(struct video_data));
...
profile_start(output_frame_render_video_name);
GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_RENDER_VIDEO, output_frame_render_video_name);
//渲染视频到纹理
render_video(video, raw_active, gpu_active, cur_texture);
GS_DEBUG_MARKER_END();
profile_end(output_frame_render_video_name);
if (raw_active) {
profile_start(output_frame_download_frame_name);
//使用frame保存视频数据的指针和linesize
frame_ready = download_frame(video, prev_texture, &frame);
profile_end(output_frame_download_frame_name);
}
}
//从显卡的textuure中将数据map到video_data *frame中
static inline bool download_frame(struct obs_core_video_mix *video,
int prev_texture, struct video_data *frame)
{
if (!video->textures_copied[prev_texture])
return false;
for (int channel = 0; channel < NUM_CHANNELS; ++channel)
{
//每个gs_stagesurf_t *surface其实是一个通道的数据内容
gs_stagesurf_t *surface =video->active_copy_surfaces[prev_texture][channel];
if (surface)
{
if (!gs_stagesurface_map(surface, &frame->data[channel],&frame->linesize[channel]))
return false;
// 用于unmap_last_surface
video->mapped_surfaces[channel] = surface;
}
}
return true;
}
//通用函数回调指针,根据Directx或者OPENGL调用
bool gs_stagesurface_map(gs_stagesurf_t *stagesurf, uint8_t **data,
uint32_t *linesize)
{
graphics_t *graphics = thread_graphics;
if (!gs_valid_p3("gs_stagesurface_map", stagesurf, data, linesize))
return 0;
return graphics->exports.gs_stagesurface_map(stagesurf, data, linesize);
}
//D3D11
bool gs_stagesurface_map(gs_stagesurf_t *stagesurf, uint8_t **data,
uint32_t *linesize)
{
D3D11_MAPPED_SUBRESOURCE map;
if (FAILED(stagesurf->device->context->Map(stagesurf->texture, 0, D3D11_MAP_READ, 0, &map)))
return false;
*data = (uint8_t *)map.pData;
*linesize = map.RowPitch;
return true;
}
对于obs->video.mixes每个obs_core_video_mix类型的成员
有NUM_TEXTURES个纹理,进行循环
有NUM_CHANNELS个通道,进行
#define NUM_CHANNELS 8
#define NUM_TEXTURES 2
从以上8x2个成员中取其中一个有效的用于保存umap.另外就是把数据保存在frame的data和linesize中。
static inline void unmap_last_surface(struct obs_core_video_mix *video)
{
for (int c = 0; c < NUM_CHANNELS; ++c) {
if (video->mapped_surfaces[c]) {
gs_stagesurface_unmap(video->mapped_surfaces[c]);
video->mapped_surfaces[c] = NULL;
}
}
}