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 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;
            }
        }
Exemple #3
0
        public void Parse()
        {
            _currMbAddr         = _sliceState.FirstMacroBlockInSlice * (MbAffFrameFlag ? 2U : 1U);
            MbFieldDecodingFlag = _sliceState.FieldPicFlag;             // The default for non-MBAFF frames

            bool moreDataFlag  = true;
            bool prevMbSkipped = false;

            while (_readerState.Valid && moreDataFlag)
            {
                if (!_sliceState.IntraCoded)
                {
                    uint mbSkipRun = _reader.GetExpGolombCoded();
                    prevMbSkipped = (mbSkipRun > 0);

                    if (mbSkipRun > 0)
                    {
                        for (uint i = 0; i < (mbSkipRun - 1); i++)
                        {
                            UpdateSkippedMacroblockPrediction();
                            NextMbAddress();

                            if (!_readerState.Valid)
                            {
                                return;                                 //Could not find expected macroblock
                            }
                        }

                        moreDataFlag = HasMoreRbspData();
                        if (moreDataFlag)
                        {
                            // Skip the last block
                            UpdateSkippedMacroblockPrediction();
                            NextMbAddress();

                            if (!_readerState.Valid)
                            {
                                return;                                 //Could not find expected macroblock
                            }
                        }
                    }
                }
                if (moreDataFlag)
                {
                    if (MbAffFrameFlag && (IsFirstMacroblockInPair() || prevMbSkipped))
                    {
                        MbFieldDecodingFlag = _reader.GetBit();                         // is field macro block
                    }

                    MacroBlockLayer();

                    moreDataFlag = HasMoreRbspData();
                }
                if (moreDataFlag)
                {
                    NextMbAddress();
                }
            }
        }
        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;
            }
        }
        // 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];
            }
        }
        // 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
            }
        }