MVDSTD:CalculateWorkBufSize

MVDSTD:CalculateWorkBufSize

Request #

Index WordDescription
00Header code [0x00030300]
01-03CalculateWorkBufSizeConfig
04-10???????????????
11u32 Video width
12u32 Video height

Response #

Index WordDescription
0Header code
1Resultcode

Description #

CalculateWorkBufSizeConfig #

OffsetDescription
0x00Unused
0x01-0x04CalculateWorkBufWithLevel
0x05-0x06CalculateWorkBufWithNumOfRefFramesA
0x07-0x08CalculateWorkBufWithNumOfRefFramesB
0x09-0x11Unused

CalculateWorkBufWithLevel #

OffsetDescription
0x00bool Enable calculation
0x01u8 Flag
0x02bool Double size
0x03u8 H.264 level

Flag #

BitDescription
0x00FLAG_NONE
0x01FLAG_ENABLE_CALCULATION
0x02FLAG_ENABLE_EXTRA_OP (see below)
0x04FLAG_UNK

H.264 level #

IndexDescription
0x00Level 1.0
0x01Level 1.0b
0x02Level 1.1
0x03Level 1.2
0x04Level 1.3
0x05Level 2.0
0x06Level 2.1
0x07Level 2.2
0x08Level 3.0
0x09Level 3.1
0x0ALevel 3.2
0x0BLevel 4.0
0x0CLevel 4.1
0x0DLevel 4.2
0x0ELevel 5.0
0x0FLevel 5.1
0x10Level 5.2

This will calculate maximum possible buffer size (==buffer size that *may’’ be needed to decode video) based on H.264 level and resolution, so any videos that are compliant with H.264 specs should be decoded with this buffer size*it seems there is some buffer overflow (some hundreds bytes according to test) when maximum number of reference frames are used’’, so adding some extra bytes (maybe around 4096Bytes is enough) is safer.

Calculation procedures are :

  • Calculate max_reference_frames based on H.264 level and resolution, 0x10 is used if max_reference_frames is greater than 0x10.
  • Calculate frame_size based on resolution.
  • Multiply frame_size and (max_reference_frames + 1) to get temp_buffer_size
  • If FLAG_ENABLE_EXTRA_OP is set, temp_buffer_size += (temp_buffer_size / 6)
  • If double size (offset 0x02) is set, temp_buffer_size *= 2
  • Finally, temp_buffer_size += 0xFC8

To perform calculation, enable calculation (ofset 0x00) and flag (offset 0x01) must be non-zero, otherwise 0 is returned.

If resolution is too high for given H.264 level, 0 is returned.

Attempting to use more than 0x10 for H.264 level (offset 0x03) will likely cause out-of-bound access.

CalculateWorkBufWithNumOfRefFramesA/B #

OffsetDescription
0x00bool Enable calculation
0x01u8 Number of reference frames

This will calculate buffer size based on resolution and number of reference frames.

Calculation procedures are :

  • Calculate frame_size based on resolution.
  • Multiply frame_size and number_of_reference_frames to get temp_buffer_size
  • Finally, for CalculateWorkBufWithNumOfRefFramesA, temp_buffer_size += 0x10800
  • Finally, for CalculateWorkBufWithNumOfRefFramesB, temp_buffer_size += 0x858

To perform calculation, enable calculation (ofset 0x00) must be non-zero, otherwise 0 is returned.

If number of reference frames (offset 0x01) is less than 0x02, 0x02 is used internally, if it’s greater than 0x10, 0x10 is used internally.


It is possible to enable more than 1 calculation methods simultaneously, in that case the largest buffer size among them is returned.

SKATER uses

cmd.CalculateWorkBufWithLevel.enable = 0x01;
cmd.CalculateWorkBufWithLevel.flag = 0x07; //(FLAG_ENABLE_CALCULATION | FLAG_ENABLE_EXTRA_OP | FLAG_UNK).
cmd.CalculateWorkBufWithLevel.doubleSize = 0x00;
cmd.CalculateWorkBufWithLevel.level = 0x0A; //Level 3.2.
cmd.CalculateWorkBufWithNumOfRefFramesA.enable = 0x00;
cmd.CalculateWorkBufWithNumOfRefFramesA.numOfReferenceFrames = 0x00;
cmd.CalculateWorkBufWithNumOfRefFramesB.enable = 0x00;
cmd.CalculateWorkBufWithNumOfRefFramesB.numOfReferenceFrames = 0x00;
cmd.width = 854; //Regardless of input video, 854 is always used.
cmd.height = 480; //Regardless of input video, 480 is always used.

and result is 9438920Bytes (0x9006C8), aka MVD_DEFAULT_WORKBUF_SIZE.

This doesn’t write to MVD state / registers at all.