Building OpenRV on macOS with DNxHD support

Assumptions:

Apple Silicon/arm64 Architecture – build machine has M4 CPU
macOS Sequoia 15.6.1
All builds to be done in $HOME/src. If that folder doesn’t exist:
mkdir ~/src; cd ~/src

Basics:

  1. Xcode 16.4, download from Apple App Store
    Install Xcode command line tools – xcode-select —install
  2. Qt 6.5.3 – Download the installer from https://my.qt.io/download, you’ll need an account to do this, then enable “Archive” to install this version
  3. Homebrew
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    brew update
  4. Install Homebrew dependencies
    brew install ninja readline sqlite3 xz zlib tcl-tk@8 autoconf automake libtool python@3.11 yasm clang-format black meson nasm pkg-config glew wget yaml-cpp pystring ptex freetype dcmtk qt@5 python@3.11
  5. Install an older version of cmake
    cd ~/Downloads; wget https://github.com/Kitware/CMake/releases/download/v3.31.7/cmake-3.31.7-macos-universal.dmg; open ./cmake-3.31.7-macos-universal.dmg
  6. Drag and drop the CMake icon to the Applications folder, then install cmake to /usr/local/bin
    sudo "/Applications/CMake.app/Contents/bin/cmake-gui" --install=/usr/local/bin

First library version mismatch: yaml-cpp

brew unlink yaml-cpp
mkdir -p /opt/homebrew/Cellar/yaml-cpp/0.7.0-static
cd ~/src
git clone https://github.com/jbeder/yaml-cpp.git
cd yaml-cpp
git checkout 0.7.0
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/homebrew/Cellar/yaml-cpp/0.7.0-static -DBUILD_SHARED_LIBS=OFF -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOOLS=OFF
cmake --build build -j
sudo cmake —install build
sudo ln -sfn /opt/homebrew/Cellar/yaml-cpp/0.7.0-static /opt/homebrew/opt/yaml-cpp

Second library version mismatch: fmt

brew unlink fmt
mkdir -p /opt/homebrew/Cellar/fmt/9.1.0
cd ~/src
curl -LO https://github.com/fmtlib/fmt/archive/refs/tags/9.1.0.tar.gz
tar xzf 9.1.0.tar.gz
cd fmt-9.1.0
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/homebrew/Cellar/fmt/9.1.0 -DBUILD_SHARED_LIBS=ON -DFMT_TEST=OFF -DFMT_DOC=OFF
cmake --build build -j
sudo cmake --install build
ln -sfn /opt/homebrew/Cellar/fmt/9.1.0 /opt/homebrew/opt/fmt

Building RV:

  1. Download the source code
    git clone --recursive https://github.com/AcademySoftwareFoundation/OpenRV.git
    cd OpenRV
  2. Make sure the build knows about Qt 5
    export Qt5_ROOT="$(brew --prefix qt@5)"
  3. Make sure that we are using the right VFX platform
    export RV_VFX_PLATFORM=CY2024
  4. Initialize the RV build command aliases
    source rvcmds.sh
  5. Make and load the Python 3.11 virtual environment
    python3.11 -m venv .venv
    source .venv/bin/activate
  6. Upgrade pip to the latest version
    pip install --upgrade pip
  7. Setup RV
    rvsetup
  8. Configure RV with support for DNxHD
    rvcfg -DRV_FFMPEG_NON_FREE_DECODERS_TO_ENABLE="dnxhd" -DRV_FFMPEG_NON_FREE_ENCODERS_TO_ENABLE="dnxhd" -DCMAKE_PREFIX_PATH="/opt/homebrew/opt/yaml-cpp:$(brew --prefix pystring):/opt/homebrew/opt/fmt"
  9. Build RV
    rvbuild
  10. Install RV – just makes the RV.app package for macOS
    rvinst
  11. Test it, to make sure it works
    cd _install; open RV.app

Extras/Installer Package:

  1. Install create-dmg
    brew install create-dmg
  2. Build the installer package – sign with your Apple Developer ID certificate if you have one
    create-dmg --volname "RV Installer" --window-pos 200 120 --window-size 600 400 --icon-size 100 --icon "RV.app" 175 190 --hide-extension "RV.app" --app-drop-link 425 190 --codesign "Developer ID Application: Alan Smithee Films Inc. (1234567890A)" ~/src/OpenRV-v3.0.0-arm64-Installer.dmg RV.app

