| 81 | slice_header::~slice_header() {} |
| 82 | |
| 83 | void slice_header::parse(reader::SubByteReaderLogging &reader, |
| 84 | SPSMap & spsMap, |
| 85 | PPSMap & ppsMap, |
| 86 | NalType nal_unit_type, |
| 87 | unsigned nal_ref_idc, |
| 88 | std::shared_ptr<slice_header> prev_pic) |
| 89 | { |
| 90 | SubByteReaderLoggingSubLevel subLevel(reader, "slice_header()"); |
| 91 | |
| 92 | this->first_mb_in_slice = reader.readUEV("first_mb_in_slice"); |
| 93 | this->slice_type_id = |
| 94 | reader.readUEV("slice_type_id", Options().withMeaningMap(sliceTypeCoding.getMeaningMap())); |
| 95 | this->slice_type = sliceTypeCoding.getValue(this->slice_type_id % 5); |
| 96 | this->slice_type_fixed = this->slice_type_id > 4; |
| 97 | this->IdrPicFlag = (nal_unit_type == NalType::CODED_SLICE_IDR); |
| 98 | |
| 99 | this->pic_parameter_set_id = reader.readUEV("pic_parameter_set_id"); |
| 100 | |
| 101 | if (ppsMap.count(this->pic_parameter_set_id) == 0) |
| 102 | throw std::logic_error("The signaled PPS was not found in the bitstream."); |
| 103 | auto refPPS = ppsMap.at(this->pic_parameter_set_id); |
| 104 | |
| 105 | if (spsMap.count(refPPS->seq_parameter_set_id) == 0) |
| 106 | throw std::logic_error("The signaled SPS was not found in the bitstream."); |
| 107 | auto refSPS = spsMap.at(refPPS->seq_parameter_set_id); |
| 108 | |
| 109 | if (refSPS->seqParameterSetData.separate_colour_plane_flag) |
| 110 | { |
| 111 | this->colour_plane_id = reader.readBits("colour_plane_id", 2); |
| 112 | } |
| 113 | int nrBits = refSPS->seqParameterSetData.log2_max_frame_num_minus4 + 4; |
| 114 | this->frame_num = reader.readBits("frame_num", nrBits); |
| 115 | if (!refSPS->seqParameterSetData.frame_mbs_only_flag) |
| 116 | { |
| 117 | this->field_pic_flag = reader.readFlag("field_pic_flag"); |
| 118 | if (this->field_pic_flag) |
| 119 | { |
| 120 | this->bottom_field_flag = reader.readFlag("bottom_field_flag"); |
| 121 | // Update |
| 122 | refSPS->seqParameterSetData.MbaffFrameFlag = |
| 123 | (refSPS->seqParameterSetData.mb_adaptive_frame_field_flag && !this->field_pic_flag); |
| 124 | refSPS->seqParameterSetData.PicHeightInMbs = refSPS->seqParameterSetData.FrameHeightInMbs / 2; |
| 125 | refSPS->seqParameterSetData.PicSizeInMbs = |
| 126 | refSPS->seqParameterSetData.PicWidthInMbs * refSPS->seqParameterSetData.PicHeightInMbs; |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | // Since the MbaffFrameFlag flag is now finally known, we can check the range of first_mb_in_slice |
| 131 | if (refSPS->seqParameterSetData.MbaffFrameFlag == 0) |
| 132 | { |
| 133 | this->firstMacroblockAddressInSlice = this->first_mb_in_slice; |
| 134 | if (this->first_mb_in_slice > refSPS->seqParameterSetData.PicSizeInMbs - 1) |
| 135 | throw std::logic_error( |
| 136 | "first_mb_in_slice shall be in the range of 0 to PicSizeInMbs - 1, inclusive"); |
| 137 | } |
| 138 | else |
| 139 | { |
| 140 | this->firstMacroblockAddressInSlice = this->first_mb_in_slice * 2; |
nothing calls this directly
no test coverage detected