H264 codec
The gamepad features a hardware H264 codec. It can decode a video feed to the screen, and encode the video feed from the camera.
Register map:
Address | Desc. |
---|---|
0xF0008404 | ??? |
0xF0008408 | ??? |
0xF000840C | ??? |
0xF0008410 | ??? |
0xF0008414 | ??? |
0xF0008418 | ??? |
0xF000841C | ??? |
0xF0008420 | ??? |
0xF0008424 | ??? |
0xF0008428 | ??? |
0xF000842C | ??? |
0xF0008430 | ??? |
0xF0008434 | ??? |
0xF0008438 | ??? |
0xF000843C | ??? |
0xF0008440 | ??? |
0xF0008444 | ??? |
0xF0008448 | ??? |
0xF000844C | ??? |
0xF0008450 | ??? |
0xF0008454 | ??? |
0xF0008458 | ??? |
0xF000845C | ??? |
0xF0008460 | Encoding buffer alert position |
0xF0008464 | Encoding buffer current position |
0xF0008468 | Encoding IRQ status/ack/disable |
0xF000846C | Encoding buffer start |
0xF0008470 | Encoding buffer end |
0xF0008474 | Encoding buffer alert offset |
0xF0008478 | ??? |
0xF000847C | Encoding buffer frame position |
0xF0008480 | ??? |
0xF000848C | ??? |
0xF000849C | ??? |
0xF00084A0 | ??? |
0xF00084A4 | buffer address for incoming h265 data? |
0xF00084A8 | another buffer address? |
0xF00084AC | ??? buffer? position? (read-only) |
0xF00084B0 | Decoding IRQ status/ack |
0xF00084B8 | ??? |
Related IRQs:
IRQ | Desc. |
---|---|
0x11 | Encoding event |
0x12 | Decoding event |
Encoding
The encoder side receives video data from the camera, encodes it, and writes the H264 bitstream to RAM.
TODO: figure out what enables/disables the encoder/decoder
TODO: figure out alignment requirements for the various buffer registers
0xF0008460
Encoding buffer alert position.
IRQ 0 fires as long as the current buffer position is greater or equal to this register.
This register is 24 bits wide.
0xF0008464
Encoding buffer current position.
This register keeps track of where the encoder is writing new data within its buffer. It is read-only.
This register is 24 bits wide.
0xF0008468
Encoding IRQ status, acknowledge, and disable.
Bits 0-7 are IRQ status flags. Bits 8-15 are IRQ acknowledge flags, ie. writing a 1 to a bit acknowledges the corresponding IRQ. Bits 16-23 are IRQ disable flags, ie. setting a bit to 1 disables the corresponding IRQ.
Due to the all-in-one nature of this register, one should avoid overwriting the disable flags when acknowledging an IRQ (ie. by ORing the register with the desired IRQ ack bitmask).
The IRQ bits are as follows:
IRQ bit | Desc. |
---|---|
0 | Position alert IRQ |
1 | Frame IRQ |
2 | Buffer wraparound |
3 | Overflow?? |
4-7 | ??? |
IRQ 0 fires when the current buffer position reaches the alert position. When acknowledging this IRQ, the alert position should be updated, otherwise the IRQ will keep firing as long as the condition is met (ie. as long as the current position is equal to or greater than the alert position).
IRQ 1 fires every time a full camera frame is encoded. Register 0xF000847C keeps track of where the frame ends in the encoding buffer. That register must be read, or this IRQ will keep firing.
IRQ 2 fires when the current buffer position reaches the end of the buffer, and wraps around to the start.
IRQ 3 fires when IRQ 1 should fire but two previous IRQ 1's have been missed (ie. register 0xF000847C hasn't been read). It keeps firing, not sure how to properly acknowledge it.
I haven't observed other IRQs yet.
The IRQs in this register trigger IRQ 0x11.
0xF000846C
Encoding buffer start address.
This register is 24 bits wide.
0xF0008470
Encoding buffer end address.
When the current buffer position reaches this address, it loops back to the start address.
This register is 24 bits wide.
0xF0008474
Encoding buffer alert offset.
This register is added to register 0xF0008460 when checking for the alert IRQ. It is typically set to the desired chunk length (for repeating the IRQ per a given chunk size).
Setting this register to zero disables the position alert IRQ.
This register is 24 bits wide.
0xF000847C
Encoding buffer frame position.
Bits | Desc. |
---|---|
0-23 | Frame position (memory address) |
24-31 | Status? 0x09=normal, 0x0B=late, 0x0E=error/too late |
Upon IRQ 1, this register points to the end of the frame that was just finished. It seems to be readable once, becoming zero after it has been read.
There is a limited backlog ability to this register: if a new IRQ 1 fires while the previous position wasn't read, this register will first return the previous position, then the latest position. However, missing more than one IRQ 1 triggers an error case.