• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }