https://wiki.multimedia.cx/api.php?action=feedcontributions&user=Sesse&feedformat=atomMultimediaWiki - User contributions [en]2024-03-29T05:20:40ZUser contributionsMediaWiki 1.39.5https://wiki.multimedia.cx/index.php?title=SpeedHQ&diff=15263SpeedHQ2017-01-08T12:11:01Z<p>Sesse: Alpha is never coded as chroma.</p>
<hr />
<div>* FOURCCs: SHQ0, SHQ1, ..., SHQ5, SHQ7, SHQ9<br />
* Company: NewTek (note: NewTek has provided samples and support in understanding the format)<br />
<br />
This is a simple intermediate codec with different subsampling and alpha support. It is generally very similar to MPEG-2 intraframe. Several variants exist:<br />
<br />
* <code>SHQ0</code>/<code>SHQ1</code> are 4:2:0 with/without alpha.<br />
* <code>SHQ2</code>/<code>SHQ3</code> are 4:2:2 with/without alpha.<br />
* <code>SHQ4</code>/<code>SHQ5</code> are 4:4:4 with/without alpha.<br />
* <code>SHQ7</code> is 422 with alpha coded the same way as luma<br />
* <code>SHQ9</code> is the same for 444 format.<br />
<br />
NewTek's NDI network codec uses SHQ2 and SHQ7.<br />
<br />
Frame is always coded as two fields, data is packed into 32-bit little-endian words and is read from LSB.<br />
<br />
First byte is quality, next three bytes form an offset to the second field. (Exception: NDI can send a frame consisting of a single field, with the second field offset equal to 4, ie., exactly overlapping with the first field.) Quantizer is 100 - quality.<br />
<br />
=== Field format ===<br />
<br />
Each field is split into four slices that can be independently decoded; each slice codes 16 lines, then skip 48 lines (coded by the other three slices), code 16 more lines, and so on until at the bottom of the field, which implicitly ends the slice. The first three bytes of each slice form a length of the slice in bytes (including the three length bytes). The next slice starts on the byte immediately after the end of the previous one, as given by the length (this might mean skipping 1–7 bits).<br />
<br />
Blocks are 8x8 pixels, and macroblocks are 16x16 pixels. Luma is coded top-left, top-right, bottom-left, bottom-right. 4:4:4 is coded YYYY UV UV UV UV (chroma is top-left, bottom-left, top-right, bottom-right). 4:2:2 is coded YYYY UV UV (chroma is top, then bottom). 4:2:0 is coded YYYY UV.<br />
<br />
Blocks are coded with static VLCs. DC coefficients are coded exactly as in MPEG-2 (same luma/chroma tables, same scheme for storing the coefficient and sign). DC prediction is taken from the previous block of the same coefficient, and restarts at 1024 for each new macroblock row (not 128 as in MPEG-2). Curiously enough, one needs to _subtract_ the stored DC value from the prediction, not add as usual.<br />
<br />
AC coefficients are coded using the same scheme as MPEG-2 (run/level with the same zigzag pattern), and with a VLC that is very similar to MPEG-2's “Table One” for AC coefficients. (It is not identical; some codewords that are illegal in MPEG-2 are used in SpeedHQ, and a few others are moved around as a consequence.) In FFmpeg format, the codes are (except that they would need to be bit-reversed due to INIT_VLC_LE demands):<br />
<br />
static const uint16_t speedhq_vlc[123][2] = {<br />
{0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},<br />
{0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},<br />
{0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},<br />
{0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},<br />
{0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},<br />
{0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},<br />
{0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},<br />
{0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},<br />
{0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},<br />
{0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},<br />
{0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},<br />
{0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},<br />
{0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},<br />
{0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},<br />
{0x11,16}, {0x10,16}, {0x18,13}, {0x17,13},<br />
{0x05, 5}, {0x07, 7}, {0xfc, 8}, {0x0c,10},<br />
{0x14,13}, {0x18,12}, {0x14,12}, {0x13,12},<br />
{0x10,12}, {0x1a,13}, {0x19,13}, {0x07, 5},<br />
{0x26, 8}, {0x1c,12}, {0x13,13}, {0x1b,12},<br />
{0x06, 6}, {0xfd, 8}, {0x12,12}, {0x1d,12},<br />
{0x07, 6}, {0x04, 9}, {0x12,13}, {0x06, 7},<br />
{0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},<br />
{0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},<br />
{0x7a, 7}, {0x10,13}, {0x21, 8}, {0x1a,16},<br />
{0x25, 8}, {0x19,16}, {0x24, 8}, {0x18,16},<br />
{0x05, 9}, {0x17,16}, {0x07, 9}, {0x16,16},<br />
{0x0d,10}, {0x15,16}, {0x1f,12}, {0x1a,12},<br />
{0x19,12}, {0x17,12}, {0x16,12}, {0x1f,13},<br />
{0x1e,13}, {0x1d,13}, {0x1c,13}, {0x1b,13},<br />
{0x1f,16}, {0x1e,16}, {0x1d,16}, {0x1c,16},<br />
{0x1b,16},<br />
{0x01,6}, /* escape */<br />
{0x06,4}, /* EOB */<br />
};<br />
static const uint8_t speedhq_level[121] = {<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 21, 22, 23, 24,<br />
25, 26, 27, 28, 29, 30, 31, 32,<br />
33, 34, 35, 36, 37, 38, 39, 40,<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 1, 2, 3, 4,<br />
5, 6, 7, 8, 9, 10, 11, 1,<br />
2, 3, 4, 5, 1, 2, 3, 4,<br />
1, 2, 3, 1, 2, 3, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1,<br />
};<br />
static const uint8_t speedhq_run[121] = {<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 2, 2, 2, 2,<br />
2, 2, 2, 2, 2, 2, 2, 3,<br />
3, 3, 3, 3, 4, 4, 4, 4,<br />
5, 5, 5, 6, 6, 6, 7, 7,<br />
8, 8, 9, 9, 10, 10, 11, 11,<br />
12, 12, 13, 13, 14, 14, 15, 15,<br />
16, 16, 17, 18, 19, 20, 21, 22,<br />
23, 24, 25, 26, 27, 28, 29, 30,<br />
31,<br />
};<br />
<br />
Escape works similarly to MPEG-2; the next six bits contain the run (non-reversed), and the next 12 bits contain the level (non-reversed), offset by 2048. There'a always an EOB at the end of each block (as in MPEG-2), and there's never a block without a DC coefficient (also as in MPEG-2). All other codes are followed by the coefficient sign (again as in MPEG-2).<br />
<br />
=== Alpha ===<br />
<br />
Alpha for SHQ1/3/5 is coded in 16x8 blocks without zigzag, coming after chroma (so e.g. SHQ3 is YYYY UV UV AA), top first, then bottom. It does not use DCT, but is still coded as run/level; first it has a codeword telling how many elements to skip (or whether this is end of block) and then a codeword for nonzero element, repeat until the EOB code. The code for run is (remember that all bit strings and literals go in little-endian order, even though they're written left to right here):<br />
<br />
{| class="wikitable"<br />
| 0 <br />
| 0<br />
|-<br />
| 10xx<br />
| xx plus 1<br />
|-<br />
| 110 <br />
| EOB<br />
|-<br />
| 111xxxxxxx<br />
| xxxxxxx<br />
|}<br />
<br />
Level codes:<br />
<br />
{| class="wikitable"<br />
| 1s<br />
| 1 or -1 (s = sign bit)<br />
|-<br />
| 01sxx<br />
| xx plus 2 (s = sign bit)<br />
|-<br />
| 00xxxxxxxx<br />
| xxxxxxxx (two's complement)<br />
|}<br />
<br />
Alpha prediction happens in vectors of 16 elements; every element predicts from the previous element, and the stored value is subtracted from the prediction to yield the actual pixel value (and next prediction for this element), with wraparound. The start value, reset for each macroblock row, is 255 for all pixels. Note that subtraction happens with 8-bit precision and wraparound, so every alpha value can be encoded despite the range of only +128/-127.<br />
<br />
Alpha for SHQ7/9 is encoded identically to luma (ie., with DCT), and comes after chroma (so e.g. SHQ7 is YYYY UV UV AAAA). It does not use the prediction scheme from SHQ1/3/5, just the regular DC prediction as from luma.<br />
<br />
=== Quantiser ===<br />
<br />
Allowed quality levels:<br />
<br />
1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 104, 112<br />
<br />
Provided quality is clipped to 99, also if it's less than 38 or odd then a nearest smaller value from default quality table is used instead.<br />
<br />
Quantisation matrix:<br />
<br />
*, 16, 19, 22, 26, 27, 29, 34,<br />
16, 16, 22, 24, 27, 29, 34, 37,<br />
19, 22, 26, 27, 29, 34, 34, 38,<br />
22, 22, 26, 27, 29, 34, 37, 40,<br />
22, 26, 27, 29, 32, 35, 40, 48,<br />
26, 27, 29, 32, 35, 40, 48, 58,<br />
26, 27, 29, 34, 38, 46, 56, 69,<br />
27, 29, 35, 38, 46, 56, 69, 83<br />
<br />
The DC quantizer is set to 16 no matter what; the other values are multiplied by (100 - quality). Each coefficient is multiplied with the corresponding quantization factor and then divided by 16 (no rounding), before the block goes to IDCT.<br />
<br />
As an optimization, DC-only blocks are special-cased; all pixels in the block get exactly the value (dc + 4) >> 3.<br />
<br />
Y'CbCr conversion uses BT.601 coefficients. Chroma positioning is center, as in MPEG-2.<br />
<br />
[[Category:Undiscovered Video Codecs]]<br />
[[Category:Video Codecs]]</div>Sessehttps://wiki.multimedia.cx/index.php?title=SpeedHQ&diff=15262SpeedHQ2017-01-07T18:48:22Z<p>Sesse: Added information about old-style alpha</p>
<hr />
<div>* FOURCCs: SHQ0, SHQ1, ..., SHQ5, SHQ7, SHQ9<br />
* Company: NewTek (note: NewTek has provided samples and support in understanding the format)<br />
<br />
This is a simple intermediate codec with different subsampling and alpha support. It is generally very similar to MPEG-2 intraframe. Several variants exist:<br />
<br />
* <code>SHQ0</code>/<code>SHQ1</code> are 4:2:0 with/without alpha.<br />
* <code>SHQ2</code>/<code>SHQ3</code> are 4:2:2 with/without alpha.<br />
* <code>SHQ4</code>/<code>SHQ5</code> are 4:4:4 with/without alpha.<br />
* <code>SHQ7</code> is 422 with alpha coded as luma and chroma blocks<br />
* <code>SHQ9</code> is the same for 444 format.<br />
<br />
NewTek's NDI network codec uses SHQ2 and SHQ7.<br />
<br />
Frame is always coded as two fields, data is packed into 32-bit little-endian words and is read from LSB.<br />
<br />
First byte is quality, next three bytes form an offset to the second field. (Exception: NDI can send a frame consisting of a single field, with the second field offset equal to 4, ie., exactly overlapping with the first field.) Quantizer is 100 - quality.<br />
<br />
=== Field format ===<br />
<br />
Each field is split into four slices that can be independently decoded; each slice codes 16 lines, then skip 48 lines (coded by the other three slices), code 16 more lines, and so on until at the bottom of the field, which implicitly ends the slice. The first three bytes of each slice form a length of the slice in bytes (including the three length bytes). The next slice starts on the byte immediately after the end of the previous one, as given by the length (this might mean skipping 1–7 bits).<br />
<br />
Blocks are 8x8 pixels, and macroblocks are 16x16 pixels. Luma is coded top-left, top-right, bottom-left, bottom-right. 4:4:4 is coded YYYY UV UV UV UV (chroma is top-left, bottom-left, top-right, bottom-right). 4:2:2 is coded YYYY UV UV (chroma is top, then bottom). 4:2:0 is coded YYYY UV.<br />
<br />
Blocks are coded with static VLCs. DC coefficients are coded exactly as in MPEG-2 (same luma/chroma tables, same scheme for storing the coefficient and sign). DC prediction is taken from the previous block of the same coefficient, and restarts at 1024 for each new macroblock row (not 128 as in MPEG-2). Curiously enough, one needs to _subtract_ the stored DC value from the prediction, not add as usual.<br />
<br />
AC coefficients are coded using the same scheme as MPEG-2 (run/level with the same zigzag pattern), and with a VLC that is very similar to MPEG-2's “Table One” for AC coefficients. (It is not identical; some codewords that are illegal in MPEG-2 are used in SpeedHQ, and a few others are moved around as a consequence.) In FFmpeg format, the codes are (except that they would need to be bit-reversed due to INIT_VLC_LE demands):<br />
<br />
static const uint16_t speedhq_vlc[123][2] = {<br />
{0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},<br />
{0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},<br />
{0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},<br />
{0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},<br />
{0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},<br />
{0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},<br />
{0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},<br />
{0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},<br />
{0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},<br />
{0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},<br />
{0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},<br />
{0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},<br />
{0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},<br />
{0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},<br />
{0x11,16}, {0x10,16}, {0x18,13}, {0x17,13},<br />
{0x05, 5}, {0x07, 7}, {0xfc, 8}, {0x0c,10},<br />
{0x14,13}, {0x18,12}, {0x14,12}, {0x13,12},<br />
{0x10,12}, {0x1a,13}, {0x19,13}, {0x07, 5},<br />
{0x26, 8}, {0x1c,12}, {0x13,13}, {0x1b,12},<br />
{0x06, 6}, {0xfd, 8}, {0x12,12}, {0x1d,12},<br />
{0x07, 6}, {0x04, 9}, {0x12,13}, {0x06, 7},<br />
{0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},<br />
{0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},<br />
{0x7a, 7}, {0x10,13}, {0x21, 8}, {0x1a,16},<br />
{0x25, 8}, {0x19,16}, {0x24, 8}, {0x18,16},<br />
{0x05, 9}, {0x17,16}, {0x07, 9}, {0x16,16},<br />
{0x0d,10}, {0x15,16}, {0x1f,12}, {0x1a,12},<br />
{0x19,12}, {0x17,12}, {0x16,12}, {0x1f,13},<br />
{0x1e,13}, {0x1d,13}, {0x1c,13}, {0x1b,13},<br />
{0x1f,16}, {0x1e,16}, {0x1d,16}, {0x1c,16},<br />
{0x1b,16},<br />
{0x01,6}, /* escape */<br />
{0x06,4}, /* EOB */<br />
};<br />
static const uint8_t speedhq_level[121] = {<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 21, 22, 23, 24,<br />
25, 26, 27, 28, 29, 30, 31, 32,<br />
33, 34, 35, 36, 37, 38, 39, 40,<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 1, 2, 3, 4,<br />
5, 6, 7, 8, 9, 10, 11, 1,<br />
2, 3, 4, 5, 1, 2, 3, 4,<br />
1, 2, 3, 1, 2, 3, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1,<br />
};<br />
static const uint8_t speedhq_run[121] = {<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 2, 2, 2, 2,<br />
2, 2, 2, 2, 2, 2, 2, 3,<br />
3, 3, 3, 3, 4, 4, 4, 4,<br />
5, 5, 5, 6, 6, 6, 7, 7,<br />
8, 8, 9, 9, 10, 10, 11, 11,<br />
12, 12, 13, 13, 14, 14, 15, 15,<br />
16, 16, 17, 18, 19, 20, 21, 22,<br />
23, 24, 25, 26, 27, 28, 29, 30,<br />
31,<br />
};<br />
<br />
Escape works similarly to MPEG-2; the next six bits contain the run (non-reversed), and the next 12 bits contain the level (non-reversed), offset by 2048. There'a always an EOB at the end of each block (as in MPEG-2), and there's never a block without a DC coefficient (also as in MPEG-2). All other codes are followed by the coefficient sign (again as in MPEG-2).<br />
<br />
=== Alpha ===<br />
<br />
Alpha for SHQ1/3/5 is coded in 16x8 blocks without zigzag, coming after chroma (so e.g. SHQ3 is YYYY UV UV AA), top first, then bottom. It does not use DCT, but is still coded as run/level; first it has a codeword telling how many elements to skip (or whether this is end of block) and then a codeword for nonzero element, repeat until the EOB code. The code for run is (remember that all bit strings and literals go in little-endian order, even though they're written left to right here):<br />
<br />
{| class="wikitable"<br />
| 0 <br />
| 0<br />
|-<br />
| 10xx<br />
| xx plus 1<br />
|-<br />
| 110 <br />
| EOB<br />
|-<br />
| 111xxxxxxx<br />
| xxxxxxx<br />
|}<br />
<br />
Level codes:<br />
<br />
{| class="wikitable"<br />
| 1s<br />
| 1 or -1 (s = sign bit)<br />
|-<br />
| 01sxx<br />
| xx plus 2 (s = sign bit)<br />
|-<br />
| 00xxxxxxxx<br />
| xxxxxxxx (two's complement)<br />
|}<br />
<br />
Alpha prediction happens in vectors of 16 elements; every element predicts from the previous element, and the stored value is subtracted from the prediction to yield the actual pixel value (and next prediction for this element), with wraparound. The start value, reset for each macroblock row, is 255 for all pixels. Note that subtraction happens with 8-bit precision and wraparound, so every alpha value can be encoded despite the range of only +128/-127.<br />
<br />
Alpha for SHQ7/9 is encoded identically to luma (ie., with DCT), and comes after chroma (so e.g. SHQ7 is YYYY UV UV AAAA). It does not use the prediction scheme from SHQ1/3/5, just the regular DC prediction as from luma.<br />
<br />
=== Quantiser ===<br />
<br />
Allowed quality levels:<br />
<br />
1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 104, 112<br />
<br />
Provided quality is clipped to 99, also if it's less than 38 or odd then a nearest smaller value from default quality table is used instead.<br />
<br />
Quantisation matrix:<br />
<br />
*, 16, 19, 22, 26, 27, 29, 34,<br />
16, 16, 22, 24, 27, 29, 34, 37,<br />
19, 22, 26, 27, 29, 34, 34, 38,<br />
22, 22, 26, 27, 29, 34, 37, 40,<br />
22, 26, 27, 29, 32, 35, 40, 48,<br />
26, 27, 29, 32, 35, 40, 48, 58,<br />
26, 27, 29, 34, 38, 46, 56, 69,<br />
27, 29, 35, 38, 46, 56, 69, 83<br />
<br />
The DC quantizer is set to 16 no matter what; the other values are multiplied by (100 - quality). Each coefficient is multiplied with the corresponding quantization factor and then divided by 16 (no rounding), before the block goes to IDCT.<br />
<br />
As an optimization, DC-only blocks are special-cased; all pixels in the block get exactly the value (dc + 4) >> 3.<br />
<br />
Y'CbCr conversion uses BT.601 coefficients. Chroma positioning is center, as in MPEG-2.<br />
<br />
[[Category:Undiscovered Video Codecs]]<br />
[[Category:Video Codecs]]</div>Sessehttps://wiki.multimedia.cx/index.php?title=SpeedHQ&diff=15261SpeedHQ2017-01-06T18:19:44Z<p>Sesse: Alpha for SHQ7/SHQ9.</p>
<hr />
<div>* FOURCCs: SHQ0, SHQ1, ..., SHQ5, SHQ7, SHQ9<br />
* Company: NewTek (note: NewTek has provided samples and support in understanding the format)<br />
<br />
This is a simple intermediate codec with different subsampling and alpha support. It is generally very similar to MPEG-2 intraframe. Several variants exist:<br />
<br />
* <code>SHQ0</code>/<code>SHQ1</code> are 4:2:0 with/without alpha.<br />
* <code>SHQ2</code>/<code>SHQ3</code> are 4:2:2 with/without alpha.<br />
* <code>SHQ4</code>/<code>SHQ5</code> are 4:4:4 with/without alpha.<br />
* <code>SHQ7</code> is 422 with alpha coded as luma and chroma blocks<br />
* <code>SHQ9</code> is the same for 444 format.<br />
<br />
NewTek's NDI network codec uses SHQ2 and SHQ7.<br />
<br />
Frame is always coded as two fields, data is packed into 32-bit little-endian words and is read from LSB.<br />
<br />
First byte is quality, next three bytes form an offset to the second field. (Exception: NDI can send a frame consisting of a single field, with the second field offset equal to 4, ie., exactly overlapping with the first field.) Quantizer is 100 - quality.<br />
<br />
=== Field format ===<br />
<br />
Each field is split into four slices that can be independently decoded; each slice codes 16 lines, then skip 48 lines (coded by the other three slices), code 16 more lines, and so on until at the bottom of the field, which implicitly ends the slice. The first three bytes of each slice form a length of the slice in bytes (including the three length bytes). The next slice starts on the byte immediately after the end of the previous one, as given by the length (this might mean skipping 1–7 bits).<br />
<br />
Blocks are 8x8 pixels, and macroblocks are 16x16 pixels. Luma is coded top-left, top-right, bottom-left, bottom-right. 4:4:4 is coded YYYY UV UV UV UV (chroma is top-left, bottom-left, top-right, bottom-right). 4:2:2 is coded YYYY UV UV (chroma is top, then bottom). 4:2:0 is coded YYYY UV.<br />
<br />
Blocks are coded with static VLCs. DC coefficients are coded exactly as in MPEG-2 (same luma/chroma tables, same scheme for storing the coefficient and sign). DC prediction is taken from the previous block of the same coefficient, and restarts at 1024 for each new macroblock row (not 128 as in MPEG-2). Curiously enough, one needs to _subtract_ the stored DC value from the prediction, not add as usual.<br />
<br />
AC coefficients are coded using the same scheme as MPEG-2 (run/level with the same zigzag pattern), and with a VLC that is very similar to MPEG-2's “Table One” for AC coefficients. (It is not identical; some codewords that are illegal in MPEG-2 are used in SpeedHQ, and a few others are moved around as a consequence.) In FFmpeg format, the codes are (except that they would need to be bit-reversed due to INIT_VLC_LE demands):<br />
<br />
static const uint16_t speedhq_vlc[123][2] = {<br />
{0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},<br />
{0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},<br />
{0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},<br />
{0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},<br />
{0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},<br />
{0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},<br />
{0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},<br />
{0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},<br />
{0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},<br />
{0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},<br />
{0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},<br />
{0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},<br />
{0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},<br />
{0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},<br />
{0x11,16}, {0x10,16}, {0x18,13}, {0x17,13},<br />
{0x05, 5}, {0x07, 7}, {0xfc, 8}, {0x0c,10},<br />
{0x14,13}, {0x18,12}, {0x14,12}, {0x13,12},<br />
{0x10,12}, {0x1a,13}, {0x19,13}, {0x07, 5},<br />
{0x26, 8}, {0x1c,12}, {0x13,13}, {0x1b,12},<br />
{0x06, 6}, {0xfd, 8}, {0x12,12}, {0x1d,12},<br />
{0x07, 6}, {0x04, 9}, {0x12,13}, {0x06, 7},<br />
{0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},<br />
{0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},<br />
{0x7a, 7}, {0x10,13}, {0x21, 8}, {0x1a,16},<br />
{0x25, 8}, {0x19,16}, {0x24, 8}, {0x18,16},<br />
{0x05, 9}, {0x17,16}, {0x07, 9}, {0x16,16},<br />
{0x0d,10}, {0x15,16}, {0x1f,12}, {0x1a,12},<br />
{0x19,12}, {0x17,12}, {0x16,12}, {0x1f,13},<br />
{0x1e,13}, {0x1d,13}, {0x1c,13}, {0x1b,13},<br />
{0x1f,16}, {0x1e,16}, {0x1d,16}, {0x1c,16},<br />
{0x1b,16},<br />
{0x01,6}, /* escape */<br />
{0x06,4}, /* EOB */<br />
};<br />
static const uint8_t speedhq_level[121] = {<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 21, 22, 23, 24,<br />
25, 26, 27, 28, 29, 30, 31, 32,<br />
33, 34, 35, 36, 37, 38, 39, 40,<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 1, 2, 3, 4,<br />
5, 6, 7, 8, 9, 10, 11, 1,<br />
2, 3, 4, 5, 1, 2, 3, 4,<br />
1, 2, 3, 1, 2, 3, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1,<br />
};<br />
static const uint8_t speedhq_run[121] = {<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 2, 2, 2, 2,<br />
2, 2, 2, 2, 2, 2, 2, 3,<br />
3, 3, 3, 3, 4, 4, 4, 4,<br />
5, 5, 5, 6, 6, 6, 7, 7,<br />
8, 8, 9, 9, 10, 10, 11, 11,<br />
12, 12, 13, 13, 14, 14, 15, 15,<br />
16, 16, 17, 18, 19, 20, 21, 22,<br />
23, 24, 25, 26, 27, 28, 29, 30,<br />
31,<br />
};<br />
<br />
Escape works similarly to MPEG-2; the next six bits contain the run (non-reversed), and the next 12 bits contain the level (non-reversed), offset by 2048. There'a always an EOB at the end of each block (as in MPEG-2), and there's never a block without a DC coefficient (also as in MPEG-2). All other codes are followed by the coefficient sign (again as in MPEG-2).<br />
<br />
Alpha for SHQ1/3/5 is coded as run-level too: first it has a codeword telling how many elements to skip (or whether this is end of block) and then a codeword for nonzero element, repeat.<br />
<br />
Alpha for SHQ7/9 is encoded identically to luma, and comes after chroma (so e.g. SHQ7 is YYYY UV UV AAAA).<br />
<br />
=== Quantiser ===<br />
<br />
Allowed quality levels:<br />
<br />
1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 104, 112<br />
<br />
Provided quality is clipped to 99, also if it's less than 38 or odd then a nearest smaller value from default quality table is used instead.<br />
<br />
Quantisation matrix:<br />
<br />
*, 16, 19, 22, 26, 27, 29, 34,<br />
16, 16, 22, 24, 27, 29, 34, 37,<br />
19, 22, 26, 27, 29, 34, 34, 38,<br />
22, 22, 26, 27, 29, 34, 37, 40,<br />
22, 26, 27, 29, 32, 35, 40, 48,<br />
26, 27, 29, 32, 35, 40, 48, 58,<br />
26, 27, 29, 34, 38, 46, 56, 69,<br />
27, 29, 35, 38, 46, 56, 69, 83<br />
<br />
The DC quantizer is set to 16 no matter what; the other values are multiplied by (100 - quality). Each coefficient is multiplied with the corresponding quantization factor and then divided by 16 (no rounding), before the block goes to IDCT.<br />
<br />
As an optimization, DC-only blocks are special-cased; all pixels in the block get exactly the value (dc + 4) >> 3.<br />
<br />
Y'CbCr conversion uses BT.601 coefficients. Chroma positioning is center, as in MPEG-2.<br />
<br />
[[Category:Undiscovered Video Codecs]]<br />
[[Category:Video Codecs]]</div>Sessehttps://wiki.multimedia.cx/index.php?title=SpeedHQ&diff=15258SpeedHQ2017-01-06T00:20:46Z<p>Sesse: More info based on the samples</p>
<hr />
<div>* FOURCCs: SHQ0, SHQ1, ..., SHQ5, SHQ7, SHQ9<br />
* Company: NewTek (note: NewTek has provided samples and support in understanding the format)<br />
<br />
This is a simple intermediate codec with different subsampling and alpha support. It is generally very similar to MPEG-2 intraframe. Several variants exist:<br />
<br />
* <code>SHQ0</code>/<code>SHQ1</code> are 4:2:0 with/without alpha.<br />
* <code>SHQ2</code>/<code>SHQ3</code> are 4:2:2 with/without alpha.<br />
* <code>SHQ4</code>/<code>SHQ5</code> are 4:4:4 with/without alpha.<br />
* <code>SHQ7</code> is 422 with alpha coded as luma and chroma blocks<br />
* <code>SHQ9</code> is the same for 444 format.<br />
<br />
NewTek's NDI network codec uses SHQ2 and SHQ7.<br />
<br />
Frame is always coded as two fields, data is packed into 32-bit little-endian words and is read from LSB.<br />
<br />
First byte is quality, next three bytes form an offset to the second field. (Exception: NDI can send a frame consisting of a single field, with the second field offset equal to 4, ie., exactly overlapping with the first field.) Quantizer is 100 - quality.<br />
<br />
=== Field format ===<br />
<br />
Each field is split into four slices that can be independently decoded; each slice codes 16 lines, then skip 48 lines (coded by the other three slices), code 16 more lines, and so on until at the bottom of the field, which implicitly ends the slice. The first three bytes of each slice form a length of the slice in bytes (including the three length bytes). The next slice starts on the byte immediately after the end of the previous one, as given by the length (this might mean skipping 1–7 bits).<br />
<br />
Blocks are 8x8 pixels, and macroblocks are 16x16 pixels. Luma is coded top-left, top-right, bottom-left, bottom-right. 4:4:4 is coded YYYY UV UV UV UV (chroma is top-left, bottom-left, top-right, bottom-right). 4:2:2 is coded YYYY UV UV (chroma is top, then bottom). 4:2:0 is coded YYYY UV.<br />
<br />
Blocks are coded with static VLCs. DC coefficients are coded exactly as in MPEG-2 (same luma/chroma tables, same scheme for storing the coefficient and sign). DC prediction is taken from the previous block of the same coefficient, and restarts at 1024 for each new macroblock row (not 128 as in MPEG-2). Curiously enough, one needs to _subtract_ the stored DC value from the prediction, not add as usual.<br />
<br />
AC coefficients are coded using the same scheme as MPEG-2 (run/level with the same zigzag pattern), and with a VLC that is very similar to MPEG-2's “Table One” for AC coefficients. (It is not identical; some codewords that are illegal in MPEG-2 are used in SpeedHQ, and a few others are moved around as a consequence.) In FFmpeg format, the codes are (except that they would need to be bit-reversed due to INIT_VLC_LE demands):<br />
<br />
static const uint16_t speedhq_vlc[123][2] = {<br />
{0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},<br />
{0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},<br />
{0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},<br />
{0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},<br />
{0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},<br />
{0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},<br />
{0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},<br />
{0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},<br />
{0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},<br />
{0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},<br />
{0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},<br />
{0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},<br />
{0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},<br />
{0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},<br />
{0x11,16}, {0x10,16}, {0x18,13}, {0x17,13},<br />
{0x05, 5}, {0x07, 7}, {0xfc, 8}, {0x0c,10},<br />
{0x14,13}, {0x18,12}, {0x14,12}, {0x13,12},<br />
{0x10,12}, {0x1a,13}, {0x19,13}, {0x07, 5},<br />
{0x26, 8}, {0x1c,12}, {0x13,13}, {0x1b,12},<br />
{0x06, 6}, {0xfd, 8}, {0x12,12}, {0x1d,12},<br />
{0x07, 6}, {0x04, 9}, {0x12,13}, {0x06, 7},<br />
{0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},<br />
{0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},<br />
{0x7a, 7}, {0x10,13}, {0x21, 8}, {0x1a,16},<br />
{0x25, 8}, {0x19,16}, {0x24, 8}, {0x18,16},<br />
{0x05, 9}, {0x17,16}, {0x07, 9}, {0x16,16},<br />
{0x0d,10}, {0x15,16}, {0x1f,12}, {0x1a,12},<br />
{0x19,12}, {0x17,12}, {0x16,12}, {0x1f,13},<br />
{0x1e,13}, {0x1d,13}, {0x1c,13}, {0x1b,13},<br />
{0x1f,16}, {0x1e,16}, {0x1d,16}, {0x1c,16},<br />
{0x1b,16},<br />
{0x01,6}, /* escape */<br />
{0x06,4}, /* EOB */<br />
};<br />
static const uint8_t speedhq_level[121] = {<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 21, 22, 23, 24,<br />
25, 26, 27, 28, 29, 30, 31, 32,<br />
33, 34, 35, 36, 37, 38, 39, 40,<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 1, 2, 3, 4,<br />
5, 6, 7, 8, 9, 10, 11, 1,<br />
2, 3, 4, 5, 1, 2, 3, 4,<br />
1, 2, 3, 1, 2, 3, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1,<br />
};<br />
static const uint8_t speedhq_run[121] = {<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 2, 2, 2, 2,<br />
2, 2, 2, 2, 2, 2, 2, 3,<br />
3, 3, 3, 3, 4, 4, 4, 4,<br />
5, 5, 5, 6, 6, 6, 7, 7,<br />
8, 8, 9, 9, 10, 10, 11, 11,<br />
12, 12, 13, 13, 14, 14, 15, 15,<br />
16, 16, 17, 18, 19, 20, 21, 22,<br />
23, 24, 25, 26, 27, 28, 29, 30,<br />
31,<br />
};<br />
<br />
Escape works similarly to MPEG-2; the next six bits contain the run (non-reversed), and the next 12 bits contain the level (non-reversed), offset by 2048. There'a always an EOB at the end of each block (as in MPEG-2), and there's never a block without a DC coefficient (also as in MPEG-2). All other codes are followed by the coefficient sign (again as in MPEG-2).<br />
<br />
Alpha is coded as run-level too: first it has a codeword telling how many elements to skip (or whether this is end of block) and then a codeword for nonzero element, repeat.<br />
<br />
=== Quantiser ===<br />
<br />
Allowed quality levels:<br />
<br />
1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 104, 112<br />
<br />
Provided quality is clipped to 99, also if it's less than 38 or odd then a nearest smaller value from default quality table is used instead.<br />
<br />
Quantisation matrix:<br />
<br />
*, 16, 19, 22, 26, 27, 29, 34,<br />
16, 16, 22, 24, 27, 29, 34, 37,<br />
19, 22, 26, 27, 29, 34, 34, 38,<br />
22, 22, 26, 27, 29, 34, 37, 40,<br />
22, 26, 27, 29, 32, 35, 40, 48,<br />
26, 27, 29, 32, 35, 40, 48, 58,<br />
26, 27, 29, 34, 38, 46, 56, 69,<br />
27, 29, 35, 38, 46, 56, 69, 83<br />
<br />
The DC quantizer is set to 16 no matter what; the other values are multiplied by (100 - quality). Each coefficient is multiplied with the corresponding quantization factor and then divided by 16 (no rounding), before the block goes to IDCT.<br />
<br />
As an optimization, DC-only blocks are special-cased; all pixels in the block get exactly the value (dc + 4) >> 3.<br />
<br />
Y'CbCr conversion uses BT.601 coefficients. Chroma positioning is center, as in MPEG-2.<br />
<br />
[[Category:Undiscovered Video Codecs]]<br />
[[Category:Video Codecs]]</div>Sessehttps://wiki.multimedia.cx/index.php?title=SpeedHQ&diff=15257SpeedHQ2017-01-05T19:16:44Z<p>Sesse: Some corrections based on information from NewTek</p>
<hr />
<div>* FOURCCs: SHQ0, SHQ1, ..., SHQ5, SHQ7, SHQ9<br />
* Company: NewTek (note: NewTek has provided support in understanding the format)<br />
<br />
This is a simple intermediate codec with different subsampling and alpha support. It is generally very similar to MPEG-2 intraframe. Several variants exist:<br />
<br />
* <code>SHQ0</code>/<code>SHQ1</code> are 4:2:0 with/without alpha (SHQ1 is either rare or nonexistant in practice).<br />
* <code>SHQ2</code>/<code>SHQ3</code> are 4:2:2 with/without alpha.<br />
* <code>SHQ4</code>/<code>SHQ5</code> are 4:4:4 with/without alpha.<br />
* <code>SHQ7</code> is 422 with alpha coded as luma and chroma blocks<br />
* <code>SHQ9</code> is the same for 444 format.<br />
<br />
NewTek's NDI network codec uses SHQ2 and SHQ7.<br />
<br />
Frame is always coded as two fields, data is packed into 32-bit little-endian words and is read from LSB.<br />
<br />
First byte is quality, next three bytes form an offset to the second field. (Exception: NDI can send a frame consisting of a single field, with the second field offset equal to 4, ie., exactly overlapping with the first field.) Quantizer is 100 - quality.<br />
<br />
=== Field format ===<br />
<br />
Each field is split into four slices that can be independently decoded; each slice codes 16 lines, then skip 48 lines (coded by the other three slices), code 16 more lines, and so on until at the bottom of the field, which implicitly ends the slice. The first three bytes of each slice form a length of the slice in bytes (including the three length bytes). The next slice starts on the byte immediately after the end of the previous one, as given by the length (this might mean skipping 1–7 bits).<br />
<br />
Blocks are 8x8 pixels, and macroblocks are 16x16 pixels (coded top-left, top-right, bottom-left, bottom-right). 4:4:4 is coded YYYY UV UV UV UV. 4:2:2 is coded YYYY UV UV. 4:2:0 is coded YYYY UV.<br />
<br />
Blocks are coded with static VLCs. DC coefficients are coded exactly as in MPEG-2 (same luma/chroma tables, same scheme for storing the coefficient and sign). DC prediction is taken from the previous block of the same coefficient, and restarts at 1024 for each new macroblock row (not 128 as in MPEG-2). Curiously enough, one needs to _subtract_ the stored DC value from the prediction, not add as usual.<br />
<br />
AC coefficients are coded using the same scheme as MPEG-2 (run/level with the same zigzag pattern), and with a VLC that is very similar to MPEG-2's “Table One” for AC coefficients. (It is not identical; some codewords that are illegal in MPEG-2 are used in SpeedHQ, and a few others are moved around as a consequence.) In FFmpeg format, the codes are (except that they would need to be bit-reversed due to INIT_VLC_LE demands):<br />
<br />
static const uint16_t speedhq_vlc[123][2] = {<br />
{0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},<br />
{0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},<br />
{0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},<br />
{0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},<br />
{0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},<br />
{0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},<br />
{0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},<br />
{0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},<br />
{0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},<br />
{0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},<br />
{0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},<br />
{0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},<br />
{0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},<br />
{0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},<br />
{0x11,16}, {0x10,16}, {0x18,13}, {0x17,13},<br />
{0x05, 5}, {0x07, 7}, {0xfc, 8}, {0x0c,10},<br />
{0x14,13}, {0x18,12}, {0x14,12}, {0x13,12},<br />
{0x10,12}, {0x1a,13}, {0x19,13}, {0x07, 5},<br />
{0x26, 8}, {0x1c,12}, {0x13,13}, {0x1b,12},<br />
{0x06, 6}, {0xfd, 8}, {0x12,12}, {0x1d,12},<br />
{0x07, 6}, {0x04, 9}, {0x12,13}, {0x06, 7},<br />
{0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},<br />
{0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},<br />
{0x7a, 7}, {0x10,13}, {0x21, 8}, {0x1a,16},<br />
{0x25, 8}, {0x19,16}, {0x24, 8}, {0x18,16},<br />
{0x05, 9}, {0x17,16}, {0x07, 9}, {0x16,16},<br />
{0x0d,10}, {0x15,16}, {0x1f,12}, {0x1a,12},<br />
{0x19,12}, {0x17,12}, {0x16,12}, {0x1f,13},<br />
{0x1e,13}, {0x1d,13}, {0x1c,13}, {0x1b,13},<br />
{0x1f,16}, {0x1e,16}, {0x1d,16}, {0x1c,16},<br />
{0x1b,16},<br />
{0x01,6}, /* escape */<br />
{0x06,4}, /* EOB */<br />
};<br />
static const uint8_t speedhq_level[121] = {<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 21, 22, 23, 24,<br />
25, 26, 27, 28, 29, 30, 31, 32,<br />
33, 34, 35, 36, 37, 38, 39, 40,<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 1, 2, 3, 4,<br />
5, 6, 7, 8, 9, 10, 11, 1,<br />
2, 3, 4, 5, 1, 2, 3, 4,<br />
1, 2, 3, 1, 2, 3, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1,<br />
};<br />
static const uint8_t speedhq_run[121] = {<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 2, 2, 2, 2,<br />
2, 2, 2, 2, 2, 2, 2, 3,<br />
3, 3, 3, 3, 4, 4, 4, 4,<br />
5, 5, 5, 6, 6, 6, 7, 7,<br />
8, 8, 9, 9, 10, 10, 11, 11,<br />
12, 12, 13, 13, 14, 14, 15, 15,<br />
16, 16, 17, 18, 19, 20, 21, 22,<br />
23, 24, 25, 26, 27, 28, 29, 30,<br />
31,<br />
};<br />
<br />
Escape works similarly to MPEG-2; the next six bits contain the run (non-reversed), and the next 12 bits contain the level (non-reversed), offset by 2048. There'a always an EOB at the end of each block (as in MPEG-2), and there's never a block without a DC coefficient (also as in MPEG-2). All other codes are followed by the coefficient sign (again as in MPEG-2).<br />
<br />
Alpha is coded as run-level too: first it has a codeword telling how many elements to skip (or whether this is end of block) and then a codeword for nonzero element, repeat.<br />
<br />
=== Quantiser ===<br />
<br />
Allowed quality levels:<br />
<br />
1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 104, 112<br />
<br />
Provided quality is clipped to 99, also if it's less than 38 or odd then a nearest smaller value from default quality table is used instead.<br />
<br />
Quantisation matrix:<br />
<br />
*, 16, 19, 22, 26, 27, 29, 34,<br />
16, 16, 22, 24, 27, 29, 34, 37,<br />
19, 22, 26, 27, 29, 34, 34, 38,<br />
22, 22, 26, 27, 29, 34, 37, 40,<br />
22, 26, 27, 29, 32, 35, 40, 48,<br />
26, 27, 29, 32, 35, 40, 48, 58,<br />
26, 27, 29, 34, 38, 46, 56, 69,<br />
27, 29, 35, 38, 46, 56, 69, 83<br />
<br />
The DC quantizer is set to 16 no matter what; the other values are multiplied by (100 - quality). Each coefficient is multiplied with the corresponding quantization factor and then divided by 16 (no rounding), before the block goes to IDCT.<br />
<br />
As an optimization, DC-only blocks are special-cased; all pixels in the block get exactly the value (dc + 4) >> 3.<br />
<br />
Y'CbCr conversion uses BT.601 coefficients. Chroma positioning is center, as in MPEG-2.<br />
<br />
[[Category:Undiscovered Video Codecs]]<br />
[[Category:Video Codecs]]</div>Sessehttps://wiki.multimedia.cx/index.php?title=SpeedHQ&diff=15256SpeedHQ2017-01-04T20:12:03Z<p>Sesse: Fixed table mispaste</p>
<hr />
<div>* FOURCCs: SHQ0, SHQ1, ..., SHQ5, SHQ7, SHQ9<br />
* Company: NewTek<br />
<br />
This is a simple intermediate codec with different subsampling and alpha support. It is generally very similar to MPEG-2 intraframe. Several variants exist:<br />
<br />
* <code>SHQ0</code>/<code>SHQ1</code> are 4:2:0 with/without alpha (SHQ1 is either rare or nonexistant in practice).<br />
* <code>SHQ2</code>/<code>SHQ3</code> are 4:2:2 with/without alpha.<br />
* <code>SHQ4</code>/<code>SHQ5</code> are 4:4:4 with/without alpha.<br />
* <code>SHQ7</code> is 422 with alpha coded as luma and chroma blocks<br />
* <code>SHQ9</code> is the same for 444 format.<br />
<br />
NewTek's NDI network codec uses SHQ2 and SHQ7.<br />
<br />
Frame is always coded as two fields, data is packed into 32-bit little-endian words and is read from LSB.<br />
<br />
First byte is quality, next three bytes form an offset to the second field. Quantizer is 100 - quality.<br />
<br />
=== Field format ===<br />
<br />
Each field is split into four slices that can be independently decoded; each slice codes 16 lines, then skip 48 lines (coded by the other three slices), code 16 more lines, and so on until at the bottom of the field, which implicitly ends the slice. The first three bytes of each slice form a length of the slice in bytes (including the three length bytes). The next slice starts on the byte immediately after the end of the previous one, as given by the length (this might mean skipping 1–7 bits).<br />
<br />
Blocks are 8x8 pixels, and macroblocks are 16x16 pixels (coded top-left, top-right, bottom-left, bottom-right). 4:4:4 is coded YYYY UV UV UV UV. 4:2:2 is coded YYYY UV UV. 4:2:0 is coded YYYY UV.<br />
<br />
Blocks are coded with static VLCs. DC coefficients are coded exactly as in MPEG-2 (same luma/chroma tables, same scheme for storing the coefficient and sign). DC prediction is taken from the previous block of the same coefficient, and restarts at 0 for each new macroblock row (not 128 as in MPEG-2). Curiously enough, one needs to _subtract_ the stored DC value from the prediction, not add as usual.<br />
<br />
AC coefficients are coded using the same scheme as MPEG-2 (run/level with the same zigzag pattern), and with a VLC that is very similar to MPEG-2's “Table One” for AC coefficients. (It is not identical; some codewords that are illegal in MPEG-2 are used in SpeedHQ, and a few others are moved around as a consequence.) In FFmpeg format, the codes are:<br />
<br />
static const uint16_t speedhq_vlc[123][2] = {<br />
{0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},<br />
{0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},<br />
{0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},<br />
{0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},<br />
{0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},<br />
{0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},<br />
{0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},<br />
{0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},<br />
{0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},<br />
{0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},<br />
{0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},<br />
{0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},<br />
{0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},<br />
{0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},<br />
{0x11,16}, {0x10,16}, {0x18,13}, {0x17,13},<br />
{0x05, 5}, {0x07, 7}, {0xfc, 8}, {0x0c,10},<br />
{0x14,13}, {0x18,12}, {0x14,12}, {0x13,12},<br />
{0x10,12}, {0x1a,13}, {0x19,13}, {0x07, 5},<br />
{0x26, 8}, {0x1c,12}, {0x13,13}, {0x1b,12},<br />
{0x06, 6}, {0xfd, 8}, {0x12,12}, {0x1d,12},<br />
{0x07, 6}, {0x04, 9}, {0x12,13}, {0x06, 7},<br />
{0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},<br />
{0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},<br />
{0x7a, 7}, {0x10,13}, {0x21, 8}, {0x1a,16},<br />
{0x25, 8}, {0x19,16}, {0x24, 8}, {0x18,16},<br />
{0x05, 9}, {0x17,16}, {0x07, 9}, {0x16,16},<br />
{0x0d,10}, {0x15,16}, {0x1f,12}, {0x1a,12},<br />
{0x19,12}, {0x17,12}, {0x16,12}, {0x1f,13},<br />
{0x1e,13}, {0x1d,13}, {0x1c,13}, {0x1b,13},<br />
{0x1f,16}, {0x1e,16}, {0x1d,16}, {0x1c,16},<br />
{0x1b,16},<br />
{0x01,6}, /* escape */<br />
{0x06,4}, /* EOB */<br />
};<br />
static const uint8_t speedhq_level[121] = {<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 21, 22, 23, 24,<br />
25, 26, 27, 28, 29, 30, 31, 32,<br />
33, 34, 35, 36, 37, 38, 39, 40,<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 1, 2, 3, 4,<br />
5, 6, 7, 8, 9, 10, 11, 1,<br />
2, 3, 4, 5, 1, 2, 3, 4,<br />
1, 2, 3, 1, 2, 3, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1,<br />
};<br />
static const uint8_t speedhq_run[121] = {<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 2, 2, 2, 2,<br />
2, 2, 2, 2, 2, 2, 2, 3,<br />
3, 3, 3, 3, 4, 4, 4, 4,<br />
5, 5, 5, 6, 6, 6, 7, 7,<br />
8, 8, 9, 9, 10, 10, 11, 11,<br />
12, 12, 13, 13, 14, 14, 15, 15,<br />
16, 16, 17, 18, 19, 20, 21, 22,<br />
23, 24, 25, 26, 27, 28, 29, 30,<br />
31,<br />
};<br />
<br />
Escape works similarly to MPEG-2; the next six bits contain the run (non-reversed), and the next 12 bits contain the level (non-reversed), offset by 2048. There'a always an EOB at the end of each block (as in MPEG-2), and there's never a block without a DC coefficient (also as in MPEG-2). All other codes are followed by the coefficient sign (again as in MPEG-2).<br />
<br />
Alpha is coded as run-level too: first it has a codeword telling how many elements to skip (or whether this is end of block) and then a codeword for nonzero element, repeat.<br />
<br />
=== Quantiser ===<br />
<br />
Allowed quality levels:<br />
<br />
1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 104, 112<br />
<br />
Provided quality is clipped to 99, also if it's less than 38 or odd then a nearest smaller value from default quality table is used instead.<br />
<br />
Quantisation matrix:<br />
<br />
*, 16, 19, 22, 26, 27, 29, 34,<br />
16, 16, 22, 24, 27, 29, 34, 37,<br />
19, 22, 26, 27, 29, 34, 34, 38,<br />
22, 22, 26, 27, 29, 34, 37, 40,<br />
22, 26, 27, 29, 32, 35, 40, 48,<br />
26, 27, 29, 32, 35, 40, 48, 58,<br />
26, 27, 29, 34, 38, 46, 56, 69,<br />
27, 29, 35, 38, 46, 56, 69, 83<br />
<br />
The DC quantizer is set to 16 no matter what; the other values are multiplied by (100 - quality). Each coefficient is multiplied with the corresponding quantization factor and then divided by 16 (no rounding). Finally, 1024 is added to the DC coefficient, and then the block goes to IDCT.<br />
<br />
As an optimization, DC-only blocks are special-cased; all pixels in the block get exactly the value (dc + 1032) >> 3.<br />
<br />
Y'CbCr conversion uses BT.601 coefficients. Chroma positioning is center, as in MPEG-2.<br />
<br />
[[Category:Undiscovered Video Codecs]]<br />
[[Category:Video Codecs]]</div>Sessehttps://wiki.multimedia.cx/index.php?title=SpeedHQ&diff=15255SpeedHQ2017-01-04T17:28:19Z<p>Sesse: /* Quantiser */ Chroma positioning</p>
<hr />
<div>* FOURCCs: SHQ0, SHQ1, ..., SHQ5, SHQ7, SHQ9<br />
* Company: NewTek<br />
<br />
This is a simple intermediate codec with different subsampling and alpha support. It is generally very similar to MPEG-2 intraframe. Several variants exist:<br />
<br />
* <code>SHQ0</code>/<code>SHQ1</code> are 4:2:0 with/without alpha (SHQ1 is either rare or nonexistant in practice).<br />
* <code>SHQ2</code>/<code>SHQ3</code> are 4:2:2 with/without alpha.<br />
* <code>SHQ4</code>/<code>SHQ5</code> are 4:4:4 with/without alpha.<br />
* <code>SHQ7</code> is 422 with alpha coded as luma and chroma blocks<br />
* <code>SHQ9</code> is the same for 444 format.<br />
<br />
NewTek's NDI network codec uses SHQ2 and SHQ7.<br />
<br />
Frame is always coded as two fields, data is packed into 32-bit little-endian words and is read from LSB.<br />
<br />
First byte is quality, next three bytes form an offset to the second field. Quantizer is 100 - quality.<br />
<br />
=== Field format ===<br />
<br />
Each field is split into four slices that can be independently decoded; each slice codes 16 lines, then skip 48 lines (coded by the other three slices), code 16 more lines, and so on until at the bottom of the field, which implicitly ends the slice. The first three bytes of each slice form a length of the slice in bytes (including the three length bytes). The next slice starts on the byte immediately after the end of the previous one, as given by the length (this might mean skipping 1–7 bits).<br />
<br />
Blocks are 8x8 pixels, and macroblocks are 16x16 pixels (coded top-left, top-right, bottom-left, bottom-right). 4:4:4 is coded YYYY UV UV UV UV. 4:2:2 is coded YYYY UV UV. 4:2:0 is coded YYYY UV.<br />
<br />
Blocks are coded with static VLCs. DC coefficients are coded exactly as in MPEG-2 (same luma/chroma tables, same scheme for storing the coefficient and sign). DC prediction is taken from the previous block of the same coefficient, and restarts at 0 for each new macroblock row (not 128 as in MPEG-2). Curiously enough, one needs to _subtract_ the stored DC value from the prediction, not add as usual.<br />
<br />
AC coefficients are coded using the same scheme as MPEG-2 (run/level with the same zigzag pattern), and with a VLC that is very similar to MPEG-2's “Table One” for AC coefficients. (It is not identical; some codewords that are illegal in MPEG-2 are used in SpeedHQ, and a few others are moved around as a consequence.) In FFmpeg format, the codes are:<br />
<br />
static const uint16_t speedhq_vlc[123][2] = {<br />
{0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},<br />
{0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},<br />
{0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},<br />
{0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},<br />
{0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},<br />
{0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},<br />
{0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},<br />
{0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},<br />
{0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},<br />
{0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},<br />
{0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},<br />
{0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},<br />
{0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},<br />
{0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},<br />
{0x11,16}, {0x10,16}, {0x18,13}, {0x17,13},<br />
{0x05, 5}, {0x07, 7}, {0xfc, 8}, {0x0c,10},<br />
{0x14,13}, {0x18,12}, {0x14,12}, {0x13,12},<br />
{0x10,12}, {0x1a,13}, {0x19,13}, {0x07, 5},<br />
{0x26, 8}, {0x1c,12}, {0x13,13}, {0x1b,12},<br />
{0x06, 6}, {0xfd, 8}, {0x12,12}, {0x1d,12},<br />
{0x07, 6}, {0x04, 9}, {0x12,13}, {0x06, 7},<br />
{0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},<br />
{0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},<br />
{0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},<br />
{0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},<br />
{0x7a, 7}, {0x10,13}, {0x21, 8}, {0x1a,16},<br />
{0x25, 8}, {0x19,16}, {0x24, 8}, {0x18,16},<br />
{0x05, 9}, {0x17,16}, {0x07, 9}, {0x16,16},<br />
{0x0d,10}, {0x15,16}, {0x1f,12}, {0x1a,12}, <br />
{0x19,12}, {0x17,12}, {0x16,12}, {0x1f,13}, <br />
{0x1e,13}, {0x1d,13}, {0x1c,13}, {0x1b,13},<br />
{0x1f,16}, {0x1e,16}, {0x1d,16}, {0x1c,16},<br />
{0x1b,16},<br />
{0x01,6}, /* escape */<br />
{0x06,4}, /* EOB */<br />
};<br />
static const uint8_t speedhq_level[121] = {<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 21, 22, 23, 24,<br />
25, 26, 27, 28, 29, 30, 31, 32,<br />
33, 34, 35, 36, 37, 38, 39, 40,<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 1, 2, 3, 4,<br />
5, 6, 7, 8, 9, 10, 11, 1,<br />
2, 3, 4, 5, 1, 2, 3, 4,<br />
1, 2, 3, 1, 2, 3, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1,<br />
};<br />
static const uint8_t speedhq_run[121] = { <br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 2, 2, 2, 2,<br />
2, 2, 2, 2, 2, 2, 2, 3,<br />
3, 3, 3, 3, 4, 4, 4, 4,<br />
5, 5, 5, 6, 6, 6, 7, 7,<br />
8, 8, 9, 9, 10, 10, 11, 11,<br />
12, 12, 13, 13, 14, 14, 15, 15,<br />
16, 16, 17, 18, 19, 20, 21, 22,<br />
23, 24, 25, 26, 27, 28, 29, 30,<br />
31,<br />
};<br />
<br />
Escape works similarly to MPEG-2; the next six bits contain the run (non-reversed), and the next 12 bits contain the level (non-reversed), offset by 2048. There'a always an EOB at the end of each block (as in MPEG-2), and there's never a block without a DC coefficient (also as in MPEG-2). All other codes are followed by the coefficient sign (again as in MPEG-2).<br />
<br />
Alpha is coded as run-level too: first it has a codeword telling how many elements to skip (or whether this is end of block) and then a codeword for nonzero element, repeat.<br />
<br />
=== Quantiser ===<br />
<br />
Allowed quality levels:<br />
<br />
1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 104, 112<br />
<br />
Provided quality is clipped to 99, also if it's less than 38 or odd then a nearest smaller value from default quality table is used instead.<br />
<br />
Quantisation matrix:<br />
<br />
*, 16, 19, 22, 26, 27, 29, 34,<br />
16, 16, 22, 24, 27, 29, 34, 37,<br />
19, 22, 26, 27, 29, 34, 34, 38,<br />
22, 22, 26, 27, 29, 34, 37, 40,<br />
22, 26, 27, 29, 32, 35, 40, 48,<br />
26, 27, 29, 32, 35, 40, 48, 58,<br />
26, 27, 29, 34, 38, 46, 56, 69,<br />
27, 29, 35, 38, 46, 56, 69, 83<br />
<br />
The DC quantizer is set to 16 no matter what; the other values are multiplied by (100 - quality). Each coefficient is multiplied with the corresponding quantization factor and then divided by 16 (no rounding). Finally, 1024 is added to the DC coefficient, and then the block goes to IDCT.<br />
<br />
As an optimization, DC-only blocks are special-cased; all pixels in the block get exactly the value (dc + 1032) >> 3.<br />
<br />
Y'CbCr conversion uses BT.601 coefficients. Chroma positioning is center, as in MPEG-2.<br />
<br />
[[Category:Undiscovered Video Codecs]]<br />
[[Category:Video Codecs]]</div>Sessehttps://wiki.multimedia.cx/index.php?title=FFmpeg_technical&diff=15254FFmpeg technical2017-01-03T21:44:54Z<p>Sesse: Symbol has changed name</p>
<hr />
<div>== Demuxer stuff ==<br />
=== How to use demuxer with raw data ===<br />
Write a parser.<br />
There are two main function - parse and split. '''parse''' is used to reconstruct precisely one frame from raw packets, '''split''' is used for extracting extradata from the same stream.<br />
<br />
Parser declarations will look like this:<br />
<br />
typedef struct MyParseContext{<br />
ParseContext pc; /* always include this first */<br />
another data<br />
};<br />
AVParser some_parser = {<br />
{ CODEC_ID_1 [CODEC_ID_2, ...] },<br />
sizeof (MyParseContext),<br />
NULL, /* usually there is no need in parser_open */<br />
my_parse,<br />
ff_parse_close, /* again, use standard close function */<br />
my_split,<br />
};<br />
<br />
And here is the code for some parser which splits frame by some markers:<br />
<br />
static int xxx_find_frame_end(XXXParseContext *pc1, const uint8_t *buf,<br />
int buf_size) {<br />
int start_found, i;<br />
uint32_t state;<br />
ParseContext *pc = &pc1->pc;<br />
start_found= pc->frame_start_found;<br />
state= pc->state;<br />
i=0;<br />
if(!start_found){<br />
for(i=0; i<buf_size; i++){<br />
state= (state<<8) | buf[i];<br />
if(state == MARKER){<br />
start_found=1;<br />
break;<br />
}<br />
}<br />
}<br />
if(start_found){<br />
for(; i<buf_size; i++){<br />
state= (state<<8) | buf[i];<br />
if(state == MARKER){<br />
pc->frame_start_found= 0;<br />
pc->state= -1;<br />
return i-3;<br />
}<br />
}<br />
}<br />
pc->frame_start_found= start_found;<br />
pc->state= state;<br />
return END_NOT_FOUND;<br />
}<br />
<br />
static int xxx_parse(AVCodecParserContext *s,<br />
AVCodecContext *avctx,<br />
uint8_t **poutbuf, int *poutbuf_size,<br />
const uint8_t *buf, int buf_size)<br />
{<br />
XXXParseContext *pc1 = s->priv_data;<br />
ParseContext *pc = &pc1->pc;<br />
int next;<br />
if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){<br />
next= buf_size;<br />
}else{<br />
next= xxx_find_frame_end(pc1, buf, buf_size);<br />
if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {<br />
*poutbuf = NULL;<br />
*poutbuf_size = 0;<br />
return buf_size;<br />
}<br />
}<br />
*poutbuf = (uint8_t *)buf;<br />
*poutbuf_size = buf_size;<br />
return next;<br />
}<br />
<br />
== Decoder stuff ==<br />
<br />
=== How to use delta frames ===<br />
There are two ways: either use your own buffer for frame data or reget old frame and modify it.<br />
This can be done by calling reget_buffer() instead of get_buffer().<br />
Usual code:<br />
<br />
if(avctx->get_buffer(avctx, &c->pic) < 0){<br />
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");<br />
return -1;<br />
}<br />
<br />
New code:<br />
<br />
c->pic.reference = 1;<br />
c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;<br />
if(avctx->reget_buffer(avctx, &c->pic) < 0){<br />
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");<br />
return -1;<br />
}<br />
<br />
=== How to use bitstream ===<br />
There are two bitstream reading methods - MSB and 32-bit little-endian word. In order to use the second you need to #define BITSTREAM_READER_LE before including bitstream.h.<br />
<br />
Simple bitstream writing:<br />
<br />
PutBitContext pb;<br />
init_put_bits(&pb, buffer, max_bytes); // max_bytes is buffer size to avoid out-of-bounds write<br />
put_bits(&pb, 13, value); // Note that the second argument is value size in bits, not actual value<br />
size = put_bits_count(&pb); // get the number of bits written so far<br />
flush_put_bits(&pb); // call this to finish bit writing so bits won't be lost in buffer<br />
<br />
Simple bitstream reading:<br />
<br />
GetBitContext gb;<br />
init_get_bits(&gb, buffer, buffer_size * 8); // init_get_bits() expects buffer size in _bits_<br />
a = get_bits(&gb, 16); // read some bits from stream<br />
b = get_sbits(&gb, 15); // read some bits from stream as signed integer<br />
c = get_bits_long(&gb, 18); // get_bits() is guaranteed to work only for bits <= 17, for greater values use get_bits_long()<br />
d = show_bits(&gb, 5); // peek bits but don't change position in bitstream, also has show_bits_long() counterpart<br />
<br />
Variable-length codes reading is also quite simple.<br />
<br />
VLC vlc;<br />
init_vlc(&vlc, MAX_BITS, codes_size,<br />
bits, bits_skip, sizeof(bits[0]),<br />
codes, codes_skip, sizeof(codes[0]), flags);<br />
value = get_vlc2(&gb, vlc.table, MAX_BITS, wrap);<br />
free_vlc(&vlc);<br />
<br />
Notes on VLC reading:<br />
* MAX_BITS is the maximum code length but not greater than 9 (i.e. if max codeword length is 5 then MAX_BITS=5 but if max codeword length is 15 then MAX_BITS=6)<br />
* *_skip should be either equal to sizeof() if bits and codes are stored in separate tables or = ((uint8_t*)bits[1])-((uint8_t*)bits[0]). For example if you store all in struct { char bits; short value;} codes[100] you should call<br />
<br />
init_vlc(&vlc, MAX_BITS, 100, &codes[0].bits, sizeof(codes[0]), 1, &codes[0].value, sizeof(codes[0]), 2, 0);<br />
<br />
* flags may be:<br />
** INIT_VLC_USE_STATIC - init codes statically ( free_vlc() is not needed)<br />
** INIT_VLC_LE - use alternative VLC reading mode<br />
<br />
* wrap = ceil(REAL_MAX_BITS/MAX_BITS) and should not be greater than 3. For example is maximum codeword size is 15 then wrap = ceil(15/9) = 2<br />
<br />
=== How to use frame reordering ===<br />
The simpliest way is to adapt decode_frame() from h263dec.c to your needs (that will also require to include MpegEncContext into your codec context).<br />
<br />
=== Some example decoder ===<br />
The simpliest decoder that does not even use bitstream reading is ATI VCR1 decoder, file libavcodec/vcr1.c.<br />
<br />
For simple codec with VLC reading look at WNV1 (file libavcodec/wnv1.c).<br />
<br />
For simple delta-frame codec look at RPZA (file libavcodec/rpza.c).<br />
<br />
== MDCT ==<br />
'''I would like to know how to do that properly''', for now this is the stuff borrowed from wmadec.c and wmaenc.c.<br />
<br />
In order to perform N-point transform you need those variables:<br />
<br />
MDCTContext mdct;<br />
DSPUtil dsp;<br />
float window[N];<br />
float output[2*N];<br />
float saved[2][N];<br />
float *prev = saved[0];<br />
float *curr = saved[1];<br />
float coefs[N]; // result of MDCT will be stored here<br />
<br />
Forward windowed MDCT:<br />
<br />
memcpy(output, saved, sizeof(float)*N);<br />
for (i = 0; i < N; i++){<br />
output[i+N] = audio[i] / (N/2) * window[N - i - 1];<br />
saved [i] = audio[i] / (N/2) * window[i];<br />
}<br />
ff_mdct_calc(&mdct, coefs, output, tmp);<br />
<br />
Backward windowed MDCT:<br />
<br />
mdct->imdct_half(mdct, curr, coefs);<br />
dsp.vector_fmul_window(out, prev, curr, window, N/2);<br />
FFSWAP(prev, curr);<br />
<br />
[[Category:FFmpeg Tutorials]]</div>Sessehttps://wiki.multimedia.cx/index.php?title=SpeedHQ&diff=15253SpeedHQ2017-01-03T20:06:10Z<p>Sesse: </p>
<hr />
<div>* FOURCCs: SHQ0, SHQ1, ..., SHQ5, SHQ7, SHQ9<br />
* Company: NewTek<br />
<br />
This is a simple intermediate codec with different subsampling and alpha support. It is generally very similar to MPEG-2 intraframe. Several variants exist:<br />
<br />
* <code>SHQ0</code>/<code>SHQ1</code> are 4:2:0 with/without alpha (SHQ1 is either rare or nonexistant in practice).<br />
* <code>SHQ2</code>/<code>SHQ3</code> are 4:2:2 with/without alpha.<br />
* <code>SHQ4</code>/<code>SHQ5</code> are 4:4:4 with/without alpha.<br />
* <code>SHQ7</code> is 422 with alpha coded as luma and chroma blocks<br />
* <code>SHQ9</code> is the same for 444 format.<br />
<br />
NewTek's NDI network codec uses SHQ2 and SHQ7.<br />
<br />
Frame is always coded as two fields, data is packed into 32-bit little-endian words and is read from LSB.<br />
<br />
First byte is quality, next three bytes form an offset to the second field. Quantizer is 100 - quality.<br />
<br />
=== Field format ===<br />
<br />
Each field is split into four slices that can be independently decoded; each slice codes 16 lines, then skip 48 lines (coded by the other three slices), code 16 more lines, and so on until at the bottom of the field, which implicitly ends the slice. The first three bytes of each slice form a length of the slice in bytes (including the three length bytes). The next slice starts on the byte immediately after the end of the previous one, as given by the length (this might mean skipping 1–7 bits).<br />
<br />
Blocks are 8x8 pixels, and macroblocks are 16x16 pixels (coded top-left, top-right, bottom-left, bottom-right). 4:4:4 is coded YYYY UV UV UV UV. 4:2:2 is coded YYYY UV UV. 4:2:0 is coded YYYY UV.<br />
<br />
Blocks are coded with static VLCs. DC coefficients are coded exactly as in MPEG-2 (same luma/chroma tables, same scheme for storing the coefficient and sign). DC prediction is taken from the previous block of the same coefficient, and restarts at 0 for each new macroblock row (not 128 as in MPEG-2). Curiously enough, one needs to _subtract_ the stored DC value from the prediction, not add as usual.<br />
<br />
AC coefficients are coded using the same scheme as MPEG-2 (run/level with the same zigzag pattern), and with a VLC that is very similar to MPEG-2's “Table One” for AC coefficients. (It is not identical; some codewords that are illegal in MPEG-2 are used in SpeedHQ, and a few others are moved around as a consequence.) In FFmpeg format, the codes are:<br />
<br />
static const uint16_t speedhq_vlc[123][2] = {<br />
{0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},<br />
{0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},<br />
{0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},<br />
{0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},<br />
{0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},<br />
{0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},<br />
{0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},<br />
{0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},<br />
{0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},<br />
{0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},<br />
{0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},<br />
{0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},<br />
{0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},<br />
{0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},<br />
{0x11,16}, {0x10,16}, {0x18,13}, {0x17,13},<br />
{0x05, 5}, {0x07, 7}, {0xfc, 8}, {0x0c,10},<br />
{0x14,13}, {0x18,12}, {0x14,12}, {0x13,12},<br />
{0x10,12}, {0x1a,13}, {0x19,13}, {0x07, 5},<br />
{0x26, 8}, {0x1c,12}, {0x13,13}, {0x1b,12},<br />
{0x06, 6}, {0xfd, 8}, {0x12,12}, {0x1d,12},<br />
{0x07, 6}, {0x04, 9}, {0x12,13}, {0x06, 7},<br />
{0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},<br />
{0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},<br />
{0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},<br />
{0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},<br />
{0x7a, 7}, {0x10,13}, {0x21, 8}, {0x1a,16},<br />
{0x25, 8}, {0x19,16}, {0x24, 8}, {0x18,16},<br />
{0x05, 9}, {0x17,16}, {0x07, 9}, {0x16,16},<br />
{0x0d,10}, {0x15,16}, {0x1f,12}, {0x1a,12}, <br />
{0x19,12}, {0x17,12}, {0x16,12}, {0x1f,13}, <br />
{0x1e,13}, {0x1d,13}, {0x1c,13}, {0x1b,13},<br />
{0x1f,16}, {0x1e,16}, {0x1d,16}, {0x1c,16},<br />
{0x1b,16},<br />
{0x01,6}, /* escape */<br />
{0x06,4}, /* EOB */<br />
};<br />
static const uint8_t speedhq_level[121] = {<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 21, 22, 23, 24,<br />
25, 26, 27, 28, 29, 30, 31, 32,<br />
33, 34, 35, 36, 37, 38, 39, 40,<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 1, 2, 3, 4,<br />
5, 6, 7, 8, 9, 10, 11, 1,<br />
2, 3, 4, 5, 1, 2, 3, 4,<br />
1, 2, 3, 1, 2, 3, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1,<br />
};<br />
static const uint8_t speedhq_run[121] = { <br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 2, 2, 2, 2,<br />
2, 2, 2, 2, 2, 2, 2, 3,<br />
3, 3, 3, 3, 4, 4, 4, 4,<br />
5, 5, 5, 6, 6, 6, 7, 7,<br />
8, 8, 9, 9, 10, 10, 11, 11,<br />
12, 12, 13, 13, 14, 14, 15, 15,<br />
16, 16, 17, 18, 19, 20, 21, 22,<br />
23, 24, 25, 26, 27, 28, 29, 30,<br />
31,<br />
};<br />
<br />
Escape works similarly to MPEG-2; the next six bits contain the run (non-reversed), and the next 12 bits contain the level (non-reversed), offset by 2048. There'a always an EOB at the end of each block (as in MPEG-2), and there's never a block without a DC coefficient (also as in MPEG-2). All other codes are followed by the coefficient sign (again as in MPEG-2).<br />
<br />
Alpha is coded as run-level too: first it has a codeword telling how many elements to skip (or whether this is end of block) and then a codeword for nonzero element, repeat.<br />
<br />
=== Quantiser ===<br />
<br />
Allowed quality levels:<br />
<br />
1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 104, 112<br />
<br />
Provided quality is clipped to 99, also if it's less than 38 or odd then a nearest smaller value from default quality table is used instead.<br />
<br />
Quantisation matrix:<br />
<br />
*, 16, 19, 22, 26, 27, 29, 34,<br />
16, 16, 22, 24, 27, 29, 34, 37,<br />
19, 22, 26, 27, 29, 34, 34, 38,<br />
22, 22, 26, 27, 29, 34, 37, 40,<br />
22, 26, 27, 29, 32, 35, 40, 48,<br />
26, 27, 29, 32, 35, 40, 48, 58,<br />
26, 27, 29, 34, 38, 46, 56, 69,<br />
27, 29, 35, 38, 46, 56, 69, 83<br />
<br />
The DC quantizer is set to 16 no matter what; the other values are multiplied by (100 - quality). Each coefficient is multiplied with the corresponding quantization factor and then divided by 16 (no rounding). Finally, 1024 is added to the DC coefficient, and then the block goes to IDCT.<br />
<br />
As an optimization, DC-only blocks are special-cased; all pixels in the block get exactly the value (dc + 1032) >> 3.<br />
<br />
Y'CbCr conversion uses BT.601 coefficients. Chroma positioning is unknown.<br />
<br />
[[Category:Undiscovered Video Codecs]]<br />
[[Category:Video Codecs]]</div>Sessehttps://wiki.multimedia.cx/index.php?title=SpeedHQ&diff=15252SpeedHQ2017-01-03T20:05:39Z<p>Sesse: </p>
<hr />
<div>* FOURCCs: SHQ0, SHQ1, ..., SHQ5, SHQ7, SHQ9<br />
* Company: NewTek<br />
<br />
This is a simple intermediate codec with different subsampling and alpha support. It is generally very similar to MPEG-2 infraframe. Several variants exist:<br />
<br />
* <code>SHQ0</code>/<code>SHQ1</code> are 4:2:0 with/without alpha (SHQ1 is either rare or nonexistant in practice).<br />
* <code>SHQ2</code>/<code>SHQ3</code> are 4:2:2 with/without alpha.<br />
* <code>SHQ4</code>/<code>SHQ5</code> are 4:4:4 with/without alpha.<br />
* <code>SHQ7</code> is 422 with alpha coded as luma and chroma blocks<br />
* <code>SHQ9</code> is the same for 444 format.<br />
<br />
NewTek's NDI network codec uses SHQ2 and SHQ7.<br />
<br />
Frame is always coded as two fields, data is packed into 32-bit little-endian words and is read from LSB.<br />
<br />
First byte is quality, next three bytes form an offset to the second field. Quantizer is 100 - quality.<br />
<br />
=== Field format ===<br />
<br />
Each field is split into four slices that can be independently decoded; each slice codes 16 lines, then skip 48 lines (coded by the other three slices), code 16 more lines, and so on until at the bottom of the field, which implicitly ends the slice. The first three bytes of each slice form a length of the slice in bytes (including the three length bytes). The next slice starts on the byte immediately after the end of the previous one, as given by the length (this might mean skipping 1–7 bits).<br />
<br />
Blocks are 8x8 pixels, and macroblocks are 16x16 pixels (coded top-left, top-right, bottom-left, bottom-right). 4:4:4 is coded YYYY UV UV UV UV. 4:2:2 is coded YYYY UV UV. 4:2:0 is coded YYYY UV.<br />
<br />
Blocks are coded with static VLCs. DC coefficients are coded exactly as in MPEG-2 (same luma/chroma tables, same scheme for storing the coefficient and sign). DC prediction is taken from the previous block of the same coefficient, and restarts at 0 for each new macroblock row (not 128 as in MPEG-2). Curiously enough, one needs to _subtract_ the stored DC value from the prediction, not add as usual.<br />
<br />
AC coefficients are coded using the same scheme as MPEG-2 (run/level with the same zigzag pattern), and with a VLC that is very similar to MPEG-2's “Table One” for AC coefficients. (It is not identical; some codewords that are illegal in MPEG-2 are used in SpeedHQ, and a few others are moved around as a consequence.) In FFmpeg format, the codes are:<br />
<br />
static const uint16_t speedhq_vlc[123][2] = {<br />
{0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},<br />
{0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},<br />
{0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},<br />
{0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},<br />
{0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},<br />
{0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},<br />
{0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},<br />
{0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},<br />
{0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},<br />
{0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},<br />
{0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},<br />
{0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},<br />
{0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},<br />
{0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},<br />
{0x11,16}, {0x10,16}, {0x18,13}, {0x17,13},<br />
{0x05, 5}, {0x07, 7}, {0xfc, 8}, {0x0c,10},<br />
{0x14,13}, {0x18,12}, {0x14,12}, {0x13,12},<br />
{0x10,12}, {0x1a,13}, {0x19,13}, {0x07, 5},<br />
{0x26, 8}, {0x1c,12}, {0x13,13}, {0x1b,12},<br />
{0x06, 6}, {0xfd, 8}, {0x12,12}, {0x1d,12},<br />
{0x07, 6}, {0x04, 9}, {0x12,13}, {0x06, 7},<br />
{0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},<br />
{0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},<br />
{0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},<br />
{0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},<br />
{0x7a, 7}, {0x10,13}, {0x21, 8}, {0x1a,16},<br />
{0x25, 8}, {0x19,16}, {0x24, 8}, {0x18,16},<br />
{0x05, 9}, {0x17,16}, {0x07, 9}, {0x16,16},<br />
{0x0d,10}, {0x15,16}, {0x1f,12}, {0x1a,12}, <br />
{0x19,12}, {0x17,12}, {0x16,12}, {0x1f,13}, <br />
{0x1e,13}, {0x1d,13}, {0x1c,13}, {0x1b,13},<br />
{0x1f,16}, {0x1e,16}, {0x1d,16}, {0x1c,16},<br />
{0x1b,16},<br />
{0x01,6}, /* escape */<br />
{0x06,4}, /* EOB */<br />
};<br />
static const uint8_t speedhq_level[121] = {<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 21, 22, 23, 24,<br />
25, 26, 27, 28, 29, 30, 31, 32,<br />
33, 34, 35, 36, 37, 38, 39, 40,<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 1, 2, 3, 4,<br />
5, 6, 7, 8, 9, 10, 11, 1,<br />
2, 3, 4, 5, 1, 2, 3, 4,<br />
1, 2, 3, 1, 2, 3, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1,<br />
};<br />
static const uint8_t speedhq_run[121] = { <br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 2, 2, 2, 2,<br />
2, 2, 2, 2, 2, 2, 2, 3,<br />
3, 3, 3, 3, 4, 4, 4, 4,<br />
5, 5, 5, 6, 6, 6, 7, 7,<br />
8, 8, 9, 9, 10, 10, 11, 11,<br />
12, 12, 13, 13, 14, 14, 15, 15,<br />
16, 16, 17, 18, 19, 20, 21, 22,<br />
23, 24, 25, 26, 27, 28, 29, 30,<br />
31,<br />
};<br />
<br />
Escape works similarly to MPEG-2; the next six bits contain the run (non-reversed), and the next 12 bits contain the level (non-reversed), offset by 2048. There'a always an EOB at the end of each block (as in MPEG-2), and there's never a block without a DC coefficient (also as in MPEG-2). All other codes are followed by the coefficient sign (again as in MPEG-2).<br />
<br />
Alpha is coded as run-level too: first it has a codeword telling how many elements to skip (or whether this is end of block) and then a codeword for nonzero element, repeat.<br />
<br />
=== Quantiser ===<br />
<br />
Allowed quality levels:<br />
<br />
1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 104, 112<br />
<br />
Provided quality is clipped to 99, also if it's less than 38 or odd then a nearest smaller value from default quality table is used instead.<br />
<br />
Quantisation matrix:<br />
<br />
*, 16, 19, 22, 26, 27, 29, 34,<br />
16, 16, 22, 24, 27, 29, 34, 37,<br />
19, 22, 26, 27, 29, 34, 34, 38,<br />
22, 22, 26, 27, 29, 34, 37, 40,<br />
22, 26, 27, 29, 32, 35, 40, 48,<br />
26, 27, 29, 32, 35, 40, 48, 58,<br />
26, 27, 29, 34, 38, 46, 56, 69,<br />
27, 29, 35, 38, 46, 56, 69, 83<br />
<br />
The DC quantizer is set to 16 no matter what; the other values are multiplied by (100 - quality). Each coefficient is multiplied with the corresponding quantization factor and then divided by 16 (no rounding). Finally, 1024 is added to the DC coefficient, and then the block goes to IDCT.<br />
<br />
As an optimization, DC-only blocks are special-cased; all pixels in the block get exactly the value (dc + 1032) >> 3.<br />
<br />
Y'CbCr conversion uses BT.601 coefficients. Chroma positioning is unknown<br />
<br />
[[Category:Undiscovered Video Codecs]]<br />
[[Category:Video Codecs]]</div>Sessehttps://wiki.multimedia.cx/index.php?title=SpeedHQ&diff=15251SpeedHQ2017-01-03T18:58:52Z<p>Sesse: A lot more information</p>
<hr />
<div>* FOURCCs: SHQ0, SHQ1, ..., SHQ5, SHQ7, SHQ9<br />
* Company: NewTek<br />
<br />
This is a simple intermediate codec with different subsampling and alpha support. It is generally very similar to MPEG-2 infraframe. Several variants exist:<br />
<br />
* <code>SHQ0</code>/<code>SHQ1</code> are 4:2:0 with/without alpha (SHQ1 is either rare or nonexistant in practice).<br />
* <code>SHQ2</code>/<code>SHQ3</code> are 4:2:2 with/without alpha.<br />
* <code>SHQ4</code>/<code>SHQ5</code> are 4:4:4 with/without alpha.<br />
* <code>SHQ7</code> is 422 with alpha coded as luma and chroma blocks<br />
* <code>SHQ9</code> is the same for 444 format.<br />
<br />
NewTek's NDI network codec uses SHQ2 and SHQ7.<br />
<br />
Frame is always coded as two fields, data is packed into 32-bit little-endian words and is read from LSB.<br />
<br />
First byte is quality, next three bytes form an offset to the second field. Quantizer is 100 - quality.<br />
<br />
=== Field format ===<br />
<br />
Each field is split into four slices that can be independently decoded; each slice codes 16 lines, then skip 48 lines (coded by the other three slices), code 16 more lines, and so on until at the bottom of the field, which implicitly ends the slice. The first three bytes of each slice form a length of the slice in bytes (including the three length bytes). The next slice starts on the byte immediately after the end of the previous one, as given by the length (this might mean skipping 1–7 bits).<br />
<br />
Blocks are 8x8 pixels, and macroblocks are 16x16 pixels (coded top-left, top-right, bottom-left, bottom-right). 4:4:4 is coded YYYY UV UV UV UV. 4:2:2 is coded YYYY UV UV. 4:2:0 is coded YYYY UV.<br />
<br />
Blocks are coded with static VLCs. DC coefficients are coded exactly as in MPEG-2 (same luma/chroma tables, same scheme for storing the coefficient and sign). DC prediction is taken from the previous block of the same coefficient, and restarts at 0 for each new macroblock row (not 128 as in MPEG-2). Curiously enough, one needs to _subtract_ the stored DC value from the prediction, not add as usual.<br />
<br />
Blocks are coded with static VLCs. DC coefficients are coded exactly as in MPEG-2 (same luma/chroma tables, same scheme for storing the coefficient and sign). DC prediction is taken from the previous block of the same coefficient, and restarts at 0 for each new macroblock row (not 128 as in MPEG-2). Curiously enough, one needs to _subtract_ the stored DC value from the prediction, not add as usual.<br />
<br />
AC coefficients are coded using the same scheme as MPEG-2 (run/level with the same zigzag pattern), and with a VLC that is very similar to MPEG-2's “Table One” for AC coefficients. (It is not identical; some codewords that are illegal in MPEG-2 are used in SpeedHQ, and a few others are moved around as a consequence.) In FFmpeg format, the codes are:<br />
<br />
static const uint16_t speedhq_vlc[123][2] = {<br />
{0x02, 2}, {0x06, 3}, {0x07, 4}, {0x1c, 5},<br />
{0x1d, 5}, {0x05, 6}, {0x04, 6}, {0x7b, 7},<br />
{0x7c, 7}, {0x23, 8}, {0x22, 8}, {0xfa, 8},<br />
{0xfb, 8}, {0xfe, 8}, {0xff, 8}, {0x1f,14},<br />
{0x1e,14}, {0x1d,14}, {0x1c,14}, {0x1b,14},<br />
{0x1a,14}, {0x19,14}, {0x18,14}, {0x17,14},<br />
{0x16,14}, {0x15,14}, {0x14,14}, {0x13,14},<br />
{0x12,14}, {0x11,14}, {0x10,14}, {0x18,15},<br />
{0x17,15}, {0x16,15}, {0x15,15}, {0x14,15},<br />
{0x13,15}, {0x12,15}, {0x11,15}, {0x10,15},<br />
{0x02, 3}, {0x06, 5}, {0x79, 7}, {0x27, 8},<br />
{0x20, 8}, {0x16,13}, {0x15,13}, {0x1f,15},<br />
{0x1e,15}, {0x1d,15}, {0x1c,15}, {0x1b,15},<br />
{0x1a,15}, {0x19,15}, {0x13,16}, {0x12,16},<br />
{0x11,16}, {0x10,16}, {0x18,13}, {0x17,13},<br />
{0x05, 5}, {0x07, 7}, {0xfc, 8}, {0x0c,10},<br />
{0x14,13}, {0x18,12}, {0x14,12}, {0x13,12},<br />
{0x10,12}, {0x1a,13}, {0x19,13}, {0x07, 5},<br />
{0x26, 8}, {0x1c,12}, {0x13,13}, {0x1b,12},<br />
{0x06, 6}, {0xfd, 8}, {0x12,12}, {0x1d,12},<br />
{0x07, 6}, {0x04, 9}, {0x12,13}, {0x06, 7},<br />
{0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},<br />
{0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},<br />
{0x1e,12}, {0x14,16}, {0x04, 7}, {0x15,12},<br />
{0x05, 7}, {0x11,12}, {0x78, 7}, {0x11,13},<br />
{0x7a, 7}, {0x10,13}, {0x21, 8}, {0x1a,16},<br />
{0x25, 8}, {0x19,16}, {0x24, 8}, {0x18,16},<br />
{0x05, 9}, {0x17,16}, {0x07, 9}, {0x16,16},<br />
{0x0d,10}, {0x15,16}, {0x1f,12}, {0x1a,12}, <br />
{0x19,12}, {0x17,12}, {0x16,12}, {0x1f,13}, <br />
{0x1e,13}, {0x1d,13}, {0x1c,13}, {0x1b,13},<br />
{0x1f,16}, {0x1e,16}, {0x1d,16}, {0x1c,16},<br />
{0x1b,16},<br />
{0x01,6}, /* escape */<br />
{0x06,4}, /* EOB */<br />
};<br />
static const uint8_t speedhq_level[121] = {<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 21, 22, 23, 24,<br />
25, 26, 27, 28, 29, 30, 31, 32,<br />
33, 34, 35, 36, 37, 38, 39, 40,<br />
1, 2, 3, 4, 5, 6, 7, 8,<br />
9, 10, 11, 12, 13, 14, 15, 16,<br />
17, 18, 19, 20, 1, 2, 3, 4,<br />
5, 6, 7, 8, 9, 10, 11, 1,<br />
2, 3, 4, 5, 1, 2, 3, 4,<br />
1, 2, 3, 1, 2, 3, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 2, 1, 2, 1, 2,<br />
1, 2, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1,<br />
};<br />
static const uint8_t speedhq_run[121] = { <br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 1, 1, 1, 1,<br />
1, 1, 1, 1, 2, 2, 2, 2,<br />
2, 2, 2, 2, 2, 2, 2, 3,<br />
3, 3, 3, 3, 4, 4, 4, 4,<br />
5, 5, 5, 6, 6, 6, 7, 7,<br />
8, 8, 9, 9, 10, 10, 11, 11,<br />
12, 12, 13, 13, 14, 14, 15, 15,<br />
16, 16, 17, 18, 19, 20, 21, 22,<br />
23, 24, 25, 26, 27, 28, 29, 30,<br />
31,<br />
};<br />
<br />
Escape works similarly to MPEG-2; the next six bits contain the run (non-reversed), and the next 12 bits contain the level (non-reversed), offset by 2048. There'a always an EOB at the end of each block (as in MPEG-2), and there's never a block without a DC coefficient (also as in MPEG-2). All other codes are followed by the coefficient sign (again as in MPEG-2).<br />
<br />
Alpha is coded as run-level too: first it has a codeword telling how many elements to skip (or whether this is end of block) and then a codeword for nonzero element, repeat.<br />
<br />
=== Quantiser ===<br />
<br />
Allowed quality levels:<br />
<br />
1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 104, 112<br />
<br />
<br />
Provided quality is clipped to 99, also if it's less than 38 or odd then a nearest smaller value from default quality table is used instead.<br />
<br />
Quantisation matrix:<br />
<br />
*, 16, 19, 22, 26, 27, 29, 34,<br />
16, 16, 22, 24, 27, 29, 34, 37,<br />
19, 22, 26, 27, 29, 34, 34, 38,<br />
22, 22, 26, 27, 29, 34, 37, 40,<br />
22, 26, 27, 29, 32, 35, 40, 48,<br />
26, 27, 29, 32, 35, 40, 48, 58,<br />
26, 27, 29, 34, 38, 46, 56, 69,<br />
27, 29, 35, 38, 46, 56, 69, 83<br />
<br />
The DC quantizer is set to 16 no matter what; the other values are multiplied by (100 - quality). Each coefficient is multiplied with the corresponding quantization factor and then divided by 16 (no rounding). Finally, 1024 is added to the DC coefficient, and then the block goes to IDCT.<br />
<br />
As an optimization, DC-only blocks are special-cased; all pixels in the block get exactly the value (dc + 1032) >> 3.<br />
<br />
Y'CbCr conversion uses BT.601 coefficients. Chroma positioning is unknown<br />
<br />
[[Category:Undiscovered Video Codecs]]<br />
[[Category:Video Codecs]]</div>Sesse