frame数据据渲染概述
2024-07-03
28
0
通过前面一节可知,所谓的obs_source_get_frame其实在整个渲染过程中,是有两个步骤的。
第一是是通过async_tick函数中通过get_closest_frame来获取frame,存储于cur_async_frame
第二是通过render_source时,调用obs_source_update_async_video更新数据到纹理中,然后调用obs_source_render_async_video进行渲染。
render_video源码如下:
static inline void render_video(obs_source_t *source)
{
if (source->info.type != OBS_SOURCE_TYPE_FILTER &&
(source->info.output_flags & OBS_SOURCE_VIDEO) == 0) {
if (source->filter_parent)
obs_source_skip_video_filter(source);
return;
}
if (source->info.type == OBS_SOURCE_TYPE_INPUT
&& (source->info.output_flags & OBS_SOURCE_ASYNC) != 0
&& !source->rendering_filter)
{
if (deinterlacing_enabled(source))
deinterlace_update_async_video(source);
//更输出源的frame数据到相应的纹理中
obs_source_update_async_video(source);
}
if (!source->context.data || !source->enabled)
{
if (source->filter_parent)
obs_source_skip_video_filter(source);
return;
}
GS_DEBUG_MARKER_BEGIN_FORMAT(GS_DEBUG_COLOR_SOURCE,
get_type_format(source->info.type),
obs_source_get_name(source));
if (source->filters.num && !source->rendering_filter)
obs_source_render_filters(source);
else if (source->info.video_render)
obs_source_main_render(source);
else if (source->filter_target)
obs_source_video_render(source->filter_target);
else if (deinterlacing_enabled(source))
deinterlace_render(source);
else
//异步渲染
obs_source_render_async_video(source);
GS_DEBUG_MARKER_END();
}
渲染涉及到两个问题:第一个是格式的转换。第二是渲染的过程的。
格式的转换
格式的转换是通过着色器实现的,最终输出的是GS_BGRX或者GS_BGRA的纹理。即所有其它格式如YUV等最终必须转换成BGRX或者BGRA的纹理。
纹理的创建是通过check_to_swap_bgrx_bgra实现的。
格式的转换是通过update_async_texrender中通过调用着色器format_conversion.effect相技的pass实现的。
渲染
转换之后是RGBX或者RGBA了,所以只有frame->data[0], frame->linesize[0]了。故调用gs_texture_set_image进行渲染到纹理。