コード例 #1
0
        private int[] WipeSliceGroupMapTypes(IPictureState pictureState, uint mapUnitsInSliceGroup0)
        {
            var  picSizeInMapUnits      = pictureState.SequenceState.PicSizeInMapUnits;
            var  mapUnitToSliceGroupMap = new int[picSizeInMapUnits];
            var  picWidthInMbs          = pictureState.SequenceState.PicWidthInMbs;
            var  picHeightInMapUnits    = pictureState.SequenceState.PicHeightInMapUnits;
            long sizeOfUpperLeftGroup   = pictureState.SliceGroupChangeDirectionFlag
                                                                                ? (pictureState.SequenceState.PicSizeInMapUnits - mapUnitsInSliceGroup0) : mapUnitsInSliceGroup0;
            var sliceGroupChangeDirectionFlag = pictureState.SliceGroupChangeDirectionFlag ? 1 : 0;             //0=right, 1=left
            int k = 0;

            for (int j = 0; j < picWidthInMbs; j++)
            {
                for (int i = 0; i < picHeightInMapUnits; i++)
                {
                    if (k++ < sizeOfUpperLeftGroup)
                    {
                        mapUnitToSliceGroupMap[i * picWidthInMbs + j] = sliceGroupChangeDirectionFlag;
                    }
                    else
                    {
                        mapUnitToSliceGroupMap[i * picWidthInMbs + j] = 1 - sliceGroupChangeDirectionFlag;
                    }
                }
            }
            return(mapUnitToSliceGroupMap);
        }
コード例 #2
0
        private int[] ForegroundWithLeftOverSliceGroupMapType(IPictureState pictureState)
        {
            var picSizeInMapUnits      = pictureState.SequenceState.PicSizeInMapUnits;
            var mapUnitToSliceGroupMap = new int[picSizeInMapUnits];
            var sliceGroupCount        = pictureState.SliceGroupCount;
            var picWidthInMbs          = pictureState.SequenceState.PicWidthInMbs;
            var topLeft     = pictureState.TopLeft;
            var bottomRight = pictureState.BottomRight;

            for (int i = 0; i < picSizeInMapUnits; i++)
            {
                mapUnitToSliceGroupMap[i] = (int)sliceGroupCount - 1;
            }
            for (int iGroup = (int)sliceGroupCount; iGroup >= 0; iGroup--)
            {
                uint yTopLeft     = topLeft[iGroup] / picWidthInMbs;
                uint xTopLeft     = topLeft[iGroup] % picWidthInMbs;
                uint yBottomRight = bottomRight[iGroup] / picWidthInMbs;
                uint xBottomRight = bottomRight[iGroup] % picWidthInMbs;
                for (uint y = yTopLeft; y <= yBottomRight; y++)
                {
                    for (uint x = xTopLeft; x <= xBottomRight; x++)
                    {
                        mapUnitToSliceGroupMap[y * picWidthInMbs + x] = iGroup;
                    }
                }
            }
            return(mapUnitToSliceGroupMap);
        }
コード例 #3
0
        public void Parse(IMpeg2VideoReader reader, IResultNodeState resultState)
        {
            IPictureState pictureState = reader.State.Picture;

            resultState.Name = Name;

            // It can occur after the last slice of the previous picture or after a sequence header
            // or group of pictures header, possible followed by user data and/or extensions.
            if ((reader.State.LastHeaderName != Slice.Name) && pictureState.Initialized)
            {
                resultState.Invalidate();
                return;
            }
            if (!reader.State.Sequence.Initialized && !reader.State.SeenGop)
            {
                reader.InsertReferenceHeaderBeforeStartCode();
            }

            pictureState.Reset();
            reader.State.Slice.Reset();

            reader.GetBits(10, Attribute.TemporalReference);
            var pictureCodingType = (PictureCodingType)reader.GetBits(3, Attribute.PictureCodingType, _pictureCodingTypeResultFormatter);

            pictureState.CodingType = pictureCodingType;
            reader.GetBits(16, Attribute.VbvDelay);

            if ((pictureCodingType == PictureCodingType.PType) || (pictureCodingType == PictureCodingType.BType))
            {
                reader.GetFlag(Attribute.FullPelForwardVector);

                byte forwardFCode = (byte)reader.GetBits(3, Attribute.ForwardFCode);
                pictureState.ForwardHorizontalFCode = forwardFCode;
                pictureState.ForwardVerticalFCode   = forwardFCode;
            }
            if (pictureCodingType == PictureCodingType.BType)
            {
                reader.GetFlag(Attribute.FullPelBackwardVector);

                byte backwardFCode = (byte)reader.GetBits(3, Attribute.BackwardFCode);
                pictureState.BackwardHorizontalFCode = backwardFCode;
                pictureState.BackwardVerticalFCode   = backwardFCode;
            }

            int  count = 0;             // Sanity check
            uint maxExtraInformationLength = reader.State.Configuration.PictureHeaderMaxLengthOfExtraInformation;

            while (reader.ShowBits(1) == 1)
            {
                reader.GetBits(1);                              // ExtraBitPicture
                reader.GetBits(8);                              // ExtraInformationPicture

                if (count++ > maxExtraInformationLength)
                {
                    resultState.Invalidate();
                    return;
                }
            }
        }
