Skip to content

Commit

Permalink
BULK improvements and press BACK to exit
Browse files Browse the repository at this point in the history
- *BULK setting removed*: both BULK and RNDIS listen at the same time.
  You can use both freely and swap between them without restarting the
  shim.
- *BULK connection loss timeout*: BULK will now consider the connection
  lost if no data is received for 3 seconds.
- *Press BACK to exit*: you can now press BACK to exit the shim at any
  time.

Implementation wise, everything is now async/poll-based.
  • Loading branch information
Knifa committed Apr 9, 2023
1 parent fac9bc9 commit fb1f638
Show file tree
Hide file tree
Showing 9 changed files with 268 additions and 235 deletions.
79 changes: 27 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Stream games via Moonlight and [fpv.wtf](https://github.com/fpv-wtf) to your DJI
FPV Goggles. Friend of
[dji-moonlight-embedded](https://github.com/Knifa/dji-moonlight-embedded).

![splash](assets/splash.png)
![splash](media/logo.png)

Latency is good, in the 7-14ms range at 120Hz (w/ 5900X + 3080Ti via GE).

Expand All @@ -18,44 +18,16 @@ Latency is good, in the 7-14ms range at 120Hz (w/ 5900X + 3080Ti via GE).
2. Update WTFOS and friends to the latest version.
3. Install [dji-moonlight-shim](https://fpv.wtf/package/fpv-wtf/dji-moonlight-shim) via the package mangaer.

### Starting
### Running

1. Select `Moonlight` from the menu.

![menu](media/menu.jpg)
![menu](media/menu.jpg)

2. Use [dji-moonlight-embedded](https://github.com/Knifa/dji-moonlight-embedded)
to stream video to the shim.

### Stopping

1. You can never leave.
2. ...but it won't be this way forever.
3. Breathe.
4. ???
5. Reboot your goggles.

### CLI

1. You can also start the shim via ADB.

```bash
$ dji-moonlight-shim

# You can also force BULK (previously called USB) mode
$ dji-moonlight-shim --usb

# ...or RNDIS mode.
$ dji-moonlight-shim --net
```
2. Ctrl-C to stop and restart the glasses service.

## Configuration

The shim can be configured via the [fpv.wtf](https://fpv.wtf/package/fpv-wtf/dji-moonlight-shim) package manager.

- `use_usb_mode`: Use BULK (previously called USB) mode by default instead of the RNDIS mode. Defaults
to `false`.
2. The shim will be awaiting a connection from both BULK or RNDIS.
3. Use [dji-moonlight-gui](https://github.com/Knifa/dji-moonlight-gui)
to stream video from your PC.
4. Press the BACK button on the goggles to exit at any time.

## Implementation

Expand All @@ -80,21 +52,23 @@ The maximum frame size is `1MB (1000000 bytes)`, which is slightly under the
maximum packet size for the decoder. Any larger and this would need to handle
packet splitting. But also, this is absolutely enormous for a single frame.

### Network Mode
### RNDIS

In network mode, the shim hosts a TCP server on port `42069` that accepts a
single connection at a time. Normal client/server stuff applies here and will
handle reconnections, etc.
For RNDIS, the shim hosts a TCP server on port `42069` that accepts a single
connection at a time. Normal client/server stuff applies here.

### USB Mode
### BULK

In USB mode, the shim reads from the FunctionFS bulk endpoint already setup by
DJI at `/dev/usb-ffs/bulk/ep1`.
For BULK, the shim reads from the FunctionFS bulk endpoint already setup by DJI
at `/dev/usb-ffs/bulk/ep1`. FunctionFS does not support non-blocking IO nor does
it support polling so reading is done from a thread into a pipe.

Currently, there's no way to tell if the USB side has connected or disconnected,
so on startup the shim just waits for the magic number to appear in this file,
at which point it assumes it's about to get the rest of the connect header,
followed by the rest of the stream. After that though, it's got no idea.
Currently, there's no way to tell if the BULK side has connected or
disconnected, so on startup the shim just waits for the magic number to appear
in this file, at which point it assumes it's about to get the rest of the
connect header, followed by the rest of the stream. After that, we rely on a
watchdog timer to detect if the connection has been lost (i.e., no data received
for some seconds).

### Booting

Expand All @@ -108,11 +82,12 @@ Everything around decoding lives in [dmi](./src/dmi) and is probably the best
way to understand how this works. Start from [dmi_pb.c](./src/dmi/dmi_pb.c).

It's driven through a handful of devices via ioctl/iomap:
- `/dev/dmi_media_control`: general control, starting/stoping the decoder,
etc.
- `/dev/dmi_video_playback`: the place where frames go.
- `/dev/mem`: general shared mem, mainly just for frame timing info here
though.

- `/dev/dmi_media_control`: general control, starting/stoping the decoder,
etc.
- `/dev/dmi_video_playback`: the place where frames go.
- `/dev/mem`: general shared mem, mainly just for frame timing info here
though.

The setup is roughly:

Expand All @@ -123,7 +98,7 @@ The setup is roughly:
Then for each frame you want to decode:

1. Claim packets via the `dmi_video_playback` device, which gives you a chunk of
shared memory to write the packet to.
shared memory to write the packet to.
2. Write the frame data along with a header to the shared memory.
3. Release the packet. This will trigger the decoder to decode the frame.

Expand Down
Binary file modified assets/splash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion ipk/control/control
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Package: dji-moonlight-shim
Version: 1.0.5
Version: 1.1.0
Maintainer: Knifa
Description: Stream games to your goggles via Moonlight!
Architecture: pigeon-glasses
Expand Down
29 changes: 1 addition & 28 deletions ipk/data/opt/bin/dji-moonlight-shim
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,6 @@ else
GLASSES_SERIVCE="dji.glasses_service"
fi

# Check if we should use USB mode.

set +e # don't choke if something goes wrong with package-config

USE_USB_MODE=$(package-config getsaved dji-moonlight-shim use_usb_mode)
if [[ $USE_USB_MODE == "true" ]]; then
echo "USB mode has been enabled via package-config."
USE_USB_MODE=1
else
USE_USB_MODE=0
fi

set -e

# Construct the shim arguments. If this script is called with arguments, pass
# them, otherwise pass --net or --usb depending on the package config.

if [[ $# -eq 0 ]]; then
if [[ $USE_USB_MODE -eq 1 ]]; then
SHIM_ARGS="--usb"
else
SHIM_ARGS="--net"
fi
else
SHIM_ARGS="$@"
fi

# Start the shim.

function cleanup {
Expand All @@ -53,4 +26,4 @@ setprop $GLASSES_SERIVCE 0
sleep 3

cd /opt/moonlight
./dji-moonlight-shim $SHIM_ARGS
./dji-moonlight-shim
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
{
"use_usb_mode": false
}
{}
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
{
"settings": {
"use_usb_mode": {
"name": "Use BULK Mode (experimental)",
"widget": "checkbox"
}
},
"settings": {},
"units": [
"dji-moonlight-shim"
]
Expand Down
12 changes: 1 addition & 11 deletions ipk/data/opt/etc/package-config/dji-moonlight-shim/schemaV2.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
{
"description": "Configure dji-moonlight-shim",
"dependencies": {},
"properties": {
"use_usb_mode": {
"enum": [
true,
false
],
"title": "Use BULK mode (experimental)",
"description": "Runs the shim in BULK mode, where frames are expected over BULK rather than over RNDIS.",
"type": "boolean"
}
},
"properties": {},
"required": [],
"title": "dji-moonlight-shim",
"type": "object",
Expand Down
Binary file added media/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit fb1f638

Please sign in to comment.