sence的item类型ffmpeg_source渲染
2024-11-19
0
0
1.获取到obs_source_frame
2.最多支持MAX_AV_PLANES即8个的图像分量,一般最多是YUV,分别对各分量调用gs_texture_set_image
3.不同的图像分量创建不同的teture,这些texture存在于source->async_textures
4.对这些不同的纹理,进行ID3D11DeviceContext::map映射,复制数据到纹理空间中
void gs_texture_set_image(gs_texture_t *tex, const uint8_t *data,
uint32_t linesize, bool flip)
{
uint8_t *ptr;
uint32_t linesize_out;
size_t row_copy;
size_t height;
if (!gs_valid_p2("gs_texture_set_image", tex, data))
return;
if (!gs_texture_map(tex, &ptr, &linesize_out))
return;
row_copy = (linesize < linesize_out) ? linesize : linesize_out;
height = gs_texture_get_height(tex);
if (flip) {
uint8_t *const end = ptr + height * linesize_out;
data += (height - 1) * linesize;
while (ptr < end) {
memcpy(ptr, data, row_copy);
ptr += linesize_out;
data -= linesize;
}
} else if (linesize == linesize_out) {
memcpy(ptr, data, row_copy * height);
} else {
uint8_t *const end = ptr + height * linesize_out;
while (ptr < end) {
memcpy(ptr, data, row_copy);
ptr += linesize_out;
data += linesize;
}
}
gs_texture_unmap(tex);
}
5.这样ffmepg解析出的mp4视频的YUV(VIDEO_FORMAT_I420)图像数据位于source->async_textures纹理中。
6.根据纹理数据格式,先用合适的tech,将YUV转换成RGBA,渲染至render_tsource->async_texrender
7。如果增加有滤镜,再次调用滤镜的进行处理
- 亮度键:luma_key_filter
- 图像掩码/混合:mask_filter
- 应用 LUT:clut_filter
- 渲染延迟:gpu_delay
- 滚动:scroll_filter
- 缩放比例:scale_filter
- 色值:color_key_filter
- 色度键:chroma_key_filter
- 色彩校正:color_filter
- 裁剪/填充:crop_filter
- 锐化:sharpness_filter
8。最后输出使用obs_source_render_async_video调用default.effect中的Draw或DrawNonlinearAlpha渲染,使用函数为obs_source_draw_texture。渲染的原理是将render_tsource->async_texrender作为tech的image参数传入,最终渲染至video->render_texture上。
- 了解了OBS的渲染原理之后,可以先用CPU模拟实现类似这样的渲染功能
- 再学习D3D11,使用GPU进行格式的转化与渲染。故对D3D11需要很熟悉,另外可以先使用OBS的渲染流程,将保存的数据使用一些特殊工具来打开看效果。