コード例 #4
0
        public Mpeg2VideoState(IMpeg2VideoConfiguration configuration, ISequenceState sequenceState, IPictureState pictureState, ISliceState sliceState)
        {
            _configuration = configuration;
            _sequenceState = sequenceState;
            _pictureState  = pictureState;
            _sliceState    = sliceState;

            Reset();
        }
コード例 #5
0
        private int[] ExplicitSliceGroupMapType(IPictureState pictureState)
        {
            var picSizeInMapUnits      = pictureState.SequenceState.PicSizeInMapUnits;
            var mapUnitToSliceGroupMap = new int[picSizeInMapUnits];

            uint[] sliceGroupId = pictureState.SliceGroupId;
            for (int i = 0; i < picSizeInMapUnits; i++)
            {
                mapUnitToSliceGroupMap[i] = (int)sliceGroupId[i % sliceGroupId.Length];
            }
            return(mapUnitToSliceGroupMap);
        }
コード例 #6
0
        private int[] DispersedSliceGroupMapType(IPictureState pictureState)
        {
            var picSizeInMapUnits      = pictureState.SequenceState.PicSizeInMapUnits;
            var mapUnitToSliceGroupMap = new int[picSizeInMapUnits];
            var sliceGroupCount        = pictureState.SliceGroupCount;
            var picWidthInMbs          = pictureState.SequenceState.PicWidthInMbs;

            for (int i = 0; i < picSizeInMapUnits; i++)
            {
                mapUnitToSliceGroupMap[i] = (int)((int)((i % picWidthInMbs) +
                                                        (((i / picWidthInMbs) * sliceGroupCount) / 2))
                                                  % (sliceGroupCount));
            }
            return(mapUnitToSliceGroupMap);
        }
