obs_source_frame
+ -

obs_source_get_frame

2024-07-03 3 0

obs_source_get_frame用于获取一个输入源的frame数据。其大致被调用过程如下:

  • scene_video_render
    • render_item(item)
      • obs_source_video_render(item->source);
        • render_video(source)
          • obs_source_update_async_video(source);//更输出源的frame数据到相应的纹理中
            • obs_source_get_frame(source);
            • update_async_textures //实际应是将frame的数据复制到纹理中
            • obs_source_release_frame(source, frame);//释放frame

obs_source_get_frame源码如下:

struct obs_source_frame *obs_source_get_frame(obs_source_t *source)
{
    struct obs_source_frame *frame = NULL;

    if (!obs_source_valid(source, "obs_source_get_frame"))
        return NULL;

    pthread_mutex_lock(&source->async_mutex);

    frame = source->cur_async_frame;
    source->cur_async_frame = NULL;

    if (frame) {
        os_atomic_inc_long(&frame->refs);
    }

    pthread_mutex_unlock(&source->async_mutex);

    return frame;
}

这里看到,其实是获取的是cur_async_frame成员,而cur_async_frame成员是在async_tick函数中通过get_closest_frame获取设置的。

static void async_tick(obs_source_t *source)
{
    uint64_t sys_time = obs->video.video_time;

    pthread_mutex_lock(&source->async_mutex);

    if (deinterlacing_enabled(source)) {
        deinterlace_process_last_frame(source, sys_time);
    }
    else
    {
        if (source->cur_async_frame)
        {
            remove_async_frame(source, source->cur_async_frame);
            source->cur_async_frame = NULL;
        }
        //设置cur_async_frame内容
        source->cur_async_frame = get_closest_frame(source, sys_time);
    }

    source->last_sys_timestamp = sys_time;

    if (deinterlacing_enabled(source))
        filter_frame(source, &source->prev_async_frame);
    filter_frame(source, &source->cur_async_frame);

    if (source->cur_async_frame)
        source->async_update_texture =    set_async_texture_size(source, source->cur_async_frame);

    pthread_mutex_unlock(&source->async_mutex);
}

而async_tick的调用是在obs_source_video_tick函数中调用的,而async_tick又是被tick_sources调用的。

bool obs_graphics_thread_loop(struct obs_graphics_context *context)
{
    context->last_time = tick_sources(obs->video.video_time, context->last_time)
    {
        obs_source_video_tick(s, seconds)
        {
            static void async_tick(obs_source_t *source)
            {
                //设置cur_async_frame内容
                source->cur_async_frame = get_closest_frame(source, sys_time);
            }
        }
    }
}

所以对于异步的设备,其tick_sources其实是用于进行时间戳同步,用于准备数据源的,当准备好时,再调用该设备的render时,会直接使用准备好的纹理进行渲染。

0 篇笔记 写笔记

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

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

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