Friday, December 12, 2025

running OpenSpace on Apple Silicon and modern Intel Macs

As written in the documentation, OpenSpace uses OpenGL double precision floating point operations extensively, and Apple Silicon does not have hardware support for it. Checking if it will downgrade gracefully to software rendering, found that OpenSpace would just crash, with Claude.ai telling me that the crash report 

Crashed Thread:        0  CrBrowserMain  Dispatch queue: com.apple.main-thread

Thread 0 Crashed:: CrBrowserMain Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib                   0x190856388 __pthread_kill + 8
1   libsystem_pthread.dylib                  0x19088f848 pthread_kill + 296
2   libsystem_c.dylib                        0x1907989e4 abort + 124
3   libGLProgrammability.dylib               0x1f0ea63e4 glpPrimitiveTypeGetScalarType + 136
4   libGLProgrammability.dylib               0x1f0e8af20 glpLLVMLoadVector + 120
5   libGLProgrammability.dylib               0x1f0e7c8f0 glpLLVMCGLValue + 1160
6   libGLProgrammability.dylib               0x1f0e771b0 glpLLVMCGAssign + 112
7   libGLProgrammability.dylib               0x1f0e7788c glpLLVMCGCommaExpr + 268
8   libGLProgrammability.dylib               0x1f0e7788c glpLLVMCGCommaExpr + 268
9   libGLProgrammability.dylib               0x1f0e771b0 glpLLVMCGAssign + 112
10  libGLProgrammability.dylib               0x1f0e7788c glpLLVMCGCommaExpr + 268
11  libGLProgrammability.dylib               0x1f0e7788c glpLLVMCGCommaExpr + 268
12  libGLProgrammability.dylib               0x1f0e771b0 glpLLVMCGAssign + 112
13  libGLProgrammability.dylib               0x1f0e7788c glpLLVMCGCommaExpr + 268
14  libGLProgrammability.dylib               0x1f0e7b5f8 glpLLVMCGBlock + 516
15  libGLProgrammability.dylib               0x1f0e722c8 glpLLVMCGNode + 632
16  libGLProgrammability.dylib               0x1f0e7b234 glpLLVMCGFunctionDefinition + 2888
17  libGLProgrammability.dylib               0x1f0e70f30 glpLLVMCGTopLevel + 1444
18  libGLProgrammability.dylib               0x1f0e985f8 glpLinkProgram + 10092
19  libGLProgrammability.dylib               0x1f0eb1ea0 ShLink + 208
20  GLEngine                                 0x1f104a3b8 gleLinkProgram + 1140
21  GLEngine                                 0x1f0fc6350 glLinkProgramARB_Exec + 180
22  OpenSpace                                0x1021f8aa4 glbinding::BasicCallHelper<void, unsigned int>::call(glbinding::Function<void, unsigned int> const*, unsigned int&&) + 44
23  OpenSpace                                0x1021f87d0 glbinding::Function<void, unsigned int>::call(unsigned int&) const + 184
24  OpenSpace                                0x1021f3a24 glbinding::Function<void, unsigned int>::operator()(unsigned int&) const + 32
25  OpenSpace                                0x1023470c8 gl::glLinkProgram(unsigned int) + 32
26  OpenSpace                                0x101e5dc2c ghoul::opengl::ProgramObject::linkProgramObject() + 44
27  OpenSpace                                0x101e5e668 ghoul::opengl::ProgramObject::Build(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, std::__1::__fs::filesystem::path const&, std::__1::__fs::filesystem::path const&, ghoul::Dictionary const&) + 1456
28  OpenSpace                                0x100a5dbac openspace::RenderEngine::buildRenderProgram(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, std::__1::__fs::filesystem::path const&, std::__1::__fs::filesystem::path const&, ghoul::Dictionary) + 316
29  OpenSpace                                0x1016ce084 openspace::globebrowsing::RenderableGlobe::recompileShaders() + 6156
30  OpenSpace                                0x1016cc82c openspace::globebrowsing::RenderableGlobe::initializeGL() + 208
31  OpenSpace                                0x100b47b88 openspace::SceneGraphNode::initializeGL() + 584
32  OpenSpace                                0x100ae4bb0 openspace::Scene::update(openspace::UpdateData const&) + 132
33  OpenSpace                                0x100a5a6d0 openspace::RenderEngine::updateScene() + 196
34  OpenSpace                                0x1007eb428 openspace::OpenSpaceEngine::loadAssets() + 972
35  OpenSpace                                0x1007ed234 openspace::OpenSpaceEngine::preSynchronization() + 156
36  OpenSpace                                0x1004303ac (anonymous namespace)::mainPreSyncFunc() + 80
37  OpenSpace                                0x100ce8b90 sgct::Engine::exec() + 288
38  OpenSpace                                0x10042d170 main + 14684
39  dyld                                     0x1904eeb98 start + 6076