コード例 #7
0
        private int[] InterleavedSliceGroupMapType(IPictureState pictureState)
        {
            var picSizeInMapUnits      = pictureState.SequenceState.PicSizeInMapUnits;
            var mapUnitToSliceGroupMap = new int[picSizeInMapUnits];
            var sliceGroupCount        = pictureState.SliceGroupCount;
            var runLengthMinus1        = pictureState.RunLengthMinus1;
            int i = 0;

            do
            {
                for (int iGroup = 0; iGroup < sliceGroupCount && i < picSizeInMapUnits; i += (int)runLengthMinus1[iGroup++] + 1)
                {
                    for (int j = 0; j <= runLengthMinus1[iGroup] && i + j < picSizeInMapUnits; j++)
                    {
                        mapUnitToSliceGroupMap[i + j] = iGroup;
                    }
                }
            } while (i < picSizeInMapUnits);
            return(mapUnitToSliceGroupMap);
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        private int[] RasterScanSliceGroupMapTypes(IPictureState pictureState, uint mapUnitsInSliceGroup0)
        {
            var  picSizeInMapUnits      = pictureState.SequenceState.PicSizeInMapUnits;
            var  mapUnitToSliceGroupMap = new int[picSizeInMapUnits];
            long sizeOfUpperLeftGroup   = pictureState.SliceGroupChangeDirectionFlag
                                                                                ? (pictureState.SequenceState.PicSizeInMapUnits - mapUnitsInSliceGroup0) : mapUnitsInSliceGroup0;
            var sliceGroupChangeDirectionFlag = pictureState.SliceGroupChangeDirectionFlag ? 1 : 0;             //0=normal, 1= reverse

            for (int i = 0; i < picSizeInMapUnits; i++)
            {
                if (i < sizeOfUpperLeftGroup)
                {
                    mapUnitToSliceGroupMap[i] = sliceGroupChangeDirectionFlag;
                }
                else
                {
                    mapUnitToSliceGroupMap[i] = 1 - sliceGroupChangeDirectionFlag;
                }
            }
            return(mapUnitToSliceGroupMap);
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        public void Parse(IMpeg2VideoReader reader, IResultNodeState resultState)
        {
            resultState.Name = Name;

            if (reader.State.LastHeaderName != PictureHeader.Name)
            {
                resultState.Invalidate();
                return;                 // Invalid header sequence
            }

            IPictureState pictureState = reader.State.Picture;

            pictureState.ForwardHorizontalFCode  = (byte)reader.GetBits(4, Attribute.ForwardHorizontalFCode);
            pictureState.ForwardVerticalFCode    = (byte)reader.GetBits(4, Attribute.ForwardVerticalFCode);
            pictureState.BackwardHorizontalFCode = (byte)reader.GetBits(4, Attribute.BackwardHorizontalFCode);
            pictureState.BackwardVerticalFCode   = (byte)reader.GetBits(4, Attribute.BackwardVerticalFCode);
            reader.GetBits(2, Attribute.IntraDCPrecision);
            pictureState.Structure                = (PictureStructure)reader.GetBits(2, Attribute.PictureStructure, _pictureStructureResultFormatter);
            pictureState.TopFieldFirst            = reader.GetFlag(Attribute.TopFieldFirst);
            pictureState.FramePredFrameDct        = reader.GetFlag(Attribute.FramePredFrameDct);
            pictureState.ConcealmentMotionVectors = reader.GetFlag(Attribute.ConcealmentMotionVectors);
            reader.GetBits(1, Attribute.QuantiserScaleType);
            pictureState.IntraVlcFormat = (reader.GetBits(1, Attribute.IntraVlcFormat) == 0) ? false : true;
            reader.GetFlag(Attribute.AlternateScan);
            pictureState.RepeatFirstField = reader.GetFlag(Attribute.RepeatFirstField);
            reader.GetFlag(Attribute.Chroma420Type);
            reader.GetFlag(Attribute.ProgressiveFrame);

            if (reader.GetFlag(Attribute.CompositeDisplayFlag))
            {
                reader.GetBits(1, Attribute.VAxis);
                reader.GetBits(3, Attribute.FieldSequence);
                reader.GetBits(1, Attribute.SubCarrier);
                reader.GetBits(7, Attribute.BurstAmplitude);
                reader.GetBits(8, Attribute.SubCarrierPhase);
            }
        }
コード例 #12
0
 public SliceStateBuilder(IPictureState pictureState)
 {
     PictureState = pictureState;
 }
コード例 #13
0
        private static bool IsNonIntraSliceInIntraCodedPicture(INalUnitReader reader, SliceType sliceType, IPictureState pictureState)
        {
            if ((reader.State.NalUnitType != NalUnitType.CodedSliceOfAnIdrPicture) && (pictureState.SequenceState.MaxNumRefFrames > 0))
            {
                return(false);                // Not an intra coded picture
            }

            // Check that the slice type indicates an inter coded slice
            return(!IsIntraCoded(sliceType));
        }
コード例 #14
0
        public IMbToSliceGroupMap CreateMacroBlockToSliceGroupMap(ISliceState sliceState)
        {
            IPictureState  pictureState = sliceState.PictureState;
            ISequenceState sequence     = sliceState.PictureState.SequenceState;

            uint picSizeInMapUnits     = sequence.PicSizeInMapUnits;
            uint sliceGroupChangeRate  = pictureState.SliceGroupChangeRate;
            uint mapUnitsInSliceGroup0 = Math.Min(sliceState.SliceGroupChangeCycle * sliceGroupChangeRate, picSizeInMapUnits);

            int[] mapUnitToSliceGroupMap;
            if (pictureState.SliceGroupCount == 1)
            {
                return(new SingleSliceGroupMap());
            }
            // num_slice_groups_minus1 is not equal to 0
            switch (pictureState.SliceGroupMapType)
            {
            case SliceGroupMapType.InterleavedSliceGroups:
                mapUnitToSliceGroupMap = InterleavedSliceGroupMapType(pictureState);
                break;

            case SliceGroupMapType.DispersedSliceGroups:
                mapUnitToSliceGroupMap = DispersedSliceGroupMapType(pictureState);
                break;

            case SliceGroupMapType.ForegroundAndLeftoverSliceGroups:
                mapUnitToSliceGroupMap = ForegroundWithLeftOverSliceGroupMapType(pictureState);
                break;

            case SliceGroupMapType.ChangingSliceGroups3:
                mapUnitToSliceGroupMap = BoxOutSliceGroupMapTypes(pictureState, mapUnitsInSliceGroup0);
                break;

            case SliceGroupMapType.ChangingSliceGroups4:
                mapUnitToSliceGroupMap = RasterScanSliceGroupMapTypes(pictureState, mapUnitsInSliceGroup0);
                break;

            case SliceGroupMapType.ChangingSliceGroups5:
                mapUnitToSliceGroupMap = WipeSliceGroupMapTypes(pictureState, mapUnitsInSliceGroup0);
                break;

            case SliceGroupMapType.ExplicitSliceGroups:
                mapUnitToSliceGroupMap = ExplicitSliceGroupMapType(pictureState);
                break;

            default:
                throw new InvalidOperationException();
            }
            if (sequence.FrameMbsOnlyFlag || sliceState.FieldPicFlag)
            {
                return(new OneMacroblockPerSliceGroupMap(mapUnitToSliceGroupMap));
            }

            if (sequence.MbAdaptiveFrameFieldFlag)             // mb_adaptive_frame_field_flag && !FieldPicFlag
            {
                return(new TwoMacroblocksPerSliceGroupMap(mapUnitToSliceGroupMap));
            }

            // if (!sequence.FrameMbsOnlyFlag && !sequence.MbAdaptiveFrameFieldFlag && !sliceState.FieldPicFlag)
            return(new OverlappingMbToSliceGroupMap(mapUnitToSliceGroupMap, sequence.PicWidthInMbs));
        }
コード例 #15
0
        private int[] BoxOutSliceGroupMapTypes(IPictureState pictureState, uint mapUnitsInSliceGroup0)
        {
            var picSizeInMapUnits      = pictureState.SequenceState.PicSizeInMapUnits;
            var mapUnitToSliceGroupMap = new int[picSizeInMapUnits];
            var picWidthInMbs          = pictureState.SequenceState.PicWidthInMbs;
            var picHeightInMapUnits    = pictureState.SequenceState.PicHeightInMapUnits;

            for (int i = 0; i < picSizeInMapUnits; i++)
            {
                mapUnitToSliceGroupMap[i] = 1;
            }
            var sliceGroupChangeDirectionFlag = pictureState.SliceGroupChangeDirectionFlag ? 1 : 0;             //1=counter-clockwise, 0=clockwise
            int x = (int)(picWidthInMbs - sliceGroupChangeDirectionFlag) / 2;
            int y = (int)(picHeightInMapUnits - sliceGroupChangeDirectionFlag) / 2;
            // ( leftBound, topBound ) = ( x, y );
            int leftBound = x;
            int topBound  = y;
            // ( rightBound, bottomBound ) = ( x, y );
            int rightBound  = x;
            int bottomBound = y;
            //( xDir, yDir ) = ( SliceGroupChangeDirectionFlag - 1, SliceGroupChangeDirectionFlag );
            int  xDir = sliceGroupChangeDirectionFlag - 1;
            int  yDir = sliceGroupChangeDirectionFlag;
            bool mapUnitVacant;

            for (int k = 0; k < mapUnitsInSliceGroup0; k += mapUnitVacant ? 1 : 0)
            {
                mapUnitVacant = (mapUnitToSliceGroupMap[y * picWidthInMbs + x] == 1);
                if (mapUnitVacant)
                {
                    mapUnitToSliceGroupMap[y * picWidthInMbs + x] = 0;
                }
                if (xDir == -1 && x == leftBound)
                {
                    leftBound = Math.Max(leftBound - 1, 0);
                    x         = leftBound;
                    //( xDir, yDir ) = ( 0, 2 * SliceGroupChangeDirectionFlag – 1 )
                    xDir = 0;
                    yDir = 2 * sliceGroupChangeDirectionFlag - 1;
                }
                else if (xDir == 1 && x == rightBound)
                {
                    rightBound = (int)Math.Min(rightBound + 1, picWidthInMbs - 1);
                    x          = rightBound;
                    //( xDir, yDir ) = ( 0, 1 – 2 * SliceGroupChangeDirectionFlag )
                    xDir = 0;
                    yDir = 1 - 2 * sliceGroupChangeDirectionFlag;
                }
                else if (yDir == -1 && y == topBound)
                {
                    topBound = Math.Max(topBound - 1, 0);
                    y        = topBound;
                    //( xDir, yDir ) = ( 1 – 2 * SliceGroupChangeDirectionFlag, 0 );
                    xDir = 1 - 2 * sliceGroupChangeDirectionFlag;
                    yDir = 0;
                }
                else if (yDir == 1 && y == bottomBound)
                {
                    bottomBound = (int)Math.Min(bottomBound + 1, picHeightInMapUnits - 1);
                    y           = bottomBound;
                    //( xDir, yDir ) = ( 2 * SliceGroupChangeDirectionFlag – 1, 0 );
                    xDir = 2 * sliceGroupChangeDirectionFlag - 1;
                    yDir = 0;
                }
                else
                {
                    //( x, y ) = ( x + xDir, y + yDir );
                    x = x + xDir;
                    y = y + yDir;
                }
            }
            return(mapUnitToSliceGroupMap);
        }