Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ Key architectural rule: The CDN/relay does not know anything about media. Anythi
# CI mirrors them to moq-dev/moq-{swift,kotlin,go}
# on each moq-ffi-v* tag.

/cpp/ # C/C++ consumers of libmoq
obs/ # OBS Studio plugin (CMake; links libmoq via MOQ_LOCAL). GPL-2.0.

/demo/ # Demos and test media
boy/ # MoQ Boy demo (ROM hosting, orchestration justfile)
relay/ # Relay server configs (relay.toml, root.toml, leaf*.toml)
Expand Down Expand Up @@ -193,6 +196,7 @@ Changes in one area usually need matching updates elsewhere, including docs. If
| `rs/moq-relay` config/behavior | `doc/bin/relay/` |
| `rs/moq-cli` | `doc/bin/cli.md` |
| `rs/moq-gst` | `doc/bin/gstreamer.md` |
| `rs/libmoq` C ABI (`moq.h`) | `cpp/obs/src`, `doc/bin/obs.md` |
| `js/{watch,publish}` UI/API | `demo/web` if it consumes the API |

## Branch Targeting
Expand Down
209 changes: 209 additions & 0 deletions cpp/obs/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
# please use clang-format version 16 or later

Standard: c++17
AccessModifierOffset: -8
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: Inline
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakStringLiterals: false # apparently unpredictable
ColumnLimit: 120
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
FixNamespaceComments: true
ForEachMacros:
- 'json_object_foreach'
- 'json_object_foreach_safe'
- 'json_array_foreach'
- 'HASH_ITER'
IncludeBlocks: Preserve
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 8
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 8
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true

PenaltyBreakAssignment: 10
PenaltyBreakBeforeFirstCallParameter: 30
PenaltyBreakComment: 10
PenaltyBreakFirstLessLess: 0
PenaltyBreakString: 10
PenaltyExcessCharacter: 100
PenaltyReturnTypeOnItsOwnLine: 60

PointerAlignment: Right
ReflowComments: false
SkipMacroDefinitionBody: true
SortIncludes: false
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
StatementMacros:
- 'Q_OBJECT'
TabWidth: 8
TypenameMacros:
- 'DARRAY'
UseTab: ForContinuationAndIndentation
---
Language: ObjC
AccessModifierOffset: 2
AlignArrayOfStructures: Right
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros:
Enabled: true
AcrossEmptyLines: false
AcrossComments: true
AllowShortBlocksOnASingleLine: Never
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: None
AttributeMacros: ['__unused', '__autoreleasing', '_Nonnull', '__bridge']
BitFieldColonSpacing: Both
#BreakBeforeBraces: Webkit
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: Never
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: true
BreakAfterAttributes: Never
BreakArrays: false
BreakBeforeConceptDeclarations: Allowed
BreakBeforeInlineASMColon: OnlyMultiline
BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterComma
ColumnLimit: 120
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: true
IndentExternBlock: Indent
IndentGotoLabels: false
IndentRequiresClause: true
IndentWidth: 4
IndentWrappedFunctionNames: true
InsertBraces: false
InsertNewlineAtEOF: true
KeepEmptyLinesAtTheStartOfBlocks: false
LambdaBodyIndentation: Signature
NamespaceIndentation: All
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 4
ObjCBreakBeforeNestedBlockParam: false
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PPIndentWidth: -1
PackConstructorInitializers: NextLine
QualifierAlignment: Leave
ReferenceAlignment: Right
RemoveSemicolon: false
RequiresClausePosition: WithPreceding
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: false
#SortUsingDeclarations: LexicographicNumeric
SortUsingDeclarations: true
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInConditionalStatement: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
Standard: c++17
TabWidth: 4
UseTab: Never
8 changes: 8 additions & 0 deletions cpp/obs/.gersemirc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/BlankSpruce/gersemi/master/gersemi/configuration.schema.json

definitions: []
line_length: 120
indent: 2
list_expansion: favour-inlining
unsafe: false
warn_about_unknown_commands: false
11 changes: 11 additions & 0 deletions cpp/obs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# CMake build trees (per the platform presets) and CPack output.
build_macos/
build_x64/
build_x86_64/
release/

# Downloaded OBS sources + prebuilt obs-deps/Qt6 (macOS/Windows buildspec).
.deps/

# Generated build counter.
cmake/.CMakeBuildNumber
119 changes: 119 additions & 0 deletions cpp/obs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
cmake_minimum_required(VERSION 3.28)

include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/common/bootstrap.cmake" NO_POLICY_SCOPE)

project(${_name} VERSION ${_version})

option(ENABLE_FRONTEND_API "Use obs-frontend-api for UI functionality" OFF)
option(ENABLE_QT "Use Qt functionality" OFF)

include(compilerconfig)
include(defaults)
include(helpers)

add_library(obs-moq MODULE)

