This is for using the MVD hardware video decoder(unknown whether MVD can do more than decoding) + hardware color-format converter. The New_3DS Internet Browser uses mvd:STD for video decoding + YUV2RGB for decoded MJPEG frames.

See here for the supported hardware decoder video codecs.

There can only be one service session open at a time for each individual MVD service.

MVD Service "mvd:STD"

Command Header Available since system version Description
0x00010082 Initialize
0x00020000 Shutdown
0x00030300 CalculateWorkBufSize
0x000400C0 Unknown. Not used by SKATER.
0x00050100 (s8 unk0, s8 unk1, s8 unk2, u32 unk3) SKATER uses hard-coded value 0 for all of these params.
0x00060000 Unknown. Not used by SKATER.
0x00070000 Used during shutdown with video-processing.
0x00080142 ProcessNALUnit
0x00090042 ControlFrameRendering
0x000A0000 GetStatus
0x000B0000 GetStatusOther(unknown what this is used for). Same output size as GetStatus.
0x000C0100 (u8 unk0, s8 unk1, u32 unk2, u32 unk3) Unknown. Not used by SKATER.
0x000D0000 Unknown. Not used by SKATER.
0x000E0202 Unknown. Not used by SKATER. The code for this appears to be similar to ProcessNALUnit, this DMAs data from the input buffer as well.
0x000F0042 (s8 unk, val0, handle) Unknown. Not used by SKATER. Presumably the command 0x000E0202 version of MVDSTD:ControlFrameRendering.
0x00100400 Unknown. Not used by SKATER.
0x00110000 Unknown. Not used by SKATER.
0x001200C0 (s8 unk0, u32 unk1, u32 unk2) Unknown. Not used by SKATER.
0x00130000 Unknown. Not used by SKATER.
0x001400C2 Unknown. Not used by SKATER. The code for this appears to be similar to ProcessNALUnit, this DMAs data from the input buffer as well.
0x00150042 (s8 unk, val0, handle) Unknown. Not used by SKATER. Presumably the command 0x001400C2 version of MVDSTD:ControlFrameRendering.
0x00160000 Unknown. Not used by SKATER.
0x00170000 Unknown. Not used by SKATER.
0x00180000 Unknown. Used during initialization regardless of the operation mode(color-conversion/video-processing).
0x00190000 Unknown. Used during shutdown regardless of the operation mode(color-conversion/video-processing).
0x001A0000 Used when doing color-format conversion. This triggers writing to the output buffer specified via config.
0x001B0040 (u8 unknown) Used during video-processing initialization. SKATER uses hard-coded value 1 for this.
0x001C0000 Used during shutdown with video-processing.
0x001D0042 GetConfig
0x001E0044 SetConfig
0x001F0902 Unknown. Not used by SKATER. This appears to write data to the specified output buffers via hardware?
0x00200002 (val0, handle) Unknown. Not used by SKATER. This loads data from the table entry which has a field matching an input parameter. This is the table used by command 0x001F0902.
0x00210100 (u32 unk0, u32 unk1, u32 unk2, u32 unk3) Unknown. Not used by SKATER. This initializes table data used by command 0x001F0902.

This one uses the I/O mapped @ 0x10207000.

This service is used by the New_3DS Internet Browser. SKATER runs the entire MVD initialization/shutdown each time the video player is entered/exited.

Linear-memory vaddrs passed to this service should be in the 0x30* region, MVD-sysmodule doesn't support the 0x14* region.

By default MVD does(?) various post-processing with the output image, this is controlled by the configuration. This post-processing isn't done at all in certain cases.

Initialization procedures:

  • Color-conversion: Use command MVDSTD:Initialize with bufsize=1, then command 0x00180000.
  • H.264: If needed, use MVDSTD:CalculateWorkBufSize. Then use MVDSTD:Initialize. Then use commands 0x00050100, 0x00180000, and 0x001B0040. Then use MVDSTD:ProcessNALUnit for each of the individual NAL-unit parameter sets("Sequence Parameter Set" and "Picture Parameter Set"), with the main video processing starting afterwards.

Shutdown procedures:

  • Color-conversion: just use command 0x00190000, then MVDSTD:Shutdown.
  • H.264: Use command 0x00090042 in a loop, waiting for it to return a retval that isn't 0x00017002. Then use commands 0x001C0000, 0x00190000, and 0x00070000. Then use MVDSTD:Shutdown.

MVDSTD configuration structure

