Multi-View Management with obs_view_t for Preview/Output Separation in OBS Studio
OBS Studio implements multi-view management through a dedicated Multiview component that renders multiple scenes simultaneously while maintaining strict visual separation between preview and program outputs using color-coded regions and dedicated rendering contexts.
The obsproject/obs-studio repository provides a sophisticated multi-view system in its frontend layer that enables broadcasters to monitor several scenes at once while preserving the critical preview-program workflow. This implementation centers on the Multiview class, which manages the visual separation and interaction logic required for professional Studio Mode operations.
Core Architecture of the Multiview Component
The Multiview Class and Data Structures
The multi-view implementation resides primarily in frontend/components/Multiview.hpp and frontend/components/Multiview.cpp. The Multiview class encapsulates all layout calculations, source reference management, and rendering logic required for displaying multiple video feeds simultaneously.
The class maintains internal collections of scene sources and generates label textures for visual identification. It handles the mathematical calculations required to partition the display surface into distinct regions for each scene thumbnail while reserving dedicated rectangles for the preview and program outputs.
Projector Integration
The OBSProjector class in frontend/widgets/OBSProjector.cpp serves as the container for Multiview instances. When creating a projector window of type ProjectorType::Multiview, the constructor instantiates a new Multiview object and configures it with user preferences.
The projector forwards all rendering calls through the OBSRenderMultiview static method, which delegates to Multiview::Render with the current window dimensions. This separation allows the Multiview component to remain agnostic of window management while the projector handles OpenGL context and windowing system interactions.
Configuration Management
User preferences for the multi-view system are persisted through OBSBasicSettings in frontend/settings/OBSBasicSettings.cpp. The implementation reads several configuration keys to control the visual presentation:
MultiviewLayout– Determines the grid arrangement of scene thumbnailsMultiviewDrawNames– Toggles the display of scene labelsMultiviewDrawAreas– Controls the visibility of safe-area overlaysmultiviewMouseSwitch– Enables click-to-switch functionality for Studio Mode
These settings propagate to the Multiview instance during initialization and when the user modifies preferences through the settings dialog.
Preview and Program Separation Mechanism
Scene Collection and Source Tracking
The Multiview::Update method queries the current scene collection via obs_frontend_get_scenes and filters scenes marked for multiview display. It creates permanent label textures for Preview and Program outputs using the CreateLabel method, then builds the multiviewScenes vector containing strong references to each scene source.
This update cycle ensures that the multiview reflects the current state of the scene collection while maintaining reference safety through OBSSource smart pointers. The method also increments showing counts for each scene to ensure proper source lifecycle management during rendering.
Rendering Pipeline and Visual Indicators
During Multiview::Render, the system implements strict visual separation through dedicated rendering regions and color-coded indicators. The rendering process follows a specific sequence:
- Thumbnail Rendering – All scene thumbnails draw first using
outerColor(gray) for normal states - Program Output – The active program source renders in its dedicated rectangle with
programColor(red) - Preview Output – When Studio Mode is active, the preview source displays with
previewColor(green); otherwise, it shows the program color
The calcPreviewProgram method calculates the exact rectangle positions for preview and program outputs based on the current layout and window aspect ratio. This ensures that regardless of the grid configuration, the critical preview and program feeds remain visually distinct and properly positioned.
Interactive Source Selection
Mouse interaction is handled through Multiview::GetSourceByPosition, which translates cursor coordinates into scene indices based on the current layout geometry and window aspect ratio. This method returns a strong reference to the selected source, enabling direct manipulation of the output.
When the multiviewMouseSwitch configuration option is enabled, clicking a thumbnail triggers SetProgramSource to switch the program output in Studio Mode. This allows operators to execute rapid scene changes directly from the multiview interface without interacting with the main scene list.
Code Implementation Examples
Creating and configuring a Multiview instance occurs within the projector initialization:
// In OBSProjector constructor (ProjectorType::Multiview)
multiview = new Multiview();
multiview->Update(
static_cast<MultiviewLayout>(config_get_int(App()->GetUserConfig(),
"BasicWindow", "MultiviewLayout")),
config_get_bool(App()->GetUserConfig(), "BasicWindow", "MultiviewDrawNames"),
config_get_bool(App()->GetUserConfig(), "BasicWindow", "MultiviewDrawAreas"));
The rendering loop delegates drawing operations to the Multiview component:
void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy)
{
Multiview *mv = static_cast<OBSProjector*>(data)->multiview;
if (!mv) return;
mv->Render(cx, cy);
}
Handling mouse events for interactive scene switching:
OBSSource source = multiview->GetSourceByPosition(mouseX, mouseY);
if (source && multiviewMouseSwitch) {
// Switch program source in Studio Mode
auto *basic = static_cast<OBSBasic*>(obs_frontend_get_main_window());
basic->SetProgramSource(source);
}
Retrieving user configuration options:
bool drawLabel = config_get_bool(App()->GetUserConfig(), "BasicWindow", "MultiviewDrawNames");
bool drawSafe = config_get_bool(App()->GetUserConfig(), "BasicWindow", "MultiviewDrawAreas");
int layout = config_get_int(App()->GetUserConfig(), "BasicWindow", "MultiviewLayout");
Summary
- The Multiview component in
frontend/components/Multiview.cppprovides the core implementation for rendering multiple scenes while maintaining strict preview/program separation. - Visual separation is enforced through dedicated rendering regions and color coding (red for program, green for preview, gray for standard thumbnails).
- The OBSProjector class integrates Multiview into the display system, handling window creation and OpenGL context management while delegating rendering to the Multiview instance.
- Interactive functionality allows direct scene switching via mouse clicks when
multiviewMouseSwitchis enabled, utilizingGetSourceByPositionfor coordinate mapping. - Configuration management through
OBSBasicSettingspersists user preferences for layout, label display, and safe-area overlays.
Frequently Asked Questions
What is the purpose of the Multiview component in OBS Studio?
The Multiview component enables broadcasters to monitor multiple scenes simultaneously within a single window while maintaining the critical separation between preview and program outputs required for professional Studio Mode workflows. It manages the layout calculations, source rendering, and interactive selection logic needed for efficient live production.
How does OBS Studio handle preview and program separation in multiview?
OBS Studio enforces separation through distinct rendering rectangles and color-coded visual indicators. The Multiview::Render method draws program sources with programColor (red) and preview sources with previewColor (green) in dedicated regions calculated by calcPreviewProgram, while standard scene thumbnails render in gray within the remaining grid space.
Can users customize the multiview layout and appearance?
Yes, users can configure the multiview through the settings interface managed by OBSBasicSettings in frontend/settings/OBSBasicSettings.cpp. Available customizations include the grid layout selection (MultiviewLayout), toggles for displaying scene names (MultiviewDrawNames) and safe-area overlays (MultiviewDrawAreas), and the option to enable mouse-click scene switching.
How does mouse interaction work in the multiview window?
Mouse interaction is processed through Multiview::GetSourceByPosition, which translates cursor coordinates into scene indices based on the current layout geometry and window aspect ratio. When the multiviewMouseSwitch configuration is enabled, clicking a valid scene thumbnail triggers SetProgramSource to switch the program output, allowing direct interaction with the live production workflow.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →