OBS从渲染到推流过程分析

obs中将渲染和生产推流数据,推流分为三个线程,整个过程交织在一起,不容易理清整个过程。下面先分别对三个过程进行分析,然后将整个过程链接起来: 

1.渲染:

//初始化
Obs.c: obs_reset_video 
//设置画布
Obs.c: obs_init_graphics
graphics.c : gs_create //一般创建使用opengl作为绘制设备
graphics.c : gs_enter_context 创建渲染画布thread_graphics
//初始化video
obs.c : obs_init_video

//开启渲染线程
obs.c : thread: obs_graphics_thread

obs-vidio.c: obs_graphics_thread //绘制线程

obs-vidio.c : while
{
    tick_sources: 拿源数据,(window capture, image ,camera…)
    output_frame; 绘制到texture上, 并将绘制后的帧数据缓存,等待发送线程获取
 	render_displays;//将opengl textture数据绘制到窗口
} 

Output_frame分支:
{
    obs-vidio.c : render_video
    {
        obs-vidio.c : render_main_texture
        obs-view.c : obs_view_render
        obs-source.c : obs_source_video_render(source)
        obs-source.c : render_video(source)
        obs-source.c : obs_source_render_async_video(source)
        obs-source.c : obs_source_draw_async_texture(source)
        obs-source.c : obs_source_draw_texture(source)
        graphics.c : gs_draw_sprite 绘制在thread_graphics
        obs-vidio.c: obs_graphics_thread
        obs-vidio.c: render_displays
        obs-vidio.c: render_display
        obs-display.c: render_display_begin
        graphics.c : gs_begin_scene
    }
	output_video_data //将opengl帧数据缓存,等待推送线程获取}
}
render_displays分支:
{
    obs-display.c : render_display	 //将opengl数据copy给窗口
}

2.生产推流数据:

//初始化
Obs.c : obs_reset_video 
//初始化video
obs.c : obs_init_video
video-io.c: video_output_open
//开启数据生产线程
video-io.c: video_thread
//
video-io.c: video_output_cur_frame
//生产的数据放入发送线程的发送队列中
video-io.c: input->callback

3.推流:

//加载rtmp插件模块
Obs-outputs.c : obs_module_load
//注册输出自定义流,rtmp_output_info中包含了输出流的线程启动函数.start
Obs-outputs.c : obs_register_output(&rtmp_output_info)

推流过程:
//创建输出
Obs-outputs.c : obs_output_create => output->video = obs->getvideo()
//绑定输出信号
Obs-outputs.c : obs_output_get_signal_handler
//
Obs-outputs.c : obs_output_set_service => output->service = service

---------------------------------------------------------------------------------------
//启动输出流线程
Obs-outputs.c :obs_output_start
Obs-outputs.c :obs_output_actual_start
//启动rtmp输出流线程
rtmp-stream.c :rtmp_output_info.start => rtmp_stream_start
rtmp-stream.c : thread : connect_thread
rtmp-stream.c try_connect
rtmp-stream.c init_send
//创建发送线程
rtmp-stream.c thread: send_thread
rtmp-stream.c obs_output_begin_data_capture
rtmp-stream.c hook_data_capture
//为obs.video.input绑定回调,生产的video数据可以通过回调添加到发送队列
rtmp-stream.c start_raw_video  callback: default_raw_video_callback

对以上的分析,obs_reset_video的调用非常关键,这个从obs中的demo中就可以看到,最先调用的就是这个obs接口,这个接口启动了两个线程,一个用于渲染和存储渲染结果,一个用于消费,将渲染后的结果发送给推送线程。

分析窗口捕获Win-Capture 

Dc-capture:
dc = CreateCompatibleDC(NULL);
bmp = CreateDIBSection(dc, &bi,DIB_RGB_COLORS, (void**)&bits,NULL, 0);
SelectObject(dc, bmp);

hdc_target = GetDC(window);
BitBlt(hdc, 0, 0, width, height,hdc_target, x, y, SRCCOPY);

Bits中是窗口的位图数据

window_capture_info
.video_tick     = wc_tick, 采集窗口数据
.video_render   = wc_render, 将采集数据绘制到texture中

 

总结:

Obs_graphics_thread线程做与图像绘制相关的任务

Tick_source -> .vidio_tick 采集源数据

Output_Frame -> .video_render 将采集数据渲染到texture中, 顺便将帧数据缓存

Display -> 将texture数据绘制到显示窗口上 obs_display_create绑定绘制窗口

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章