/Play/ps.js
JavaScript | 234 lines | 195 code | 20 blank | 19 comment | 37 complexity | 7eec353789c8f8685896378b500f84bc MD5 | raw file
1'use strict'; 2 3/** 4 * Represents a Sequence Parameter Set (SPS) 5 * 6 * Clause 7.4.2.2 7 */ 8var SPS = (function() { 9 function constructor() {}; 10 11 constructor.prototype.decode = function (stream) { 12 traceln("| + Sequence Parameter Set"); 13 this.profile_idc = stream.readBits(8); 14 traceln("| | profile_idc: " + this.profile_idc); 15 this.constrained_set0_flag = stream.readBit(); 16 traceln("| | constrained_set0_flag: " + this.constrained_set0_flag); 17 this.constrained_set1_flag = stream.readBit(); 18 traceln("| | constrained_set1_flag: " + this.constrained_set1_flag); 19 this.constrained_set2_flag = stream.readBit(); 20 traceln("| | constrained_set2_flag: " + this.constrained_set2_flag); 21 assert(stream.readBits(5) == 0); 22 this.level_idc = stream.readBits(8); 23 traceln("| | level_idc: " + this.level_idc); 24 assertRange(this.level_idc, 0, 51); 25 assert(mapLev2Idx[this.level_idc] != 255); 26 this.seq_parameter_set_id = stream.uev(); 27 traceln("| | seq_parameter_set_id: " + this.seq_parameter_set_id); 28 assertRange(this.seq_parameter_set_id, 0, 31); 29 this.log2_max_frame_num_minus4 = stream.uev(); 30 traceln("| | log2_max_frame_num_minus4: " + this.log2_max_frame_num_minus4); 31 assertRange(this.log2_max_frame_num_minus4, 0, 12); 32 this.pic_order_cnt_type = stream.uev(); 33 traceln("| | pic_order_cnt_type: " + this.pic_order_cnt_type); 34 if (this.pic_order_cnt_type == 0) { 35 this.log2_max_pic_order_cnt_lsb_minus4 = stream.uev(); 36 traceln("| | log2_max_pic_order_cnt_lsb_minus4: " + this.log2_max_pic_order_cnt_lsb_minus4); 37 } else if (this.pic_order_cnt_type == 1) { 38 this.delta_pic_order_always_zero_flag = stream.readBit(); 39 traceln("| | delta_pic_order_always_zero_flag: " + this.delta_pic_order_always_zero_flag); 40 this.offset_for_non_ref_pic = stream.sev32(); 41 traceln("| | offset_for_non_ref_pic: " + this.offset_for_non_ref_pic); 42 this.offset_for_top_to_bottom_field = stream.sev32(); 43 traceln("| | offset_for_top_to_bottom_field: " + this.offset_for_top_to_bottom_field); 44 this.num_ref_frames_in_pic_order_cnt_cycle = stream.uev(); 45 traceln("| | num_ref_frames_in_pic_order_cnt_cycle: " + this.num_ref_frames_in_pic_order_cnt_cycle); 46 this.offset_for_ref_frame = []; 47 for (var i = 0; i < this.num_ref_frames_in_pic_order_cnt_cycle; i++) { 48 offset_for_ref_frame[i] = stream.sev32(); 49 traceln("| | offset_for_ref_frame[ " + i + "]: " + this.offset_for_ref_frame[i]); 50 } 51 } 52 this.num_ref_frames = stream.uev(); 53 traceln("| | num_ref_frames: " + this.num_ref_frames); 54 assertRange(this.num_ref_frames, 0, 16); 55 this.gaps_in_frame_num_value_allowed_flag = stream.readBit(); 56 traceln("| | gaps_in_frame_num_value_allowed_flag: " + this.gaps_in_frame_num_value_allowed_flag); 57 this.pic_width_in_mbs_minus1 = stream.uev(); 58 traceln("| | pic_width_in_mbs_minus1: " + this.pic_width_in_mbs_minus1); 59 60 this.pic_height_in_map_units_minus1 = stream.uev(); 61 traceln("| | pic_height_in_map_units_minus1: " + this.pic_height_in_map_units_minus1); 62 this.frame_mbs_only_flag = stream.readBit(); 63 traceln("| | frame_mbs_only_flag: " + this.frame_mbs_only_flag); 64 this.mb_adaptive_frame_field_flag = 0; 65 if (!this.frame_mbs_only_flag) { 66 this.mb_adaptive_frame_field_flag = stream.readBit(); 67 traceln("| | mb_adaptive_frame_field_flag: " + this.mb_adaptive_frame_field_flag); 68 } 69 this.direct_8x8_inference_flag = stream.readBit(); 70 traceln("| | direct_8x8_inference_flag: " + this.direct_8x8_inference_flag); 71 this.frame_cropping_flag = stream.readBit(); 72 traceln("| | frame_cropping_flag: " + this.frame_cropping_flag); 73 this.frame_crop_left_offset = 0; 74 this.frame_crop_right_offset = 0; 75 this.frame_crop_top_offset = 0; 76 this.frame_crop_bottom_offset = 0; 77 if (this.frame_cropping_flag) { 78 this.frame_crop_left_offset = stream.uev(); 79 traceln("| | frame_crop_left_offset: " + this.frame_crop_left_offset); 80 this.frame_crop_right_offset = stream.uev(); 81 traceln("| | frame_crop_right_offset: " + this.frame_crop_right_offset); 82 this.frame_crop_top_offset = stream.uev(); 83 traceln("| | frame_crop_top_offset: " + this.frame_crop_top_offset); 84 this.frame_crop_bottom_offset = stream.uev(); 85 traceln("| | frame_crop_bottom_offset: " + this.frame_crop_bottom_offset); 86 } 87 this.vui_parameters_present_flag = stream.readBit(); 88 traceln("| | vui_parameters_present_flag: " + this.vui_parameters_present_flag); 89 if (this.vui_parameters_present_flag) { 90 unexpected(); 91 } 92 decoder.SequenceParameterSets[this.seq_parameter_set_id] = this; 93 }; 94 95 constructor.prototype.toString = function () { 96 return "SPS: " + getProperties(this, true); 97 }; 98 99 return constructor; 100})(); 101 102 103/** 104 * Represents a Picture Parameter Set (PPS) 105 * 106 * Clause 7.4.2.2 107 * 108 * Book 5.5, Parameter sets remain inactive, until they are activated when referenced in slice headers. Slice 109 * headers activate PPSs which in turn activate SPSs. 110 */ 111var PPS = (function() { 112 function constructor() { } 113 114 constructor.prototype.decode = function (stream) { 115 traceln("| + Picture Parameter Set"); 116 this.pic_parameter_set_id = stream.uev(); 117 traceln("| | pic_parameter_set_id: " + this.pic_parameter_set_id); 118 assertRange(this.pic_parameter_set_id, 0, 255); 119 120 /* Register Picture Parameter Set */ 121 decoder.PictureParameterSets[this.pic_parameter_set_id] = this; 122 123 this.seq_parameter_set_id = stream.uev(); 124 traceln("| | seq_parameter_set_id: " + this.seq_parameter_set_id); 125 assertRange(this.seq_parameter_set_id, 0, 31); 126 this.entropy_coding_mode_flag = stream.readBit(); 127 traceln("| | entropy_coding_mode_flag: " + this.entropy_coding_mode_flag); 128 129 /* Only CAVLC (entropy_coding_mode_flag == false) is supported. */ 130 if (this.entropy_coding_mode_flag) { 131 unexpected(); 132 } 133 this.pic_order_present_flag = stream.readBit(); 134 traceln("| | pic_order_present_flag: " + this.pic_order_present_flag); 135 this.num_slice_groups_minus1 = stream.uev(); 136 traceln("| | num_slice_groups_minus1: " + this.num_slice_groups_minus1); 137 if (this.num_slice_groups_minus1 > MAX_NUM_SLICE_GROUP - 1) { 138 unexpected(); 139 } 140 this.slice_group_change_rate_minus1 = 0; 141 if (this.num_slice_groups_minus1 > 0) { 142 this.slice_group_map_type = stream.uev(); 143 traceln("| | slice_group_map_type: " + this.slice_group_map_type); 144 if (this.slice_group_map_type == 0) { 145 this.run_length_minus1 = []; 146 for (var i = 0; i <= this.num_slice_groups_minus1; i++) { 147 this.run_length_minus1[i] = stream.uev(); 148 traceln("| | run_length_minus1[" + i + "]: " + this.run_length_minus1[i]); 149 } 150 } else if (this.slice_group_map_type == 2) { 151 this.top_left = []; 152 this.bottom_right = []; 153 for ( var i = 0; i < this.num_slice_groups_minus1; i++) { 154 this.top_left[i] = stream.uev(); 155 traceln("| | top_left[" + i + "]: " + this.top_left[i]); 156 this.bottom_right[i] = stream.uev(); 157 traceln("| | bottom_right[" + i + "]: " + this.bottom_right[i]); 158 } 159 } else if (this.slice_group_map_type == 3 160 || this.slice_group_map_type == 4 161 || this.slice_group_map_type == 5) { 162 163 this.slice_group_change_direction_flag = stream.readBit(); 164 traceln("| | slice_group_change_direction_flag: " + this.slice_group_change_direction_flag); 165 this.slice_group_change_rate_minus1 = stream.uev(); 166 traceln("| | slice_group_change_rate_minus1: " + this.slice_group_change_rate_minus1); 167 } else if (this.slice_group_map_type == 6) { 168 this.pic_size_in_map_units_minus1 = stream.uev(); 169 traceln("| | pic_size_in_map_units_minus1: " + this.pic_size_in_map_units_minus1); 170 /* ceil(log2(num_slice_groups_minus1+1)) bits */ 171 var numBits = 0; 172 var i = this.num_slice_groups_minus1; 173 while (i > 0) { 174 numBits++; 175 i >>>= 1; 176 } 177 178 var sps = decoder.SequenceParameterSets[this.seq_parameter_set_id]; 179 if (sps == null) { 180 unexpected(); 181 } 182 183 var picWidthInMbs = sps.pic_width_in_mbs_minus1 + 1; 184 var picHeightInMapUnits = sps.pic_height_in_map_units_minus1 + 1; 185 var picSizeInMapUnits = picWidthInMbs * picHeightInMapUnits; 186 187 /* information has to be consistent with the seq_param */ 188 if (this.pic_size_in_map_units_minus1 != picSizeInMapUnits - 1) { 189 unexpected(); 190 } 191 192 this.slice_group_id = []; 193 for (i = 0; i < picSizeInMapUnits; i++) { 194 this.slice_group_id[i] = stream.readBits(numBits); 195 traceln("| | slice_group_id[" + i + "]: " + this.slice_group_id[i]); 196 } 197 } 198 } 199 200 /* Number of reference pictures in listX. */ 201 this.num_ref_idx_l0_active_minus1 = stream.uev(); 202 traceln("| | num_ref_idx_l0_active_minus1: " + this.num_ref_idx_l0_active_minus1); 203 assertRange(this.num_ref_idx_l0_active_minus1, 0, 31); 204 this.num_ref_idx_l1_active_minus1 = stream.uev(); 205 traceln("| | num_ref_idx_l1_active_minus1: " + this.num_ref_idx_l1_active_minus1); 206 assertRange(this.num_ref_idx_l1_active_minus1, 0, 31); 207 208 this.weighted_pred_flag = stream.readBit(); 209 traceln("| | weighted_pred_flag: " + this.weighted_pred_flag); 210 this.weighted_bipred_idc = stream.readBits(2); 211 traceln("| | weighted_bipred_idc: " + this.weighted_bipred_idc); 212 assertRange(this.weighted_bipred_idc, 0, 3); 213 this.pic_init_qp_minus26 = stream.sev(); 214 traceln("| | pic_init_qp_minus26: " + this.pic_init_qp_minus26); 215 assertRange(this.pic_init_qp_minus26, -26, 25); 216 this.pic_init_qs_minus26 = stream.sev(); 217 traceln("| | pic_init_qs_minus26: " + this.pic_init_qs_minus26); 218 assertRange(this.pic_init_qs_minus26, -26, 25); 219 this.chroma_qp_index_offset = stream.sev(); 220 traceln("| | chroma_qp_index_offset: " + this.chroma_qp_index_offset); 221 assertRange(this.chroma_qp_index_offset, -12, 12); 222 this.pic_parameter_set_id = stream.readBits(3); 223 // traceln("| | pic_parameter_set_id: " + this.pic_parameter_set_id); 224 this.deblocking_filter_control_present_flag = this.pic_parameter_set_id >> 2; 225 this.constrained_intra_pred_flag = (this.pic_parameter_set_id >> 1) & 1; 226 this.redundant_pic_cnt_present_flag = this.pic_parameter_set_id & 1; 227 }; 228 229 constructor.prototype.toString = function () { 230 return "PPS: " + getProperties(this, true); 231 }; 232 233 return constructor; 234})();