下面是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 开始视频指令