下面是spice-server-0.14.0開啓之後初始化視頻編碼器並進行編碼選擇,之後傳輸圖片至客戶端spice-gtk的函數調用過程:
從reds.c開始:
spice_server_new 注:每一個虛擬機都有一個spice_server_new
spice_server_init
1、do_spice_init
1、main_channel_new input_channel_new
2、reds->allow_multiple_clients 設置允許多個客戶端同時連接
2、reds_set_video_codecs_from_string 設置默認的視頻編碼方式
1、一個二維數組代表所有的默認編碼方式 default_video_codecs[] = "spice:mjpeg;" "gstreamer:mjpeg;gstreamer:h264;gstreamer:vp8;gstreamer:vp9;"
2、創建video_codecs是一個g_array數組裏面解析了上面的字符串一個一個放入這個數組中,最後賦值給reds中的video_codecs
3、RedVideoCodec new_codec; //找到配置信息之後初始化這個結構體
new_codec.create = video_encoder_procs[encoder_index]; //左邊是函數指針,右邊是實現方法(這裏其實就是編碼器的初始化)
new_codec.type = video_codec_names[codec_index].id; //左邊是協議枚舉變量,右邊是reds全局數組中的實際值
new_codec.cap = video_codec_caps[codec_index]; //和第二個值類似
4、reds->config->video_codecs = video_codecs;
red-worker.c->display_channel_new
display_channel.c
1、display_channel_new
1、設置video_codecs作爲他的屬性,從reds中的reds_get_video_codecs獲取
2、display_channel_get_property獲取屬性解出編碼方式,如:"spice:mjpeg;"
2、display_channel_class_init
1、channel_class->handle_message = dcc_handle_message;設置接收客戶端信息回調函數
2、channel_class->send_item = dcc_send_item;設置發送客戶端信息回調函數,
注:其實這裏具體誰發送誰接收我們就不細看了,調用者是個未知數,我們下面只看調用的時候做了什麼
3、display_channel_constructed
1、display_channel_init_video_streams(video-stream.c裏面)
4、display_channel_process_draw 這裏開始拿到數據以後解析是視頻還是普通圖片發給客戶端
1、display_channel_add_drawable 這裏其實是一個識別視頻的過程,檢測圖片的某些特徵是否是視頻的特徵
1、current_add
1、current_add_equal
1、video_stream_maintenance(video-stream.c裏面)
display_channel.c->video-stream.c
video-stream.c
1、display_channel_init_video_streams
2、video_stream_maintenance
1、video_stream_add_frame
1、is_stream_start判斷是否開始視頻
1、display_channel_create_stream創建視頻
1、初始化一系列信息
2、dcc_create_stream 這裏面是填充dcc.c裏面的agent這個結構體
1、dcc_create_video_encoder 根據信息創建編碼器等信息
red_worker.c->dcc_new
dcc.c
1、display_channel_client_constructed
1、dcc_init_stream_agents 視頻初始化
2、image_encoders_init 圖片初始化
2、dcc_handle_message這裏接收來自客戶端的信息
1、dcc_handle_preferred_video_codec_type處理客戶端發送過來的視頻編碼方式並解析
1、dcc_update_preferred_video_codecs解析完之後設置,解析出來應該是gstreamer:h264之類的東西
2、賦值到RedVideoCodec這個結構體中下次視頻編碼就用這個編
具體客戶端調用->dcc_send.c裏面的指令
dcc_send.c
1、dcc_send_item這裏用來發送信息給客戶端
1、marshall_qxl_drawable 普通顯示數據指令,此處會將圖片進行壓縮傳輸(會選擇是否有損),如果如果圖片屬於視頻,也在此進行傳輸
2、marshall_stream_start 開始視頻指令