indicates that 

The crash is happening in Apple's OpenGL shader compiler (libGLProgrammability.dylib) when OpenSpace tries to compile shaders for the globe rendering. Look at the stack:

Frame 26-29: OpenSpace is compiling shaders for RenderableGlobe
Frame 19-21: Apple's OpenGL implementation tries to link the shader program
Frame 3: The shader compiler encounters something it can't handle and aborts 

Now, this could possibly be due to some filesystem issues, restrictions due to running OpenSpace from command-line from a sub-folder of my home folder instead of Applications folder, but I got a similar crash when running OpenSpace inside UTM on Ubuntu 24.04 (using the daily build deb file yesterday) if I enable hardware acceleration. 

Unfortunately, mesa on MacOS doesn't seem to enable software rendering - 
brew install mesa

# Set environment variables to use Mesa's software renderer
export LIBGL_ALWAYS_SOFTWARE=1
export GALLIUM_DRIVER=llvmpipe

# Run OpenSpace
./OpenSpace.app/Contents/MacOS/OpenSpace 

But the same crash is observed. Claude says,
Unfortunately, Mesa on macOS is limited. The Homebrew Mesa package primarily provides: OSMesa (off-screen rendering) and some utilities

But it won't override Apple's OpenGL framework the way it does on Linux. macOS applications are hardcoded to use /System/Library/Frameworks/OpenGL.framework

Then, tried disabling hardware acceleration and running the same OpenSpace deb file on Ubuntu 24.04, and that works. Around 8 fps, and the frame-rate does not seem to improve much beyond 20 fps or so even if we use something like onlyEarth.profile or loading individual assets to the empty profile, etc. But this could be still useful for offline work, validating single-precision builds and so on.

And so now to single-precision builds - I'll try to build for Mac Apple Silicon and see what happens.

Also, maybe I can try building for Intel Macs with these patches - with XCode for MacOS26, many of the incompatibilities and unsupported implementations are now ironed out, so we need far fewer patches. And github now has MacOS26 public runners.

Sunday, November 30, 2025

tuning lossless ffmpeg command-line with Claude

The ffmpeg command

ffmpeg -y -r 30 -i in_%05d.jpg -i ../NormPeak-6dBENG.wav -c:v hevc_nvenc -preset lossless -global_quality 18 -pix_fmt nv12 -c:a aac -b:a 192k ~/Downloads/4kframes.mp4

gives the following warnings - 