Poor Man’s QTake

On my current show, I needed to have access to the video feed from the DIT cart, but resources were limited and we sadly did not have a video assist/playback person to help. On large budget projects you would typically install the QTake app on your iPad so you didn’t have to stand in the often crowded space next to the monitor, but what to do on this one?

I came up with a solution. Sound was kind enough to let me attach a BNC cable to their video out port on their cart, and from there, I needed a few more pieces of tech. These were:

  1. A BlackMagic Design Web Presenter HD – $515 new at BHPhotoVideo.com; likely cheaper used on eBay
  2. A Raspberry Pi – I had a RPi 3 Model B Plus hanging around, which works just fine. You can pick a new RPi 5 up from adafruit.com for $80 and a case for $15.95.
  3. An Ethernet Cable
  4. A reasonably modern iPad with the VLC app

First, you need to provision the RPi. I used their handy Raspberry Pi Imager to install. The link is a macOS download; just search the internet for Raspberry Pi Imager for other operating systems. Be sure to set up your new RPi to connect to the same WiFi that your iPad will eventually connect to, and turn SSH on.

When the device is powered up, SSH into it, connect an Ethernet cable between the Web Presenter and your RPi, and assign a static IP address to the wired Ethernet port:

sudo nmcli c edit "Wired connection 1"set ipv4.method manualset ipv4.address 172.16.0.2/29save persistentactivatequit

Next, you’ll need to set up a RTMP server on your RPi. I asked ChatGPT for help on this – I’ve edited the instructions somewhat after I tested them to make sure that they work.

Now, time to configure the Web Presenter. BlackMagic’s Web Presenter Setup utility is super easy to use. The download link is once again for macOS. I set it up as follows:

I chose “POORQTAKE” as a key for my live stream, and clicked the “On Air” Button on the front of the unit.

Last, on the iPad, I launch VLC, click the “Open Network Stream” button, and use the URL rtmp://YOUR.RPI.WIFI.IP/live/POORQTAKE, and click “Open Network Stream”, and there you have it!

Setting up a RTMP Server on a RPi

Setting up an RTMP (Real-Time Messaging Protocol) streaming server on a Raspberry Pi can be done using a software package like NGINX with the RTMP module. Here’s a step-by-step guide to get you started:

Requirements:

  • A Raspberry Pi (preferably a 3B, 3B+, or 4 for better performance)
  • Raspbian or Raspberry Pi OS installed
  • Internet connection

Step 1: Update Your System

Open a terminal and update your system packages:

sudo apt update
sudo apt upgrade -y

Step 2: Install Dependencies

You need to install the required dependencies to build NGINX from source:

sudo apt install -y build-essential libpcre3 libpcre3-dev libssl-dev zlib1g-dev libpcre3 libpcre3-dev openssl libssl-dev

Step 3: Download NGINX and the RTMP Module

You will need to download both NGINX and the RTMP module:

cd ~
wget http://nginx.org/download/nginx-1.25.2.tar.gz
wget https://github.com/arut/nginx-rtmp-module/archive/refs/heads/master.zip

Unpack the files:

tar -zxvf nginx-1.25.2.tar.gz
unzip master.zip

Step 4: Build and Install NGINX with RTMP Module

Navigate to the NGINX source directory and configure the build:

cd nginx-1.25.2
./configure --with-http_ssl_module --add-module=../nginx-rtmp-module-master

Compile and install:

make
sudo make install

Step 5: Configure NGINX for RTMP

Edit the NGINX configuration file located at /usr/local/nginx/conf/nginx.conf:

sudo nano /usr/local/nginx/conf/nginx.conf

Add the following RTMP configuration to the nginx.conf file:

worker_processes  1;

events {
worker_connections 1024;

}

http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;

location / {
root html;
index index.html index.htm;
}
}

}

rtmp {
server {
listen 1935;
chunk_size 4096;

application live {
live on;
record off;
}
}

}

Save the file and exit.

Step 6: Start NGINX

You can now start NGINX using the following command:

sudo /usr/local/nginx/sbin/nginx

Step 7: Test Your RTMP Server

