最近接了个需求,要在源列表的每个源进行视频预览类似如下图:
一、OBS所有的视频预览包括主窗口的预览都是继承OBSQTDisplay这个类。
在SourceTreeItem构造函数中添加以下代码
// 预览窗口
play = new OBSQTDisplay();
play->setFixedWidth(100);
auto addDrawCallback = [this]() {
obs_display_add_draw_callback(play->GetDisplay(), OBSRender,this);
obs_display_set_background_color(play->GetDisplay(), 0x000000);
};
connect(play, &OBSQTDisplay::DisplayCreated, addDrawCallback);
boxLayout->addWidget(play);
二、实现回调函数voidOBSRender(void *data, uint32_t cx, uint32_t cy)
static inline void startRegion(int vX, int vY, int vCX, int vCY, float oL,
float oR, float oT, float oB)
{
gs_projection_push();
gs_viewport_push();
gs_set_viewport(vX, vY, vCX, vCY);
gs_ortho(oL, oR, oT, oB, -100.0f, 100.0f);
}
static inline void endRegion()
{
gs_viewport_pop();
gs_projection_pop();
}
void SourceTreeItem::OBSRender(void *data, uint32_t cx, uint32_t cy)
{
SourceTreeItem *window = reinterpret_cast<SourceTreeItem *>(data);
//if (!window->ready)
// return;
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSSource source = window->source;
uint32_t targetCX;
uint32_t targetCY;
int x, y;
int newCX, newCY;
float scale;
if (source) {
targetCX = std::max(obs_source_get_width(source), 1u);
targetCY = std::max(obs_source_get_height(source), 1u);
} else {
struct obs_video_info ovi;
obs_get_video_info(&ovi);
targetCX = ovi.base_width;
targetCY = ovi.base_height;
}
GetScaleAndCenterPos(targetCX, targetCY, cx, cy, x, y, scale);
newCX = int(scale * float(targetCX));
newCY = int(scale * float(targetCY));
startRegion(x, y, newCX, newCY, 0.0f, float(targetCX), 0.0f,
float(targetCY));
if (source)
//将所要预览的源添加在obs_source_video_render函数
obs_source_video_render(source);
else
obs_render_main_texture();
endRegion();
}
三、OBS其他类似预览都是按照此方法进行预览的