Introducing the Disney+ Application Development Kit (ADK)
Tom Schroeder, Sr. SWE / Technical Lead, Native Client Platform, Living Room Devices
Dustin Jordan, Technical Lead, Native Client Platform, Living Room Devices
Sky Schulz, Manager Software Engineering, Native Client Platform, Living Room Devices
Ryan Cain, Senior Director, Living Room Devices
Mike Hanley, VP Software Engineering, Living Room Devices
Michael Fay, VP Media Distribution Technology
Disney’s success in going Direct to Consumer has created remarkable demand from ISPs and operators worldwide to get the must-have Disney+ application on their devices for their consumers. To meet this growing demand for our service to be installed locally on set top boxes, Disney Streaming needed to develop unique software that would enable a baseline for our partners to deploy with that gave them access to our content fast and efficiently while still enabling us to control the environment and ensure a QoE that our customers expect.
Even before the launch of Disney+ in November 2019 we knew we’d have a large number of our partners very interested in having an opportunity to launch Disney+ on their devices. From set-top boxes to uber-powerful game consoles, Disney+ would be and is showing up on a wide range of devices across the globe.
In order to support this device footprint, both where we’d be doing the porting and where our partners knew their devices the best, we knew we’d need to build an incredibly portable runtime that would run on everything from 10+ year old MIPS based devices to modern x64 processors and GPUs.
This bootstrapped our effort to build our Native Client Platform v2 (NCPv2) codenamed “m5”. (Feel free to speculate on the meaning of “m5”, it does have something to do with Mickey, but if you’d really like to know, send us your resume and join our exciting endeavor.)
The NCPv2 engineering effort began late 2019, and less than 18 months later we launched. This 2019 start was a File -> New Project effort where our runtime is written entirely from the ground up in C ’99 for broad device and compiler compatibility. For client app development we chose Rust, targeting WebAssembly (WASM), for ease of web deployment and app updatability outside of any firmware update cycles that limit our ability to update the C-based runtime.
It is amazing to think that in just 18 months we went from a whiteboard to running on tens of millions of devices worldwide!
A Brief History of the Disney+ ADK
For the last 2 years, teams around the world have been collaborating and developing an Application Development Kit (ADK) which encompasses the code that enables licensed distributors to port the Disney+ application onto their own platforms and streamline the process straight to testing and QA with us. The ADK is available as a software package that contains all the tools a distributor could need to build on their diverse device platform. The recently launched Disney+ ADK will be used in cases where our partners have a deployed platform and need a series of libraries and particular programming language or to include advanced hardware that can communicate with an appropriate embedded system to represent to their users the Disney+ experience. The ADK offers a common way for over a thousand different combinations of deployments and allows our Disney teams to normalize the market and enable distributors while keeping our teams focused and nimble on our next set of features and products.
In Spring of 2019 our leadership team tasked us with coming up with a plan to create the Disney+ ADK program in order to be able to provide the Disney+ application to our video distributors around the globe. At the same time, internally, we also saw a number of platforms where we’d need to roll out our own runtime for devices that don’t provide a robust software development environment.
Imagine being asked to port your crown jewel application and run it on millions of new devices and delight customers with our amazing Disney storytelling in hundreds of new regions throughout the world. What an amazing opportunity!
With this challenge we knew we couldn’t build a team of thousands of engineers who specialized in the most esoteric and secure hardware and middleware in the world. Instead we needed a plan that would allow us to scale to these hundreds of unique devices.
Enter the Disney+ ADK, where we have taken our ground-up build of NCPv2 and created a clean abstraction layer and built a well documented program for our distributors, who know their hardware and software best, to port our runtime to their devices. Phew, no need to learn every MIPS SoC released over ten years ago!
Technical Details of the ADK
Now that we had a plan for how we’d provide the Disney+ ADK to our distributors, we needed to dig into the technical specifics of actually delivering on our great ideas.
We broke down our delivery into a few major components, including the following:
- Native Client Platform v2 Runtime: written in C’99 and deployed as a binary to set-top boxes and game consoles.
- Native Video Engine: written in C++’98, named Disney Streaming Native Video Engine (DSS-NVE)
- Platform Abstraction Layer: for hardware porting named Steamboat
- Application Runner Binary: written in C’99 and codenamed Merlin
- Disney+ Client Application: The Disney+ client application. Written in Rust, compiled to WebAssembly, remotely web hosted in AWS
The various components were designed from the onset to allow us to support multiple distributors and multiple client applications without requiring bespoke client application implementations (hence the abstraction with a runtime and hardware porting layer).
How it works: The simplest way to understand the ADK solution is to compare it to a traditional browser-based solution. In a browser-based solution, you have two basic components:
- The browser engine, which contains a video player sub-component, and is written in a compiled language like C
Notice that in this architecture, the browser engine is provided by the platform vendor, and the application is provided by Disney Streaming.
Why it matters: There is a common misconception that a HTML5 browser-based application can just be deployed on any browser-capable device and it will just work. In practice, browser capabilities on set-top boxes are very mixed and each new device becomes essentially a new application development cycle because of differences in browser implementation.
Disney+ ADK Components
For the engineers reading this post, now we’re getting to the really interesting part.
Native Client Platform v2 Runtime (m5 Core)
NCPv2 contains all of the native runtime services including but not limited to rendering, input, and network service required by the application team to build Disney+.
NCPv2 is responsible for loading and running the application code, running the main application message loop, network and persistence operations, and rendering dispatch and display output.
Depending on the particular installation NCPv2 may also be a burned in component and therefore not be easily updatable.
NCPv2 is also delivered as either a binary executable for partners where we do the ports or source code for partners who do the port themselves.
Internally, we built NCPv2 for Windows, Linux, Raspberry Pi 1/2/3/4, PlayStation 4, and a number of other partner reference devices.
Native Video Engine
Our DS-NVE or Native Video Engine is the bread and butter of our application experience, since who doesn’t want to watch videos on Disney+? It contains a significant amount of proprietary technology and must be delivered in binary form both internally and externally.
DS-NVE incorporates everything that’s needed to playback video in Disney+ from our 720p streams to UHD Dolby Vision and Dolby Atmos playback.
Platform Abstraction Layer (Steamboat)
The Steamboat API provides three major platform abstraction services:
1. NCPv2 Core Runtime (Steamboat Core);
2. NCPv2 Render Hardware Interface (Steamboat RHI);
3. DS-NVE media APIs (Steamboat Media).
Steamboat Core provides fundamental features, such as memory management, threading, file I/O, and low-level network I/O.
Steamboat RHI provides an abstraction layer over bespoke graphics hardware APIs, such as OpenGL ES, PlayStation, DirectX, or Metal.
Steamboat Media provides an interface to platform-specific media functionality.
Thanks to our Partner Integration Engineering team the average distributor needs to only implement 14 methods of the Core Runtime, before they can run the Disney+ application (outside of video playback). This is due in large part to reference implementation ports provided with the ADK. A default POSIX port using an OpenGL ES rendering back-end has served as the most popular starting point. Many distributors have the application running on their devices in as little as a single afternoon!
Distributors don’t have to stop there. The Steamboat RHI allows distributors to implement their own rendering back-end. This could be a more modern version of OpenGL, or something completely different like DirectX or Vulkan. In fact, the Core team leveraged the RHI to port m5 onto both PlayStation 4 and 5 earlier this year. The Steamboat RHI is structured as such, that these rendering ports were bootstrapped within a few days, and ready for production in as many weeks.
Application Runner Binary (Merlin)
The Application Runner Binary contains the entry point of the m5 application and is where execution starts. Its primary responsibility is to perform a software update of the m5 application, load the core engine framework binary application and call the main engine entry point.
The AppRunner is architected to be a “burned in” component of the m5 platform, meaning that it may exist in ROM and not be updatable. Therefore it is designed to be simple and reliable and the NCP Core team will be particularly diligent in its testing and automation of this piece of code since it may not be patchable remotely.
Since the AppRunner is delivered as a binary application it represents an integration point for channel partners.
Disney+ Client Application
The application code contains all the logic for the specific application being built on top of the Core Engine Runtime.
The application code is designed to be updatable by the application runner component, Merlin, and therefore is not in a machine executable format, but a compiled Web Assembly module that is remotely hosted in the cloud. The application is downloaded, dynamically loaded at boot time, then interpreted by the Core Engine throughout its runtime lifecycle. Because the application is developed on top of the Core runtime APIs and the Steamboat platform abstraction layer, no integration with a platform- or vendor-specific SDK is required. This has the added benefit that application updates can be made available to our guests around the world, any time day or night, without having to make binary updates to their device, circumventing lengthy vendor submission processes along the way.
Given the large number of platforms and the differences in device capabilities (e.g. CPU performance, amount of memory, GPU performance, video capabilities like HDR and 4K/UHD support) we leverage Raspberry Pi’s as a cost-effective solution for development. By benchmarking core and application performance on such slim device profiles, we can guarantee a sincerely enjoyable guest experience across an even wider spectrum of devices like aforementioned consoles and set top boxes.
Often we will setup a Raspberry cluster as shown below:
A development build of the Disney+ application running 71 FPS on a Raspberry Pi 4:
Test Tooling & Automation
To help distributors integrate the ADK into their set-top boxes we developed a comprehensive suite of tests which leverage a Command and Control (C&C) bus in the m5 Core. The C&C bus leverages WebSockets to allow for:
- Console access to the ADK
- Ability to run tests directly on the set-top box using a web experience as part of our Partner Portal
- Enable test automation scenarios
Distributors are able to utilize the certification tooling all along the porting process. It begins with an initial tier of unit tests built around Steamboat, to allow partners to test individual system components as they are ported to a new device. Once the initial tier is complete, subsequent tiers of integration tests are available to test the application running on the new device. This includes scripted automation tests and a soft remote!
Global partners are lining up to engage our ADK and deliver the Disney+ experience to their users and with thousands of combinations of devices, systems and middleware. Disney’s approach to ADK remains the best way to maintain market relevance while assuring our velocity inside Disney Streaming as we develop more products and launch in more areas. Only with this technology are we able to meet the market demand at scale and control our experience while ensuring that our customers are satisfied with a consistent experience every time they see the Disney+ logo, no matter what device they are on or where they choose to experience our content.