To test your RTMP server, you can use a streaming software like OBS Studio:

  1. Open OBS Studio and go to Settings.
  2. Under Stream, select Custom.
  3. Enter the RTMP server URL: rtmp://<Your-Raspberry-Pi-IP>/live
  4. Set the stream key to whatever you like.

Step 8: Verify Your Stream

To view your stream, you can use a media player like VLC:

  1. Open VLC and go to Media > Open Network Stream.
  2. Enter: rtmp://<Your-Raspberry-Pi-IP>/live/<stream-key>.

Optional: Enable NGINX on Boot

To have NGINX start automatically on boot, add it to your rc.local:

sudo nano /etc/rc.local

Add the following line before exit 0:

/usr/local/nginx/sbin/nginx

Save and exit.

You’re Done!

Your Raspberry Pi is now set up as an RTMP streaming server. You can stream video content to it and serve it to multiple clients.

VFX Supervision on “Breathe”

VFX work on Thunder Road’s “Breathe” by Brainstorm Digital

In March of 2023, I met with Thunder Road, and during the initial meeting, they asked if I might be interested in taking over VFX Supervision duties on a film they had recently completed principal photography on – “Breathe“, directed by Stefon Bristol, and starring Jennifer Hudson, Milla Jovovich, Quvenzhané Wallis, and Sam Worthington.

This movie is set in Brooklyn, New York in the year 2039. In this world, due to the ravages of man-made climate change, the oxygen has vanished from Earth’s atmosphere, and the oceans have evaporated. All that remains is a desert wasteland, devoid of life, where all oxygen-dependent life forms have gone extinct. All, except for a very clever family, who have figured out a way to produce oxygen, grow food, and survive inside a heavily-fortified former nursery in Bushwick.

The movie was entirely shot in Pennsylvania. Exteriors were filmed in a neighborhood in Chester, PA; interiors on a sound stage, and a few additional exteriors were shot in downtown Philadelphia.

The VFX challenge here was to take the exterior photography and realistically set it in a post-apocalyptic, desiccated New York. Special care had to be taken to ensure that no green plant life was visible anywhere. In addition, we had to fully consider how the built environment would react to an atmosphere devoid of oxygen and moisture. Metal would not rust, and concrete would rapidly lose its structural integrity, as two examples.

In order to bring our director’s vision to life, I turned to the following creative partners:

We were able to complete a total of 394 visual effects shots in a period of 10 weeks. These included construction of 7 distinct all-CG environments; 6 NYC environments were done by Brainstorm, and the Philadelphia exteriors were done by Nexodus.

I couldn’t be more proud of the work that we were able to pull off on this project. The environments that we built really contributed to the sense of isolation and dread that the heroes in our story felt. Principal photography did not take place in many exterior locations, and the VFX in this film really fleshed out the world that Stefon Bristol was trying to build.

As a parting gift, Mr. Bristol was kind enough to reward me with a main-on-end credit on his film – my very first! It looks good here coming from the Avid, but it looked even better seeing it on the big screen in April of this year!

The Beer Barrel/Flanders Red Experiment

Back in October 2016, I went to a garage sale at the Eagle Rock Brewery. Most of the guys who are involved with that fine establishment have been and still are avid home brewers. The garage sale was a treasure trove of goodies, and I scored this sweet, 59.6 gallon used wine barrel for $50. I believe the wine barrel was originally used at a vineyard in France. The Eagle Rock Brewery guys used it to barrel age a sour. Here’s the barrel just sitting in my garage:

Barrel on the hand cart

I needed to be able to lay the barrel on its side in order to fill it. Morebeer.com sells metal wine barrel racks for about $100, however, their profile was too tall, and I needed the rack to be on casters. It would eventually live underneath my basement stairs, so I needed to make sure that it took up as little space as possible. I also thought that it would be a lot easier to deal with if I could roll it around while full, hence the casters. So I built this:

Wooden barrel cradle

The barrel sits nicely in the cradle, and it looks pretty smart too, if I do say so myself:

Barrel sitting in the cradle

Now, I needed to fill it! The most laborious process here involved brewing 60 gallons of Flanders Red. Sadly, my home brew setup only allows me to brew 5 gallons at a time, so, this took four weekends of hard work. I pitched two packets of Roseleare Ale Yeast when I brewed the first batch, but after that, I just added more wort. Since this would be a sour beer, I didn’t need to be as fastidious about my sanitation as usual. In order to speed up the process considerably, I cooled the wort by tossing in 10 pounds of ice. Brought it down to about 65º in a matter of minutes! Also, since the recipe called for a 90 minute boil, it helped get my gravity close to the target original gravity of 1.061.

