D3D11
+ -

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;
        }
    }
}

0 篇笔记 写笔记

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

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

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