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綁定繪製窗口

 

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