[aist#1:0/pcm_s16le @ 0x59f7e96fbfc0] Guessed Channel Layout: stereo
....

[in#0/image2 @ 0x59f7e96f4e40] Thread message queue blocking; consider raising the thread_queue_size option (current value: 8)

[swscaler @ 0x59f7e97ae500] deprecated pixel format used, make sure you did set range correctly

    Last message repeated 3 times

[hevc_nvenc @ 0x59f7e9701880] The selected preset is deprecated. Use p1 to p7 + -tune or fast/medium/slow.

[hevc_nvenc @ 0x59f7e9701880] Using global_quality with nvenc is deprecated. Use qp instead. 

Claude's suggestion to fix - 

ffmpeg -y -r 30 -i in_%05d.jpg -thread_queue_size 512 -i ../NormPeak-6dBENG.wav -c:v hevc_nvenc -preset p7 -tune lossless -cq 0 -pix_fmt yuv420p -c:a aac -b:a 192k ~/Downloads/4kframes.mp4

Friday, November 28, 2025

MIDI-mapper for OpenSpace (or any javascript API)

With the help of Claude.ai, I've put up a MIDI-mapper for OpenSpace at OpenSpace MIDI mapping.

The readme.txt lists the prompts used, and usage. Copy-pasting from my post on OpenSpace Slack: With this, we can control OpenSpace using any MIDI control surface or MIDI instrument. Interesting effects like speeding up time for one (MIDI) violin string, slowing down for another string, etc can be thought of.

I've used our KORG nanokontrol - earlier version of this product - to do the development and testing.

By adding suitable functions, this could be extended to call any javascript API using a MIDI controller or MIDI instrument.

Thursday, November 27, 2025

Bosch Wiper blades for Hyundai Santro

 PB helped me out with the following info:

Attached is the wiper blades size for Santro
List shows 20" on Driver side and 16" on Passenger side




TYPES OF BOSCH WIPERS
Bosch Clear Advantage — a flat-blade / beam-style wiper. Designed to give uniform pressure across the windshield, better contact, smoother wiping, and more streak-free clearing (especially good in heavy rain or at high speeds).

Bosch ECO (conventional / bracket-frame wiper)
 — a more traditional wiper with a metal (or mixed) frame + rubber blade. Usually more budget-friendly and covers basic everyday wiping needs.

AMAZON LINKS
Bosch Clear Advantage 16"
I have been using Bosch ECO, and it works well. 
Will try Clear Advantage next time.

And, found that there were video guides on how to fit the blades, in the amazon listings. Also available on youtube, at Bosch ECO and Clear Advantage.

On my (new) Santro, the 20" blade seems a bit short. Perhaps I'll try the 21-inch blade next time.

Friday, November 21, 2025

hardware accelerated video encoding on Intel Iris graphics has issues with jpg frames input - resolved

 From ChatGPT,

ffmpeg -i filename_%05d.jpg -c:v hevc_qsv -preset veryslow -global_quality 0 output_lossless_qsv.mkv

For 4K (4096x4096) files, this was running at around 8 fps on my i5 laptop, as against 2 fps for non-accelerated libx264. The mistake I made earlier was to put the preset before the -c:v.
  • -i must come before input options end.
  • All encoder options (-c:v, -preset, -global_quality) must be placed after the input and before the output filename.

If you place -preset before -i filename_%05d.jpg, FFmpeg thinks it’s a decoder option, causing the error:

Codec AVOption preset ... is not a decoding option.

With audio, we would need something like

ffmpeg -r 30 -i KG-LS_%05d.jpg -i audio.wav \

  -c:v hevc_qsv -preset veryslow -global_quality 0 \

  -c:a aac -b:a 192k \

  -shortest \

  output_with_audio.mkv

# or on Windows,

ffmpeg -r 30 -i KG-LS_%05d.jpg -i audio.wav ^

  -c:v hevc_qsv -preset veryslow -global_quality 0 ^

  -c:a aac -b:a 192k ^

  -shortest ^

  output_with_audio.mkv


Edit - this produces a low-bitrate video with colour issues on VLC (and perhaps on other players. The python front-end presets, like the command below, might be useful - 
FFmpeg command to copy-paste:
ffmpeg -y -i in_%05d.jpg -i map_x_directp2.pgm -i map_y_directp2.pgm -i weight_alpha_mask.png -filter_complex '[0:v][1:v][2:v]remap[remapped];[3:v]format=gray,scale=4096:4096,colorchannelmixer=rr=1:gg=1:bb=1[mask_rgb];[remapped][mask_rgb]blend=all_mode=multiply[blended];[blended]scale=3840:2160,setsar=1,setdar=16/9,format=yuv420p[out]' -map '[out]' -map '0:a?' -c:v hevc_qsv -preset fast -crf 23 -pix_fmt yuv420p -c:a aac -b:a 128k D:/out-W4K.mp4

So, without warping, that would be - 
ffmpeg -y -i in_%05d.jpg -i audio.wav -c:v hevc_qsv -preset veryslow -crf 1 -pix_fmt yuv420p -c:a aac -b:a 128k out.mp4

But unfortunately, even the warping command produces a low bitrate video with colour issues. Green tinted instead of purple tinted for the earlier videos. Even changing the codec to libx265 did not help. So, some incompatibility in the input frames is suspected. Maybe I'll just use avidemux instead instead of trying to troubleshoot.

From ffmpeg -h
Getting help:
    -h      -- print basic options
    -h long -- print more options
    -h full -- print all options (including all format and codec specific options, very long)
    -h type=name -- print all options for the named decoder/encoder/demuxer/muxer/filter/bsf/protocol

ffmpeg -h encoder=hevc_qsv
....
  -preset            <int>        E..V....... (from 1 to 7) (default medium)
     veryfast        7            E..V.......
     faster          6            E..V.......
     fast            5            E..V.......
     medium          4            E..V.......
     slow            3            E..V.......
     slower          2            E..V.......
     veryslow        1            E..V.......

....
  -profile           <int>        E..V....... (from 0 to INT_MAX) (default unknown)
     unknown         0            E..V.......
     main            1            E..V.......
     main10          2            E..V.......
     mainsp          3            E..V.......
     rext            4            E..V.......
     scc             9            E..V.......


    
Claude.ai pointed out that the colour tint issues are probably due to wrong pixel format, and the low bitrate is probably because "QSV's CRF implementation is unreliable". So, suggestion is to use nv12 pixel format and global_quality instead of CRF, where quality of 15-20 is near lossless. Or force a high bitrate if that doesn't work - -b:v 20M -maxrate 25M

ffmpeg -y -r 30 -i in_%05d.jpg -i audio.wav -c:v hevc_qsv -preset veryslow -global_quality 18 -pix_fmt nv12 -c:a aac -b:a 128k out.mp4

And that solved the problem.

No colour tint, hevc_qsv encoder resulted in a 25 Mbps video, libx265 encoder with the same preset and quality settings but without the -pix_fmt nv12 resulted in a 7 Mbps video, both of good quality.

Sunday, November 09, 2025

Send user digests - Moodle task fails - sends hundreds of emails to Admin

On one of our Moodle instances, emails are supposed to go out through Google Workspace using Google SMTP servers. That being the case, we can't send an unlimited number of emails. So, email notifications had been globally - Site Administration > General > Messaging > Notification settings, which is located at server.url/admin/message.php

When there was a request to allow emails of a particular type to particular users, after enabling the email notification plugin at the above page, the next time a forum post was made, there was a cascade of Send user digests failed and Send user notifications failed messages.

For the immediate failure messages to stop, deleted all the adhoc tasks from mod_forum,

delete from prefix_task_adhoc  where prefix_task_adhoc.component = 'mod_forum';

I had previously set emailstop=1 on the database users table, for all users except the handful which should receive emails. Possibly the reason for the failures was that forcesubscribe=1 was set for many forums for many / all users. 

So, now I set it to zero (email disabled) for all forums on this instance, with

update prefix_forum set prefix_forum.forcesubscribe = 0;

and also updated the defaults,
Site administration > plugins > plugins overview > (chose mod_forum) > settings >

site.url/admin/settings.php?section=modsettingforum

and set subscription mode = subscription disabled for both defaults,
forum_announcementsubscription
and
forum_subscription 

Also, went to prefix_forum_subscriptions table and deleted all entries - which I suppose would be various users' subscriptions to various forums.

Hopefully this is sufficient to prevent the hundreds of failed send notification tasks. 

Update 13 Nov - Again received hundreds of task failed messages. Asked Claude.ai, and made the following changes as suggested, in addition to the above.

# Individual discussion subscriptions might still exist
DELETE FROM prefix_forum_digests;
DELETE FROM prefix_forum_discussion_subs;
UPDATE prefix_user SET maildigest = 0 WHERE emailstop = 1;
# Users might be getting auto-subscribed when they post
UPDATE prefix_forum SET trackingtype = 0;
TRUNCATE prefix_forum_track_prefs;

Tuesday, November 04, 2025

run 'Issue Certificates' task more often

There was a request for setting up email notifications for one Moodle course, a particular user to be notified when any user completes that course. I had earlier set many tasks to run less often due to our server being overloaded. 'Issue Certificates' task was one of them, especially since it needed some optimizations as per this thread. Checking the logs, I could see that issue certificates was taking between 30 and 120 seconds - so, increased the scheduled task cron frequency from once a day to once an hour, for two of our Moodle instances. 

Set to run every hour at the 30th minute (8:30, 9:30 etc) on one instance and at the 45th minute (8:45, 9:45, etc) on the other instance, in Site Administration > Server > Tasks > Scheduled tasks > \mod_customcert\task\issue_certificates_task