1 /* 2 Copyright (c) 2011 Stanislav Vitvitskiy 3 4 Permission is hereby granted, free of charge, to any person obtaining a copy of this 5 software and associated documentation files (the "Software"), to deal in the Software 6 without restriction, including without limitation the rights to use, copy, modify, 7 merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 8 permit persons to whom the Software is furnished to do so, subject to the following 9 conditions: 10 11 The above copyright notice and this permission notice shall be included in all copies or 12 substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 15 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 16 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 17 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 18 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 19 OR OTHER DEALINGS IN THE SOFTWARE. 20 */ 21 package com.googlecode.mp4parser.h264.model; 22 23 import com.googlecode.mp4parser.h264.read.CAVLCReader; 24 import com.googlecode.mp4parser.h264.write.CAVLCWriter; 25 26 import java.io.IOException; 27 import java.io.InputStream; 28 import java.io.OutputStream; 29 30 /** 31 * Sequence Parameter Set structure of h264 bitstream 32 * <p/> 33 * capable to serialize and deserialize with CAVLC bitstream 34 * 35 * @author Stanislav Vitvitskiy 36 */ 37 public class SeqParameterSet extends BitstreamElement { 38 public int pic_order_cnt_type; 39 public boolean field_pic_flag; 40 public boolean delta_pic_order_always_zero_flag; 41 public boolean weighted_pred_flag; 42 public int weighted_bipred_idc; 43 public boolean entropy_coding_mode_flag; 44 public boolean mb_adaptive_frame_field_flag; 45 public boolean direct_8x8_inference_flag; 46 public ChromaFormat chroma_format_idc; 47 public int log2_max_frame_num_minus4; 48 public int log2_max_pic_order_cnt_lsb_minus4; 49 public int pic_height_in_map_units_minus1; 50 public int pic_width_in_mbs_minus1; 51 public int bit_depth_luma_minus8; 52 public int bit_depth_chroma_minus8; 53 public boolean qpprime_y_zero_transform_bypass_flag; 54 public int profile_idc; 55 public boolean constraint_set_0_flag; 56 public boolean constraint_set_1_flag; 57 public boolean constraint_set_2_flag; 58 public boolean constraint_set_3_flag; 59 public int level_idc; 60 public int seq_parameter_set_id; 61 public boolean residual_color_transform_flag; 62 public int offset_for_non_ref_pic; 63 public int offset_for_top_to_bottom_field; 64 public int num_ref_frames; 65 public boolean gaps_in_frame_num_value_allowed_flag; 66 public boolean frame_mbs_only_flag; 67 public boolean frame_cropping_flag; 68 public int frame_crop_left_offset; 69 public int frame_crop_right_offset; 70 public int frame_crop_top_offset; 71 public int frame_crop_bottom_offset; 72 public int[] offsetForRefFrame; 73 public VUIParameters vuiParams; 74 public ScalingMatrix scalingMatrix; 75 public int num_ref_frames_in_pic_order_cnt_cycle; 76 read(InputStream is)77 public static SeqParameterSet read(InputStream is) throws IOException { 78 CAVLCReader reader = new CAVLCReader(is); 79 SeqParameterSet sps = new SeqParameterSet(); 80 81 sps.profile_idc = (int) reader.readNBit(8, "SPS: profile_idc"); 82 sps.constraint_set_0_flag = reader 83 .readBool("SPS: constraint_set_0_flag"); 84 sps.constraint_set_1_flag = reader 85 .readBool("SPS: constraint_set_1_flag"); 86 sps.constraint_set_2_flag = reader 87 .readBool("SPS: constraint_set_2_flag"); 88 sps.constraint_set_3_flag = reader 89 .readBool("SPS: constraint_set_3_flag"); 90 reader.readNBit(4, "SPS: reserved_zero_4bits"); 91 sps.level_idc = (int) reader.readNBit(8, "SPS: level_idc"); 92 sps.seq_parameter_set_id = reader.readUE("SPS: seq_parameter_set_id"); 93 94 if (sps.profile_idc == 100 || sps.profile_idc == 110 95 || sps.profile_idc == 122 || sps.profile_idc == 144) { 96 sps.chroma_format_idc = ChromaFormat.fromId(reader 97 .readUE("SPS: chroma_format_idc")); 98 if (sps.chroma_format_idc == ChromaFormat.YUV_444) { 99 sps.residual_color_transform_flag = reader 100 .readBool("SPS: residual_color_transform_flag"); 101 } 102 sps.bit_depth_luma_minus8 = reader 103 .readUE("SPS: bit_depth_luma_minus8"); 104 sps.bit_depth_chroma_minus8 = reader 105 .readUE("SPS: bit_depth_chroma_minus8"); 106 sps.qpprime_y_zero_transform_bypass_flag = reader 107 .readBool("SPS: qpprime_y_zero_transform_bypass_flag"); 108 boolean seqScalingMatrixPresent = reader 109 .readBool("SPS: seq_scaling_matrix_present_lag"); 110 if (seqScalingMatrixPresent) { 111 readScalingListMatrix(reader, sps); 112 } 113 } else { 114 sps.chroma_format_idc = ChromaFormat.YUV_420; 115 } 116 sps.log2_max_frame_num_minus4 = reader 117 .readUE("SPS: log2_max_frame_num_minus4"); 118 sps.pic_order_cnt_type = reader.readUE("SPS: pic_order_cnt_type"); 119 if (sps.pic_order_cnt_type == 0) { 120 sps.log2_max_pic_order_cnt_lsb_minus4 = reader 121 .readUE("SPS: log2_max_pic_order_cnt_lsb_minus4"); 122 } else if (sps.pic_order_cnt_type == 1) { 123 sps.delta_pic_order_always_zero_flag = reader 124 .readBool("SPS: delta_pic_order_always_zero_flag"); 125 sps.offset_for_non_ref_pic = reader 126 .readSE("SPS: offset_for_non_ref_pic"); 127 sps.offset_for_top_to_bottom_field = reader 128 .readSE("SPS: offset_for_top_to_bottom_field"); 129 sps.num_ref_frames_in_pic_order_cnt_cycle = reader 130 .readUE("SPS: num_ref_frames_in_pic_order_cnt_cycle"); 131 sps.offsetForRefFrame = new int[sps.num_ref_frames_in_pic_order_cnt_cycle]; 132 for (int i = 0; i < sps.num_ref_frames_in_pic_order_cnt_cycle; i++) { 133 sps.offsetForRefFrame[i] = reader 134 .readSE("SPS: offsetForRefFrame [" + i + "]"); 135 } 136 } 137 sps.num_ref_frames = reader.readUE("SPS: num_ref_frames"); 138 sps.gaps_in_frame_num_value_allowed_flag = reader 139 .readBool("SPS: gaps_in_frame_num_value_allowed_flag"); 140 sps.pic_width_in_mbs_minus1 = reader 141 .readUE("SPS: pic_width_in_mbs_minus1"); 142 sps.pic_height_in_map_units_minus1 = reader 143 .readUE("SPS: pic_height_in_map_units_minus1"); 144 sps.frame_mbs_only_flag = reader.readBool("SPS: frame_mbs_only_flag"); 145 if (!sps.frame_mbs_only_flag) { 146 sps.mb_adaptive_frame_field_flag = reader 147 .readBool("SPS: mb_adaptive_frame_field_flag"); 148 } 149 sps.direct_8x8_inference_flag = reader 150 .readBool("SPS: direct_8x8_inference_flag"); 151 sps.frame_cropping_flag = reader.readBool("SPS: frame_cropping_flag"); 152 if (sps.frame_cropping_flag) { 153 sps.frame_crop_left_offset = reader 154 .readUE("SPS: frame_crop_left_offset"); 155 sps.frame_crop_right_offset = reader 156 .readUE("SPS: frame_crop_right_offset"); 157 sps.frame_crop_top_offset = reader 158 .readUE("SPS: frame_crop_top_offset"); 159 sps.frame_crop_bottom_offset = reader 160 .readUE("SPS: frame_crop_bottom_offset"); 161 } 162 boolean vui_parameters_present_flag = reader 163 .readBool("SPS: vui_parameters_present_flag"); 164 if (vui_parameters_present_flag) 165 sps.vuiParams = ReadVUIParameters(reader); 166 167 reader.readTrailingBits(); 168 169 return sps; 170 } 171 readScalingListMatrix(CAVLCReader reader, SeqParameterSet sps)172 private static void readScalingListMatrix(CAVLCReader reader, 173 SeqParameterSet sps) throws IOException { 174 sps.scalingMatrix = new ScalingMatrix(); 175 for (int i = 0; i < 8; i++) { 176 boolean seqScalingListPresentFlag = reader 177 .readBool("SPS: seqScalingListPresentFlag"); 178 if (seqScalingListPresentFlag) { 179 sps.scalingMatrix.ScalingList4x4 = new ScalingList[8]; 180 sps.scalingMatrix.ScalingList8x8 = new ScalingList[8]; 181 if (i < 6) { 182 sps.scalingMatrix.ScalingList4x4[i] = ScalingList.read( 183 reader, 16); 184 } else { 185 sps.scalingMatrix.ScalingList8x8[i - 6] = ScalingList.read( 186 reader, 64); 187 } 188 } 189 } 190 } 191 ReadVUIParameters(CAVLCReader reader)192 private static VUIParameters ReadVUIParameters(CAVLCReader reader) 193 throws IOException { 194 VUIParameters vuip = new VUIParameters(); 195 vuip.aspect_ratio_info_present_flag = reader 196 .readBool("VUI: aspect_ratio_info_present_flag"); 197 if (vuip.aspect_ratio_info_present_flag) { 198 vuip.aspect_ratio = AspectRatio.fromValue((int) reader.readNBit(8, 199 "VUI: aspect_ratio")); 200 if (vuip.aspect_ratio == AspectRatio.Extended_SAR) { 201 vuip.sar_width = (int) reader.readNBit(16, "VUI: sar_width"); 202 vuip.sar_height = (int) reader.readNBit(16, "VUI: sar_height"); 203 } 204 } 205 vuip.overscan_info_present_flag = reader 206 .readBool("VUI: overscan_info_present_flag"); 207 if (vuip.overscan_info_present_flag) { 208 vuip.overscan_appropriate_flag = reader 209 .readBool("VUI: overscan_appropriate_flag"); 210 } 211 vuip.video_signal_type_present_flag = reader 212 .readBool("VUI: video_signal_type_present_flag"); 213 if (vuip.video_signal_type_present_flag) { 214 vuip.video_format = (int) reader.readNBit(3, "VUI: video_format"); 215 vuip.video_full_range_flag = reader 216 .readBool("VUI: video_full_range_flag"); 217 vuip.colour_description_present_flag = reader 218 .readBool("VUI: colour_description_present_flag"); 219 if (vuip.colour_description_present_flag) { 220 vuip.colour_primaries = (int) reader.readNBit(8, 221 "VUI: colour_primaries"); 222 vuip.transfer_characteristics = (int) reader.readNBit(8, 223 "VUI: transfer_characteristics"); 224 vuip.matrix_coefficients = (int) reader.readNBit(8, 225 "VUI: matrix_coefficients"); 226 } 227 } 228 vuip.chroma_loc_info_present_flag = reader 229 .readBool("VUI: chroma_loc_info_present_flag"); 230 if (vuip.chroma_loc_info_present_flag) { 231 vuip.chroma_sample_loc_type_top_field = reader 232 .readUE("VUI chroma_sample_loc_type_top_field"); 233 vuip.chroma_sample_loc_type_bottom_field = reader 234 .readUE("VUI chroma_sample_loc_type_bottom_field"); 235 } 236 vuip.timing_info_present_flag = reader 237 .readBool("VUI: timing_info_present_flag"); 238 if (vuip.timing_info_present_flag) { 239 vuip.num_units_in_tick = (int) reader.readNBit(32, 240 "VUI: num_units_in_tick"); 241 vuip.time_scale = (int) reader.readNBit(32, "VUI: time_scale"); 242 vuip.fixed_frame_rate_flag = reader 243 .readBool("VUI: fixed_frame_rate_flag"); 244 } 245 boolean nal_hrd_parameters_present_flag = reader 246 .readBool("VUI: nal_hrd_parameters_present_flag"); 247 if (nal_hrd_parameters_present_flag) 248 vuip.nalHRDParams = readHRDParameters(reader); 249 boolean vcl_hrd_parameters_present_flag = reader 250 .readBool("VUI: vcl_hrd_parameters_present_flag"); 251 if (vcl_hrd_parameters_present_flag) 252 vuip.vclHRDParams = readHRDParameters(reader); 253 if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) { 254 vuip.low_delay_hrd_flag = reader 255 .readBool("VUI: low_delay_hrd_flag"); 256 } 257 vuip.pic_struct_present_flag = reader 258 .readBool("VUI: pic_struct_present_flag"); 259 boolean bitstream_restriction_flag = reader 260 .readBool("VUI: bitstream_restriction_flag"); 261 if (bitstream_restriction_flag) { 262 vuip.bitstreamRestriction = new VUIParameters.BitstreamRestriction(); 263 vuip.bitstreamRestriction.motion_vectors_over_pic_boundaries_flag = reader 264 .readBool("VUI: motion_vectors_over_pic_boundaries_flag"); 265 vuip.bitstreamRestriction.max_bytes_per_pic_denom = reader 266 .readUE("VUI max_bytes_per_pic_denom"); 267 vuip.bitstreamRestriction.max_bits_per_mb_denom = reader 268 .readUE("VUI max_bits_per_mb_denom"); 269 vuip.bitstreamRestriction.log2_max_mv_length_horizontal = reader 270 .readUE("VUI log2_max_mv_length_horizontal"); 271 vuip.bitstreamRestriction.log2_max_mv_length_vertical = reader 272 .readUE("VUI log2_max_mv_length_vertical"); 273 vuip.bitstreamRestriction.num_reorder_frames = reader 274 .readUE("VUI num_reorder_frames"); 275 vuip.bitstreamRestriction.max_dec_frame_buffering = reader 276 .readUE("VUI max_dec_frame_buffering"); 277 } 278 279 return vuip; 280 } 281 readHRDParameters(CAVLCReader reader)282 private static HRDParameters readHRDParameters(CAVLCReader reader) 283 throws IOException { 284 HRDParameters hrd = new HRDParameters(); 285 hrd.cpb_cnt_minus1 = reader.readUE("SPS: cpb_cnt_minus1"); 286 hrd.bit_rate_scale = (int) reader.readNBit(4, "HRD: bit_rate_scale"); 287 hrd.cpb_size_scale = (int) reader.readNBit(4, "HRD: cpb_size_scale"); 288 hrd.bit_rate_value_minus1 = new int[hrd.cpb_cnt_minus1 + 1]; 289 hrd.cpb_size_value_minus1 = new int[hrd.cpb_cnt_minus1 + 1]; 290 hrd.cbr_flag = new boolean[hrd.cpb_cnt_minus1 + 1]; 291 292 for (int SchedSelIdx = 0; SchedSelIdx <= hrd.cpb_cnt_minus1; SchedSelIdx++) { 293 hrd.bit_rate_value_minus1[SchedSelIdx] = reader 294 .readUE("HRD: bit_rate_value_minus1"); 295 hrd.cpb_size_value_minus1[SchedSelIdx] = reader 296 .readUE("HRD: cpb_size_value_minus1"); 297 hrd.cbr_flag[SchedSelIdx] = reader.readBool("HRD: cbr_flag"); 298 } 299 hrd.initial_cpb_removal_delay_length_minus1 = (int) reader.readNBit(5, 300 "HRD: initial_cpb_removal_delay_length_minus1"); 301 hrd.cpb_removal_delay_length_minus1 = (int) reader.readNBit(5, 302 "HRD: cpb_removal_delay_length_minus1"); 303 hrd.dpb_output_delay_length_minus1 = (int) reader.readNBit(5, 304 "HRD: dpb_output_delay_length_minus1"); 305 hrd.time_offset_length = (int) reader.readNBit(5, 306 "HRD: time_offset_length"); 307 return hrd; 308 } 309 write(OutputStream out)310 public void write(OutputStream out) throws IOException { 311 CAVLCWriter writer = new CAVLCWriter(out); 312 313 writer.writeNBit(profile_idc, 8, "SPS: profile_idc"); 314 writer.writeBool(constraint_set_0_flag, "SPS: constraint_set_0_flag"); 315 writer.writeBool(constraint_set_1_flag, "SPS: constraint_set_1_flag"); 316 writer.writeBool(constraint_set_2_flag, "SPS: constraint_set_2_flag"); 317 writer.writeBool(constraint_set_3_flag, "SPS: constraint_set_3_flag"); 318 writer.writeNBit(0, 4, "SPS: reserved"); 319 writer.writeNBit(level_idc, 8, "SPS: level_idc"); 320 writer.writeUE(seq_parameter_set_id, "SPS: seq_parameter_set_id"); 321 322 if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 323 || profile_idc == 144) { 324 writer.writeUE(chroma_format_idc.getId(), "SPS: chroma_format_idc"); 325 if (chroma_format_idc == ChromaFormat.YUV_444) { 326 writer.writeBool(residual_color_transform_flag, 327 "SPS: residual_color_transform_flag"); 328 } 329 writer.writeUE(bit_depth_luma_minus8, "SPS: "); 330 writer.writeUE(bit_depth_chroma_minus8, "SPS: "); 331 writer.writeBool(qpprime_y_zero_transform_bypass_flag, 332 "SPS: qpprime_y_zero_transform_bypass_flag"); 333 writer.writeBool(scalingMatrix != null, "SPS: "); 334 if (scalingMatrix != null) { 335 for (int i = 0; i < 8; i++) { 336 if (i < 6) { 337 writer.writeBool( 338 scalingMatrix.ScalingList4x4[i] != null, 339 "SPS: "); 340 if (scalingMatrix.ScalingList4x4[i] != null) { 341 scalingMatrix.ScalingList4x4[i].write(writer); 342 } 343 } else { 344 writer.writeBool( 345 scalingMatrix.ScalingList8x8[i - 6] != null, 346 "SPS: "); 347 if (scalingMatrix.ScalingList8x8[i - 6] != null) { 348 scalingMatrix.ScalingList8x8[i - 6].write(writer); 349 } 350 } 351 } 352 } 353 } 354 writer.writeUE(log2_max_frame_num_minus4, 355 "SPS: log2_max_frame_num_minus4"); 356 writer.writeUE(pic_order_cnt_type, "SPS: pic_order_cnt_type"); 357 if (pic_order_cnt_type == 0) { 358 writer.writeUE(log2_max_pic_order_cnt_lsb_minus4, 359 "SPS: log2_max_pic_order_cnt_lsb_minus4"); 360 } else if (pic_order_cnt_type == 1) { 361 writer.writeBool(delta_pic_order_always_zero_flag, 362 "SPS: delta_pic_order_always_zero_flag"); 363 writer.writeSE(offset_for_non_ref_pic, 364 "SPS: offset_for_non_ref_pic"); 365 writer.writeSE(offset_for_top_to_bottom_field, 366 "SPS: offset_for_top_to_bottom_field"); 367 writer.writeUE(offsetForRefFrame.length, "SPS: "); 368 for (int i = 0; i < offsetForRefFrame.length; i++) 369 writer.writeSE(offsetForRefFrame[i], "SPS: "); 370 } 371 writer.writeUE(num_ref_frames, "SPS: num_ref_frames"); 372 writer.writeBool(gaps_in_frame_num_value_allowed_flag, 373 "SPS: gaps_in_frame_num_value_allowed_flag"); 374 writer.writeUE(pic_width_in_mbs_minus1, "SPS: pic_width_in_mbs_minus1"); 375 writer.writeUE(pic_height_in_map_units_minus1, 376 "SPS: pic_height_in_map_units_minus1"); 377 writer.writeBool(frame_mbs_only_flag, "SPS: frame_mbs_only_flag"); 378 if (!frame_mbs_only_flag) { 379 writer.writeBool(mb_adaptive_frame_field_flag, 380 "SPS: mb_adaptive_frame_field_flag"); 381 } 382 writer.writeBool(direct_8x8_inference_flag, 383 "SPS: direct_8x8_inference_flag"); 384 writer.writeBool(frame_cropping_flag, "SPS: frame_cropping_flag"); 385 if (frame_cropping_flag) { 386 writer.writeUE(frame_crop_left_offset, 387 "SPS: frame_crop_left_offset"); 388 writer.writeUE(frame_crop_right_offset, 389 "SPS: frame_crop_right_offset"); 390 writer.writeUE(frame_crop_top_offset, "SPS: frame_crop_top_offset"); 391 writer.writeUE(frame_crop_bottom_offset, 392 "SPS: frame_crop_bottom_offset"); 393 } 394 writer.writeBool(vuiParams != null, "SPS: "); 395 if (vuiParams != null) 396 writeVUIParameters(vuiParams, writer); 397 398 writer.writeTrailingBits(); 399 } 400 writeVUIParameters(VUIParameters vuip, CAVLCWriter writer)401 private void writeVUIParameters(VUIParameters vuip, CAVLCWriter writer) 402 throws IOException { 403 writer.writeBool(vuip.aspect_ratio_info_present_flag, 404 "VUI: aspect_ratio_info_present_flag"); 405 if (vuip.aspect_ratio_info_present_flag) { 406 writer.writeNBit(vuip.aspect_ratio.getValue(), 8, 407 "VUI: aspect_ratio"); 408 if (vuip.aspect_ratio == AspectRatio.Extended_SAR) { 409 writer.writeNBit(vuip.sar_width, 16, "VUI: sar_width"); 410 writer.writeNBit(vuip.sar_height, 16, "VUI: sar_height"); 411 } 412 } 413 writer.writeBool(vuip.overscan_info_present_flag, 414 "VUI: overscan_info_present_flag"); 415 if (vuip.overscan_info_present_flag) { 416 writer.writeBool(vuip.overscan_appropriate_flag, 417 "VUI: overscan_appropriate_flag"); 418 } 419 writer.writeBool(vuip.video_signal_type_present_flag, 420 "VUI: video_signal_type_present_flag"); 421 if (vuip.video_signal_type_present_flag) { 422 writer.writeNBit(vuip.video_format, 3, "VUI: video_format"); 423 writer.writeBool(vuip.video_full_range_flag, 424 "VUI: video_full_range_flag"); 425 writer.writeBool(vuip.colour_description_present_flag, 426 "VUI: colour_description_present_flag"); 427 if (vuip.colour_description_present_flag) { 428 writer.writeNBit(vuip.colour_primaries, 8, 429 "VUI: colour_primaries"); 430 writer.writeNBit(vuip.transfer_characteristics, 8, 431 "VUI: transfer_characteristics"); 432 writer.writeNBit(vuip.matrix_coefficients, 8, 433 "VUI: matrix_coefficients"); 434 } 435 } 436 writer.writeBool(vuip.chroma_loc_info_present_flag, 437 "VUI: chroma_loc_info_present_flag"); 438 if (vuip.chroma_loc_info_present_flag) { 439 writer.writeUE(vuip.chroma_sample_loc_type_top_field, 440 "VUI: chroma_sample_loc_type_top_field"); 441 writer.writeUE(vuip.chroma_sample_loc_type_bottom_field, 442 "VUI: chroma_sample_loc_type_bottom_field"); 443 } 444 writer.writeBool(vuip.timing_info_present_flag, 445 "VUI: timing_info_present_flag"); 446 if (vuip.timing_info_present_flag) { 447 writer.writeNBit(vuip.num_units_in_tick, 32, 448 "VUI: num_units_in_tick"); 449 writer.writeNBit(vuip.time_scale, 32, "VUI: time_scale"); 450 writer.writeBool(vuip.fixed_frame_rate_flag, 451 "VUI: fixed_frame_rate_flag"); 452 } 453 writer.writeBool(vuip.nalHRDParams != null, "VUI: "); 454 if (vuip.nalHRDParams != null) { 455 writeHRDParameters(vuip.nalHRDParams, writer); 456 } 457 writer.writeBool(vuip.vclHRDParams != null, "VUI: "); 458 if (vuip.vclHRDParams != null) { 459 writeHRDParameters(vuip.vclHRDParams, writer); 460 } 461 462 if (vuip.nalHRDParams != null || vuip.vclHRDParams != null) { 463 writer 464 .writeBool(vuip.low_delay_hrd_flag, 465 "VUI: low_delay_hrd_flag"); 466 } 467 writer.writeBool(vuip.pic_struct_present_flag, 468 "VUI: pic_struct_present_flag"); 469 writer.writeBool(vuip.bitstreamRestriction != null, "VUI: "); 470 if (vuip.bitstreamRestriction != null) { 471 writer 472 .writeBool( 473 vuip.bitstreamRestriction.motion_vectors_over_pic_boundaries_flag, 474 "VUI: motion_vectors_over_pic_boundaries_flag"); 475 writer.writeUE(vuip.bitstreamRestriction.max_bytes_per_pic_denom, 476 "VUI: max_bytes_per_pic_denom"); 477 writer.writeUE(vuip.bitstreamRestriction.max_bits_per_mb_denom, 478 "VUI: max_bits_per_mb_denom"); 479 writer.writeUE( 480 vuip.bitstreamRestriction.log2_max_mv_length_horizontal, 481 "VUI: log2_max_mv_length_horizontal"); 482 writer.writeUE( 483 vuip.bitstreamRestriction.log2_max_mv_length_vertical, 484 "VUI: log2_max_mv_length_vertical"); 485 writer.writeUE(vuip.bitstreamRestriction.num_reorder_frames, 486 "VUI: num_reorder_frames"); 487 writer.writeUE(vuip.bitstreamRestriction.max_dec_frame_buffering, 488 "VUI: max_dec_frame_buffering"); 489 } 490 491 } 492 writeHRDParameters(HRDParameters hrd, CAVLCWriter writer)493 private void writeHRDParameters(HRDParameters hrd, CAVLCWriter writer) 494 throws IOException { 495 writer.writeUE(hrd.cpb_cnt_minus1, "HRD: cpb_cnt_minus1"); 496 writer.writeNBit(hrd.bit_rate_scale, 4, "HRD: bit_rate_scale"); 497 writer.writeNBit(hrd.cpb_size_scale, 4, "HRD: cpb_size_scale"); 498 499 for (int SchedSelIdx = 0; SchedSelIdx <= hrd.cpb_cnt_minus1; SchedSelIdx++) { 500 writer.writeUE(hrd.bit_rate_value_minus1[SchedSelIdx], "HRD: "); 501 writer.writeUE(hrd.cpb_size_value_minus1[SchedSelIdx], "HRD: "); 502 writer.writeBool(hrd.cbr_flag[SchedSelIdx], "HRD: "); 503 } 504 writer.writeNBit(hrd.initial_cpb_removal_delay_length_minus1, 5, 505 "HRD: initial_cpb_removal_delay_length_minus1"); 506 writer.writeNBit(hrd.cpb_removal_delay_length_minus1, 5, 507 "HRD: cpb_removal_delay_length_minus1"); 508 writer.writeNBit(hrd.dpb_output_delay_length_minus1, 5, 509 "HRD: dpb_output_delay_length_minus1"); 510 writer.writeNBit(hrd.time_offset_length, 5, "HRD: time_offset_length"); 511 } 512 513 @Override toString()514 public String toString() { 515 return "SeqParameterSet{ " + 516 "\n pic_order_cnt_type=" + pic_order_cnt_type + 517 ", \n field_pic_flag=" + field_pic_flag + 518 ", \n delta_pic_order_always_zero_flag=" + delta_pic_order_always_zero_flag + 519 ", \n weighted_pred_flag=" + weighted_pred_flag + 520 ", \n weighted_bipred_idc=" + weighted_bipred_idc + 521 ", \n entropy_coding_mode_flag=" + entropy_coding_mode_flag + 522 ", \n mb_adaptive_frame_field_flag=" + mb_adaptive_frame_field_flag + 523 ", \n direct_8x8_inference_flag=" + direct_8x8_inference_flag + 524 ", \n chroma_format_idc=" + chroma_format_idc + 525 ", \n log2_max_frame_num_minus4=" + log2_max_frame_num_minus4 + 526 ", \n log2_max_pic_order_cnt_lsb_minus4=" + log2_max_pic_order_cnt_lsb_minus4 + 527 ", \n pic_height_in_map_units_minus1=" + pic_height_in_map_units_minus1 + 528 ", \n pic_width_in_mbs_minus1=" + pic_width_in_mbs_minus1 + 529 ", \n bit_depth_luma_minus8=" + bit_depth_luma_minus8 + 530 ", \n bit_depth_chroma_minus8=" + bit_depth_chroma_minus8 + 531 ", \n qpprime_y_zero_transform_bypass_flag=" + qpprime_y_zero_transform_bypass_flag + 532 ", \n profile_idc=" + profile_idc + 533 ", \n constraint_set_0_flag=" + constraint_set_0_flag + 534 ", \n constraint_set_1_flag=" + constraint_set_1_flag + 535 ", \n constraint_set_2_flag=" + constraint_set_2_flag + 536 ", \n constraint_set_3_flag=" + constraint_set_3_flag + 537 ", \n level_idc=" + level_idc + 538 ", \n seq_parameter_set_id=" + seq_parameter_set_id + 539 ", \n residual_color_transform_flag=" + residual_color_transform_flag + 540 ", \n offset_for_non_ref_pic=" + offset_for_non_ref_pic + 541 ", \n offset_for_top_to_bottom_field=" + offset_for_top_to_bottom_field + 542 ", \n num_ref_frames=" + num_ref_frames + 543 ", \n gaps_in_frame_num_value_allowed_flag=" + gaps_in_frame_num_value_allowed_flag + 544 ", \n frame_mbs_only_flag=" + frame_mbs_only_flag + 545 ", \n frame_cropping_flag=" + frame_cropping_flag + 546 ", \n frame_crop_left_offset=" + frame_crop_left_offset + 547 ", \n frame_crop_right_offset=" + frame_crop_right_offset + 548 ", \n frame_crop_top_offset=" + frame_crop_top_offset + 549 ", \n frame_crop_bottom_offset=" + frame_crop_bottom_offset + 550 ", \n offsetForRefFrame=" + offsetForRefFrame + 551 ", \n vuiParams=" + vuiParams + 552 ", \n scalingMatrix=" + scalingMatrix + 553 ", \n num_ref_frames_in_pic_order_cnt_cycle=" + num_ref_frames_in_pic_order_cnt_cycle + 554 '}'; 555 } 556 }