On October 30, 2016, I finally filled the barrel! Here it is, up to the brim:

Barrel full to the top!

I got the gravity relatively close to the target – my final number was 1.060. I calculated this rather unscientifically by taking a gravity reading for each 5 gallon batch, adding them all together, and dividing by 12. So, assuming each batch was exactly 5.000 gallons, this number will be totally accurate!

Here is the full barrel, tucked neatly under the stairs:

Barrel safely stowed under the basement stairs.

I’m going to taste this after 6 months of aging, on April 30th, 2017. I plan on aging it for 18 months, so I plan to filter it and transfer it to kegs on April 30th, 2018. I can’t wait to share with all my friends!

 

Lexus LaceUp Series – Ventura Half Marathon Race Report

This is the first race in a series of races as I train and prepare for my Boston qualifying attempt on May 28th, 2017.

This race took place on Saturday, October 22nd, 2016, with a start and finish at Surfer’s Point, in Ventura, CA.

For readers who have not been to Ventura, I highly recommend it as both a city to check out and as a host city for endurance events. I have done several triathlons here previously. Most of the events take place right on the water, and it is usually quite cool, even in the summer time.

I was particularly concerned about this race, as I had come down with a sinus infection the previous weekend. I felt under the weather throughout the week, and had missed three different training runs. I stayed late at work on Friday night and got in to Ventura around 9:00 pm. By the time I got some dinner and got settled for the night, it was around 10:30 pm. I stayed in a lovely AirBnB on Friday night that was about a mile away from the starting line. However, I was unable to get to sleep immediately, so when I awoke up at 5:30 am, I estimate that I had a little over six hours of sleep, which was not ideal.

When the alarm rang, I checked the weather on my phone and it said that it was 56º out, and from the sound of the windows rattling around, it was also a little windy. Sadly, I had to leave my phone in my room, as I was by myself and didn’t want to carry it, so I don’t have any pictures to accompany this post.

I ate a Luna bar, drank a bit of water, and jogged the mile to the starting line, having left my AirBnB at around 6:00 am. I signed my waiver and stood in line for my bib number and timing chip. By the time I had all of my paperwork in order, I was actually a little chilly, so I went for another 8 minute jog down the beach.

The race started at 7:00 am, so at around 6:50, I made my way to the starting line. There were no corrals at this event, nor were there elite runners. There were several pacers visible, so I figured I would stick with the 1:40 pacer as my goal pace for this race was 1:38:15.

The organizers were prompt, and the race started at 7:00 on the nose. There was no starting gun or air horn, since they wanted to be quiet for the neighbors. Instead, they had a lady come out and shout “3, 2, 1, GO!!!”. Somehow, it felt a little more personal than an air horn. I was off! My coach had warned me to try and keep the pace between 7:25 and 7:35, and if I was really struggling, to not go slower than 7:45. To heed her advice, I figured I would stick with the 1:40 pace group, but it seems that the pacer was a little over eager, as we completed the first mile in 7:18! It would appear that he realized this and slowed way down, but I kept going, so for the majority of the race I was running by myself.

I neglected to heed my coach’s advice for the next couple of miles. The first part of the race is a loop that goes South for a mile and a half along a road, and then hooks back up with the shore line bike path and heads North to return to the starting line. I believe that this is the entire 5K course. The sun had not yet risen, it was cool, flat, and sheltered from the wind. I felt very strong, and my heart rate stayed in the 160-range, so I figured I was OK.

Turns out, I had made a grievous error in judgement; I had started too hard. Around mile 3.5, the shore line bike bath took a hard right turn, and began to head inland, up the hill towards Ojai. The sun had come up at this point, and I had neglected to wear sunglasses. The worst part, however, was that it was quite windy that day, and as I begin to head up the hill, I was faced with what seemed to be a 20-mph head wind. I slowed down considerably, from 7:25 a mile to 7:37 and then 7:43. I remembered that I couldn’t go slower than 7:45, but I was giving it everything I had to make that pace.