if(${BUILD_PLUGIN})
find_package(libobs REQUIRED)
# FFmpeg dependency
include(FindPkgConfig)
pkg_check_modules(FFMPEG REQUIRED libavcodec libavutil libswscale libswresample)
target_include_directories(obs-moq PRIVATE ${FFMPEG_INCLUDE_DIRS})
target_link_directories(obs-moq PRIVATE ${FFMPEG_LIBRARY_DIRS})
target_link_libraries(obs-moq PRIVATE ${FFMPEG_LIBRARIES})
else()
find_package(FFmpeg REQUIRED avcodec avutil swscale swresample)
target_link_libraries(obs-moq PRIVATE FFmpeg::avcodec FFmpeg::avutil FFmpeg::swscale FFmpeg::swresample)
endif()

target_link_libraries(obs-moq PRIVATE OBS::libobs)

option(MOQ_LOCAL "Path to moq repo for local development" "")

if(MOQ_LOCAL)
add_subdirectory(${MOQ_LOCAL}/rs/libmoq moq)
target_link_libraries(obs-moq PRIVATE moq)
else()
include(FetchContent)
FetchContent_Declare(
moq
URL
https://github.com/moq-dev/moq/releases/download/libmoq-v${MOQ_VERSION}/moq-${MOQ_VERSION}-${MOQ_TARGET}.${MOQ_ARCHIVE}
)
FetchContent_MakeAvailable(moq)

find_package(moq REQUIRED PATHS ${moq_SOURCE_DIR} NO_DEFAULT_PATH)
target_link_libraries(obs-moq PRIVATE moq::moq)
endif()
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

# The obs-deps Qt6 build references the AGL framework transitively (via
# WrapOpenGL), but recent macOS SDKs ship no linkable AGL binary -- it exists
# only in the runtime dyld shared cache. Generate a stub whose install name
# points at the real framework so the link succeeds; dyld resolves AGL at load.
if(
(ENABLE_QT OR ENABLE_FRONTEND_API)
AND APPLE
AND NOT EXISTS "${CMAKE_OSX_SYSROOT}/System/Library/Frameworks/AGL.framework/Versions/A/AGL"
)
set(_agl_stub_dir "${CMAKE_BINARY_DIR}/agl-stub")
set(_agl_stub_lib "${_agl_stub_dir}/AGL.framework/AGL")
if(NOT EXISTS "${_agl_stub_lib}")
file(MAKE_DIRECTORY "${_agl_stub_dir}/AGL.framework")
set(_agl_arch_flags "")
foreach(_arch IN LISTS CMAKE_OSX_ARCHITECTURES)
list(APPEND _agl_arch_flags "-arch" "${_arch}")
endforeach()
execute_process(
COMMAND
xcrun clang -dynamiclib ${_agl_arch_flags} -install_name /System/Library/Frameworks/AGL.framework/Versions/A/AGL
-o "${_agl_stub_lib}" -x c /dev/null
RESULT_VARIABLE _agl_stub_result
)
if(NOT _agl_stub_result EQUAL 0)
message(WARNING "Failed to build AGL stub (${_agl_stub_result}); Qt link may fail")
endif()
endif()
target_link_options(obs-moq PRIVATE "-F${_agl_stub_dir}")
endif()

if(ENABLE_FRONTEND_API)
find_package(obs-frontend-api REQUIRED)
target_link_libraries(obs-moq PRIVATE OBS::obs-frontend-api)
endif()

if(ENABLE_QT)
find_package(Qt6 COMPONENTS Widgets Core)
target_link_libraries(obs-moq PRIVATE Qt6::Core Qt6::Widgets)
target_compile_options(
obs-moq
PRIVATE $<$<C_COMPILER_ID:Clang,AppleClang>:-Wno-quoted-include-in-framework-header -Wno-comma>
)
set_target_properties(
obs-moq
PROPERTIES AUTOMOC ON AUTOUIC ON AUTORCC ON
)
endif()

target_sources(
obs-moq
PRIVATE
src/obs-moq.cpp
src/moq-output.h
src/moq-service.h
src/moq-output.cpp
src/moq-service.cpp
src/moq-source.cpp
src/moq-source.h
)

# The dock requires both the frontend API (to register it) and Qt (to build it).
if(ENABLE_FRONTEND_API AND ENABLE_QT)
target_sources(obs-moq PRIVATE src/moq-dock.cpp src/moq-dock.h)
target_compile_definitions(obs-moq PRIVATE MOQ_FRONTEND_ENABLED MOQ_VERSION_STRING="${MOQ_VERSION}")
endif()

if(${BUILD_PLUGIN})
set_target_properties_plugin(obs-moq PROPERTIES OUTPUT_NAME ${_name})
else()
set_target_properties_obs(obs-moq PROPERTIES FOLDER plugins PREFIX "")
endif()
Loading