obs视频参数配置
2024-04-26
47
0
由于本人对高级图形编程从未接触过,故为学习OBS也需要浅浅的了解一下。
OBS关于图形配置及相关的回调函数调用,由一个结构体obs_video_info主载。
struct obs_video_info {
#ifndef SWIG
/**
* Graphics module to use (usually "libobs-opengl" or "libobs-d3d11")
*/
const char *graphics_module;
#endif
uint32_t fps_num; /**< Output FPS numerator */
uint32_t fps_den; /**< Output FPS denominator */
uint32_t base_width; /**< Base compositing width */
uint32_t base_height; /**< Base compositing height */
uint32_t output_width; /**< Output width */
uint32_t output_height; /**< Output height */
enum video_format output_format; /**< Output format */
/** Video adapter index to use (NOTE: avoid for optimus laptops) */
uint32_t adapter;
/** Use shaders to convert to different color formats */
bool gpu_conversion;
enum video_colorspace colorspace; /**< YUV type (if YUV) */
enum video_range_type range; /**< YUV range (if YUV) */
enum obs_scale_type scale_type; /**< How to scale if scaling */
};
关于这些参数的设由在ResetVideo中设置,其参数来源于配置文件和默认参数。
int OBSBasic::ResetVideo()
{
if (outputHandler && outputHandler->Active())
return OBS_VIDEO_CURRENTLY_ACTIVE;
ProfileScope("OBSBasic::ResetVideo");
struct obs_video_info ovi;
int ret;
GetConfigFPS(ovi.fps_num, ovi.fps_den);
const char *colorFormat =config_get_string(basicConfig, "Video", "ColorFormat");
const char *colorSpace = config_get_string(basicConfig, "Video", "ColorSpace");
const char *colorRange =config_get_string(basicConfig, "Video", "ColorRange");
ovi.graphics_module = App()->GetRenderModule();
ovi.base_width =(uint32_t)config_get_uint(basicConfig, "Video", "BaseCX");
ovi.base_height =(uint32_t)config_get_uint(basicConfig, "Video", "BaseCY");
ovi.output_width =(uint32_t)config_get_uint(basicConfig, "Video", "OutputCX");
ovi.output_height =(uint32_t)config_get_uint(basicConfig, "Video", "OutputCY");
ovi.output_format = GetVideoFormatFromName(colorFormat);
ovi.colorspace = GetVideoColorSpaceFromName(colorSpace);
ovi.range = astrcmpi(colorRange, "Full") == 0 ? VIDEO_RANGE_FULL: VIDEO_RANGE_PARTIAL;
ovi.adapter =config_get_uint(App()->GlobalConfig(), "Video", "AdapterIdx");
ovi.gpu_conversion = true;
ovi.scale_type = GetScaleType(basicConfig);
if (ovi.base_width < 32 || ovi.base_height < 32) {
ovi.base_width = 1920;
ovi.base_height = 1080;
config_set_uint(basicConfig, "Video", "BaseCX", 1920);
config_set_uint(basicConfig, "Video", "BaseCY", 1080);
}
if (ovi.output_width < 32 || ovi.output_height < 32)
{
ovi.output_width = ovi.base_width;
ovi.output_height = ovi.base_height;
config_set_uint(basicConfig, "Video", "OutputCX",ovi.base_width);
config_set_uint(basicConfig, "Video", "OutputCY",ovi.base_height);
}
ret = AttemptToResetVideo(&ovi);
if (ret == OBS_VIDEO_CURRENTLY_ACTIVE) {
blog(LOG_WARNING, "Tried to reset when already active");
return ret;
}
if (ret == OBS_VIDEO_SUCCESS) {
ResizePreview(ovi.base_width, ovi.base_height);
if (program)
ResizeProgram(ovi.base_width, ovi.base_height);
float sdr_white_level = (float)config_get_uint(basicConfig, "Video", "SdrWhiteLevel");
float hdr_nominal_peak_level = (float)config_get_uint(basicConfig, "Video","HdrNominalPeakLevel");
obs_set_video_levels(sdr_white_level, hdr_nominal_peak_level);
OBSBasicStats::InitializeValues();
OBSProjector::UpdateMultiviewProjectors();
}
return ret;
}
所以最终调用AttemptToResetVideo->obs_reset_video来进行初始化:
其中根据标识:
- graphics_module指定了是使用OPENGL还是D3D11,其值为DLL的名称字符串
- fps_num:帧率的分子
- fps_den:帧率的分母,
故实际的帧率为:
double obsFPS = (double)ovi.fps_num / (double)ovi.fps_den;
另外:
static int obs_init_video(struct obs_video_info *ovi)
{
struct obs_core_video *video = &obs->video;
//一帧多少ns den/num 表示1帧多长时间
//
// ovi.fps_num = 30 000;
// ovi.fps_den = 1001; 1001秒30 000 帧
video->video_frame_interval_ns = util_mul_div64(1000000000ULL, ovi->fps_den, ovi->fps_num); //den*1000000000ULL/num
video->video_half_frame_interval_ns = util_mul_div64(500000000ULL, ovi->fps_den, ovi->fps_num);
...
}
实际为 rtn = num*mul/div
static inline uint64_t util_mul_div64(uint64_t num, uint64_t mul, uint64_t div)
{
#if defined(_MSC_VER) && defined(_M_X64) && (_MSC_VER >= 1920)
unsigned __int64 high;
const unsigned __int64 low = _umul128(num, mul, &high);
unsigned __int64 rem;
return _udiv128(high, low, div, &rem);
#else
const uint64_t rem = num % div;
return (num / div) * mul + (rem * mul) / div;
#endif
}
- base_width:画面宽度
- base_height:画布高度
- output_width:输出宽度(和画布不同需要缩放)
- output_height:同output_width
输出的长和宽需要进行字节对齐:/* align to multiple-of-two and SSE alignment sizes */ ovi->output_width &= 0xFFFFFFFC;//宽度必须是4的倍数 ovi->output_height &= 0xFFFFFFFE;//长度必须是2的倍数
- video_format:视频格式
- adapter:适配器索引
- gpu_conversion:GPUC加速
- video_colorspace:颜色空间(标准/扩展)
- video_range_type:颜色范围
- obs_scale_type:缩放方式
这些参数对应于OBS的一些配置: