OBS
+ -

OSB线程-obs_graphics_thread

2024-04-26 4 0

根据OSB官方文档介绍,Libobs库有3个线程,分别为:osb_graphic线程,obs_video线程和obs_audio线程。

对于任意一个应用软件,其线程架构的设计,可以准确地了解一个应用软件的设计思路,更进一步地理解应用软件的框架设计。
另外,理解了此类软件的框架设计,吸取别人优秀的设计思想,也可以帮助我们设计更加合理、健状、清晰的自己的同类软件。也以,理清这些东西,具有深刻的意义。其实这也从另一方面验证了为什么此类开源软件在介绍自己时,总从线程来介绍起的。

obs_graphics_thread

obs_graphics_thread专门用于libobs视频的渲染。
obs_graphics_thread的函数名obs_graphics_thread,其非APPLE版的创建方式如下:

    errorcode = pthread_create(&video->video_thread, NULL,obs_graphics_thread, obs);

其调用关系如下:

- main-QT入口函数
- int run_program(fstream &logFile, int argc, char *argv[])
    - OBSBasic::OBSInit()
    - int OBSBasic::ResetVideo()
    ------libobs-------
        - int AttemptToResetVideo(struct obs_video_info *ovi)
        - int obs_reset_video(struct obs_video_info *ovi)
         - int obs_init_video(struct obs_video_info *ovi)
            - pthread_create(obs_graphics_thread)

类的继承关系如下:

class OBSBasic : public OBSMainWindow 
class OBSApp : public QApplication

故OBSApp是应用类,而OBSBasic是主窗口类,所以初始化就和MFC类似了

bool OBSApp::OBSInit()
{
    mainWindow = new OBSBasic();
    mainWindow->OBSInit();
}

obs_graphics_thread线程的源代码如下:

void *obs_graphics_thread(void *param)
{
    uint64_t last_time = 0;
    uint64_t interval = video_output_get_frame_time(obs->video.video);
    uint64_t frame_time_total_ns = 0;
    uint64_t fps_total_ns = 0;
    uint32_t fps_total_frames = 0;

    obs->video.video_time = os_gettime_ns();

    os_set_thread_name("libobs: graphics thread");

    const char *video_thread_name =
        profile_store_name(obs_get_profiler_name_store(),
            "obs_graphics_thread(%g"NBSP"ms)", interval / 1000000.);
    profile_register_root(video_thread_name, interval);

    srand((unsigned int)time(NULL));

    while (!video_output_stopped(obs->video.video)) {
        uint64_t frame_start = os_gettime_ns();
        uint64_t frame_time_ns;

        profile_start(video_thread_name);

        profile_start(tick_sources_name);
        last_time = tick_sources(obs->video.video_time, last_time);
        profile_end(tick_sources_name);

        profile_start(render_displays_name);
        render_displays();
        profile_end(render_displays_name);

        profile_start(output_frame_name);
        output_frame();
        profile_end(output_frame_name);

        frame_time_ns = os_gettime_ns() - frame_start;

        profile_end(video_thread_name);

        profile_reenable_thread();

        video_sleep(&obs->video, &obs->video.video_time, interval);

        frame_time_total_ns += frame_time_ns;
        fps_total_ns += (obs->video.video_time - last_time);
        fps_total_frames++;

        if (fps_total_ns >= 1000000000ULL) {
            obs->video.video_fps = (double)fps_total_frames /
                ((double)fps_total_ns / 1000000000.0);
            obs->video.video_avg_frame_time_ns =
                frame_time_total_ns / (uint64_t)fps_total_frames;

            frame_time_total_ns = 0;
            fps_total_ns = 0;
            fps_total_frames = 0;
        }
    }

    UNUSED_PARAMETER(param);
    return NULL;
}

obs_graphics_thread使用render_displays函数对加入的资源进行渲染并显示到画面窗口中。这里使用的是d3d11或都opengl,对应于libobs-d3d11和libobs-opengl。
同样的output_frame,用于输出视频帧。

由于本人对这一块不熟悉,只能当前烂尾了。

0 篇笔记 写笔记

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

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

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