3DS video uploading

elysia asked what this particular line on the Nintendo 3DS Internet Browser Specs manual meant:

3D Video Format (Uploaded).mkv (To play the video, its format must be changed on the site which the video was uploaded to. Some videos may not play after the format is changed)

and it made us really curious because it sounded just like a bad translation so it made it want to look at what it originally said and then try out the uploading features to see what the actual limitations were.

Document Investigation

Through doing a web search for “インターネットintānettoブラウザーburauzā 3ds mkv”, we found the Japanese equivalent of the page. It’s https://www.nintendo.co.jp/hardware/3dsseries/browser/modal_net.html. It literally says something like:

Format of 3D movies at upload time:.mkv (However, to actually play those movies, the site you upload it to has to convert it. Even then, there's situations where the movie doesn't play even after conversion.)

We decided to actually test uploading a video to see this in practice.

Uploading

We spun up a file uploader and pointed the New 3DS at it. We selected a video we’ve recorded before and clicked upload. And then it shows a screen I’ve never seen before with a special animation when it’s remuxing to mkv!! It took about 20 seconds to convert for a 20 second video. Here it is in action:

(We used a program called Chokistream, along with ChirunoMod 3DS, to capture this over the network without needing capture hardware. The conversion is a lot faster if you’re not running a capture at the same time.)

The uploading feature doesn’t seem super well-tested, though. The second time we tried upload a video in the same session, it would upload a corrupted file, even if it was the exact same recording. A quick look at the bytes seems to reveal that it leaves out the codec info from the second upload onwards, while still writing out the actual video packets themselves. The workaround is to restart the browser after each upload.

Inspecting the video file

Raw FFprobe output
Input #0, matroska,webm, from 'HNI_0090.MKV':
  Metadata:
    encoder         : Nintendo
  Duration: N/A, start: 0.000000, bitrate: N/A
  Stream #0:0(eng): Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 480x480, SAR 1:1 DAR 1:1, 20 fps, 20 tbr, 1000k tbn (default)
      Metadata:
        stereo_mode     : top_bottom
      Side data:
        stereo3d: top and bottom, view: packed, primary eye: none
  Stream #0:1(eng): Audio: aac (LC), 16000 Hz, mono, fltp (default)
Or download the raw file yourself.

It seems to produce a 480x480 MJPEG video, with 16 kHz AAC mono audio. That’s double the 480x240 we’d expect. That’s because the top half contains the left eye data, and the bottom half contains the right eye data. It also contains metadata that tells video players they should switch into 3D mode.

To compare the specs of this with the AVI file on the SD card of the 3DS: The AVI file has the two stereo channels as two separate 420x240 MJPEG streams, instead of stacking them. The audio is stored as IMA ADPCM (very simple way of compressing audio developed by the Interactive Multimedia Association[1]) instead of AAC. So, instead of just being a remux like I assumed, it’s a very simple file conversion instead. We assume this style of MKV was chosen simply because that’d allow you to upload them to YouTube or other video sites at the time and have the 3D “just work”.

Playing it back again

We then tried serving the MKV file back to the 3DS. However, that didn’t work.

While it feels a little silly that the 3DS can’t play back a file it generated itself, it does explain the warning in the 3DS Browser Specs page. It’s also congruent with what the Nintendo page says earlier about the 3DS being able to play back:

Video FormatsMP4, M3U8+TS (HLS)
Video CodecH.264 - MPEG-4 AVC Video (max. 854x480 at level 3.2, 3D-compatible)

When we tried converting it to mp4 without any special flags we’d get weird pillarboxing effect so we squashed it to half height and that kind of worked?

ffmpeg -i HNI_0090.MKV -vf "scale=iw:ih/2" -c:a copy -movflags +faststart squashey.mp4

Try it here on your 3DS and it’ll show in 3D. I think it uses heuristics to know it needs to be 3D because I don’t see metadata saying it needs to be 3D.

Summary

(To play the video, its format must be changed on the site which the video was uploaded to.)

The reason why this disclaimer exists is that the 3DS uploads MKVs, but it can only play MP4s. Yes, that’s silly. But it’s also proves that it's not a wrong translation at all, the language is weird because it's explaining something weird! It's just an awkward limitation stemming from how they decided to solve a particular problem without making the 3DS browser even more complex than it already is.

weird aside its writing down for itself We created a network on the laptop with the same SSID and credentials as the phone's hotspot to try and get Chiruno streaming working with better performance. The 3DS refused to connect to it with the error message "Wireless communication is currently disabled.", despite it... being on... We changed the hotspot to a new SSID and it connected perfectly fine. Maybe it knew it was an impostor somehow?! i had to do so much garbage with nmtui and iptables and dhclient i hated it.

  1. https://wiki.multimedia.cx/index.php/IMA_ADPCM ↩︎