The turnaround was at mile 8. After I came through it, what was once an uphill battle facing a head wind was now a gentle downhill with a tail wind. My pace picked back up again, and I was feeling more confident. However, I tried to remind myself that I shouldn’t go faster than 7:20.

The sun had risen at this point and it was warming up considerably. There was not a lot of shade on the bike path, and around mile 10.5, I started to really feel it. It wasn’t that my heart rate was too high, it was hovering around 172. It felt as if I had ran out of gas, and that my legs didn’t have anything left. I had been munching on Clif Blocks – one every 10 minutes or so, but this time, I ate two, for a little extra kick. After about a half a mile, I felt better, and continued to press on. I was sticking to around a 7:25 pace.

Just after I passed the marker for mile 12, I felt the same exhaustion again, except this time it was considerably more intense. The downhill of the bike path had transitioned into a slight uphill on city streets, and we were now in full sun. My pace slowed down to 8:00, and my heart rate spiked to 180. I was really struggling at this point. Fortunately for me, a lady that I had seen at the starting line and had struck up a conversation with passed me. I recognized her, said hello, and she gave me some words of encouragement.

It was just what I needed to hear. I realized that I had less than half a mile to go, so I gritted my teeth and decided to push as hard as I possibly could. I got my pace down to 7:43, and when I passed the marker for mile 13, I transitioned to as much of a sprint as I could muster.

I crossed the finish line and stopped my watch. I had done the race in 1:38:59. This was slightly slower than my goal pace of 1:38:15, but my GPS said that I had gone 13.24 miles, which is a little longer than a half marathon, so in reality, I had actually beaten my goal pace by a couple of seconds. It’s not official, but I’ll take it!

I felt light headed and a little nauseated after I finished, as I had given it everything I had. After I stretched out, got myself some pizza, a little water, and even a free beer and a massage, I felt much better!

I would definitely run this race again. I felt as though the water stops were a little infrequent, but then again, I probably could have done a better job with hydration the night before and the day of.

Here are the official results of my finish:

Ventura Half Results

Here are the nitty-gritty details, from Garmin Connect:

https://connect.garmin.com/modern/activity/1417222576

Thanks for reading!

Why not try and qualify for the Boston Marathon?

In April of this year, I decided that I would try and qualify for the Boston Marathon. I don’t believe that I was born a talented athlete; in fact, far from it. However, I figured out in my early thirties that I was actually pretty decent at endurance sports. I might not be super fast, but I had the determination, desire, and the build to run for long distances.

After you run a couple of marathons, and an assortment of 10k races and the like, where do you go from there? I love triathlons as well. I have done a half Ironman, along with several sprint and Olympic distance races. The next logical step might be a full Ironman. This scares me a little bit though. The volume of training required for a full Ironman is tremendous. Sure, you could do less if you just want to finish, but I’d like to do more than just finish. I’d like to finish strong.

Maybe for the next year or year and a half, I should focus on my running, and see if I can do something that most would consider impossible: qualify for the Boston Marathon. When I made the decision, I was about to turn 37. In my age group, men ages 35-39, I would have to run a qualifying race in 3:10:00 or better. That’s a 7:15 pace per mile. That seems pretty daunting, especially when you consider that beating 3:10 doesn’t necessarily guarantee you a spot in the race; it depends on how many other people in my age group qualify that year, as spots are limited and awarded based on your qualifying time.

My fitness at the time was not terrible. The last 10k race I had done was on 12/05/2015, and I completed this in 47:31. According to my GPS, it was a distance of 6.26 miles, with an average pace of 7:36 a mile. Then, I checked the race time predictors that are available online. In order to run a 3:10 marathon, I should probably be able to run a 10k in 41:17, at a pace of 6:39 per mile. That’s an improvement of nearly a minute per mile. I think, when I was 12 or 13, I ran a mile in 6:36. The last time I attempted to run a mile where I actually kept records was on 05/15/2011. That day, I ran the mile in 6:44. So how in the hell do I get from a 47:31 10k to a 41:17 10k?

I guess it was time to get serious. I reached out to my friend Taryn and asked her if she would consider coaching me. She agreed, and has been invaluable in helping me along the way. I figure that anyone who has ran 35 marathons (now, probably 40) could offer some pretty relevant advice on how to run just one.

