private static void DecodePictureOrderCount(INalUnitReader reader, ISequenceStateBuilder builder) { uint pictureOrderCountType = reader.GetExpGolombCoded(Attribute.PictureOrderCountType, 2); // pic_order_cnt_type builder.PictureOrderCountType = pictureOrderCountType; switch (pictureOrderCountType) { case 0: builder.Log2MaxPicOrderCntLsbMinus4 = reader.GetExpGolombCoded(Attribute.Log2MaxPictureOrderCountLsbMinus4, 12); // log2_max_pic_order_cnt_lsb_minus4us4 break; case 1: builder.DeltaPicOrderAlwaysZeroFlag = reader.GetBit(); // delta_pic_order_always_zero_flag reader.GetSignedExpGolombCoded(); // offset_for_non_ref_pic reader.GetSignedExpGolombCoded(); // offset_for_top_to_bottom_field // num_ref_frames_in_pic_order_cnt_cycle uint numRefFramesInPicOrderCntCycle = reader.GetExpGolombCoded(Attribute.NumRefFramesInPicOrderCountCycle, 255); for (uint i = 0; i < numRefFramesInPicOrderCntCycle; i++) { reader.GetSignedExpGolombCoded(); // offset_for_ref_frame[i] } break; case 2: break; } }
private static void GetHrdParameters(INalUnitReader reader, IState resultState) { uint cpbCntMinus1 = reader.GetExpGolombCoded(); // cpb_cnt_minus1 reader.GetBits(4); // bit_rate_scale reader.GetBits(4); // cpb_size_scale // for (SchedSelIdx = 0; SchedSelIdx <= cpb_cnt_minus1; SchedSelIdx++) for (int schedSelIdx = 0; schedSelIdx <= cpbCntMinus1; schedSelIdx++) { if (!reader.HasMoreRbspData()) { resultState.Invalidate(); return; } reader.GetExpGolombCoded(); // bit_rate_value_minus1[SchedSelIdx] reader.GetExpGolombCoded(); // cpb_size_value_minus1[SchedSelIdx] reader.GetBit(); // cbr_flag[SchedSelIdx] } reader.GetBits(5); // initial_cpb_removal_delay_length_minus1 reader.GetBits(5); // cpb_removal_delay_length_minus1 reader.GetBits(5); // dpb_output_delay_length_minus1 reader.GetBits(5); // time_offset_length }
private static long GetAbsoluteOffset(INalUnitReader reader) { if (reader.Position == 0) { return(reader.GetDataPacket(reader.Position, 1).StartOffset); } return(reader.GetDataPacket(reader.Position - 1, 1).EndOffset); }
private void ParseSliceGroupMap(INalUnitReader reader, IState resultState, IPictureStateBuilder builder, uint sliceGroupCount) { var sliceGroupMapType = (SliceGroupMapType)reader.GetExpGolombCoded(Attribute.SliceGroupMapType, _sliceGroupMapTypeFormatter); // slice_group_map_type builder.SliceGroupMapType = sliceGroupMapType; switch (sliceGroupMapType) { case SliceGroupMapType.InterleavedSliceGroups: uint[] runLengthMinus1 = new uint[sliceGroupCount]; for (int iGroup = 0; iGroup < sliceGroupCount; iGroup++) { runLengthMinus1[iGroup] = reader.GetExpGolombCoded(); // run_length_minus1[iGroup] } builder.RunLengthMinus1 = runLengthMinus1; break; case SliceGroupMapType.DispersedSliceGroups: break; case SliceGroupMapType.ForegroundAndLeftoverSliceGroups: uint[] topLeft = new uint[sliceGroupCount - 1]; uint[] bottomRight = new uint[sliceGroupCount - 1]; for (int iGroup = 0; iGroup < (sliceGroupCount - 1); iGroup++) { topLeft[iGroup] = reader.GetExpGolombCoded(); bottomRight[iGroup] = reader.GetExpGolombCoded(); } builder.TopLeft = topLeft; builder.BottomRight = bottomRight; break; case SliceGroupMapType.ChangingSliceGroups3: case SliceGroupMapType.ChangingSliceGroups4: case SliceGroupMapType.ChangingSliceGroups5: builder.SliceGroupChangeDirectionFlag = reader.GetBit(); builder.SliceGroupChangeRateMinus1 = reader.GetExpGolombCoded(); break; case SliceGroupMapType.ExplicitSliceGroups: uint pictureSizeInMapUnits = 1 + reader.GetExpGolombCoded(); // pic_size_in_map_units_minus1 int syntaxElementSize = DetectorUtils.Log2(sliceGroupCount - 1) + 1; uint[] sliceGroupId = new uint[pictureSizeInMapUnits]; for (int i = 0; i < pictureSizeInMapUnits; i++) { sliceGroupId[i] = reader.GetBits(syntaxElementSize); } builder.SliceGroupId = sliceGroupId; break; default: resultState.Invalidate(); break; } }
public void Parse(INalUnitReader reader, IResultNodeState resultState) { reader.GetFixedBits(1, 0, Attribute.ForbiddenZeroBit); reader.State.NalRefIdc = reader.GetBits(2, Attribute.NalRefIdc); reader.State.NalUnitType = (NalUnitType)reader.GetBits(5, Attribute.NalUnitType); INalUnitPayloadParser nalUnitPayloadParser; if (!_nalUnitParsers.TryGetValue(reader.State.NalUnitType, out nalUnitPayloadParser)) { resultState.Invalidate(); return; } //Parse remainder with specific nalunitparser (NOTE: Is not a sub-object) nalUnitPayloadParser.Parse(reader, resultState); if (!resultState.Valid) { return; // Stop processing of invalid NAL unit. } if (!CanParseNalUnitType(reader.State.SliceState, reader.State.NalUnitType)) { // Forward to the estimated end of the NAL unit reader.Position = reader.Length; resultState.Invalidate(); // Invalidates the result resultState.Recover(); // Revalidates the reader state so parsing can continue! return; } if (reader.State.NalUnitType == NalUnitType.SequenceParameterSet) { return; // Note: SPS validate their own data! } if (reader.State.NalUnitType == NalUnitType.PictureParameterSet) { return; // Note: PPS validate their own data! } if (!IsSlice(reader.State.NalUnitType) || !reader.State.SliceState.PictureState.EntropyCodingMode) { if (reader.GetBits(1) != 1) // rbsp_stop_one_bit (equal to 1) { resultState.Invalidate(); return; } } if (IsSlice(reader.State.NalUnitType) && resultState.Valid) { return; // Random (e.g. audio) data is allowed after a valid slice } reader.ReadZeroAlignmentBits(); }
private static uint ReadPayloadValue(INalUnitReader reader) { uint value = 0; uint b = reader.GetByte(true); while (b == 0xff) { value += 255; b = reader.GetByte(true); } return(value + b); }
public void Parse(INalUnitReader reader, IResultNodeState resultState) { _sliceHeader.Parse(reader, resultState); if (reader.Position < reader.Length) { reader.Result.AddAttribute(Attribute.HeaderEndPosition, GetAbsoluteOffset(reader)); } _sliceData.Parse(reader, resultState); // Note: slice_trailing_bits() is handled by INalUnitParser }
public void Parse(INalUnitReader reader, IResultNodeState resultState) { resultState.Name = Name; var state = reader.State; if (!state.SequenceStates.Initialized && !state.PictureStates.Initialized) { if (reader.TryDefaultHeaders(resultState, () => _slice.Parse(reader, resultState))) { return; // Slice successfully decoded! } } _slice.Parse(reader, resultState); }
// scaling_list( scalingList, sizeOfScalingList, useDefaultScalingMatrixFlag ) private static void ScalingList(INalUnitReader reader, int[] scalingList, int sizeOfScalingList, bool useDefaultScalingMatrixFlag) { int lastScale = 8; int nextScale = 8; for (int j = 0; j < sizeOfScalingList; j++) { if (nextScale != 0) { uint deltaScale = reader.GetExpGolombCoded(); // delta_scale nextScale = (int)(lastScale + deltaScale + 256) % 256; useDefaultScalingMatrixFlag = (j == 0 && nextScale == 0); } scalingList[j] = (nextScale == 0) ? lastScale : nextScale; lastScale = scalingList[j]; } }
public CavlcSliceData(INalUnitReader reader, IState readerState) { _reader = reader; _readerState = readerState; _sliceState = reader.State.SliceState; _pictureState = _sliceState.PictureState; _sequenceState = _pictureState.SequenceState; _coeffTokenChromaDc = (ChromaFormat == ChromaFormat.YCbCr420) ? CoeffTokenChromaDc420 : CoeffTokenChromaDc422; _lumaCodedCoefficients = new CodedCoefficients(_sliceState, PicHeightInMbs, SubBlockPartition.Luma); _chromaCodedCoefficients = new CodedCoefficients[2]; _subMbTypes = new ISubMacroblockType[4]; SubBlockPartition chromaSubBlockPartition = ChromaArrayTypeSubBlockPartitions[_sequenceState.ChromaFormat.ChromaFormatIdc]; for (int i = 0; i < _chromaCodedCoefficients.Length; i++) { _chromaCodedCoefficients[i] = new CodedCoefficients(_sliceState, PicHeightInMbs, chromaSubBlockPartition); } MbToSliceGroupMap = _mbToSliceGroup.CreateMacroBlockToSliceGroupMap(_sliceState); }
public void Parse(INalUnitReader reader, IResultNodeState resultState) { resultState.Name = Name; uint payloadType = ReadPayloadValue(reader); resultState.AddAttribute(Attribute.PayloadType, payloadType); uint payloadSize = ReadPayloadValue(reader); resultState.AddAttribute(Attribute.PayloadSize, payloadSize); //skip payload for (int i = 0; i < payloadSize; i++) { reader.GetByte(true); } // payload type = (FF)* E5 // payload size = (FF)* 01 // payload = 9C }
public CabacSliceData(INalUnitReader reader, IState readerState) { _reader = reader; _readerState = readerState; _sliceState = reader.State.SliceState; _pictureState = _sliceState.PictureState; _sequenceState = _pictureState.SequenceState; _unavailableMacroblockState = _sliceState.IntraCoded ? MacroblockState.UnavailableIntraCoded : MacroblockState.UnavailableInterCoded; _macroblockStates = new MacroblockState[PicSizeInMbs]; _motionFieldL0 = IsList0Predicted ? new MotionField(_sliceState) : null; _motionFieldL1 = IsList1Predicted ? new MotionField(_sliceState) : null; _subMbTypes = new ISubMacroblockType[4]; _arithmeticDecoder = new ArithmeticDecoder(reader); for (int i = 0; i < _macroblockStates.Length; i++) { _macroblockStates[i] = _unavailableMacroblockState; } MbToSliceGroupMap = _mbToSliceGroup.CreateMacroBlockToSliceGroupMap(_sliceState); }
// 7.3.2.2 PictureState parameter set RBSP syntax public void Parse(INalUnitReader reader, IResultNodeState resultState) { resultState.Name = Name; uint pictureParameterSetId = reader.GetExpGolombCoded(Attribute.PictureParameterSetId, 255 /*7.4.2.2*/); uint sequenceParameterSetId = reader.GetExpGolombCoded(Attribute.SequenceParameterSetId, 31 /*7.4.2.2*/); var sequenceState = reader.State.SequenceStates[sequenceParameterSetId]; if (sequenceState == null) { resultState.Invalidate(); return; } IPictureStateBuilder builder = new PictureStateBuilder(pictureParameterSetId, sequenceState); builder.EntropyCodingMode = reader.GetBit(Attribute.EntropyCodingMode); builder.BottomFieldPicOrderInFramePresentFlag = reader.GetBit(Attribute.PictureOrderPresent); uint numSliceGroupsMinus1 = reader.GetExpGolombCoded(Attribute.NumSliceGroupsMinus1, 7 /*A.2*/); builder.NumSliceGroupsMinus1 = numSliceGroupsMinus1; if (numSliceGroupsMinus1 > 0) { if (sequenceState.Profile == Profile.Main) { resultState.Invalidate(); return; } ParseSliceGroupMap(reader, resultState, builder, (numSliceGroupsMinus1 + 1)); // FIXME: this code contains too many bugs, so it is disabled for now! resultState.Invalidate(); // (end of FIXME) if (!resultState.Valid) { return; } } builder.NumRefIdxL0DefaultActiveMinus1 = reader.GetExpGolombCoded(Attribute.NumRefIdxl0DefaultActiveMinus1, 31 /*7.4.2.2*/); builder.NumRefIdxL1DefaultActiveMinus1 = reader.GetExpGolombCoded(Attribute.NumRefIdxl1DefaultActiveMinus1, 31 /*7.4.2.2*/); builder.WeightedPredFlag = reader.GetBit(Attribute.WeightedPrediction); builder.WeightedBipredIdc = reader.GetBits(2, Attribute.WeightedBidirectionalPrediction, _weightBidirectionalPredictionFormatter); // SliceQPY = 26 + PicInitQpMinus26 + slice_qp_delta int qpBdOffset = (6 * ((int)sequenceState.BitDepthLuma - 8)); builder.PicInitQpMinus26 = reader.GetSignedExpGolombCoded(Attribute.PictureInitialQPyMinus26, -(26 + qpBdOffset), 25); reader.GetSignedExpGolombCoded(Attribute.PictureInitialQSyMinus26, -26, 25); // pic_init_qs_minus26; relative to 26 reader.GetSignedExpGolombCoded(Attribute.ChromaQpIndexOffset, -12, 12); // chroma_qp_index_offset builder.DeblockingFilterControlPresentFlag = reader.GetBit(Attribute.DeblockingFilterControlPresent); reader.GetBit(Attribute.ConstrainedIntraPrediction); // constrained_intra_pred_flag builder.RedundantPicCntPresentFlag = reader.GetBit(Attribute.RedundantPictureControlPresent); // Note: Total size upto this point is between 11 and 59 bits (+ 'slice group map') if (reader.HasMoreRbspData()) // more_rbsp_data() { builder.Transform8X8ModeFlag = reader.GetBit(); // transform_8x8_mode_flag bool picScalingMatrixPresentFlag = reader.GetBit(); //if (picScalingMatrixPresentFlag) // pic_scaling_matrix_present_flag //{ // for (int i = 0; i < 6 + 2 * pictureState.transform_8x8_mode_flag; i++) // { // bool picScalingListPresentFlag = reader.GetBit(); // if (picScalingListPresentFlag) // pic_scaling_list_present_flag[i] // { // if (i < 6) // { // throw new NotImplementedException("scaling_list(ScalingList4x4[i], 16, UseDefaultScalingMatrix4x4Flag[i]);"); // TODO // } // else // { // throw new NotImplementedException("scaling_list(ScalingList8x8[i – 6], 64, UseDefaultScalingMatrix8x8Flag[i – 6]);"); // TODO // } // } // } //} reader.GetSignedExpGolombCoded(); // second_chroma_qp_index_offset } // rbsp_trailing_bits() if (reader.ShowBits(1) == 1) { reader.GetBit(); // rbsp_stop_one_bit (equal to 1) // trailing zero bits } if (resultState.Valid) { reader.State.PictureStates[pictureParameterSetId] = builder.Build(); } }
// 7.3.2.1.1 SequenceState parameter set data syntax public void Parse(INalUnitReader reader, IResultNodeState resultState) { // Constraints from 7.4.2.11 resultState.Name = Name; Profile profileIdc = reader.GetBits(8, Attribute.ProfileIdc, _profileValidator); reader.GetBits(6); // constraint_set{0-5}_flag if (reader.GetBits(2) != 0) // reserved_zero_2bits { resultState.Invalidate(); return; } reader.GetByte(false, Attribute.LevelIdc, 59); // level_idc, Table A-1 - Level limits uint sequenceParameterSetId = reader.GetExpGolombCoded(Attribute.SequenceParameterSetId, 31); ISequenceStateBuilder builder = new SequenceStateBuilder(sequenceParameterSetId); builder.ByteStreamFormat = reader.State.ByteStreamFormat; builder.ProfileIdc = profileIdc; if (IsHighProfile(profileIdc)) { uint chromaFormatIdc = reader.GetExpGolombCoded(Attribute.ChromaFormatIdc, 3); // Table 6-1 builder.ChromaFormatIdc = chromaFormatIdc; if (chromaFormatIdc == 3) { builder.SeparateColourPlaneFlag = reader.GetBit(Attribute.SeparateColorPlaneFlag); } builder.BitDepthLumaMinus8 = reader.GetExpGolombCoded(Attribute.BitDepthLumaArraySampleMinus8, 6); builder.BitDepthChromaMinus8 = reader.GetExpGolombCoded(Attribute.BitDepthChromaArraySampleMinus8, 6); reader.GetBit(); // qpprime_y_zero_transform_bypass_flag if (reader.GetBit()) // seq_scaling_matrix_present_flag { for (int i = 0; i < ((chromaFormatIdc != 3) ? 8 : 12); i++) { if (reader.GetBit()) // seq_scaling_list_present_flag[i] { // FIXME: scaling_list() is not implemented!! resultState.Invalidate(); return; } } } } builder.Log2MaxFrameNumMinus4 = reader.GetExpGolombCoded(Attribute.Log2MaxFrameNumMinus4, 28); DecodePictureOrderCount(reader, builder); uint maxDpbFramesUpperLimit = (profileIdc == Profile.MultiviewHigh) ? 160U : 16U; //could use the exact maxDpbFrames, but this is easier builder.MaxNumRefFrames = reader.GetExpGolombCoded(Attribute.MaxNumberReferenceFrames, maxDpbFramesUpperLimit); reader.GetBit(); // gaps_in_frame_num_value_allowed_flag builder.PicWidthInMbsMinus1 = reader.GetExpGolombCoded(Attribute.PictureWidthInMacroBlocksMinus1, 543); builder.PicHeightInMapUnitsMinus1 = reader.GetExpGolombCoded(Attribute.PictureHeightInMapUnitsMinus1, 543); var frameMbsOnlyFlag = reader.GetBit(Attribute.FrameMbsOnlyFlag); builder.FrameMbsOnlyFlag = frameMbsOnlyFlag; if (!frameMbsOnlyFlag) { builder.MbAdaptiveFrameFieldFlag = reader.GetBit(); } bool direct8X8InferenceFlag = reader.GetBit(); builder.Direct8X8InferenceFlag = direct8X8InferenceFlag; if (!frameMbsOnlyFlag && !direct8X8InferenceFlag) { resultState.Invalidate(); return; } if (reader.GetBit()) // frame_cropping_flag { // TODO: Cropping should not exceed the size of a frame! reader.GetExpGolombCoded(Attribute.FrameCropLeftOffset, 8703); reader.GetExpGolombCoded(Attribute.FrameCropRightOffset, 8703); reader.GetExpGolombCoded(Attribute.FrameCropTopOffset, 8703); reader.GetExpGolombCoded(Attribute.FrameCropBottomOffset, 8703); } if (reader.GetBit()) // vui_parameters_present_flag { GetVuiParameters(reader, resultState); } if (reader.ShowBits(1) == 1) { reader.GetBit(); // rbsp_stop_one_bit (equal to 1) // trailing zero bits } if (resultState.Valid) { reader.State.SequenceStates[sequenceParameterSetId] = builder.Build(); } }
private static void GetVuiParameters(INalUnitReader reader, IResultNodeState resultState) { const byte extendedSar = 255; // Extended_SAR bool aspectRatioInfoPresentFlag = reader.GetBit(); if (aspectRatioInfoPresentFlag) // aspect_ratio_info_present_flag { byte aspectRatioIdc = reader.GetByte(false); if (aspectRatioIdc == extendedSar) // aspect_ratio_idc { reader.GetBits(16); // sar_width reader.GetBits(16); // sar_height } } bool overscanInfoPresentFlag = reader.GetBit(); if (overscanInfoPresentFlag) // overscan_info_present_flag { reader.GetBit(); // overscan_appropriate_flag } bool videoSignalTypePresentFlag = reader.GetBit(); if (videoSignalTypePresentFlag) // video_signal_type_present_flag { reader.GetBits(3); // video_format reader.GetBit(); // video_full_range_flag bool colourDescriptionPresentFlag = reader.GetBit(); if (colourDescriptionPresentFlag) // colour_description_present_flag { reader.GetByte(false); // colour_primaries reader.GetByte(false); // transfer_characteristics reader.GetByte(false); // matrix_coefficients } } bool chromaLocInfoPresentFlag = reader.GetBit(); if (chromaLocInfoPresentFlag) // chroma_loc_info_present_flag { reader.GetExpGolombCoded(); // chroma_sample_loc_type_top_field reader.GetExpGolombCoded(); // chroma_sample_loc_type_bottom_field } bool timingInfoPresentFlag = reader.GetBit(); if (timingInfoPresentFlag) // timing_info_present_flag { reader.GetBits(32); // num_units_in_tick reader.GetBits(32); // time_scale reader.GetBit(); // fixed_frame_rate_flag } bool nalHrdParametersPresentFlag = reader.GetBit(); if (nalHrdParametersPresentFlag) //nal_hrd_parameters_present_flag { GetHrdParameters(reader, resultState); // hrd_parameters() } bool vclHrdParametersPresentFlag = reader.GetBit(); if (vclHrdParametersPresentFlag) // vcl_hrd_parameters_present_flag { GetHrdParameters(reader, resultState); // hrd_parameters() } if (nalHrdParametersPresentFlag || vclHrdParametersPresentFlag) { reader.GetBit(); // low_delay_hrd_flag } reader.GetBit(); // pic_struct_present_flag bool bitstreamRestrictionFlag = reader.GetBit(); if (bitstreamRestrictionFlag) // bitstream_restriction_flag { reader.GetBit(); // motion_vectors_over_pic_boundaries_flag reader.GetExpGolombCoded(); // max_bytes_per_pic_denom reader.GetExpGolombCoded(); // max_bits_per_mb_denom reader.GetExpGolombCoded(); // log2_max_mv_length_horizontal reader.GetExpGolombCoded(); // log2_max_mv_length_vertical reader.GetExpGolombCoded(); // num_reorder_frames reader.GetExpGolombCoded(); // max_dec_frame_buffering } }
public void Parse(INalUnitReader reader, IResultNodeState resultState) { resultState.Name = Name; }