Offset Size Description
0x0 0x4 Input format type, see below.
0x4 0x4 The default for this is 0x0. Must be <=5. When non-zero, the type value at offset 0x0 must be one of the following: 0x00020001, 0x00010001, 0x00010005, 0x00010006, or 0x00010007.
0x8 0x4 The default for this is 0x0. This must be <=1. Referred to as "H264 range" in SKATER. When 0x1 the output image is brighter than normal.
0x0C 0x4 Input video width. Must be >=width_min and <width_max. This must be aligned: the low <dimensions_alignment>-bits must be clear.
0x10 0x4 Input video height. Must be >=height_min and <height_max. This must be aligned: the low <dimensions_alignment>-bits must be clear.
0x14 0x4 Input data physical address, only set for color-conversion. This isn't used when the value at offset 0x4 is 0x1 or 0x5.
0x18 0x4 Physical data address, only used for color-conversion when the type value has bitmask 0x20000 set. This isn't used when the value at offset 0x4 is 0x1 or 0x5.
0x1C 0x4 Physical data address, only used for color-conversion when the type value is 0x20000. This isn't used when the value at offset 0x4 is 0x1 or 0x5.
0x20 0x4 Physical data address, for color-conversion. This isn't used when the value at offset 0x4 is 0x0 or 0x4.
0x24 0x4 Physical data address, only used for color-conversion when the type value has bitmask 0x20000 set. This isn't used when the value at offset 0x4 is 0x0 or 0x4.
0x40 0x4 When non-zero this enables usage of the 4 words starting at offset 0x44. SKATER sets this to 0x0 for color-conversion, and 0x1 for video processing(this flag isn't mandatory for the latter).
0x44 0x4 See offset 0x40. The default for this is 0x0. Must be <=widthval. Where widthval = <width value from the field at offset 0xC>. The low 4-bits of this value must be clear.
0x48 0x4 See offset 0x40. The default for this is 0x0. Must be <=heightval. Where heightval = <height value from the field at offset 0x10>. The low 4-bits of this value must be clear.
0x4C 0x4 See offset 0x40. Output video height. Must be >=16 and <=heightval. Where heightval = <height value from the field at offset 0x10>. The low 3-bits of this value must be clear.
0x50 0x4 See offset 0x40. Output video width. Must be >=width_min and <=widthval. Where widthval = <width value from the field at offset 0xC>. The low 3-bits of this value must be clear.
0x54 0x4 The default for this is 0x0. Must be <=5. For video processing, and when this value is non-zero, the type value at offset 0x0 must not be any of the following: 0x00010004, 0x00010001, 0x0x00100001, or 0x00200001. For video processing, the type value at offset 0x0 must not be 0x80000 when this value at offset 0x54 is non-zero.
0x58 0x4 Output format type, see below. SKATER writes value 0x40002 here. The physaddr at offset 0x68 is only checked when this is value 0x00020001.
0x5C 0x4 Output video width. Must be >=16, and must be <somewidth_statefield.
0x60 0x4 Output video height. Must be >=16, and must be <someheight_statefield.
0x64 0x4 Output data physical address.
0x68 0x4 Output data physical address, only set for color-conversion.
0xA8 0x4 Unknown, doesn't seem to have a visible affect on the output.
0xAC 0x4 Unknown, must be zero for video-processing.
0xD8 0x4 Unknown, must be zero for video-processing.
0x104 0x4 Unknown, seems to be related to the fields following this.
0x108 0x4 u32 output_x_pos. Output X position in the output buffer.
0x10C 0x4 u32 output_y_pos. Same as above except for the Y pos.
0x110 0x4 u32 output_width_override. The low 2-bits must be clear. When the output width is less than this, this value is used to align the output image width to the specified value via value0-pixels. When this value is less than the output width, this value is used for the output width instead.
0x114 0x4 Same as the field at offset 0x110 except for the output height.
0x118 0x4 Unknown, when non-zero it seems the output buffer isn't written any more?

The size of this structure is fixed to 0x11C-bytes. The user process does the LINEAR-mem vaddr->physaddr conversion for the above physaddrs, when modifying the config struct before using MVDSTD:SetConfig. For the above physaddrs that are checked/used, the physaddr must not be 0x0, and the physaddr must be 8-byte aligned(low 3-bits clear).

For color-conversion, the output frame is split into two images via the two output physaddrs.

For *_min/*_max/dimensions_alignment mentioned above: *_min = 16 for color-conversion, 48 for video processing. *_max = 2048 for color-conversion, 4672 for video processing. dimensions_alignment = 4 for color-conversion, 3 for video processing.

The configuration doesn't seem to change at all while SKATER is running video processing(each MVDSTD:SetConfig input config appears to the same).

SKATER video processing config

When processing video, SKATER gets the config, updates all of the fields listed below, then uses MVDSTD:SetConfig.

Offset Size Description Written value
0x0 0x4 Input format type. 0x00020001(H.264), hard-coded.
0x8 0x4 Loaded from unique input state. This is the 'range' field in the following debug print: "H264 w=%d h=%d range=%d pics=%d multi=%d\n".
0xC 0x4 Input video width. Loaded from unique input state.
0x10 0x4 Input video height. Loaded from unique input state.
0x40 0x4 Flag 0x1, hard-coded.
0x44 0x4 Loaded from unique input state.
0x48 0x4 Loaded from unique input state.
0x4C 0x4 Loaded from unique input state.
0x50 0x4 Loaded from unique input state.
0x54 0x4 0x0, hard-coded.
0x58 0x4 Output format type. Loaded from unique input state.
0x5C 0x4 Output video width. Loaded from unique input state.
0x60 0x4 Output video height. Loaded from unique input state.
0x64 0x4 Output data physical address.
0x68 0x4 Output data physical address, only set for color-conversion. 0x0, hard-coded.
0xA8 0x4 0x1, hard-coded.
0xAC 0x4 0x0, hard-coded.
0xD8 0x4 0x0, hard-coded.
0x104 0x4 0x1, hard-coded.
0x108 0x4 Loaded from unique input state.
0x10C 0x4 Loaded from unique input state.
0x110 0x4 Loaded from unique input state.
0x114 0x4 Loaded from unique input state.
0x118 0x4 0x0, hard-coded.

"Loaded from unique input state" refers to the field being loaded from state seperate from the other fields used for this configuration structure.

Input formats

Type value Mode Description
0x00010001 Color conversion yuyv422
0x00010002 Video processing ?
0x00010004 Video processing ?
0x00010005 Color conversion ?
0x00010006 Color conversion ?
0x00010007 Color conversion ?
0x00020000 Color conversion ?
0x00020001 Video processing H.264
0x00020002 ? ?
0x00080000 Video processing Same as 0x00020001, except with gray-scale?
0x00080001 Video processing ?
0x00180001 Video processing ?

Output formats

Type value Description
0x00010001 See the input format type.
0x00010005 Unknown. A certain MVD state field must not be set to 0x8170 in order to use this.
0x00010006 Unknown, see 0x00010005 for the usage requirement.
0x00010007 Unknown, see 0x00010005 for the usage requirement.
0x00010008 A certain MVD-module state field must not be set to 0x8170 in order to use this. Whether this can actually be used is determined by another MVD-module state field.
0x00010009 Unknown, see 0x00010008 for the usage requirements.
0x0001000A Unknown, see 0x00010008 for the usage requirements.
0x0001000B Unknown, see 0x00010008 for the usage requirements.
0x00020001 Some sort of YUV format?
0x00040000 Unknown, doesn't write anything to the out-buffer when doing color-conversion.
0x00040001 RGB555
0x00040002 BGR565
0x00040003 Some sort of 2-byte format it seems?
0x00040004 RGB565
0x00041000 Unknown, doesn't write anything to the out-buffer when doing color-conversion.
0x00041001 y400a?
0x00041002 y400a?

MVD Service "l2b:u"

This one uses the I/O mapped @ 0x10130000.

MVD Service "l2b2:u"

This uses the same command-handler as "l2b:u".

MVD Service "y2r2:u"

This one uses the I/O mapped @ 0x10102000.

MVD Result-codes

Result-code Internal MVD status-code Description
0xD961710F Invalid configuration, mainly when setting the config.
0x17000 OK
0x17002 Busy. When returned by command 0x00090042 during video processing, SKATER uses the {MVDSTD:GetConfig, MVDSTD:SetConfig, and 0x00090042} commands again(same config as before). The SKATER code for this includes this debug string: "H264 output %lld us corrected to %lld us\n".

Supported H.264 Levels and Profiles

Level Baseline Main High High 10 (High10, High10p, Hi10p or 10-bit H.264) High 4:2:2 (High422p or High422) High 4:4:4 Predictive (Hi444PP)
1 Yes Yes Yes Yes Untested Untested
1b Yes Yes Yes Yes Untested Untested
1.1 Yes Yes Yes Yes Untested Untested
1.2 Yes Yes Yes Yes Untested Untested
1.3 Yes Yes Yes Yes Untested Untested
2 Yes Yes Yes Yes Untested Untested
2.1 Yes Yes Yes Yes Untested Untested
2.2 Yes Yes Yes Yes Untested Untested
3 Yes Yes Yes Yes Untested Untested
3.1 Yes Yes Yes Yes Untested Untested
3.2 Yes Yes Yes Yes Untested Untested
4 No (untested) No (untested) No (untested) No (untested) No (untested) No (untested)
4.1 No (untested) No (untested) No (untested) No (untested) No (untested) No (untested)
4.2 No (untested) No (untested) No (untested) No (untested) No (untested) No (untested)
5 No (untested) No (untested) No (untested) No (untested) No (untested) No (untested)
5.1 No (untested) No (untested) No (untested) No (untested) No (untested) No (untested)
5.2 No (untested) No (untested) No (untested) No (untested) No (untested) No (untested)

created using the New 3DS Internet Browser, New 3DS Internet Browser Specs and the following test pages:
Baseline Profile Test
Main Profile Test
High Profile Test
High10 Profile Test