As I write this, I am just shy of six months into the training. The first four months were dedicated to building a good, solid base. Right now, I am focused on training for the California International Marathon, on December 4th. This is going to be my first prep race, just to see how I do. I am going to attempt to qualify for the Boston Marathon by running the Mountains 2 Beach Marathon on May 28th, 2017. Yesterday, I ran a half marathon in 1:38:59, which is a dramatic improvement from where I was. Maybe next May I’ll make it!!!

MacOS idle time daemon

I put together a pretty simple daemon which has been compiled for and tested on MacOS 10.9.1 Mavericks. It is designed to run in the background, and at pre-set intervals check the system idle time. When that idle time meets or exceeds a pre-configured value, the daemon runs an executable. When the user moves the mouse or presses any key on the keyboard, the daemon will execute another program.

This can be incredibly useful if you would like workstations to participate in a render farm if they are idle for a certain amount of time, but remove themselves from the farm when they are being used by an artist.

To use, start by downloading the installer:

idleexecd

Or, if you would like to see how I did it, build it yourself, or use the code for something else:

idleexecd.src

Configuring the daemon involves two mandatory steps, and one optional one.

First, edit the configuration file, located at /Library/Preferences/org.n3d.idleexecd.config.plist. I originally wrote this to put machines on a Deadline render farm, so it is configured to do just that. The config file looks like this:

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”>
<plist version=”1.0″>
<array>
<dict>
<key>Process Name</key>
<string>DeadlineSlave</string>
<key>Run As</key>
<string>farm</string>
<key>Idle Time Launch Delay</key>
<integer>15</integer>
<key>Startup Command</key>
<string>/Applications/Thinkbox/Deadline6/DeadlineLauncher.app/Contents/MacOS/DeadlineLauncher -slave -nogui</string>
<key>Shutdown Command</key>
<string>/Applications/Thinkbox/Deadline6/DeadlineSlave.app/Contents/MacOS/DeadlineSlave -shutdown</string>
</dict>
</array>
</plist>

For process name, choose any value that is appropriate.  Run as is the user that the process will execute as. Pick any valid user besides root. The idle time launch delay is the idle time, in minutes, that the daemon will wait before it executes the startup command. The startup command will be executed when the machine has gone idle for the set amount of time. When the user moves the mouse or hits a key on the keyboard, the shutdown command will be executed. To add multiple commands to execute, simply copy and paste everything between <dict> and </dict> including the tags, and enter new command specifications.

If you wish to edit configuration parameters for the daemon, such as log file destination, edit /Library/LaunchDaemons/org.n3d.idleexecd.plist. The -p 1 command line argument is the polling interval, in seconds. Leaving this default will cause the daemon to check the idle time every second. This can be increased to 10 seconds, but when the user interacts with the machine, they may have to wait up to 10 seconds before the daemon responds to the input. The -v argument specifies verbose logging. The default location for logging is /var/log/idleexecd.log.

Last, reboot your machine for the changes to take effect.

TL;DR: Download and install idleexecd to have your OSX 10.9 workstation participate in a Deadline 6 render farm after it has been idle for 15 minutes.

Adding a .3DL file to Hiero’s Viewer

1. Copy the .3dl file into the following directory:

/Applications/Hiero1.6v1/Hiero1.6v1.app/Contents/Plugins/OCIO/nuke-default/luts

2. Edit the following file in your favorite text editor:

/Applications/Hiero1.6v1/Hiero1.6v1.app/Contents/Plugins/OCIO/nuke-default/config.ocio

3. Look for the section in the file that specifies the display luts. It looks like this:

displays:
  default:
    - !<View> {name: None, colorspace: raw}
    - !<View> {name: sRGB, colorspace: sRGB}
    - !<View> {name: rec709, colorspace: rec709}

4. Add another view definition for your custom LUT:

    - !<View> {name: LogCRec709, colorspace: LogCRec709}

5. Go to the very end of the file, and add a colorspace definition:

  - !<ColorSpace>
    name: LogCRec709
    family: ""
    equalitygroup: ""
    bitdepth: 32f
    description: |
      Conversion from Alexa LogC to Rec. 709
    isdata: false
    allocation: uniform
    allocationvars: [-0.125, 1.125]
    from_reference: !<FileTransform> {src: LogC_to_Rec709.3dl, interpolation: linear}

6. Restart Hiero

And that should do it.