====== Hacking the Insta360 ONE RS ======
{{ .:insta360:insta360-one-rs-4k.jpg?direct&360|The Insta360 ONE RS with the 4K Boost lens}}
Just two years after purchasing the **[[sjcam-8pro|SJCAM SJ8 Pro]]**, in June 2023 I decided to replace my action camera with a new **Insta360 ONE RS**. The SJCAM was quite good (but only after heavily customizing the firmware, both in terms of **color balance** and **video codec parameters**). The real sore point of the SJCAM is that **it is impossible to use it without looking at the screen**: if you press the REC button without looking you will never know if you have activated recording, if you have stopped it or if you have simply exited stand-by.
The Insta360 seems quite promising: it uses the same Ambarella H22 processor so it should allow **the same level of hacking** as the SJCAM, it seems to offer better support (firmware updates) and has different hardware modules (4K lens or dual 360° lens).
The best result I have achieved is to have **[[insta360_one_rs_wifi_reverse_engineering|reverse engineered the WiFi protocol]]**, so that I can control the camera with **[[https://github.com/RigacciOrg/insta360-wifi-api/|open source programs (Python scripts)]]** instead of the crap Android app that comes with it.
^ Hardware Specifications ^^
^ Hardware | 00A |
^ Firmware shipped | v2.0.0.4 |
^ Firmware upgraded (2023-06-15) | v2.0.8.4 |
^ Hardware SoC | Ambarella H22EVK K2 Board (DT) |
^ CPU | AArch64 Processor, 4 cores |
^ RAM | 90 Mb |
^ NAND memory | Toshiba TC58NVG1S3H 256 MiB |
^ Specifications with Boost 4K lens ^^
^ Sensor size | 1/2" 8000x6000 pixels |
^ Image resolution | 48 Mpixels JPEG |
^ Focal length | 16mm (35 mm equiv.) |
^ Aperture | F2.4 |
^ Weight | 125.3 g |
^ Size | 70.1 x 49.1 x 32.6 mm |
^ Video resolution | 4K @60 fps |
===== Defects and Problems =====
* Cannot activate the camera for first use without the app
* Cannot set date and time without the app
* WiFi open to the world with known password
===== Start and stop recording =====
The camera plays **different sounds** on power-on, power-off, start recording and stop recording, so you can somewhat **operate the camera without looking at its screen**. Unfortunately the sounds are not too so loud.
^ Power button | When the camera is off, press it shortly once to **power-on** the camera.\\ When the camera is on, press it shortly once to **toggle the screen on/off**.\\ When the camera is on, press it for ~2 seconds to **power-off** the camera.\\ For all the operations there is a **different acoustic feedback**. |
^ Record button | When the camera is on, press it shortly once to **start or stop recording**.\\ If the camera has the **screen turned off**, it will turn on again and start recroding, all with a single press.\\ If the camera is off and **QuickCapture** is enabled, press it once to **power-on the camera and start recording**.\\ If you started a QuickCapture, press it once to **stop recording and power-off the camera**. |
===== Start recording reaction times =====
^ Normal Recording | Start recording pressing the REC button: less than **one second**. |
^ QuickCapture | Start recording from camera turned off, pressing the REC button with QuickCapture mode enabled: less than **6 seconds**. |
===== Video Files Produced =====
^ Resolution ^ Bitrate ^ Format ^ GOP ^ Audio ^
| 4k 60fps | 100.0 Mb/s | AVC Main@L5.2 | M=1, N=15 | AAC LC 192 kb/s |
| 1080 60fps | 60.0 Mb/s | AVC Main@L5.2 | M=1, N=15 | AAC LC 192 kb/s |
===== Horizon lock and stabilization =====
The Insta360 ONE RS provides the **horizon lock** feature, but only in **software post-processing**.
To enable it:
* Tap the **video parameters** at the bottom of the screen to open the **adjust video mode** menu.
* Select **Post** instead of //FlowState//. This means that video stabilization will be performed in software post-production (out of the camera). FlowState means instead that stabilization is performed in-camera (videos saved on the SD card are already stabilized).
* Select a **4K** video mode with **30 fps or lower**.
* **Swipe left** from the right side to open the **shooting parameters** menu, you will find the **Horizon Lock** option that can be enabled or disabled.
Like any other videos captured with **Post FlowState stabilization**, you will find unstabilized videos on the SD card. The footage will have un-cropped frames and embedded metadata about **angular velocity**, **accelerometer** and **exposure time**. For each clip, both the low resolution video and the full resolution video have the same metadata.
It is possible to extract such metadata e.g. with the **exiftool** command line tool:
exiftool -api RequestAll=3 -api largefilesupport=1 -extractEmbedded "video.mp4"
It seems that there are about 1000 samples per second for angular velocity and accelerometer and one exposure time for each frame.
===== The Android app =====
=== Android app minimal requirements ===
* Android 64-bit system
* 4 Gb RAM
* 3 Gb storage space
* CPU minimal:
* Kirin 980
* Snapdragon 845
* Exynos 9810
===== Android app not working =====
The **[[https://play.google.com/store/apps/details?id=com.arashivision.insta360akiko|Insta360 Android App]]** is an huge monster of **676 Mb** to download (version 1.40.1, June 2023). Once installed it occupies **1.06 Gb** for the app and 128 Mb for the cache. The app requires **WiFi** and **Bluetooth** to be activated, it finds the camera and connect to it using the WiFi access point provided by the Insta360 camera.
Pairing the camera with the app is required to "activate" the camera. At the first activation you need to enable Bluetooth and WiFi on the Android device, probably the Bluetooth channel is used to broadcast the presence of the camera to the device and to pass the WiFi credentials (SSID and password) to then connect the phone to the camera's WiFi access point. It is required to accept the pairing on the screen of the Insta360.
[{{.:insta360:insta360-app-size.png?200|Insta360 Android App Size}}]
[{{.:insta360:insta360-wifi-ssid.png?200|Insta360 WiFi SSID}}]
I have a problem with the app, when I try to open the live view to use it as a camera remote control, **the app crashes**:
{{.:insta360:insta360-has-stopped.jpg?120|Instal360 Has Stopped}}
===== WiFi Communications =====
When the camera starts with the WiFi enabled, is turns on the **access point mode**, the SSID is composed by the serial number and the password is **88888888**. If something goes wrong the WiFi configuration could be reset and the password will be **1234567890**. The IP address of the camera is **192.168.42.1** and it accepts max 5 clients.
Using **nmap** I got the list of the opened ports on the camera:
PORT STATE SERVICE
23/tcp open telnet
53/tcp open domain
80/tcp open http
111/tcp open rpcbind
2049/tcp open nfs
6666/tcp open irc
7878/tcp open owms
8787/tcp open msgsrvr
9888/tcp open cyborg-systems
35215/tcp open unknown
39585/tcp open unknown
45223/tcp open unknown
56769/tcp open unknown
57041/tcp open unknown
You can access the GNU/Linux operating system running on the camera using **telnet**, login **root** without password.
It seems that the control commands are sent over port **TCP/6666**, but they are **not in cleartext**. Instead it seems that data transfer (e.g. retrieving videos an phots) happen over port **TCP/80** using plain HTTP protocol and URLs.
Port **TCP/7878** is open and it seems to accept **Ambarella API commands** like the ones accepted by the [[sjcam-8pro-ambarella-wifi-api|SJCAM SJ8 Pro camera]], but I was not able to start a communication because I always receive an error when I send the AMBA_START_SESSION command.
==== WiFi Configuration ====
The WiFi access point service is started by the script **/usr/local/share/script/wifi_start.sh**.
In normal conditions the starting is demanded to **/usr/local/share/script/ap_start.sh**, which uses the values found in **/pref/wifi.conf**. Is something goes wrong, the configuration is reset using the content of **/usr/local/share/script/wifi.conf**, where the AP_PASSWD is 1234567890.
If the file **/proc/ambarella/wifi.conf** exists (it is something called "Fast boot") the starting is demanded to **/usr/local/share/script/ap.sh** using the wifi.conf content to pass the command line parameters:
ap.sh [SSID] [PSK] [CHANNEL]
The directory **/pref/** is actually stored into an **ambafs** partition named **a:** bind-mounted from **/tmp/FL0/pref/**. The ambafs (Ambarella Filesystem?) is managed by a proprietary kernel module. The ambafs is also used to mount the SD Card under **/tmp/SD0**, reading the the device named **c:**.
==== Customize WiFi Configuration ====
How to change at least the WiFi password? FIXME
It turned out that changing the WiFi password into the file **/pref/wifi.conf** does not work: when you power cycle the camera that file will be overwritten with the default values.
===== Firmware Upgrades =====
==== In App Upgrade ====
It is possibile to upgrade the firmware using the Android app: the app will check if an upgrade is available from the internet, then it downloads and copies it to the camera.
==== SD Card Upgrade ====
{{ .:insta360:insta360-firmware-upgrade.jpg?100|Insta360 Firmware Upgrade}}
It is also possibile to manually download a new firmware from the [[https://www.insta360.com/download|download site]], copy the file **Insta360OneRFW.bin** into the root directory of the SD card and power-on the camera. Once the firmware is flashed, the file is automatically removed from the SD card.
==== Firmware file anatomy ====
The anatomy of a firmare file is as follow (analyzed with some problems using **[[https://github.com/RigacciOrg/ambarella-h22-firmware-tools|ambarella-h22-firmware-unpack]]**):
^ Ambarella Firmware Sections found by Magic 90EB24A3 ^^^^^^
^ Sect. ^ Header ^ Section ^ Len ^ CRC32 ^ Note ^
| #1 | 0x00000230 | 0x00000330 | 27358092 | 0xD173F88F OK | Real Time Operating System (RTOS) image |
| #2 | 0x01A176BC | 0x01A177BC | 3852288 | 0x7A2024CB OK | ROMFS with RTOS microcode: default_binary.bin, orccode.bin and orcme.bin |
| #3 | 0x01DC3FBC | 0x01DC40BC | 10676224 | 0x889668C0 OK | ROMFS with files for color profiles, LUTs, sounds, etc. |
| #4 | 0x027F28BC | 0x027F29BC | 7919624 | 0x9D4BC0E3 OK | Linux kernel ARM64 boot executable Image. |
| #5 | 0x02F801C4 | 0x02F802C4 | 14458880 | 0xDCD5AFC8 OK | Linux root filesystem (Squashfs). |
| #6 | 0x03D4A2C4 | 0x03D4A3C4 | 25138 | 0x97606C13 OK | Device Tree Blob. |
===== Partitions =====
The **Insta360 ONE RS** camera does run two operating systems at once: **RTOS** and **GNU/Linux**. RTOS is dedicated to operate the camera (buttons operations, touch screen, video recording, etc.), GNU/Linux is dedicated e.g. to WiFi operations, etc.
Here it is an overview of the partitions used:
^ Partition ^ Size (kb) ^ Label ^ Content ^ From firmware file ^
| mtdblock0 | 128 | VENDOR_DATA | :?: | None |
| mtdblock1 | 32768 | SYS_SW | Real Time Operating System (RTOS) image | Section #1 at offset 0x00000330 |
| mtdblock2 | 6144 | DSP_uCode | ROMFS: RTOS microcode binary files | Section #2 at offset 0x01A177BC |
| mtdblock3 | 40960 | SYS_DATA | ROMFS: RTOS data files (color tables, etc.) | Section #3 at offset 0x01DC40BC |
| mtdblock4 | 16384 | LINUX_Kernel |Linux Kernel at offset 0x00000000\\ Device Tree at offset 0x00fe0000 | Section #4 at offset 0x027F29BC\\ Section #6 at offset 0x03D4A3C4 |
| mtdblock5 | 16384 | LINUX_RFS | Linux root filesystem | Section #5 at offset 0x02F802C4 |
| mtdblock6 | 19968 | VIDEO_REC_IDX | Index of files stored into the SD card | None |
| mtdblock7 | 4608 | CALIB | :?: | None |
| mtdblock8 | 3584 | USER_SETTING | User settings | None |
| mtdblock9 | 100992 | DRIVE_A | Storage **a:** mounted into **/tmp/FL0/** | None |
During normal camera usage only **mtdblock6**, **mtdblock8** and **mtdblock9** are changed.
===== USB Modes =====
The Instal360 ONE RS has four different USB modes that you can choose from the settings menu. A GNU/Linux host will detect the different modes with different VendorID and ProductID, except the Quick Reader mode, which is not detected at all.
^ Mode ^ Vendor:Product ^ Linux Kernel Label ^ Usage ^
^ U-Disk Mode | 070a:4026 | Oki Electric Industry Co., Ltd A9 Platform | Allow access to media on the SD card using the USB storage protocol. |
^ WebCam | 2e1a:00c0 | Amba Insta360 One RS | Get the video stream to the attached PC, e.g. using **guvcview** in GNU/Linux. |
^ Quick Reader | | | Enable the the [[https://store.insta360.com/product/quick_reader_horizontal_version|Quick Reader]] accessory. |
^ Android | 2e1a:0002 | Arashi Vision Insta360 ONERS | Should be used to operate the camera through the USB cable from an Android (or other OS) host. See [[https://github.com/Insta360Develop/CameraSDK-Cpp#setup-camera|CameraSDK]]. |
**WARNING**: Streaming the WebCam video into a **GNU/Linux** computer using **guvcview**, resulted into a **greenish image**. Start the ''guvcview'' program with the **%%--format=bgr3%%** option (formats ''bgr3'' and ''rgb3'' seem to work). The **overall reliability with this setting is poor**: starting and stopping ''guvcview'' results in a non-working device; I had to unplug/plug the USB cable and powercycle the camera to get the video stream again.
===== Useful GNU/Linux Commands =====
Extract JPEG and GIF files from a binary image:
binwalk --dd 'jpeg image:jpeg' mtdblock1.bin
binwalk --dd 'gif image:gif' mtdblock1.bin
Mount a Linux Squashfs image:
mount -o loop,ro mtdblock5.bin /mnt
Extract the kernel image and the device tree blob from the partition #4 image:
# Extract the Kernel Image
dd if=mtdblock4.bin of=part4-a.kernel-image.bin bs=1 count=7919624
# Extract the Device Tree Blob, offset is 0x00fe0000
dd if=mtdblock4.bin of=part4-b.device-tree.bin bs=1 skip=16646144 count=25138
===== Shooting modes with Boost 4K lens =====
^ Photo ^^
^ Standard | |
^ HDR (AEB) | |
^ Burst | |
^ Starlapse | |
^ Night Shot | |
^ Interval | |
^ Video ^^
^ FlowState (in-camera stabilization) | |
^ Post FlowState (app stabilization) | |
^ Active HDR | |
^ Slow Motion | |
^ Timelapse | |
^ TimeShift | |
^ Loop Recording | |
^ 6K Widescreen Mode | |
===== Web References =====
* **[[https://www.reddit.com/r/Insta360/comments/wwra18/psa_reminder_wifi_password_still_cant_be_changed/|PSA Reminder: WiFi password still can't be changed.]]**
* **[[https://www.reddit.com/r/Insta360/comments/scsue6/really_cool_insta360_one_x2_hidden_feature/|Really cool Insta360 One X2 hidden feature!]]**
* **[[https://github.com/Insta360Develop/CameraSDK-Cpp|Insta360Develop CameraSDK-Cpp]]**
* **[[https://github.com/Insta360Develop/ProCameraApi|Insta360Develop ProCameraApi]]**
* **[[https://github.com/Insta360Develop/CameraSDK-Android|Insta360Develop CameraSDK-Android]]**
* **[[https://hackaday.io/project/188975-insta360-x3-ble-remote-control-with-esp32|Insta360 X3 BLE remote control with ESP32]]**
* **[[https://t-shaped.nl/2020/reverse-engineering-the-vuze-xr-camera|Reverse engineering the Vuze XR camera – Tommy van der Vorst]]**
* **[[https://github.com/marin-m/pbtk|pbtk - Reverse engineering Protobuf apps]]**
* **[[https://pypi.org/project/protobuf/|Googlegroups Python protobuf]]**
* **[[https://www.freecodecamp.org/news/googles-protocol-buffers-in-python/|How to Use Google's Protocol Buffers in Python]]**
* **[[https://exiftool.org/forum/index.php?topic=11984.0|Export Gyro data from Insta360 file]]**
* **[[https://exiftool.org/forum/index.php?topic=13486.0|How extract motion data from Caddx Peanut / Insta360 go2 mp4 files for Gyroflow?]]**
* **[[https://github.com/sweebee/Insta360GyroExport|Insta360GyroExport]]** - Extract gyro data from Insta360 video files generating a blackbox CSV file.