# Difference between revisions of "VGM Video"

(document XVD) |
(→V2K-II: document V2K-II) |
||

Line 23: | Line 23: | ||

==V2K-II== | ==V2K-II== | ||

Frame format: | |||

16 bits - flags | |||

if (flags & 8) { | |||

8 bits - fade speed | |||

} | |||

if (flags & 1) { | |||

skip frame - fade the previous frame if needed, do nothing else | |||

} | |||

if (flags & 0x20) { | |||

4 bits - unknown | |||

4 bits - unknown | |||

} | |||

8 bits - quantiser | |||

if (flags & 0x100) { | |||

8 bits - altquant difference | |||

if (flags & 0x200) { | |||

read bit plane with flags telling which quantiser macroblock should use | |||

} | |||

} | |||

if (flags & 2) { // intra frame | |||

reset state | |||

} else { | |||

if (flags & 0x40) { | |||

8 bits - number of default MVs (0-3) | |||

if (num_def_mv == 0) { | |||

8 bits signed - mv_x | |||

8 bits signed - mv_y | |||

} else { | |||

read num_def_mv MVs in the same format as above | |||

decode per-macroblock default motion vector index using arithmetic coder with top/left/topleft context | |||

} | |||

} | |||

if (flags & 0x400) { | |||

all macroblocks are inter | |||

} else { | |||

decode intra-MB flags using arithmetic coder with top/left/topleft/previous value context | |||

} | |||

decode MVS using arithmetic coder with top/left/topleft/previous value context | |||

add corresponding full-pel default per-macroblock MV to each halfpel block MV if applicable | |||

} | |||

if (!(flags & 4)) { | |||

decode Y blocks | |||

decode U blocks | |||

decode V blocks | |||

} else { | |||

decode wavelet picture | |||

} | |||

Plane decoding with arithmetic coder and codebooks: | |||

decode block uncoded flags using arithmetic coder and top/left/topleft context | |||

for each 8x8 block { | |||

if (intra block) { | |||

read 8-bit DC | |||

if (!uncoded block) { | |||

decode coefficients 1-64 for a block | |||

} | |||

} else if (!uncoded block) { | |||

decode coefficients 0-64 for a block | |||

} | |||

} | |||

Wavelet decoding seems to be based on LGT 5/3 wavelet, discarding HH band, and coding data in bitslicing mode (i.e. all top bits first, then next-to-top bits, etc etc) using binary runs. | |||

==XVD== | ==XVD== |

## Revision as of 10:59, 17 February 2021

- Company: XVD Corporation (DigitalStream-USA)
- FourCC: VGMV
- Samples: http://samples.mplayerhq.hu/internets/bha-xvd-vg2/ http://web.archive.org/web/http://xvd.bha.co.jp/download/sample.html
- Binaries: http://web.archive.org/web/*/http://updater.bha.co.jp:80/XVDplusWin/* http://web.archive.org/web/*/http://updater.bha.co.jp:80/XVDfree/*

Java player: http://www.ila-ila.com/xvd-hist/sites/lab1454/eng/products/jpl_dm2.htm

There are several codecs in this family:

- VT
- Domain
- VT2k aka BigBits
- V2K-II
- XVD

## VT

TODO

## Domain

TODO

## V2K

TODO

## V2K-II

Frame format:

16 bits - flags if (flags & 8) { 8 bits - fade speed } if (flags & 1) { skip frame - fade the previous frame if needed, do nothing else } if (flags & 0x20) { 4 bits - unknown 4 bits - unknown } 8 bits - quantiser if (flags & 0x100) { 8 bits - altquant difference if (flags & 0x200) { read bit plane with flags telling which quantiser macroblock should use } } if (flags & 2) { // intra frame reset state } else { if (flags & 0x40) { 8 bits - number of default MVs (0-3) if (num_def_mv == 0) { 8 bits signed - mv_x 8 bits signed - mv_y } else { read num_def_mv MVs in the same format as above decode per-macroblock default motion vector index using arithmetic coder with top/left/topleft context } } if (flags & 0x400) { all macroblocks are inter } else { decode intra-MB flags using arithmetic coder with top/left/topleft/previous value context } decode MVS using arithmetic coder with top/left/topleft/previous value context add corresponding full-pel default per-macroblock MV to each halfpel block MV if applicable } if (!(flags & 4)) { decode Y blocks decode U blocks decode V blocks } else { decode wavelet picture }

Plane decoding with arithmetic coder and codebooks:

decode block uncoded flags using arithmetic coder and top/left/topleft context for each 8x8 block { if (intra block) { read 8-bit DC if (!uncoded block) { decode coefficients 1-64 for a block } } else if (!uncoded block) { decode coefficients 0-64 for a block } }

Wavelet decoding seems to be based on LGT 5/3 wavelet, discarding HH band, and coding data in bitslicing mode (i.e. all top bits first, then next-to-top bits, etc etc) using binary runs.

## XVD

This is the last instalment in VGM Video series. Now the codec is DCT-only and uses either context-adaptive binary coder, arithmetic coder or a mix of arithmetic coder and variable-length codes. There is still one halfpel-precision motion vector per 8x8 block.

### Extradata format

4 bytes - width 4 bytes - height 4 bytes - bitrate? 4 bytes - FPS 4 bytes - edge size (always 4?) 4 bytes - unknown (always 1?) 4 bytes - flags

Flags meaning:

- bit 8 - probably interlaced coding
- bit 9 - use DC prediction
- bit 10 - use MV prediction
- bit 11 - use binary coder

### Frame format

16 bits - flags if (flags & 1) { this is skip frame, do nothing else } 8 bits - quantiser if (flags & 0x100) { 8 bits - altquant difference if (flags & 0x200) { read bit plane with flags telling which quantiser macroblock should use } } if (flags & 2) { // intra frame reset binary coder state } else { if (flags & 0x40) { 8 bits - number of default MVs (0-3) if (num_def_mv == 0) { 8 bits signed - mv_x 8 bits signed - mv_y } else { read num_def_mv MVs in the same format as above decode per-macroblock default motion vector index using arithmetic coder with top/left/topleft context } } if (flags & 0x400) { all macroblocks are inter } else if (use_bincoder) { decode intra-MB flags using binary coder with top/left/topleft/previous value context } else { decode intra-MB flags using arithmetic coder with top/left/topleft/previous value context } if (!(flags & 0x800)) { decode MVS using arithmetic coder with top/left/topleft/previous value context } else if (use_bincoder) { decode x component using binary coder with top/left/topleft/previous value context for values >= 3 read that amount of bits as actual value; read sign bits for component decode y component using binary coder with top/left/topleft/previous value context for values >= 3 read that amount of bits as actual value; read sign bits for component median-predict MVs } else { decode MV present flags using arithmetic coder with top/left/topleft/previous value context decode actual MVs using MV codebook and apply prediction on them if codec flags say so } add corresponding full-pel default per-macroblock MV to each halfpel block MV if applicable } decode Y plane using either binary coder or arithmetic coder and codebooks decode U plane using either binary coder or arithmetic coder and codebooks decode V plane using either binary coder or arithmetic coder and codebooks

DC prediction uses gradient prediction from neighbouring intra-coded blocks.

Plane decoding with arithmetic coder and codebooks:

decode block uncoded flags using arithmetic coder and top/left/topleft context for each 8x8 block { if (intra block) { if (!use_dc_pred) { read 8-bit DC } else if (block has no intra-block top neighbours) { read DC using raw DC codebook } else { read DC difference using DC difference codebook add predicted DC value } if (!uncoded block) { decode coefficients 1-64 for a block } } else if (!uncoded block) { decode coefficients 0-64 for a block } }

Coefficients decoding is done in this case with a simple run-length inter or intra codebook.

Plane decoding with binary coder:

for each 8x8 block { decode block uncoded flag for current block using top/left/topleft context if (intra block) { decode DC difference by unary coding for actual value length and N bypass bits for the DC difference value add DC prediction (use 128 when it is not available) if (!uncoded block) { decode coefficients 1-64 for a block } } else if (!uncoded) { decode coefficients 0-64 for a block } }

Coefficients decoding is done by decoding the unary value for number of coefficients and N run-length pairs using position-adaptive models.