xSTUDIO is a cutting-edge media playback and review application designed specifically for professionals in the Visual Effects, Feature Animation, and Film/TV Post-Production industries. Built with performance at its core, xSTUDIO provides an intuitive interface backed by a robust C++ engine and comprehensive Python APIs for seamless pipeline integration.
- π High-Performance Playback Engine - Optimized for large media files and high-resolution formats
- π¨ Professional Review Tools - Advanced color management, annotations, and comparison tools
- π Timeline & Playlist Management - Sophisticated media organization and playlist creation
- π Extensible Plugin Architecture - Custom plugins for specialized workflows
- π Python API Integration - Complete Python SDK for pipeline automation
- π Multi-Platform Support - Linux, Windows (macOS coming soon)
- π₯ Collaborative Features - Session sharing and remote control capabilities
- π Comprehensive Annotation System - Drawing tools, notes, and markup features
- VFX Artists & Supervisors - Review shots, compare versions, annotate feedback
- Animation Directors - Timeline scrubbing, frame-by-frame analysis
- Post-Production Teams - Collaborative review sessions, playlist management
- Pipeline Engineers - Python API integration, custom tool development
xSTUDIO is built on a sophisticated actor-based architecture using the C++ Actor Framework (CAF), providing excellent scalability, thread safety, and modularity.
graph TB
subgraph "User Interface Layer"
QML[QML/Qt Interface]
VP[OpenGL Viewport]
UI[UI Components]
end
subgraph "Application Layer"
GA[Global Actor<br/>Central Coordinator]
SA[Studio Actor<br/>Top-level Container]
SESS[Session Actor<br/>Project Management]
end
subgraph "Media Pipeline"
PH[Playhead Actor<br/>Playback Control]
PL[Playlist Actor<br/>Media Organization]
TL[Timeline Actor<br/>Sequence Management]
MR[Media Reader<br/>File I/O]
MC[Media Cache<br/>Buffer Management]
end
subgraph "Plugin System"
PM[Plugin Manager]
CO[Color Operations]
VO[Viewport Overlays]
DS[Data Sources]
MH[Media Hooks]
end
subgraph "External Integration"
PY[Python API]
HTTP[HTTP Client]
SG[Shotgun Integration]
SYNC[Sync Gateway]
end
QML --> GA
VP --> PH
UI --> SA
GA --> SA
SA --> SESS
SESS --> PL
SESS --> TL
PL --> PH
TL --> PH
PH --> MR
MR --> MC
GA --> PM
PM --> CO
PM --> VO
PM --> DS
PM --> MH
GA --> PY
GA --> HTTP
HTTP --> SG
GA --> SYNC
style GA fill:#e1f5fe
style SA fill:#f3e5f5
style SESS fill:#e8f5e8
style PH fill:#fff3e0
style PM fill:#fce4ec
sequenceDiagram
participant UI as QML Interface
participant GA as Global Actor
participant SA as Studio Actor
participant SESS as Session Actor
participant PH as Playhead Actor
participant MR as Media Reader
UI->>GA: User Action (Play)
GA->>SA: Forward Command
SA->>SESS: Session Control
SESS->>PH: Playback Request
PH->>MR: Frame Request
MR-->>PH: Image Buffer
PH-->>SESS: Frame Ready
SESS-->>SA: Update State
SA-->>GA: Status Update
GA-->>UI: UI Refresh
Note over GA, MR: All communication via<br/>asynchronous messages
graph LR
subgraph "Plugin Types"
CO[Color Operations<br/>β’ Grading<br/>β’ LUTs<br/>β’ Effects]
MR[Media Readers<br/>β’ FFmpeg<br/>β’ OpenEXR<br/>β’ Custom Formats]
VO[Viewport Overlays<br/>β’ HUD Elements<br/>β’ Annotations<br/>β’ Masks]
DS[Data Sources<br/>β’ Shotgun<br/>β’ Database<br/>β’ File Systems]
MH[Media Hooks<br/>β’ Pipeline Integration<br/>β’ Custom Processing]
end
subgraph "Plugin System"
PM[Plugin Manager]
PF[Plugin Factory]
PL[Plugin Loader]
end
subgraph "Core System"
VP[Viewport]
MP[Media Pipeline]
UI[User Interface]
end
PM --> PF
PM --> PL
PF --> CO
PF --> MR
PF --> VO
PF --> DS
PF --> MH
VP --> CO
VP --> VO
MP --> MR
MP --> MH
UI --> DS
style PM fill:#e3f2fd
style VP fill:#f1f8e9
style MP fill:#fce4ec
System Requirements:
- Linux: Ubuntu 22.04+, CentOS 7+, Rocky Linux 9.1+
- Windows: Windows 10/11 with Visual Studio 2019+
- Hardware: OpenGL 3.3+, 8GB+ RAM recommended
- Dependencies: CMake 3.12+, Qt5.15+, Python 3.8+
git clone https://github.com/AcademySoftwareFoundation/xstudio.git
cd xstudioUbuntu 22.04:
sudo apt install build-essential cmake git python3-pip
sudo apt install qtbase5-dev qtdeclarative5-dev qtquickcontrols2-5-dev
sudo apt install libspdlog-dev libfmt-dev libssl-dev zlib1g-dev
sudo apt install libglu1-mesa-dev libglew-dev libfreetype-dev
sudo apt install libjpeg-dev libpulse-dev nlohmann-json3-devSee detailed platform-specific instructions:
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)./bin/xstudio.binFor containerized development:
# Build Docker image
docker build -t xstudio .
# Enable X11 forwarding (Linux)
sudo xhost +local:root
# Run container with GPU support
docker run --rm -it --gpus all \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e DISPLAY=$DISPLAY \
xstudio bash
# Launch xSTUDIO inside container
./build/bin/xstudio.binxstudio/
βββ src/ # Core C++ source code
β βββ global/ # Global actor and system coordination
β βββ studio/ # Top-level application container
β βββ session/ # Project/session management
β βββ media/ # Media handling and sources
β βββ playhead/ # Playback control and timeline
β βββ playlist/ # Media organization
β βββ ui/ # User interface components
β β βββ qml/ # QML UI components
β β βββ opengl/ # OpenGL rendering
β β βββ viewport/ # Main viewport implementation
β βββ plugin/ # Plugin implementations
β β βββ colour_op/ # Color operation plugins
β β βββ media_reader/ # Media format readers
β β βββ data_source/ # External data integration
β β βββ viewport_overlay/ # HUD and overlay plugins
β βββ utility/ # Core utilities and helpers
βββ include/xstudio/ # Public header files
βββ python/ # Python API and bindings
βββ ui/qml/ # QML interface files
βββ share/ # Configuration and resources
βββ docs/ # Documentation
The core of xSTUDIO is built on the C++ Actor Framework (CAF):
// Example: Creating an actor
class MyActor : public caf::event_based_actor {
public:
MyActor(caf::actor_config& cfg) : caf::event_based_actor(cfg) {
behavior_.assign(
[=](play_atom) {
// Handle play command
send(playhead_, play_atom_v);
}
);
}
caf::behavior make_behavior() override { return behavior_; }
private:
caf::behavior behavior_;
caf::actor playhead_;
};Media processing follows this flow:
graph LR
A[Media File] --> B[Media Reader Plugin]
B --> C[Image Buffer]
C --> D[Color Pipeline]
D --> E[Cache]
E --> F[Viewport Renderer]
F --> G[Display]
style C fill:#e1f5fe
style D fill:#f3e5f5
style E fill:#e8f5e8
Creating a Color Operation Plugin:
class MyColorOp : public plugin::ColourOpPlugin {
public:
MyColorOp(caf::actor_config& cfg) : ColourOpPlugin(cfg) {}
// Implement color transformation
void apply_colour_operation(
ImageBufPtr& image,
const ColourOperationDataPtr& op_data
) override {
// Your color processing here
process_pixels(image->buffer(), op_data);
}
private:
void process_pixels(uint8_t* pixels, const ColourOperationDataPtr& data);
};
// Register plugin
extern "C" {
plugin::PluginFactoryPtr plugin_factory() {
return std::make_shared<plugin::PluginFactory>(
plugin::PluginType::ColourOp,
"MyColorOp",
[]() { return std::make_shared<MyColorOp>(); }
);
}
}- Create header file in
include/xstudio/myfeature/:
class MyFeatureActor : public caf::event_based_actor {
public:
MyFeatureActor(caf::actor_config& cfg);
caf::behavior make_behavior() override;
private:
caf::behavior behavior_;
};- Implement in
src/myfeature/src/:
MyFeatureActor::MyFeatureActor(caf::actor_config& cfg)
: caf::event_based_actor(cfg) {
// Register with system
system().registry().put("MYFEATURE", this);
behavior_.assign(
[=](my_action_atom, const std::string& data) {
// Handle your custom message
return process_action(data);
}
);
}- Add CMakeLists.txt and integrate with build system
QML Component:
// MyFeaturePanel.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import xStudio 1.0
Rectangle {
id: root
property alias myFeatureModel: model
MyFeatureModel {
id: model
backend: app_window.session
}
Column {
Button {
text: "My Action"
onClicked: model.performAction()
}
ListView {
model: model
delegate: Text { text: model.displayName }
}
}
}C++ Backend Model:
class MyFeatureModel : public QAbstractListModel {
Q_OBJECT
public:
explicit MyFeatureModel(QObject* parent = nullptr);
Q_INVOKABLE void performAction();
// QAbstractListModel interface
int rowCount(const QModelIndex& parent) const override;
QVariant data(const QModelIndex& index, int role) const override;
private:
caf::actor backend_;
std::vector<MyData> data_;
};# Build with testing enabled
cmake .. -DBUILD_TESTING=ON
make -j$(nproc)
# Run specific tests
./src/myfeature/test/myfeature_test
# Run all C++ tests
make testcd python/test
pytest test_myfeature.py -v# Start xSTUDIO in test mode
./bin/xstudio.bin --session test_session -e -n
# Run Python integration tests
python integration_test.py- Modern C++17 features encouraged
- RAII patterns for resource management
- Smart pointers over raw pointers
- const-correctness throughout
- CAF message passing for actor communication
# Format C++ code (if enabled)
ninja clangformat
# Check with clang-tidy
ninja clang-tidy# Example commit message
git commit -m "feat(playhead): add frame-accurate seeking
- Implement sub-frame positioning
- Add timeline scrubbing support
- Update playback controls UI
- Add unit tests for seek accuracy
Closes #123"The Python API provides complete access to xSTUDIO's functionality:
import xstudio
# Connect to running xSTUDIO instance
connection = xstudio.Connection()
connection.connect_remote("localhost", 45500)
# Create new session
session = connection.create_session("My Project")
# Add media to playlist
media = session.create_media("/path/to/video.mov")
playlist = session.create_playlist("Shots")
playlist.add_media(media)
# Control playback
playhead = session.playhead
playhead.play()
playhead.seek_to_frame(100)
# Add annotations
annotation = session.create_annotation("Review note")
annotation.set_frame(100)
annotation.set_text("Fix this shot")# Custom media processing pipeline
class RenderReviewPipeline:
def __init__(self, xstudio_connection):
self.xs = xstudio_connection
def process_shots(self, shot_list):
session = self.xs.create_session("Render Review")
for shot in shot_list:
# Create media from render path
media = session.create_media(shot.render_path)
# Apply color correction
if shot.lut_path:
media.apply_lut(shot.lut_path)
# Add to appropriate playlist
playlist = session.get_playlist(shot.sequence)
playlist.add_media(media)
# Auto-generate thumbnails
media.generate_thumbnail()
return session# Control running xSTUDIO instance
xstudio-control --host localhost --port 45500 \
--command "session.playhead.play()"
# Inject Python scripts
xstudio-inject --script my_pipeline.py
# Batch operations
xstudio-control --batch << EOF
session = create_session("Batch")
for f in glob.glob("*.mov"):
add_media(f)
EOFxSTUDIO uses JSON-based configuration stored in share/preference/:
// core_playhead.json
{
"playback": {
"fps": 24.0,
"loop_mode": "LOOP",
"audio_enabled": true
},
"cache": {
"max_frames": 1000,
"preroll_frames": 10
}
}// ui_viewport.json
{
"hotkeys": {
"space": "play_pause",
"j": "step_backward",
"k": "step_forward",
"home": "go_to_start",
"end": "go_to_end"
}
}// plugin_color_pipeline_ocio.json
{
"ocio_config": "/studio/config/aces_1.2/config.ocio",
"default_view": "sRGB",
"working_space": "ACEScg"
}CMake can't find Qt5:
# Set Qt5 path explicitly
export CMAKE_PREFIX_PATH=/usr/lib/x86_64-linux-gnu/cmake/Qt5Missing OpenGL drivers:
# Install Mesa drivers (Ubuntu)
sudo apt install mesa-utils libgl1-mesa-dev
# Test OpenGL
glxinfo | grep "direct rendering"xSTUDIO won't start:
# Check dependencies
ldd ./bin/xstudio.bin
# Run with debug logging
./bin/xstudio.bin --log-level debug --log-file xstudio.logPoor playback performance:
# Check GPU usage
nvidia-smi # For NVIDIA GPUs
glxinfo | grep "renderer"
# Adjust cache settings in preferences
# Increase memory limits in core_cache.jsonPlugin loading fails:
# Check plugin paths
export XSTUDIO_PLUGIN_PATH=/path/to/plugins
# Verify plugin dependencies
ldd /path/to/plugin.so# Enable debug features
cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON
# Run with debugger
gdb ./bin/xstudio.bin
(gdb) run --log-level debug# View log files
tail -f xstudio.log
# Filter specific components
grep "MediaReader" xstudio.log
grep "ERROR" xstudio.logWe welcome contributions! Here's how to get started:
- Fork the repository and clone your fork
- Create a feature branch:
git checkout -b feature/my-feature - Set up development environment:
mkdir build-dev && cd build-dev cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON make -j$(nproc)
- Follow the coding standards (see CONTRIBUTING.md)
- Write comprehensive tests for new features
- Update documentation for API changes
- Sign the CLA (required for all contributions)
- Ensure all tests pass:
make test && pytest python/test/ - Run code formatting:
ninja clangformat - Update CHANGELOG.md with your changes
- Create detailed PR description with:
- What the change does
- Why it's needed
- How to test it
- Any breaking changes
- User Guide - Complete user documentation
- API Reference - C++ API documentation
- Python API - Python bindings documentation
- Build Guides - Platform-specific build instructions
- Plugin Development - Creating custom plugins
xSTUDIO is licensed under the Apache License 2.0.
- Academy Software Foundation for project stewardship
- DNEG for the original development and open-sourcing
- Contributors who have helped improve xSTUDIO
- Open-source projects that xSTUDIO builds upon:
- GitHub Issues: Report bugs or request features
- Discussions: Community discussions
- Documentation: User guides and API docs
Built with β€οΈ for the Film & VFX Community
π Star us on GitHub | π Report Issues | π¬ Discussions