draft-ietf-cellar-ffv1-v4-06.txt | draft-ietf-cellar-ffv1-v4-07.txt | |||
---|---|---|---|---|
cellar M. Niedermayer | cellar M. Niedermayer | |||
Internet-Draft D. Rice | Internet-Draft D. Rice | |||
Intended status: Standards Track J. Martinez | Intended status: Standards Track J. Martinez | |||
Expires: March 19, 2020 September 16, 2019 | Expires: 12 April 2020 10 October 2019 | |||
FFV1 Video Coding Format Version 4 | FFV1 Video Coding Format Version 4 | |||
draft-ietf-cellar-ffv1-v4-06 | draft-ietf-cellar-ffv1-v4-07 | |||
Abstract | Abstract | |||
This document defines FFV1, a lossless intra-frame video encoding | This document defines FFV1, a lossless intra-frame video encoding | |||
format. FFV1 is designed to efficiently compress video data in a | format. FFV1 is designed to efficiently compress video data in a | |||
variety of pixel formats. Compared to uncompressed video, FFV1 | variety of pixel formats. Compared to uncompressed video, FFV1 | |||
offers storage compression, frame fixity, and self-description, which | offers storage compression, frame fixity, and self-description, which | |||
makes FFV1 useful as a preservation or intermediate video format. | makes FFV1 useful as a preservation or intermediate video format. | |||
Status of This Memo | Status of This Memo | |||
skipping to change at page 1, line 34 ¶ | skipping to change at page 1, line 34 ¶ | |||
Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
Drafts is at https://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
This Internet-Draft will expire on 19 March 2020. | This Internet-Draft will expire on 12 April 2020. | |||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2019 IETF Trust and the persons identified as the | Copyright (c) 2019 IETF Trust and the persons identified as the | |||
document authors. All rights reserved. | document authors. All rights reserved. | |||
This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
Provisions Relating to IETF Documents (https://trustee.ietf.org/ | Provisions Relating to IETF Documents (https://trustee.ietf.org/ | |||
license-info) in effect on the date of publication of this document. | license-info) in effect on the date of publication of this document. | |||
Please review these documents carefully, as they describe your rights | Please review these documents carefully, as they describe your rights | |||
skipping to change at page 2, line 32 ¶ | skipping to change at page 2, line 32 ¶ | |||
3.2. Samples . . . . . . . . . . . . . . . . . . . . . . . . . 10 | 3.2. Samples . . . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
3.3. Median Predictor . . . . . . . . . . . . . . . . . . . . 10 | 3.3. Median Predictor . . . . . . . . . . . . . . . . . . . . 10 | |||
3.4. Context . . . . . . . . . . . . . . . . . . . . . . . . . 11 | 3.4. Context . . . . . . . . . . . . . . . . . . . . . . . . . 11 | |||
3.5. Quantization Table Sets . . . . . . . . . . . . . . . . . 11 | 3.5. Quantization Table Sets . . . . . . . . . . . . . . . . . 11 | |||
3.6. Quantization Table Set Indexes . . . . . . . . . . . . . 12 | 3.6. Quantization Table Set Indexes . . . . . . . . . . . . . 12 | |||
3.7. Color spaces . . . . . . . . . . . . . . . . . . . . . . 12 | 3.7. Color spaces . . . . . . . . . . . . . . . . . . . . . . 12 | |||
3.7.1. YCbCr . . . . . . . . . . . . . . . . . . . . . . . . 12 | 3.7.1. YCbCr . . . . . . . . . . . . . . . . . . . . . . . . 12 | |||
3.7.2. RGB . . . . . . . . . . . . . . . . . . . . . . . . . 13 | 3.7.2. RGB . . . . . . . . . . . . . . . . . . . . . . . . . 13 | |||
3.8. Coding of the Sample Difference . . . . . . . . . . . . . 15 | 3.8. Coding of the Sample Difference . . . . . . . . . . . . . 15 | |||
3.8.1. Range Coding Mode . . . . . . . . . . . . . . . . . . 15 | 3.8.1. Range Coding Mode . . . . . . . . . . . . . . . . . . 15 | |||
3.8.2. Golomb Rice Mode . . . . . . . . . . . . . . . . . . 19 | 3.8.2. Golomb Rice Mode . . . . . . . . . . . . . . . . . . 20 | |||
4. Bitstream . . . . . . . . . . . . . . . . . . . . . . . . . . 22 | 4. Bitstream . . . . . . . . . . . . . . . . . . . . . . . . . . 25 | |||
4.1. Parameters . . . . . . . . . . . . . . . . . . . . . . . 23 | 4.1. Parameters . . . . . . . . . . . . . . . . . . . . . . . 26 | |||
4.1.1. version . . . . . . . . . . . . . . . . . . . . . . . 24 | 4.1.1. version . . . . . . . . . . . . . . . . . . . . . . . 28 | |||
4.1.2. micro_version . . . . . . . . . . . . . . . . . . . . 24 | 4.1.2. micro_version . . . . . . . . . . . . . . . . . . . . 28 | |||
4.1.3. coder_type . . . . . . . . . . . . . . . . . . . . . 25 | 4.1.3. coder_type . . . . . . . . . . . . . . . . . . . . . 29 | |||
4.1.4. state_transition_delta . . . . . . . . . . . . . . . 26 | 4.1.4. state_transition_delta . . . . . . . . . . . . . . . 30 | |||
4.1.5. colorspace_type . . . . . . . . . . . . . . . . . . . 26 | 4.1.5. colorspace_type . . . . . . . . . . . . . . . . . . . 30 | |||
4.1.6. chroma_planes . . . . . . . . . . . . . . . . . . . . 27 | 4.1.6. chroma_planes . . . . . . . . . . . . . . . . . . . . 31 | |||
4.1.7. bits_per_raw_sample . . . . . . . . . . . . . . . . . 27 | 4.1.7. bits_per_raw_sample . . . . . . . . . . . . . . . . . 31 | |||
4.1.8. log2_h_chroma_subsample . . . . . . . . . . . . . . . 27 | 4.1.8. log2_h_chroma_subsample . . . . . . . . . . . . . . . 31 | |||
4.1.9. log2_v_chroma_subsample . . . . . . . . . . . . . . . 28 | 4.1.9. log2_v_chroma_subsample . . . . . . . . . . . . . . . 32 | |||
4.1.10. extra_plane . . . . . . . . . . . . . . . . . . . . . 28 | 4.1.10. extra_plane . . . . . . . . . . . . . . . . . . . . . 32 | |||
4.1.11. num_h_slices . . . . . . . . . . . . . . . . . . . . 28 | 4.1.11. num_h_slices . . . . . . . . . . . . . . . . . . . . 32 | |||
4.1.12. num_v_slices . . . . . . . . . . . . . . . . . . . . 28 | 4.1.12. num_v_slices . . . . . . . . . . . . . . . . . . . . 32 | |||
4.1.13. quant_table_set_count . . . . . . . . . . . . . . . . 28 | 4.1.13. quant_table_set_count . . . . . . . . . . . . . . . . 32 | |||
4.1.14. states_coded . . . . . . . . . . . . . . . . . . . . 28 | 4.1.14. states_coded . . . . . . . . . . . . . . . . . . . . 32 | |||
4.1.15. initial_state_delta . . . . . . . . . . . . . . . . . 29 | 4.1.15. initial_state_delta . . . . . . . . . . . . . . . . . 33 | |||
4.1.16. ec . . . . . . . . . . . . . . . . . . . . . . . . . 29 | 4.1.16. ec . . . . . . . . . . . . . . . . . . . . . . . . . 33 | |||
4.1.17. intra . . . . . . . . . . . . . . . . . . . . . . . . 29 | 4.1.17. intra . . . . . . . . . . . . . . . . . . . . . . . . 33 | |||
4.2. Configuration Record . . . . . . . . . . . . . . . . . . 30 | 4.2. Configuration Record . . . . . . . . . . . . . . . . . . 34 | |||
4.2.1. reserved_for_future_use . . . . . . . . . . . . . . . 30 | 4.2.1. reserved_for_future_use . . . . . . . . . . . . . . . 34 | |||
4.2.2. configuration_record_crc_parity . . . . . . . . . . . 30 | 4.2.2. configuration_record_crc_parity . . . . . . . . . . . 34 | |||
4.2.3. Mapping FFV1 into Containers . . . . . . . . . . . . 31 | 4.2.3. Mapping FFV1 into Containers . . . . . . . . . . . . 35 | |||
4.3. Frame . . . . . . . . . . . . . . . . . . . . . . . . . . 32 | 4.3. Frame . . . . . . . . . . . . . . . . . . . . . . . . . . 36 | |||
4.4. Slice . . . . . . . . . . . . . . . . . . . . . . . . . . 33 | 4.4. Slice . . . . . . . . . . . . . . . . . . . . . . . . . . 37 | |||
4.5. Slice Header . . . . . . . . . . . . . . . . . . . . . . 33 | 4.5. Slice Header . . . . . . . . . . . . . . . . . . . . . . 38 | |||
4.5.1. slice_x . . . . . . . . . . . . . . . . . . . . . . . 33 | 4.5.1. slice_x . . . . . . . . . . . . . . . . . . . . . . . 39 | |||
4.5.2. slice_y . . . . . . . . . . . . . . . . . . . . . . . 34 | 4.5.2. slice_y . . . . . . . . . . . . . . . . . . . . . . . 39 | |||
4.5.3. slice_width . . . . . . . . . . . . . . . . . . . . . 34 | 4.5.3. slice_width . . . . . . . . . . . . . . . . . . . . . 39 | |||
4.5.4. slice_height . . . . . . . . . . . . . . . . . . . . 34 | 4.5.4. slice_height . . . . . . . . . . . . . . . . . . . . 39 | |||
4.5.5. quant_table_set_index_count . . . . . . . . . . . . . 34 | 4.5.5. quant_table_set_index_count . . . . . . . . . . . . . 40 | |||
4.5.6. quant_table_set_index . . . . . . . . . . . . . . . . 34 | 4.5.6. quant_table_set_index . . . . . . . . . . . . . . . . 40 | |||
4.5.7. picture_structure . . . . . . . . . . . . . . . . . . 34 | 4.5.7. picture_structure . . . . . . . . . . . . . . . . . . 40 | |||
4.5.8. sar_num . . . . . . . . . . . . . . . . . . . . . . . 35 | 4.5.8. sar_num . . . . . . . . . . . . . . . . . . . . . . . 40 | |||
4.5.9. sar_den . . . . . . . . . . . . . . . . . . . . . . . 35 | 4.5.9. sar_den . . . . . . . . . . . . . . . . . . . . . . . 41 | |||
4.5.10. reset_contexts . . . . . . . . . . . . . . . . . . . 35 | 4.5.10. reset_contexts . . . . . . . . . . . . . . . . . . . 41 | |||
4.5.11. slice_coding_mode . . . . . . . . . . . . . . . . . . 36 | 4.5.11. slice_coding_mode . . . . . . . . . . . . . . . . . . 41 | |||
4.6. Slice Content . . . . . . . . . . . . . . . . . . . . . . 36 | 4.6. Slice Content . . . . . . . . . . . . . . . . . . . . . . 41 | |||
4.6.1. primary_color_count . . . . . . . . . . . . . . . . . 36 | 4.6.1. primary_color_count . . . . . . . . . . . . . . . . . 42 | |||
4.6.2. plane_pixel_height . . . . . . . . . . . . . . . . . 36 | 4.6.2. plane_pixel_height . . . . . . . . . . . . . . . . . 42 | |||
4.6.3. slice_pixel_height . . . . . . . . . . . . . . . . . 36 | 4.6.3. slice_pixel_height . . . . . . . . . . . . . . . . . 42 | |||
4.6.4. slice_pixel_y . . . . . . . . . . . . . . . . . . . . 37 | 4.6.4. slice_pixel_y . . . . . . . . . . . . . . . . . . . . 42 | |||
4.7. Line . . . . . . . . . . . . . . . . . . . . . . . . . . 37 | 4.7. Line . . . . . . . . . . . . . . . . . . . . . . . . . . 43 | |||
4.7.1. plane_pixel_width . . . . . . . . . . . . . . . . . . 37 | 4.7.1. plane_pixel_width . . . . . . . . . . . . . . . . . . 43 | |||
4.7.2. slice_pixel_width . . . . . . . . . . . . . . . . . . 37 | 4.7.2. slice_pixel_width . . . . . . . . . . . . . . . . . . 43 | |||
4.7.3. slice_pixel_x . . . . . . . . . . . . . . . . . . . . 37 | 4.7.3. slice_pixel_x . . . . . . . . . . . . . . . . . . . . 43 | |||
4.7.4. sample_difference . . . . . . . . . . . . . . . . . . 37 | 4.7.4. sample_difference . . . . . . . . . . . . . . . . . . 44 | |||
4.8. Slice Footer . . . . . . . . . . . . . . . . . . . . . . 38 | 4.8. Slice Footer . . . . . . . . . . . . . . . . . . . . . . 44 | |||
4.8.1. slice_size . . . . . . . . . . . . . . . . . . . . . 38 | 4.8.1. slice_size . . . . . . . . . . . . . . . . . . . . . 44 | |||
4.8.2. error_status . . . . . . . . . . . . . . . . . . . . 38 | 4.8.2. error_status . . . . . . . . . . . . . . . . . . . . 44 | |||
4.8.3. slice_crc_parity . . . . . . . . . . . . . . . . . . 38 | 4.8.3. slice_crc_parity . . . . . . . . . . . . . . . . . . 45 | |||
4.9. Quantization Table Set . . . . . . . . . . . . . . . . . 39 | 4.9. Quantization Table Set . . . . . . . . . . . . . . . . . 45 | |||
4.9.1. quant_tables . . . . . . . . . . . . . . . . . . . . 39 | 4.9.1. quant_tables . . . . . . . . . . . . . . . . . . . . 46 | |||
4.9.2. context_count . . . . . . . . . . . . . . . . . . . . 39 | 4.9.2. context_count . . . . . . . . . . . . . . . . . . . . 46 | |||
5. Restrictions . . . . . . . . . . . . . . . . . . . . . . . . 39 | 5. Restrictions . . . . . . . . . . . . . . . . . . . . . . . . 47 | |||
6. Security Considerations . . . . . . . . . . . . . . . . . . . 40 | 6. Security Considerations . . . . . . . . . . . . . . . . . . . 47 | |||
7. Media Type Definition . . . . . . . . . . . . . . . . . . . . 41 | 7. Media Type Definition . . . . . . . . . . . . . . . . . . . . 48 | |||
8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 42 | 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 50 | |||
9. Appendixes . . . . . . . . . . . . . . . . . . . . . . . . . 42 | 9. Appendixes . . . . . . . . . . . . . . . . . . . . . . . . . 50 | |||
9.1. Decoder implementation suggestions . . . . . . . . . . . 42 | 9.1. Decoder implementation suggestions . . . . . . . . . . . 50 | |||
9.1.1. Multi-threading Support and Independence of | 9.1.1. Multi-threading Support and Independence of | |||
Slices . . . . . . . . . . . . . . . . . . . . . . . 43 | Slices . . . . . . . . . . . . . . . . . . . . . . . 50 | |||
10. Changelog . . . . . . . . . . . . . . . . . . . . . . . . . . 43 | 10. Changelog . . . . . . . . . . . . . . . . . . . . . . . . . . 50 | |||
11. Normative References . . . . . . . . . . . . . . . . . . . . 43 | 11. Normative References . . . . . . . . . . . . . . . . . . . . 50 | |||
12. Informative References . . . . . . . . . . . . . . . . . . . 44 | 12. Informative References . . . . . . . . . . . . . . . . . . . 51 | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 45 | Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 52 | |||
1. Introduction | 1. Introduction | |||
This document describes FFV1, a lossless video encoding format. The | This document describes FFV1, a lossless video encoding format. The | |||
design of FFV1 considers the storage of image characteristics, data | design of FFV1 considers the storage of image characteristics, data | |||
fixity, and the optimized use of encoding time and storage | fixity, and the optimized use of encoding time and storage | |||
requirements. FFV1 is designed to support a wide range of lossless | requirements. FFV1 is designed to support a wide range of lossless | |||
video applications such as long-term audiovisual preservation, | video applications such as long-term audiovisual preservation, | |||
scientific imaging, screen recording, and other video encoding | scientific imaging, screen recording, and other video encoding | |||
scenarios that seek to avoid the generational loss of lossy video | scenarios that seek to avoid the generational loss of lossy video | |||
skipping to change at page 17, line 36 ¶ | skipping to change at page 18, line 5 ¶ | |||
255 contexts per 8-bit symbol that is not only a waste of memory but | 255 contexts per 8-bit symbol that is not only a waste of memory but | |||
also requires more past data to reach a reasonably good estimate of | also requires more past data to reach a reasonably good estimate of | |||
the probabilities. Alternatively assuming a Laplacian distribution | the probabilities. Alternatively assuming a Laplacian distribution | |||
and only dealing with its variance and mean (as in Huffman coding) | and only dealing with its variance and mean (as in Huffman coding) | |||
would also be possible, however, for maximum flexibility and | would also be possible, however, for maximum flexibility and | |||
simplicity, the chosen method uses a single symbol to encode if a | simplicity, the chosen method uses a single symbol to encode if a | |||
number is 0, and if not, encodes the number using its exponent, | number is 0, and if not, encodes the number using its exponent, | |||
mantissa and sign. The exact contexts used are best described by the | mantissa and sign. The exact contexts used are best described by the | |||
following code, followed by some comments. | following code, followed by some comments. | |||
pseudo-code | type --------------------------------------------------------------|----- void put_symbol(RangeCoder *c, uint8_t *state, int v, int \ | is_signed) { | int i; | put_rac(c, state+0, !v); | if (v) { | int a= abs(v); | int e= log2(a); | | for (i = 0; i < e; i++) { | put_rac(c, state+1+min(i,9), 1); //1..10 | } | | put_rac(c, state+1+min(i,9), 0); | for (i = e-1; i >= 0; i--) { | put_rac(c, state+22+min(i,9), (a>>i)&1); //22..31 | } | | if (is_signed) { | put_rac(c, state+11 + min(e, 10), v < 0); //11..21| } | } | } | | pseudo-code | type | |||
--------------------------------------------------------------|----- | ||||
void put_symbol(RangeCoder *c, uint8_t *state, int v, int \ | | ||||
is_signed) { | | ||||
int i; | | ||||
put_rac(c, state+0, !v); | | ||||
if (v) { | | ||||
int a= abs(v); | | ||||
int e= log2(a); | | ||||
| | ||||
for (i = 0; i < e; i++) { | | ||||
put_rac(c, state+1+min(i,9), 1); //1..10 | | ||||
} | | ||||
| | ||||
put_rac(c, state+1+min(i,9), 0); | | ||||
for (i = e-1; i >= 0; i--) { | | ||||
put_rac(c, state+22+min(i,9), (a>>i)&1); //22..31 | | ||||
} | | ||||
| | ||||
if (is_signed) { | | ||||
put_rac(c, state+11 + min(e, 10), v < 0); //11..21| | ||||
} | | ||||
} | | ||||
} | | ||||
3.8.1.3. Initial Values for the Context Model | 3.8.1.3. Initial Values for the Context Model | |||
At keyframes all Range coder state variables are set to their initial | At keyframes all Range coder state variables are set to their initial | |||
state. | state. | |||
3.8.1.4. State Transition Table | 3.8.1.4. State Transition Table | |||
one_state_{i} = | one_state_{i} = | |||
default_state_transition_{i} + state_transition_delta_{i} | default_state_transition_{i} + state_transition_delta_{i} | |||
skipping to change at page 19, line 49 ¶ | skipping to change at page 21, line 5 ¶ | |||
The end of the bitstream of the "Frame" is filled with 0-bits until | The end of the bitstream of the "Frame" is filled with 0-bits until | |||
that the bitstream contains a multiple of 8 bits. | that the bitstream contains a multiple of 8 bits. | |||
3.8.2.1. Signed Golomb Rice Codes | 3.8.2.1. Signed Golomb Rice Codes | |||
This coding mode uses Golomb Rice codes. The VLC is split into 2 | This coding mode uses Golomb Rice codes. The VLC is split into 2 | |||
parts, the prefix stores the most significant bits and the suffix | parts, the prefix stores the most significant bits and the suffix | |||
stores the k least significant bits or stores the whole number in the | stores the k least significant bits or stores the whole number in the | |||
ESC case. | ESC case. | |||
pseudo-code | type --------------------------------------------------------------|----- int get_ur_golomb(k) { | for (prefix = 0; prefix < 12; prefix++) { | if (get_bits(1)) { | return get_bits(k) + (prefix << k) | } | } | return get_bits(bits) + 11 | } | | int get_sr_golomb(k) { | v = get_ur_golomb(k); | if (v & 1) return - (v >> 1) - 1; | else return (v >> 1); | } | pseudo-code | type | |||
--------------------------------------------------------------|----- | ||||
int get_ur_golomb(k) { | | ||||
for (prefix = 0; prefix < 12; prefix++) { | | ||||
if (get_bits(1)) { | | ||||
return get_bits(k) + (prefix << k) | | ||||
} | | ||||
} | | ||||
return get_bits(bits) + 11 | | ||||
} | | ||||
| | ||||
int get_sr_golomb(k) { | | ||||
v = get_ur_golomb(k); | | ||||
if (v & 1) return - (v >> 1) - 1; | | ||||
else return (v >> 1); | | ||||
} | ||||
3.8.2.1.1. Prefix | 3.8.2.1.1. Prefix | |||
+----------------+-------+ | +----------------+-------+ | |||
| bits | value | | | bits | value | | |||
+================+=======+ | +================+=======+ | |||
| 1 | 0 | | | 1 | 0 | | |||
+----------------+-------+ | +----------------+-------+ | |||
| 01 | 1 | | | 01 | 1 | | |||
+----------------+-------+ | +----------------+-------+ | |||
skipping to change at page 21, line 40 ¶ | skipping to change at page 23, line 5 ¶ | |||
3.8.2.2.1. Run Length Coding | 3.8.2.2.1. Run Length Coding | |||
The run value is encoded in 2 parts, the prefix part stores the more | The run value is encoded in 2 parts, the prefix part stores the more | |||
significant part of the run as well as adjusting the run_index that | significant part of the run as well as adjusting the run_index that | |||
determines the number of bits in the less significant part of the | determines the number of bits in the less significant part of the | |||
run. The 2nd part of the value stores the less significant part of | run. The 2nd part of the value stores the less significant part of | |||
the run as it is. The run_index is reset for each "Plane" and slice | the run as it is. The run_index is reset for each "Plane" and slice | |||
to 0. | to 0. | |||
pseudo-code | type --------------------------------------------------------------|----- log2_run[41]={ | 0, 0, 0, 0, 1, 1, 1, 1, | 2, 2, 2, 2, 3, 3, 3, 3, | 4, 4, 5, 5, 6, 6, 7, 7, | 8, 9,10,11,12,13,14,15, | 16,17,18,19,20,21,22,23, | 24, | }; | | if (run_count == 0 && run_mode == 1) { | if (get_bits(1)) { | run_count = 1 << log2_run[run_index]; | if (x + run_count <= w) { | run_index++; | } | } else { | if (log2_run[run_index]) { | run_count = get_bits(log2_run[run_index]); | } else { | run_count = 0; | } | if (run_index) { | run_index--; | } | run_mode = 2; | } | } | | pseudo-code | type | |||
--------------------------------------------------------------|----- | ||||
log2_run[41]={ | | ||||
0, 0, 0, 0, 1, 1, 1, 1, | | ||||
2, 2, 2, 2, 3, 3, 3, 3, | | ||||
4, 4, 5, 5, 6, 6, 7, 7, | | ||||
8, 9,10,11,12,13,14,15, | | ||||
16,17,18,19,20,21,22,23, | | ||||
24, | | ||||
}; | | ||||
| | ||||
if (run_count == 0 && run_mode == 1) { | | ||||
if (get_bits(1)) { | | ||||
run_count = 1 << log2_run[run_index]; | | ||||
if (x + run_count <= w) { | | ||||
run_index++; | | ||||
} | | ||||
} else { | | ||||
if (log2_run[run_index]) { | | ||||
run_count = get_bits(log2_run[run_index]); | | ||||
} else { | | ||||
run_count = 0; | | ||||
} | | ||||
if (run_index) { | | ||||
run_index--; | | ||||
} | | ||||
run_mode = 2; | | ||||
} | | ||||
} | | ||||
The log2_run function is also used within [ISO.14495-1.1999]. | The log2_run function is also used within [ISO.14495-1.1999]. | |||
3.8.2.2.2. Level Coding | 3.8.2.2.2. Level Coding | |||
Level coding is identical to the normal difference coding with the | Level coding is identical to the normal difference coding with the | |||
exception that the 0 value is removed as it cannot occur: | exception that the 0 value is removed as it cannot occur: | |||
diff = get_vlc_symbol(context_state); if (diff >= 0) { diff++; } | diff = get_vlc_symbol(context_state); | |||
if (diff >= 0) { | ||||
diff++; | ||||
} | ||||
Note, this is different from JPEG-LS, which doesn't use prediction in | Note, this is different from JPEG-LS, which doesn't use prediction in | |||
run mode and uses a different encoding and context model for the last | run mode and uses a different encoding and context model for the last | |||
difference On a small set of test "Samples" the use of prediction | difference On a small set of test "Samples" the use of prediction | |||
slightly improved the compression rate. | slightly improved the compression rate. | |||
3.8.2.3. Scalar Mode | 3.8.2.3. Scalar Mode | |||
Each difference is coded with the per context mean prediction removed | Each difference is coded with the per context mean prediction removed | |||
and a per context value for k. | and a per context value for k. | |||
get_vlc_symbol(state) { i = state->count; k = 0; while (i < state->error_sum) { k++; i += i; } v = get_sr_golomb(k); if (2 * state->drift < -state->count) { v = -1 - v; } ret = sign_extend(v + state->bias, bits); state->error_sum += abs(v); state->drift += v; if (state->count == 128) { state->count >>= 1; state->drift >>= 1; state->error_sum >>= 1; } state->count++; if (state->drift <= -state->count) { state->bias = max(state->bias - 1, -128); state->drift = max(state->drift + state->count, -state->count + 1); } else if (state->drift > 0) { state->bias = min(state->bias + 1, 127); state->drift = min(state->drift - state->count, 0); } return ret; } | get_vlc_symbol(state) { | |||
i = state->count; | ||||
k = 0; | ||||
while (i < state->error_sum) { | ||||
k++; | ||||
i += i; | ||||
} | ||||
v = get_sr_golomb(k); | ||||
if (2 * state->drift < -state->count) { | ||||
v = -1 - v; | ||||
} | ||||
ret = sign_extend(v + state->bias, bits); | ||||
state->error_sum += abs(v); | ||||
state->drift += v; | ||||
if (state->count == 128) { | ||||
state->count >>= 1; | ||||
state->drift >>= 1; | ||||
state->error_sum >>= 1; | ||||
} | ||||
state->count++; | ||||
if (state->drift <= -state->count) { | ||||
state->bias = max(state->bias - 1, -128); | ||||
state->drift = max(state->drift + state->count, | ||||
-state->count + 1); | ||||
} else if (state->drift > 0) { | ||||
state->bias = min(state->bias + 1, 127); | ||||
state->drift = min(state->drift - state->count, 0); | ||||
} | ||||
return ret; | ||||
} | ||||
3.8.2.4. Initial Values for the VLC context state | 3.8.2.4. Initial Values for the VLC context state | |||
At keyframes all coder state variables are set to their initial | At keyframes all coder state variables are set to their initial | |||
state. | state. | |||
drift = 0; error_sum = 4; bias = 0; count = 1; | drift = 0; | |||
error_sum = 4; | ||||
bias = 0; | ||||
count = 1; | ||||
4. Bitstream | 4. Bitstream | |||
An FFV1 bitstream is composed of a series of 1 or more "Frames" and | An FFV1 bitstream is composed of a series of 1 or more "Frames" and | |||
(when required) a "Configuration Record". | (when required) a "Configuration Record". | |||
Within the following sub-sections, pseudo-code is used to explain the | Within the following sub-sections, pseudo-code is used to explain the | |||
structure of each FFV1 bitstream component, as described in the | structure of each FFV1 bitstream component, as described in the | |||
section on Pseudo-Code (#pseudocode). The following table lists | section on Pseudo-Code (#pseudocode). The following table lists | |||
symbols used to annotate that pseudo-code in order to define the | symbols used to annotate that pseudo-code in order to define the | |||
skipping to change at page 23, line 52 ¶ | skipping to change at page 27, line 5 ¶ | |||
4.1. Parameters | 4.1. Parameters | |||
The "Parameters" section contains significant characteristics about | The "Parameters" section contains significant characteristics about | |||
the decoding configuration used for all instances of "Frame" (in FFV1 | the decoding configuration used for all instances of "Frame" (in FFV1 | |||
version 0 and 1) or the whole FFV1 bitstream (other versions), | version 0 and 1) or the whole FFV1 bitstream (other versions), | |||
including the stream version, color configuration, and quantization | including the stream version, color configuration, and quantization | |||
tables. The pseudo-code below describes the contents of the | tables. The pseudo-code below describes the contents of the | |||
bitstream. | bitstream. | |||
pseudo-code | type --------------------------------------------------------------|----- Parameters( ) { | version | ur if (version >= 3) { | micro_version | ur } | coder_type | ur if (coder_type > 1) { | for (i = 1; i < 256; i++) { | state_transition_delta[ i ] | sr } | } | colorspace_type | ur if (version >= 1) { | bits_per_raw_sample | ur } | chroma_planes | br log2_h_chroma_subsample | ur log2_v_chroma_subsample | ur extra_plane | br if (version >= 3) { | num_h_slices - 1 | ur num_v_slices - 1 | ur quant_table_set_count | ur } | for (i = 0; i < quant_table_set_count; i++) { | QuantizationTableSet( i ) | } | if (version >= 3) { | for (i = 0; i < quant_table_set_count; i++) { | states_coded | br if (states_coded) { | for (j = 0; j < context_count[ i ]; j++) { | for (k = 0; k < CONTEXT_SIZE; k++) { | initial_state_delta[ i ][ j ][ k ] | sr } | } | } | } | ec | ur intra | ur } | } | | pseudo-code | type | |||
--------------------------------------------------------------|----- | ||||
Parameters( ) { | | ||||
version | ur | ||||
if (version >= 3) { | | ||||
micro_version | ur | ||||
} | | ||||
coder_type | ur | ||||
if (coder_type > 1) { | | ||||
for (i = 1; i < 256; i++) { | | ||||
state_transition_delta[ i ] | sr | ||||
} | | ||||
} | | ||||
colorspace_type | ur | ||||
if (version >= 1) { | | ||||
bits_per_raw_sample | ur | ||||
} | | ||||
chroma_planes | br | ||||
log2_h_chroma_subsample | ur | ||||
log2_v_chroma_subsample | ur | ||||
extra_plane | br | ||||
if (version >= 3) { | | ||||
num_h_slices - 1 | ur | ||||
num_v_slices - 1 | ur | ||||
quant_table_set_count | ur | ||||
} | | ||||
for (i = 0; i < quant_table_set_count; i++) { | | ||||
QuantizationTableSet( i ) | | ||||
} | | ||||
if (version >= 3) { | | ||||
for (i = 0; i < quant_table_set_count; i++) { | | ||||
states_coded | br | ||||
if (states_coded) { | | ||||
for (j = 0; j < context_count[ i ]; j++) { | | ||||
for (k = 0; k < CONTEXT_SIZE; k++) { | | ||||
initial_state_delta[ i ][ j ][ k ] | sr | ||||
} | | ||||
} | | ||||
} | | ||||
} | | ||||
ec | ur | ||||
intra | ur | ||||
} | | ||||
} | | ||||
CONTEXT_SIZE is 32. | ||||
4.1.1. version | 4.1.1. version | |||
"version" specifies the version of the FFV1 bitstream. | "version" specifies the version of the FFV1 bitstream. | |||
Each version is incompatible with other versions: decoders SHOULD | Each version is incompatible with other versions: decoders SHOULD | |||
reject a file due to an unknown version. | reject a file due to an unknown version. | |||
Decoders SHOULD reject a file with version <= 1 && | Decoders SHOULD reject a file with version <= 1 && | |||
ConfigurationRecordIsPresent == 1. | ConfigurationRecordIsPresent == 1. | |||
skipping to change at page 28, line 42 ¶ | skipping to change at page 32, line 42 ¶ | |||
4.1.12. num_v_slices | 4.1.12. num_v_slices | |||
"num_v_slices" indicates the number of vertical elements of the slice | "num_v_slices" indicates the number of vertical elements of the slice | |||
raster. | raster. | |||
Inferred to be 1 if not present. | Inferred to be 1 if not present. | |||
4.1.13. quant_table_set_count | 4.1.13. quant_table_set_count | |||
"quant_table_set_count" indicates the number of Quantization | "quant_table_set_count" indicates the number of Quantization | |||
Table Sets. | Table Sets. "quant_table_set_count" MUST be less than or equal to 8. | |||
Inferred to be 1 if not present. | Inferred to be 1 if not present. | |||
MUST NOT be 0. | MUST NOT be 0. | |||
4.1.14. states_coded | 4.1.14. states_coded | |||
"states_coded" indicates if the respective Quantization Table Set has | "states_coded" indicates if the respective Quantization Table Set has | |||
the initial states coded. | the initial states coded. | |||
skipping to change at page 30, line 27 ¶ | skipping to change at page 34, line 27 ¶ | |||
Table 15 | Table 15 | |||
4.2. Configuration Record | 4.2. Configuration Record | |||
In the case of a FFV1 bitstream with "version >= 3", a "Configuration | In the case of a FFV1 bitstream with "version >= 3", a "Configuration | |||
Record" is stored in the underlying "Container", at the track header | Record" is stored in the underlying "Container", at the track header | |||
level. It contains the "Parameters" used for all instances of | level. It contains the "Parameters" used for all instances of | |||
"Frame". The size of the "Configuration Record", "NumBytes", is | "Frame". The size of the "Configuration Record", "NumBytes", is | |||
supplied by the underlying "Container". | supplied by the underlying "Container". | |||
pseudo-code | type -----------------------------------------------------------|----- ConfigurationRecord( NumBytes ) { | ConfigurationRecordIsPresent = 1 | Parameters( ) | while (remaining_symbols_in_syntax(NumBytes - 4)) { | reserved_for_future_use | br/ur/sr } | configuration_record_crc_parity | u(32) } | | pseudo-code | type | |||
-----------------------------------------------------------|----- | ||||
ConfigurationRecord( NumBytes ) { | | ||||
ConfigurationRecordIsPresent = 1 | | ||||
Parameters( ) | | ||||
while (remaining_symbols_in_syntax(NumBytes - 4)) { | | ||||
reserved_for_future_use | br/ur/sr | ||||
} | | ||||
configuration_record_crc_parity | u(32) | ||||
} | | ||||
4.2.1. reserved_for_future_use | 4.2.1. reserved_for_future_use | |||
"reserved_for_future_use" has semantics that are reserved for future | "reserved_for_future_use" has semantics that are reserved for future | |||
use. | use. | |||
Encoders conforming to this version of this specification SHALL NOT | Encoders conforming to this version of this specification SHALL NOT | |||
write this value. | write this value. | |||
Decoders conforming to this version of this specification SHALL | Decoders conforming to this version of this specification SHALL | |||
skipping to change at page 32, line 17 ¶ | skipping to change at page 36, line 25 ¶ | |||
4.3. Frame | 4.3. Frame | |||
A "Frame" is an encoded representation of a complete static image. | A "Frame" is an encoded representation of a complete static image. | |||
The whole "Frame" is provided by the underlaying container. | The whole "Frame" is provided by the underlaying container. | |||
A "Frame" consists of the keyframe field, "Parameters" (if version | A "Frame" consists of the keyframe field, "Parameters" (if version | |||
<=1), and a sequence of independent slices. The pseudo-code below | <=1), and a sequence of independent slices. The pseudo-code below | |||
describes the contents of a "Frame". | describes the contents of a "Frame". | |||
pseudo-code | type --------------------------------------------------------------|----- Frame( NumBytes ) { | keyframe | br if (keyframe && !ConfigurationRecordIsPresent { | Parameters( ) | } | while (remaining_bits_in_bitstream( NumBytes )) { | Slice( ) | } | } | | pseudo-code | type | |||
--------------------------------------------------------------|----- | ||||
Frame( NumBytes ) { | | ||||
keyframe | br | ||||
if (keyframe && !ConfigurationRecordIsPresent { | | ||||
Parameters( ) | | ||||
} | | ||||
while (remaining_bits_in_bitstream( NumBytes )) { | | ||||
Slice( ) | | ||||
} | | ||||
} | | ||||
Architecture overview of slices in a "Frame": | Architecture overview of slices in a "Frame": | |||
+-----------------------------------------------------------------+ | +-----------------------------------------------------------------+ | |||
+=================================================================+ | +=================================================================+ | |||
| first slice header | | | first slice header | | |||
+-----------------------------------------------------------------+ | +-----------------------------------------------------------------+ | |||
| first slice content | | | first slice content | | |||
+-----------------------------------------------------------------+ | +-----------------------------------------------------------------+ | |||
| first slice footer | | | first slice footer | | |||
skipping to change at page 33, line 17 ¶ | skipping to change at page 38, line 5 ¶ | |||
A "Slice" is an independent spatial sub-section of a "Frame" that is | A "Slice" is an independent spatial sub-section of a "Frame" that is | |||
encoded separately from an other region of the same "Frame". The use | encoded separately from an other region of the same "Frame". The use | |||
of more than one "Slice" per "Frame" can be useful for taking | of more than one "Slice" per "Frame" can be useful for taking | |||
advantage of the opportunities of multithreaded encoding and | advantage of the opportunities of multithreaded encoding and | |||
decoding. | decoding. | |||
A "Slice" consists of a "Slice Header" (when relevant), a "Slice | A "Slice" consists of a "Slice Header" (when relevant), a "Slice | |||
Content", and a "Slice Footer" (when relevant). The pseudo-code | Content", and a "Slice Footer" (when relevant). The pseudo-code | |||
below describes the contents of a "Slice". | below describes the contents of a "Slice". | |||
pseudo-code | type --------------------------------------------------------------|----- Slice( ) { | if (version >= 3) { | SliceHeader( ) | } | SliceContent( ) | if (coder_type == 0) { | while (!byte_aligned()) { | padding | u(1) } | } | if (version <= 1) { | while (remaining_bits_in_bitstream( NumBytes ) != 0) {| reserved | u(1) } | } | if (version >= 3) { | SliceFooter( ) | } | } | | pseudo-code | type | |||
--------------------------------------------------------------|----- | ||||
Slice( ) { | | ||||
if (version >= 3) { | | ||||
SliceHeader( ) | | ||||
} | | ||||
SliceContent( ) | | ||||
if (coder_type == 0) { | | ||||
while (!byte_aligned()) { | | ||||
padding | u(1) | ||||
} | | ||||
} | | ||||
if (version <= 1) { | | ||||
while (remaining_bits_in_bitstream( NumBytes ) != 0) {| | ||||
reserved | u(1) | ||||
} | | ||||
} | | ||||
if (version >= 3) { | | ||||
SliceFooter( ) | | ||||
} | | ||||
} | | ||||
"padding" specifies a bit without any significance and used only for | "padding" specifies a bit without any significance and used only for | |||
byte alignment. MUST be 0. | byte alignment. MUST be 0. | |||
"reserved" specifies a bit without any significance in this revision | "reserved" specifies a bit without any significance in this revision | |||
of the specification and may have a significance in a later revision | of the specification and may have a significance in a later revision | |||
of this specification. | of this specification. | |||
Encoders SHOULD NOT fill these bits. | Encoders SHOULD NOT fill these bits. | |||
skipping to change at page 33, line 46 ¶ | skipping to change at page 39, line 5 ¶ | |||
conforming to the revised specification could not do the difference | conforming to the revised specification could not do the difference | |||
between a revised bitstream and a buggy bitstream. | between a revised bitstream and a buggy bitstream. | |||
4.5. Slice Header | 4.5. Slice Header | |||
A "Slice Header" provides information about the decoding | A "Slice Header" provides information about the decoding | |||
configuration of the "Slice", such as its spatial position, size, and | configuration of the "Slice", such as its spatial position, size, and | |||
aspect ratio. The pseudo-code below describes the contents of the | aspect ratio. The pseudo-code below describes the contents of the | |||
"Slice Header". | "Slice Header". | |||
pseudo-code | type --------------------------------------------------------------|----- SliceHeader( ) { | slice_x | ur slice_y | ur slice_width - 1 | ur slice_height - 1 | ur for (i = 0; i < quant_table_set_index_count; i++) { | quant_table_set_index[ i ] | ur } | picture_structure | ur sar_num | ur sar_den | ur if (version >= 4) { | reset_contexts | br slice_coding_mode | ur } | } | | pseudo-code | type | |||
--------------------------------------------------------------|----- | ||||
SliceHeader( ) { | | ||||
slice_x | ur | ||||
slice_y | ur | ||||
slice_width - 1 | ur | ||||
slice_height - 1 | ur | ||||
for (i = 0; i < quant_table_set_index_count; i++) { | | ||||
quant_table_set_index[ i ] | ur | ||||
} | | ||||
picture_structure | ur | ||||
sar_num | ur | ||||
sar_den | ur | ||||
if (version >= 4) { | | ||||
reset_contexts | br | ||||
slice_coding_mode | ur | ||||
} | | ||||
} | | ||||
4.5.1. slice_x | 4.5.1. slice_x | |||
"slice_x" indicates the x position on the slice raster formed by | "slice_x" indicates the x position on the slice raster formed by | |||
num_h_slices. | num_h_slices. | |||
Inferred to be 0 if not present. | Inferred to be 0 if not present. | |||
4.5.2. slice_y | 4.5.2. slice_y | |||
skipping to change at page 36, line 30 ¶ | skipping to change at page 42, line 5 ¶ | |||
Table 18 | Table 18 | |||
4.6. Slice Content | 4.6. Slice Content | |||
A "Slice Content" contains all "Line" elements part of the "Slice". | A "Slice Content" contains all "Line" elements part of the "Slice". | |||
Depending on the configuration, "Line" elements are ordered by | Depending on the configuration, "Line" elements are ordered by | |||
"Plane" then by row (YCbCr) or by row then by "Plane" (RGB). | "Plane" then by row (YCbCr) or by row then by "Plane" (RGB). | |||
pseudo-code | type --------------------------------------------------------------|----- SliceContent( ) { | if (colorspace_type == 0) { | for (p = 0; p < primary_color_count; p++) { | for (y = 0; y < plane_pixel_height[ p ]; y++) { | Line( p, y ) | } | } | } else if (colorspace_type == 1) { | for (y = 0; y < slice_pixel_height; y++) { | for (p = 0; p < primary_color_count; p++) { | Line( p, y ) | } | } | } | } | | pseudo-code | type | |||
--------------------------------------------------------------|----- | ||||
SliceContent( ) { | | ||||
if (colorspace_type == 0) { | | ||||
for (p = 0; p < primary_color_count; p++) { | | ||||
for (y = 0; y < plane_pixel_height[ p ]; y++) { | | ||||
Line( p, y ) | | ||||
} | | ||||
} | | ||||
} else if (colorspace_type == 1) { | | ||||
for (y = 0; y < slice_pixel_height; y++) { | | ||||
for (p = 0; p < primary_color_count; p++) { | | ||||
Line( p, y ) | | ||||
} | | ||||
} | | ||||
} | | ||||
} | | ||||
4.6.1. primary_color_count | 4.6.1. primary_color_count | |||
"primary_color_count" is defined as "1 + ( chroma_planes ? 2 : 0 ) + | "primary_color_count" is defined as "1 + ( chroma_planes ? 2 : 0 ) + | |||
( extra_plane ? 1 : 0 )". | ( extra_plane ? 1 : 0 )". | |||
4.6.2. plane_pixel_height | 4.6.2. plane_pixel_height | |||
"plane_pixel_height[ p ]" is the height in pixels of plane p of the | "plane_pixel_height[ p ]" is the height in pixels of plane p of the | |||
slice. | slice. | |||
skipping to change at page 37, line 20 ¶ | skipping to change at page 43, line 11 ¶ | |||
"slice_pixel_y" is the slice vertical position in pixels. | "slice_pixel_y" is the slice vertical position in pixels. | |||
Its value is "floor( slice_y * frame_pixel_height / num_v_slices )". | Its value is "floor( slice_y * frame_pixel_height / num_v_slices )". | |||
4.7. Line | 4.7. Line | |||
A "Line" is a list of the sample differences (relative to the | A "Line" is a list of the sample differences (relative to the | |||
predictor) of primary color components. The pseudo-code below | predictor) of primary color components. The pseudo-code below | |||
describes the contents of the "Line". | describes the contents of the "Line". | |||
pseudo-code | type --------------------------------------------------------------|----- Line( p, y ) { | if (colorspace_type == 0) { | for (x = 0; x < plane_pixel_width[ p ]; x++) { | sample_difference[ p ][ y ][ x ] | } | } else if (colorspace_type == 1) { | for (x = 0; x < slice_pixel_width; x++) { | sample_difference[ p ][ y ][ x ] | } | } | } | | pseudo-code | type | |||
--------------------------------------------------------------|----- | ||||
Line( p, y ) { | | ||||
if (colorspace_type == 0) { | | ||||
for (x = 0; x < plane_pixel_width[ p ]; x++) { | | ||||
sample_difference[ p ][ y ][ x ] | | ||||
} | | ||||
} else if (colorspace_type == 1) { | | ||||
for (x = 0; x < slice_pixel_width; x++) { | | ||||
sample_difference[ p ][ y ][ x ] | | ||||
} | | ||||
} | | ||||
} | | ||||
4.7.1. plane_pixel_width | 4.7.1. plane_pixel_width | |||
"plane_pixel_width[ p ]" is the width in "Pixels" of "Plane" p of the | "plane_pixel_width[ p ]" is the width in "Pixels" of "Plane" p of the | |||
slice. | slice. | |||
"plane_pixel_width[ 0 ]" and "plane_pixel_width[ 1 + ( chroma_planes | "plane_pixel_width[ 0 ]" and "plane_pixel_width[ 1 + ( chroma_planes | |||
? 2 : 0 ) ]" value is "slice_pixel_width". | ? 2 : 0 ) ]" value is "slice_pixel_width". | |||
If "chroma_planes" is set to 1, "plane_pixel_width[ 1 ]" and | If "chroma_planes" is set to 1, "plane_pixel_width[ 1 ]" and | |||
skipping to change at page 38, line 13 ¶ | skipping to change at page 44, line 20 ¶ | |||
described in the section on Samples (#samples). | described in the section on Samples (#samples). | |||
4.8. Slice Footer | 4.8. Slice Footer | |||
A "Slice Footer" provides information about slice size and | A "Slice Footer" provides information about slice size and | |||
(optionally) parity. The pseudo-code below describes the contents of | (optionally) parity. The pseudo-code below describes the contents of | |||
the "Slice Footer". | the "Slice Footer". | |||
Note: "Slice Footer" is always byte aligned. | Note: "Slice Footer" is always byte aligned. | |||
pseudo-code | type --------------------------------------------------------------|----- SliceFooter( ) { | slice_size | u(24) if (ec) { | error_status | u(8) slice_crc_parity | u(32) } | } | | pseudo-code | type | |||
--------------------------------------------------------------|----- | ||||
SliceFooter( ) { | | ||||
slice_size | u(24) | ||||
if (ec) { | | ||||
error_status | u(8) | ||||
slice_crc_parity | u(32) | ||||
} | | ||||
} | | ||||
4.8.1. slice_size | 4.8.1. slice_size | |||
"slice_size" indicates the size of the slice in bytes. | "slice_size" indicates the size of the slice in bytes. | |||
Note: this allows finding the start of slices before previous slices | Note: this allows finding the start of slices before previous slices | |||
have been fully decoded, and allows parallel decoding as well as | have been fully decoded, and allows parallel decoding as well as | |||
error resilience. | error resilience. | |||
4.8.2. error_status | 4.8.2. error_status | |||
skipping to change at page 39, line 21 ¶ | skipping to change at page 46, line 4 ¶ | |||
need to be stored as it is identical to the first with flipped sign. | need to be stored as it is identical to the first with flipped sign. | |||
"scale" and "len_count[ i ][ j ]" are temporary values used for the | "scale" and "len_count[ i ][ j ]" are temporary values used for the | |||
computing of "context_count[ i ]" and are not used outside | computing of "context_count[ i ]" and are not used outside | |||
Quantization Table Set pseudo-code. | Quantization Table Set pseudo-code. | |||
Example: | Example: | |||
Table: 0 0 1 1 1 1 2 2 -2 -2 -2 -1 -1 -1 -1 0 | Table: 0 0 1 1 1 1 2 2 -2 -2 -2 -1 -1 -1 -1 0 | |||
Stored values: 1, 3, 1 | Stored values: 1, 3, 1 | |||
pseudo-code | type | ||||
pseudo-code | type --------------------------------------------------------------|----- QuantizationTableSet( i ) { | scale = 1 | for (j = 0; j < MAX_CONTEXT_INPUTS; j++) { | QuantizationTable( i, j, scale ) | scale *= 2 * len_count[ i ][ j ] - 1 | } | context_count[ i ] = ceil( scale / 2 ) | } | | --------------------------------------------------------------|----- | |||
QuantizationTableSet( i ) { | | ||||
scale = 1 | | ||||
for (j = 0; j < MAX_CONTEXT_INPUTS; j++) { | | ||||
QuantizationTable( i, j, scale ) | | ||||
scale *= 2 * len_count[ i ][ j ] - 1 | | ||||
} | | ||||
context_count[ i ] = ceil( scale / 2 ) | | ||||
} | | ||||
MAX_CONTEXT_INPUTS is 5. | MAX_CONTEXT_INPUTS is 5. | |||
pseudo-code | type --------------------------------------------------------------|----- QuantizationTable(i, j, scale) { | v = 0 | for (k = 0; k < 128;) { | len - 1 | ur for (a = 0; a < len; a++) { | quant_tables[ i ][ j ][ k ] = scale * v | k++ | } | v++ | } | for (k = 1; k < 128; k++) { | quant_tables[ i ][ j ][ 256 - k ] = \ | -quant_tables[ i ][ j ][ k ] | } | quant_tables[ i ][ j ][ 128 ] = \ | -quant_tables[ i ][ j ][ 127 ] | len_count[ i ][ j ] = v | } | | pseudo-code | type | |||
--------------------------------------------------------------|----- | ||||
QuantizationTable(i, j, scale) { | | ||||
v = 0 | | ||||
for (k = 0; k < 128;) { | | ||||
len - 1 | ur | ||||
for (a = 0; a < len; a++) { | | ||||
quant_tables[ i ][ j ][ k ] = scale * v | | ||||
k++ | | ||||
} | | ||||
v++ | | ||||
} | | ||||
for (k = 1; k < 128; k++) { | | ||||
quant_tables[ i ][ j ][ 256 - k ] = \ | | ||||
-quant_tables[ i ][ j ][ k ] | | ||||
} | | ||||
quant_tables[ i ][ j ][ 128 ] = \ | | ||||
-quant_tables[ i ][ j ][ 127 ] | | ||||
len_count[ i ][ j ] = v | | ||||
} | | ||||
4.9.1. quant_tables | 4.9.1. quant_tables | |||
"quant_tables[ i ][ j ][ k ]" indicates the quantification table | "quant_tables[ i ][ j ][ k ]" indicates the quantification table | |||
value of the Quantized Sample Difference "k" of the Quantization | value of the Quantized Sample Difference "k" of the Quantization | |||
Table "j" of the Set Quantization Table Set "i". | Table "j" of the Set Quantization Table Set "i". | |||
4.9.2. context_count | 4.9.2. context_count | |||
"context_count[ i ]" indicates the count of contexts for Quantization | "context_count[ i ]" indicates the count of contexts for Quantization | |||
Table Set "i". | Table Set "i". "context_count[ i ]" MUST be less than or equal to | |||
32768. | ||||
5. Restrictions | 5. Restrictions | |||
To ensure that fast multithreaded decoding is possible, starting with | To ensure that fast multithreaded decoding is possible, starting with | |||
version 3 and if "frame_pixel_width * frame_pixel_height" is more | version 3 and if "frame_pixel_width * frame_pixel_height" is more | |||
than 101376, "slice_width * slice_height" MUST be less or equal to | than 101376, "slice_width * slice_height" MUST be less or equal to | |||
"num_h_slices * num_v_slices / 4". Note: 101376 is the frame size in | "num_h_slices * num_v_slices / 4". Note: 101376 is the frame size in | |||
"Pixels" of a 352x288 frame also known as CIF ("Common Intermediate | "Pixels" of a 352x288 frame also known as CIF ("Common Intermediate | |||
Format") frame size format. | Format") frame size format. | |||
skipping to change at page 43, line 32 ¶ | skipping to change at page 50, line 44 ¶ | |||
10. Changelog | 10. Changelog | |||
See https://github.com/FFmpeg/FFV1/commits/master | See https://github.com/FFmpeg/FFV1/commits/master | |||
(https://github.com/FFmpeg/FFV1/commits/master) | (https://github.com/FFmpeg/FFV1/commits/master) | |||
11. Normative References | 11. Normative References | |||
[I-D.ietf-cellar-ffv1] | [I-D.ietf-cellar-ffv1] | |||
Niedermayer, M., Rice, D., and J. Martinez, "FFV1 Video | Niedermayer, M., Rice, D., and J. Martinez, "FFV1 Video | |||
Coding Format Version 0, 1, and 3", Internet Draft, draft- | Coding Format Version 0, 1, and 3", Internet-Draft, draft- | |||
ietf-cellar-ffv1-08, August 13, 2019, | ietf-cellar-ffv1-09, 6 September 2019, | |||
<https://www.ietf.org/archive/id/draft-ietf-cellar- | <https://tools.ietf.org/html/draft-ietf-cellar-ffv1-09>. | |||
ffv1-08>. | ||||
[ISO.15444-1.2016] | [ISO.15444-1.2016] | |||
International Organization for Standardization, | International Organization for Standardization, | |||
"Information technology -- JPEG 2000 image coding system: | "Information technology -- JPEG 2000 image coding system: | |||
Core coding system", October 2016. | Core coding system", October 2016. | |||
[ISO.9899.1990] | [ISO.9899.1990] | |||
International Organization for Standardization, | International Organization for Standardization, | |||
"Programming languages - C", 1990. | "Programming languages - C", 1990. | |||
skipping to change at page 44, line 26 ¶ | skipping to change at page 51, line 35 ¶ | |||
September 2012, <https://www.rfc-editor.org/info/rfc6716>. | September 2012, <https://www.rfc-editor.org/info/rfc6716>. | |||
[RFC6838] Freed, N., Klensin, J., and T. Hansen, "Media Type | [RFC6838] Freed, N., Klensin, J., and T. Hansen, "Media Type | |||
Specifications and Registration Procedures", BCP 13, | Specifications and Registration Procedures", BCP 13, | |||
RFC 6838, DOI 10.17487/RFC6838, January 2013, | RFC 6838, DOI 10.17487/RFC6838, January 2013, | |||
<https://www.rfc-editor.org/info/rfc6838>. | <https://www.rfc-editor.org/info/rfc6838>. | |||
12. Informative References | 12. Informative References | |||
[Address-Sanitizer] | [Address-Sanitizer] | |||
The Clang Team, "ASAN AddressSanitizer website", September | The Clang Team, "ASAN AddressSanitizer website", undated, | |||
2019, <https://clang.llvm.org/docs/AddressSanitizer.html>. | <https://clang.llvm.org/docs/AddressSanitizer.html>. | |||
[AVI] Microsoft, "AVI RIFF File Reference", September 2019, | [AVI] Microsoft, "AVI RIFF File Reference", undated, | |||
<https://msdn.microsoft.com/en-us/library/windows/desktop/ | <https://msdn.microsoft.com/en-us/library/windows/desktop/ | |||
dd318189%28v=vs.85%29.aspx>. | dd318189%28v=vs.85%29.aspx>. | |||
[HuffYUV] Rudiak-Gould, B., "HuffYUV", December 2003, | [HuffYUV] Rudiak-Gould, B., "HuffYUV", December 2003, | |||
<https://web.archive.org/web/20040402121343/ | <https://web.archive.org/web/20040402121343/ | |||
http://cultact-server.novi.dk/kpo/huffyuv/huffyuv.html>. | http://cultact-server.novi.dk/kpo/huffyuv/huffyuv.html>. | |||
[ISO.14495-1.1999] | [ISO.14495-1.1999] | |||
International Organization for Standardization, | International Organization for Standardization, | |||
"Information technology -- Lossless and near-lossless | "Information technology -- Lossless and near-lossless | |||
skipping to change at page 45, line 17 ¶ | skipping to change at page 52, line 27 ¶ | |||
matroska/>. | matroska/>. | |||
[NUT] Niedermayer, M., "NUT Open Container Format", December | [NUT] Niedermayer, M., "NUT Open Container Format", December | |||
2013, <https://ffmpeg.org/~michael/nut.txt>. | 2013, <https://ffmpeg.org/~michael/nut.txt>. | |||
[range-coding] | [range-coding] | |||
Nigel, G. and N. Martin, "Range encoding: an algorithm for | Nigel, G. and N. Martin, "Range encoding: an algorithm for | |||
removing redundancy from a digitised message.", July 1979. | removing redundancy from a digitised message.", July 1979. | |||
[REFIMPL] Niedermayer, M., "The reference FFV1 implementation / the | [REFIMPL] Niedermayer, M., "The reference FFV1 implementation / the | |||
FFV1 codec in FFmpeg", September 2019, | FFV1 codec in FFmpeg", undated, <https://ffmpeg.org>. | |||
<https://ffmpeg.org>. | ||||
[VALGRIND] Valgrind Developers, "Valgrind website", September 2019, | [VALGRIND] Valgrind Developers, "Valgrind website", undated, | |||
<https://valgrind.org/>. | <https://valgrind.org/>. | |||
[YCbCr] Wikipedia, "YCbCr", September 2019, | [YCbCr] Wikipedia, "YCbCr", undated, | |||
<https://en.wikipedia.org/w/index.php?title=YCbCr>. | <https://en.wikipedia.org/w/index.php?title=YCbCr>. | |||
Authors' Addresses | Authors' Addresses | |||
Michael Niedermayer | Michael Niedermayer | |||
Email: michael@niedermayer.cc | Email: michael@niedermayer.cc | |||
Dave Rice | Dave Rice | |||
End of changes. 29 change blocks. | ||||
99 lines changed or deleted | 371 lines changed or added | |||
This html diff was produced by rfcdiff 1.47. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |