obs_core_video_mix
+ -

obs_core_video_mix使用

2024-07-01 13 0

obs_core_video_mix使用在视频线程,其总的入口调用函数为output_frames()。

bool obs_graphics_thread_loop(struct obs_graphics_context *context)
{
...

    //GPU渲染并内容输出
    profile_start(output_frame_name);
    output_frames();
    profile_end(output_frame_name);
...
}

output_frames中枚举所有的obs_core_video_mix,并分别调用output_frame。
所以这里的obs_core_video_mix最多有两个,一个是主的视图obs_core_video_mix,另一个就是启用了OBS虚拟相机的obs_core_video_mix。

static inline void output_frames(void)
{
    pthread_mutex_lock(&obs->video.mixes_mutex);
    for (size_t i = 0, num = obs->video.mixes.num; i < num; i++) 
    {
        struct obs_core_video_mix *mix = obs->video.mixes.array[i];
        if (mix->view) 
        {
            output_frame(mix);
        }
        else 
        {
            obs->video.mixes.array[i] = NULL;
            obs_free_video_mix(mix);
            da_erase(obs->video.mixes, i);
            i--;
            num--;
        }
    }
    pthread_mutex_unlock(&obs->video.mixes_mutex);
}

在output_frame中,其调用render_video进行渲染到render_texure,再根据是否否大小一致进行转换到output_texture

static inline void render_video(struct obs_core_video_mix *video,
                bool raw_active, const bool gpu_active,
                int cur_texture)
{
...
    //先渲染到render_texture
    render_main_texture(video);
...
    if (raw_active || gpu_active) 
    {
        //渲染输出
        gs_texture_t *output_texture = render_output_texture(video);
    }
    ...
}

render_main_texture

render_main_texture函数如下:

static inline void render_main_texture(struct obs_core_video_mix *video)
{
    uint32_t base_width = video->ovi.base_width;
    uint32_t base_height = video->ovi.base_height;

    profile_start(render_main_texture_name);
    GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_MAIN_TEXTURE, render_main_texture_name);

//设置背景颜色
    struct vec4 clear_color;
    vec4_set(&clear_color, 0.0f, 0.0f, 0.0f, 0.0f);

//设置颜色空间及当前渲染目标纹理
    gs_set_render_target_with_color_space(video->render_texture, NULL, video->render_space);

//使用颜色清除背景空间
    gs_clear(GS_CLEAR_COLOR, &clear_color, 1.0f, 0);

//设置尺寸
    set_render_size(base_width, base_height);

//draw_callbacks
    pthread_mutex_lock(&obs->data.draw_callbacks_mutex);
    for (size_t i = obs->data.draw_callbacks.num; i > 0; i--)
    {
        struct draw_callback *const callback =    obs->data.draw_callbacks.array + (i - 1);
        callback->draw(callback->param, base_width, base_height);
    }
    pthread_mutex_unlock(&obs->data.draw_callbacks_mutex);

    /* In some cases we can reuse a previous mix's texture and save re-rendering everything */
    size_t reuse_idx;
    if (can_reuse_mix_texture(video, &reuse_idx))
        draw_mix_texture(reuse_idx);
    else
        obs_view_render(video->view);

    video->texture_rendered = true;

//rendered_callbacks
    pthread_mutex_lock(&obs->data.draw_callbacks_mutex);
    for (size_t i = 0; i < obs->data.rendered_callbacks.num; ++i)
    {
        struct rendered_callback *const callback =    &obs->data.rendered_callbacks.array[i];
        callback->rendered(callback->param);
    }
    pthread_mutex_unlock(&obs->data.draw_callbacks_mutex);

    GS_DEBUG_MARKER_END();
    profile_end(render_main_texture_name);
}

而render_output_texture的

static inline gs_texture_t *
render_output_texture(struct obs_core_video_mix *mix)
{
    struct obs_video_info *const ovi = &mix->ovi;
    gs_texture_t *texture = mix->render_texture;
    gs_texture_t *target = mix->output_texture;
    const uint32_t width = gs_texture_get_width(target);
    const uint32_t height = gs_texture_get_height(target);

    //尺寸不一样,需要转换
    if ((width == ovi->base_width) && (height == ovi->base_height))
        return texture;

    //转换
    return target;
}

0 篇笔记 写笔记

作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

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

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